/*
  Priority4 Go demo consolidated stylesheet.
  Generated from former demo page-level CSS files and inline PHP style blocks.
*/



/* ==========================================================================
   Source: demo/assets/css/index.css
   ========================================================================== */

/* ============================================================================
 * index.css
 * ----------------------------------------------------------------------------
 * App shell / chrome for /response/index.php. Extracted from the inline
 * <style> block; restyled in Liquid Glass.
 *
 * What's in here:
 *   - Font-size root rules (moved from <style id="fn-fontsize-rules">)
 *   - Top chrome wrapper, hero header, hero ID pills, hamburger menu
 *   - Status bar (with new response-count chips on the right half)
 *   - Pull-to-refresh circle
 *   - Tabbar (frosted glass, strongest blur — most-seen surface)
 *   - Page host & page transitions
 *   - Off-canvas drawer (frosted glass strong, modal-like)
 *   - Desktop boxed-layout media query
 *   - Mobile correction media queries
 *
 * Token sources (read-only — defined in liquid-glass.css):
 *   --fn-* : brand / surface / text
 *   --lg-* : glass material (surface, edge, divider, blur, shadow, radius)
 *
 * Load AFTER liquid-glass.css.
 * ========================================================================= */


/* ─────────────────────────────────────────────────────────────────────────
 * Font-size rules (root). Settings JS toggles data-fn-fontsize on <html>;
 * we never modify these via JS, so they live here permanently.
 * ──────────────────────────────────────────────────────────────────────── */
html { font-size: 18.4px !important; }
html[data-fn-fontsize="standard"] { font-size: 18.4px !important; }
html[data-fn-fontsize="large"]    { font-size: 20px !important; }
html[data-fn-fontsize="xlarge"]   { font-size: 22px !important; }
body { font-size: 1rem !important; }


/* ─────────────────────────────────────────────────────────────────────────
 * Top chrome wrapper — pins the hero + status bar to the top of the
 * viewport. The hero stays a solid brand colour (Liquid Glass keeps hero
 * surfaces solid for identity); only the status bar below uses glass.
 * ──────────────────────────────────────────────────────────────────────── */
/* ─────────────────────────────────────────────────────────────────────────
 * Top chrome wrapper — floating island matching the tabbar.
 *
 *   - Detached from screen edges with margin all around (0.65rem sides,
 *     0.45rem from the safe-area). Stays BELOW the iOS status bar area
 *     so time/wifi/battery render normally over the body backdrop.
 *   - Hero gets ALL FOUR corners at --lg-r-md (1rem). Standard floating-
 *     island roundness, symmetric with the tabbar at the bottom.
 *   - Status bar sits INSIDE the wrapper, below the hero, transparent
 *     — badge + chips float as individual glass tiles.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-top-chrome {
    position: fixed;
    top:   calc(var(--fn-safe-top) + 0.45rem);
    left:  0.3rem;
    right: 0.3rem;
    z-index: 50;
}

.fn-hero {
    background: var(--fn-header-bg);
    color: #fff;
    /* All four corners at the same moderate radius — symmetric with
       the tabbar's floating-island feel. */
    border-radius: var(--lg-r-md);
    box-shadow: 0 14px 36px -10px rgba(0,0,0,.28),
                0 4px 12px -4px rgba(0,0,0,.14);
    overflow: hidden;
    transition: background .25s ease;
}

.fn-hero-inner {
    /* Horizontal padding 0.55rem — bell icon (left) and ff_no/station
       badge (right) sit equally inset from the chrome edges. Tuned
       up from 0.35rem on user feedback: the button + station were
       too close to the chrome edge before. */
    padding: .85rem .55rem 1rem;
    display: flex;
    flex-direction: column;
}

.fn-hero-row1 {
    display: flex;
    align-items: center;
    gap: .55rem;
    min-width: 0;
}

.fn-hero-icon {
    width: 2.1rem;
    height: 2.1rem;
    border-radius: .5rem;
    background: rgba(255,255,255,.18);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    flex-shrink: 0;
    border: 0;
    padding: 0;
    cursor: pointer;
    font-family: inherit;
    color: inherit;
    transition: filter .12s ease, transform .1s ease;
}
.fn-hero-icon:active {
    transform: scale(.92);
    filter: brightness(.85);
}

.fn-hero-brand-wrap {
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
}
.fn-hero-brand {
    font-weight: 800;
    color: #fff;
    font-size: 1.1rem;
    line-height: 1;
    letter-spacing: -.01em;
}
.fn-hero-subtitle {
    font-size: .74rem;
    opacity: .9;
    line-height: 1;
    margin-top: .22rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fn-hero-id {
    margin-left: auto;
    flex-shrink: 0;
    background: rgba(255,255,255,.16);
    border-radius: var(--lg-r-sm);
    display: inline-flex;
    align-items: center;
    overflow: hidden;
    line-height: 1;
}
.fn-hero-id-cell {
    padding: .42rem .65rem;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-weight: 700;
    font-size: .8rem;
    color: #fff;
    white-space: nowrap;
}
.fn-hero-id-cell + .fn-hero-id-cell {
    border-left: 1px solid rgba(255,255,255,.18);
}
.fn-hero-id-cell .mdi {
    font-size: .95rem;
    opacity: .85;
}

@media (max-width: 380px) {
    .fn-hero-subtitle {
        display: none;
    }
}


/* ─────────────────────────────────────────────────────────────────────────
 * STATUS BAR removed — the "Awaiting response" badge and per-type count
 * chips that used to live in a strip below the hero are now rendered
 * inside each call card (see .fn-call-myresp in home.css). The hero is
 * the only thing in .fn-top-chrome now, which is why --fn-top-chrome-h
 * dropped from 11rem to 5rem in liquid-glass.css.
 * ──────────────────────────────────────────────────────────────────────── */


/* ─────────────────────────────────────────────────────────────────────────
 * Pull-to-refresh circle — floats below the chrome on pull.
 * Strong frosted glass so it stands out against any page content.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-ptr-circle {
    position: fixed;
    top: calc(var(--fn-top-chrome-h) + .25rem);
    left: 50%;
    z-index: 60;
    width: 3.5rem;
    height: 3.5rem;
    margin-left: -1.75rem;
    border-radius: 50%;
    background-color: var(--lg-surface-strong);
    backdrop-filter: var(--lg-blur-strong);
    -webkit-backdrop-filter: var(--lg-blur-strong);
    border: 1px solid var(--lg-edge-strong);
    box-shadow: var(--lg-shadow-strong);
    color: var(--fn-text);
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    transform: translateY(-5rem) scale(.85);
    opacity: 0;
    transition: transform .25s cubic-bezier(.2,.8,.2,1), opacity .2s ease;
}
.fn-ptr-circle.armed { transition: none; }
.fn-ptr-circle.refreshing {
    transform: translateY(.35rem) scale(1);
    opacity: 1;
}
.fn-ptr-circle .mdi {
    font-size: 1.7rem;
    transition: transform .25s ease, opacity .2s ease;
}
.fn-ptr-circle.ready .mdi.fn-ptr-arrow {
    transform: rotate(180deg);
    color: #198754;
}
.fn-ptr-circle .fn-ptr-spin {
    display: none;
    animation: fnPtrSpin .9s linear infinite;
}
.fn-ptr-circle.refreshing .fn-ptr-arrow { display: none; }
.fn-ptr-circle.refreshing .fn-ptr-spin  { display: inline-block; }

@keyframes fnPtrSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}


/* ─────────────────────────────────────────────────────────────────────────
 * TABBAR — floating glass island
 *
 * Treatment:
 *   - Detached from screen edges (small margin all around) so it reads
 *     as a floating shelf rather than a pinned bar.
 *   - Fully rounded corners, strong frosted glass, top-edge specular
 *     highlight, layered drop shadow underneath.
 *   - Active tab gets a soft glass pill BEHIND its icon+label. Pill is
 *     always rendered (every tab has a ::before) but starts at opacity 0;
 *     adding .active fades it in. This means tab-to-tab transitions
 *     animate smoothly instead of jumping.
 *   - Replaces the old 3px line-on-top indicator entirely.
 *
 * Mobile-only — desktop layout still has `.fn-tabbar { display: none }`
 * in the @media (hover: hover) block further down.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-tabbar {
    position: fixed;
    left:   0.65rem;
    right:  0.65rem;
    bottom: calc(var(--fn-safe-bottom) + 0.45rem);
    z-index: 100;
    height: var(--fn-tabbar-h);

    background-color: var(--lg-tabbar-surface);
    backdrop-filter: var(--lg-blur-strong);
    -webkit-backdrop-filter: var(--lg-blur-strong);
    border: 1px solid var(--lg-edge);
    /* All four corners at the same moderate-pill radius. */
    border-radius: 1.75rem;
    box-shadow: var(--lg-tabbar-shadow);
    overflow: hidden;
    isolation: isolate;

    display: grid;
    grid-template-columns: repeat(5, 1fr);
    transition: background-color .25s ease, border-color .25s ease;
}

/* Removed the ::after specular highlight — in dark mode it created a
   "reflection" line at the top of the tabbar that looked artificial.
   Light mode also reads cleaner without it now that the surface is
   more translucent and the body backdrop provides natural variation. */

.fn-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .2rem;
    background: transparent;
    border: 0;
    color: var(--fn-tabbar-text);
    cursor: pointer;
    padding: .4rem .25rem;
    font-family: inherit;
    transition: color .18s var(--lg-ease), transform .12s var(--lg-ease);
    position: relative;
    z-index: 1;
}
.fn-tab:active { transform: scale(.95); }

/* Active pill — rendered on every tab, faded in only when .active.
   Inset slightly inside the tab cell so adjacent active pills wouldn't
   touch even if both somehow rendered. Soft inner highlight + soft
   shadow underneath sells the "small floating chip" feel. */
.fn-tab::before {
    content: '';
    position: absolute;
    top:    0.32rem;
    bottom: 0.32rem;
    left:   0.28rem;
    right:  0.28rem;
    /* Radius chosen so the pill's outer corners curve concentrically
       with the tabbar's outer corners. Tabbar = 1.75rem; pill is
       inset ~0.30rem from the tab edge; concentric → 1.75 - 0.30
       = 1.45rem. Makes the active tab read as "nested inside" the
       tabbar shape rather than a smaller pill stuck in a bigger one. */
    border-radius: 1.45rem;
    background-color: var(--lg-tabbar-pill-bg);
    box-shadow: var(--lg-tabbar-pill-shadow);
    opacity: 0;
    transform: scale(0.92);
    transition: opacity .22s var(--lg-ease),
                transform .28s var(--lg-spring);
    z-index: -1;
    pointer-events: none;
}
.fn-tab.active::before {
    opacity: 1;
    transform: scale(1);
}
.fn-tab.active {
    color: var(--lg-tabbar-pill-fg);
}

.fn-tab .mdi {
    /* Was 1.7rem. Shrunk to 1.5rem on user feedback that the active
       pill's content felt too close to the pill edges, especially
       on dark tabbar colours where the pill background is most
       visible. Smaller icon = more breathing inside the pill. */
    font-size: 1.5rem;
    line-height: 1;
    transition: transform .18s var(--lg-ease);
}
.fn-tab.active .mdi {
    transform: scale(1.05);
}
.fn-tab .label {
    /* Was 0.72rem. Shrunk to 0.65rem so the wider labels ("Preplan",
       "Settings") have visible inset from pill edges. */
    font-size: .65rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: .02em;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Page host & per-page transitions
 * ──────────────────────────────────────────────────────────────────────── */
.fn-page-host {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    padding-top: calc(var(--fn-safe-top) + 0.45rem + var(--fn-top-chrome-h) + 0.5rem);
    padding-bottom: calc(var(--fn-tabbar-h) + var(--fn-safe-bottom) + 1.5rem);
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}
.fn-page {
    display: none;
    opacity: 0;
    transition: opacity .25s ease-in-out;
}
.fn-page.active {
    display: block;
    opacity: 1;
}
.fn-page.fn-page--full.active {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--fn-safe-top) - var(--fn-top-chrome-h) - var(--fn-tabbar-h) - var(--fn-safe-bottom) - 2.4rem);
    min-height: 20rem;
}
.fn-page-inner {
    /* Padding-x 0.85rem matches:
       (a) the hero content position (chrome left 0.3rem + hero-inner
           pad 0.55rem = 0.85rem from screen)
       (b) the address stage's .fn-addr-stage horizontal padding
       So home/crew/preplan/settings content sits at exactly the same
       horizontal alignment as everything else.

       max-width REMOVED. Was 640px which constrained content to ~63%
       of an iPad screen — the address page (page--full) skips
       page-inner and fills the full page-host width, making it visibly
       wider than the others. Letting page-inner inherit page-host's
       natural width brings parity.

       width: 100% + box-sizing: border-box is defensive — when this
       element is also a flex item with display: flex (as on the preplan
       root), Safari iPadOS was resolving the cross-axis width to
       content-size instead of stretching to fill, leaving content
       centred narrow. Explicit width forces full-width regardless of
       flex resolution. */
    padding: .2rem .85rem;
    margin: 0 auto;
    width: 100%;
    box-sizing: border-box;
}
.fn-page-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem 1rem;
    color: var(--fn-text-muted);
}
.fn-page-loading .mdi {
    font-size: 2rem;
    opacity: .4;
    margin-bottom: .4rem;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Hamburger button — only visible on desktop layout.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-hero-menu-btn {
    display: none;
    background: rgba(255, 255, 255, .18);
    border: 0;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: .5rem;
    color: #fff;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    flex-shrink: 0;
    padding: 0;
    transition: transform .1s ease, background .15s ease;
}
.fn-hero-menu-btn .mdi { line-height: 1; }
.fn-hero-menu-btn:hover  { background: rgba(255, 255, 255, .25); }
.fn-hero-menu-btn:active { transform: scale(.95); }


/* ─────────────────────────────────────────────────────────────────────────
 * Off-canvas drawer — sheet-like, strong frosted glass.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-offcanvas[hidden] { display: none; }
.fn-offcanvas {
    position: fixed;
    inset: 0;
    z-index: 200;
}
.fn-offcanvas-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .55);
    opacity: 0;
    transition: opacity .2s ease;
}
.fn-offcanvas.is-open .fn-offcanvas-backdrop { opacity: 1; }

.fn-offcanvas-panel {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 280px;
    max-width: 80vw;
    background-color: var(--lg-surface-strong);
    backdrop-filter: var(--lg-blur-strong);
    -webkit-backdrop-filter: var(--lg-blur-strong);
    border-right: 1px solid var(--lg-edge);
    box-shadow: var(--lg-shadow-strong);
    transform: translateX(-100%);
    transition: transform .25s ease;
    display: flex;
    flex-direction: column;
}
.fn-offcanvas.is-open .fn-offcanvas-panel {
    transform: translateX(0);
}
.fn-offcanvas-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1rem 1rem 1.25rem;
    border-bottom: 1px solid var(--lg-divider);
}
.fn-offcanvas-title {
    font-weight: 800;
    color: var(--fn-text);
    font-size: 1.05rem;
    letter-spacing: .01em;
}
.fn-offcanvas-close {
    background: transparent;
    border: 0;
    padding: .25rem;
    color: var(--fn-text);
    cursor: pointer;
    font-size: 1.6rem;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: .4rem;
    transition: background .15s ease;
}
.fn-offcanvas-close:hover { background: var(--lg-hover); }

.fn-offcanvas-nav {
    display: flex;
    flex-direction: column;
    padding: .5rem;
    gap: .15rem;
    overflow-y: auto;
}
.fn-offcanvas-link {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .75rem .9rem;
    border-radius: var(--lg-r-sm);
    border: 0;
    background: transparent;
    color: var(--fn-text);
    cursor: pointer;
    font-size: 1rem;
    font-weight: 600;
    font-family: inherit;
    text-align: left;
    transition: background .15s ease, color .15s ease;
}
.fn-offcanvas-link:hover  { background: var(--lg-hover); }
.fn-offcanvas-link.active {
    background: var(--fn-brand);
    color: #fff;
}
.fn-offcanvas-link .mdi {
    font-size: 1.3rem;
    flex-shrink: 0;
    line-height: 1;
}


/* ─────────────────────────────────────────────────────────────────────────
 * DESKTOP / WIDE-VIEWPORT — boxed layout for mouse-primary devices.
 * Hides the tabbar, shows the hamburger, gives the chrome a contained
 * frame with a soft drop shadow.
 * ──────────────────────────────────────────────────────────────────────── */
@media (hover: hover) and (pointer: fine) {
    :root {
        --fn-tabbar-h: 0px;
        --fn-safe-bottom: 0px;
    }

    html, body {
        position: static;
        height: auto;
        min-height: 100%;
        overflow-x: hidden;
        overflow-y: auto;
        overscroll-behavior: auto;
    }

    body {
        /* On desktop the body backdrop reads better with a slightly
           deeper base — same gradient pools, slightly more saturation. */
        background-color: #e9edf3;
    }

    .fn-hero-menu-btn { display: inline-flex; }

    .fn-top-chrome {
        position: sticky;
        top: 1rem;
        left: auto;
        right: auto;
        width: calc(100% - 2rem);
        max-width: 1180px;
        margin: 1rem auto 0 auto;
        border-radius: var(--lg-r-md) var(--lg-r-md) 0 0;
        box-shadow: 0 10px 30px rgba(0, 0, 0, .12);
        overflow: hidden;
    }
    .fn-hero { box-shadow: none; }
    .fn-hero-inner { padding: 1.2rem .55rem; }

    .fn-hero-icon,
    .fn-hero-menu-btn {
        width: 1.9rem;
        height: 1.9rem;
        border-radius: .45rem;
        font-size: 1rem;
    }
    .fn-hero-brand { font-size: 1rem; }
    .fn-hero-subtitle { display: none; }
    .fn-hero-id-cell {
        padding: .35rem .55rem;
        font-size: .76rem;
    }

    .fn-ptr-circle { display: none; }
    .fn-tabbar { display: none; }

    .fn-page-host {
        position: relative;
        top: auto;
        left: auto;
        right: auto;
        bottom: auto;
        width: calc(100% - 2rem);
        max-width: 1180px;
        transform: none;
        margin: 0 auto 1rem auto;

        background-color: var(--lg-surface);
        backdrop-filter: var(--lg-blur);
        -webkit-backdrop-filter: var(--lg-blur);
        border: 1px solid var(--lg-edge);
        border-top: 0;
        border-radius: 0 0 var(--lg-r-md) var(--lg-r-md);
        box-shadow: var(--lg-shadow-strong);

        padding-top: 1rem;
        padding-bottom: 1rem;
        overflow-y: auto;
        overflow-x: hidden;
        overscroll-behavior: auto;
        min-height: calc(100vh - var(--fn-top-chrome-h) - 2rem);
    }
    .fn-page-inner {
        /* Was max-width: 1100px which made home/crew/preplan/settings
           visibly narrower than the address page (which uses page--full
           and gets the full page-host width). Now page-inner matches
           page-host (1180px max). Padding tightened from 1rem to 0.85rem
           so the side breathing matches the address stage's
           .fn-addr-stage horizontal padding (.85rem). */
        max-width: 100%;
        padding: 1rem .85rem;
        margin: 0 auto;
    }
    .fn-page.fn-page--full.active {
        height: calc(100vh - var(--fn-top-chrome-h) - 3rem);
        min-height: 28rem;
    }

    .fn-offcanvas {
        pointer-events: none;
    }
    .fn-offcanvas.is-open {
        pointer-events: auto;
    }
    .fn-offcanvas-backdrop {
        background: rgba(49, 58, 70, .25);
    }
    .fn-offcanvas-panel {
        position: absolute;
        top: calc(var(--fn-top-chrome-h) + 1.5rem);
        left: calc((100vw - min(1180px, calc(100vw - 2rem))) / 2);
        bottom: auto;
        width: 280px;
        max-width: calc(100vw - 2rem);
        border-radius: var(--lg-r-lg);
        overflow: hidden;
        box-shadow: 0 14px 35px rgba(0, 0, 0, .18);
        transform: translateY(-.75rem);
        opacity: 0;
        transition: transform .2s ease, opacity .2s ease;
    }
    .fn-offcanvas.is-open .fn-offcanvas-panel {
        transform: translateY(0);
        opacity: 1;
    }
}


/* ─────────────────────────────────────────────────────────────────────────
 * MOBILE — touch-primary corrections. Restores fixed app-shell + scrollable
 * page-host so the chrome stays put while content scrolls.
 * ──────────────────────────────────────────────────────────────────────── */
@media (hover: none) and (pointer: coarse) {
    .fn-page-host:has(#fn-page-home.active) {
        overflow-y: hidden;
    }

    .fn-page-host {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        height: auto;
        max-height: none;
        padding-top: calc(var(--fn-safe-top) + 0.45rem + var(--fn-top-chrome-h) + 0.5rem);
        padding-bottom: calc(var(--fn-tabbar-h) + var(--fn-safe-bottom) + 1.5rem);
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-y: contain;
        box-sizing: border-box;
    }
    .fn-page-inner { padding-bottom: 0.5rem; }
    #fn-page-settings { padding-bottom: 2.5rem; }

    .fn-page.fn-page--full.active {
        height: calc(100dvh - var(--fn-safe-top) - var(--fn-top-chrome-h) - var(--fn-tabbar-h) - var(--fn-safe-bottom) - 2.4rem);
    }
}



/* ==========================================================================
   Source: demo/assets/css/home.css
   ========================================================================== */

/* ============================================================================
 * home.css
 * ----------------------------------------------------------------------------
 * Home tab — call carousel, call cards, response button grid.
 * Extracted from /response/pages/home.php inline <style>; restyled in
 * Liquid Glass.
 *
 * Includes the scrubber addition (counter + draggable track that replaces
 * the dot strip when call count > DOTS_MAX). The JS that builds it lives
 * inline in home.php; this is just the styling.
 *
 * Load AFTER liquid-glass.css and index.css.
 * ========================================================================= */


/* ─────────────────────────────────────────────────────────────────────────
 * Mobile carousel layout — clamp the home tab to the viewport so only one
 * card is on screen at a time, scrolling internal to .fn-call-body.
 * ──────────────────────────────────────────────────────────────────────── */
@media (hover: none) and (pointer: coarse) {
    #fn-page-home.active {
        height: calc(100dvh - var(--fn-safe-top) - var(--fn-top-chrome-h) - var(--fn-tabbar-h) - var(--fn-safe-bottom) - 2rem);
        overflow: hidden;
    }
    #fn-page-home .fn-page-inner {
        height: 100%;
        padding-top: .1rem;
        /* Bottom padding zeroed — was 0.5rem of wasted space below the
           controls. Reclaiming it lets the card grow without pushing
           the controls under the tabbar. */
        padding-bottom: 0;
        overflow: hidden;
        box-sizing: border-box;
    }
    #fn-page-home .fn-carousel {
        /* Was 3.3rem reserved for controls. Reduced to 2.9rem to give
           the call-card more height. Matched against the controls
           block which is now 2.4rem (arrows) + 0.35rem (top margin)
           + 0.15rem (bottom margin) = 2.9rem. */
        height: calc(100% - 2.9rem);
        overflow-x: auto;
        overflow-y: hidden;
        /* Vertical padding trimmed from 4px to 2px — saves 0.25rem of
           slide vertical reserve, going straight into the call card.
           Horizontal padding zeroed — card now sits at page-inner edge,
           aligned with chrome content edges. */
        padding: 2px 0;
        box-sizing: border-box;
    }
    #fn-page-home .fn-carousel-slide {
        height: 100%;
        padding-right: 3px;
        box-sizing: border-box;
    }
    #fn-page-home .fn-call-card {
        height: 100%;
        min-height: 0;
        width: calc(100% - 1px);
        max-width: calc(100% - 1px);
        overflow: hidden;
    }
    #fn-page-home .fn-call-body {
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        touch-action: pan-y pan-x;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }
    #fn-page-home .fn-call-body::-webkit-scrollbar {
        display: none;
        width: 0;
        height: 0;
    }
    #fn-page-home .fn-call-section .value.message {
        scrollbar-width: none;
        -ms-overflow-style: none;
    }
    #fn-page-home .fn-call-section .value.message::-webkit-scrollbar {
        display: none;
        width: 0;
        height: 0;
    }
}


/* ─────────────────────────────────────────────────────────────────────────
 * Carousel — horizontal scroll-snap container, one slide per call.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-carousel {
    display: flex;
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-x;
    scrollbar-width: none;
    -ms-overflow-style: none;
    align-items: flex-start;
    width: 100%;
    border-radius: var(--lg-r-lg);
    box-sizing: border-box;
    scroll-behavior: auto;
    padding: 4px 0;
}
.fn-carousel::-webkit-scrollbar { display: none; }

.fn-carousel-slide {
    flex: 0 0 100%;
    width: 100%;
    max-width: 100%;
    scroll-snap-align: center;
    scroll-snap-stop: always;
    box-sizing: border-box;
    padding-right: 1px;
    min-width: 0;
}
.fn-carousel-slide:last-child { padding-right: 0; }


/* ─────────────────────────────────────────────────────────────────────────
 * Carousel controls — Prev/Next arrows flanking either dots OR the
 * scrubber depending on call count.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-carousel-ctrls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    /* Tighter vertical rhythm — was .65rem/.25rem (sum 0.9rem); now
       .35rem/.15rem (sum 0.5rem). Combined with 2.4rem arrows we fit
       cleanly in the 2.9rem carousel reservation. */
    margin: .35rem 0 .15rem;
    padding: 0 .25rem;
}
.fn-carousel-ctrls[hidden] { display: none !important; }

.fn-carousel-arrow {
    flex-shrink: 0;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    border: 1px solid var(--lg-edge);
    background-color: var(--lg-surface);
    backdrop-filter: var(--lg-blur);
    -webkit-backdrop-filter: var(--lg-blur);
    color: var(--fn-text);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-family: inherit;
    padding: 0;
    box-shadow: var(--lg-shadow);
    transition: transform var(--lg-t-base) var(--lg-spring),
                background-color var(--lg-t-base) var(--lg-ease),
                box-shadow var(--lg-t-base) var(--lg-ease),
                opacity .15s ease;
}
.fn-carousel-arrow:active:not(:disabled) {
    transform: scale(.92);
    background-color: var(--lg-pressed);
}
.fn-carousel-arrow:disabled {
    opacity: .35;
    cursor: not-allowed;
}
.fn-carousel-arrow .mdi {
    font-size: 1.3rem;
    line-height: 1;
}

.fn-carousel-arrow.fn-jump {
    background-color: var(--fn-brand);
    background-image: var(--lg-fill-primary);
    color: #fff;
    border-color: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    margin-right: .9rem;
}
.fn-carousel-arrow.fn-jump:active:not(:disabled) {
    filter: brightness(.85);
}
.fn-carousel-arrow.fn-jump .mdi { font-size: 1.2rem; }


/* ─────────────────────────────────────────────────────────────────────────
 * Dots — shown when call count ≤ DOTS_MAX (12). One row, no wrap; the
 * scrubber takes over when there are too many to fit.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-carousel-dots {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    flex-wrap: wrap;
    flex: 1 1 auto;
}
.fn-carousel-dot {
    width: .55rem;
    height: .55rem;
    border-radius: 50%;
    border: 0;
    background: var(--fn-text-muted);
    opacity: .35;
    padding: 0;
    cursor: pointer;
    transition: opacity .2s, transform .2s, width .25s, background .2s;
}
.fn-carousel-dot.active {
    background: var(--fn-brand);
    opacity: 1;
    width: 1.5rem;
    border-radius: .35rem;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Scrubber — shown when call count > DOTS_MAX. Counter on the left, thin
 * track with draggable thumb. Replaces the dot strip; the JS that wires
 * pointer events lives in home.php.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-carousel-scrubber {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    gap: .55rem;
    min-width: 0;
    padding: 0 .25rem;
}
.fn-carousel-counter {
    flex: 0 0 auto;
    font-size: .72rem;
    font-weight: 700;
    color: var(--fn-text-muted);
    font-variant-numeric: tabular-nums;
    letter-spacing: .01em;
    user-select: none;
    min-width: 2.8rem;
    text-align: center;
}
.fn-carousel-counter strong {
    color: var(--fn-text);
    font-weight: 800;
}
.fn-carousel-track {
    flex: 1 1 auto;
    position: relative;
    height: 1.5rem;
    cursor: pointer;
    touch-action: none;
    user-select: none;
}
.fn-carousel-track::before {
    content: "";
    position: absolute;
    left: 0; right: 0; top: 50%;
    height: .25rem;
    transform: translateY(-50%);
    background: var(--fn-text-muted);
    opacity: .22;
    border-radius: 999px;
}
.fn-carousel-thumb {
    position: absolute;
    top: 50%;
    width: 1.3rem;
    height: .55rem;
    background: var(--fn-brand);
    border-radius: 999px;
    transform: translate(-50%, -50%);
    transition: left .18s ease, width .15s ease, height .15s ease;
    pointer-events: none;
}
.fn-carousel-track.is-dragging .fn-carousel-thumb {
    transition: none;
    width: 1.6rem;
    height: .7rem;
}


/* ─────────────────────────────────────────────────────────────────────────
 * CALL CARD — the hero element on the home tab. Full Liquid Glass: real
 * blur, frosted-strong surface for readability, specular highlight from
 * the top edge, layered drop shadow.
 *
 * Only one card is visible at a time (carousel snap), so the cost of
 * backdrop-filter is fine — single surface in view.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-call-card {
    position: relative;
    background-color: var(--lg-surface);
    backdrop-filter: var(--lg-blur);
    -webkit-backdrop-filter: var(--lg-blur);
    border: 1px solid var(--lg-edge);
    border-radius: var(--lg-r-lg);
    overflow: hidden;
    box-shadow: var(--lg-shadow);
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
    transition: box-shadow .25s ease, border-color .25s ease;
    display: flex;
    flex-direction: column;
    /* Y = 2.0rem (was 1.8; bumped to maintain scrubber clearance from
       tabbar after the hero grew from 3.2rem → 4rem). Slide reserve
       still 3.25rem above Y. X = 2.0 + 3.25 + 0.05 buffer = 5.3rem. */
    height: calc(100vh  - var(--fn-safe-top) - var(--fn-top-chrome-h) - var(--fn-tabbar-h) - var(--fn-safe-bottom) - 5.3rem);
    height: calc(100dvh - var(--fn-safe-top) - var(--fn-top-chrome-h) - var(--fn-tabbar-h) - var(--fn-safe-bottom) - 5.3rem);
    min-height: 16rem;
    isolation: isolate;
}

/* Specular top-edge highlight via ::before */
.fn-call-card::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background-image: var(--lg-specular);
    pointer-events: none;
    z-index: 0;
}
.fn-call-card > * { position: relative; z-index: 1; }

/* Selected slide — brand-coloured edge + amplified shadow. */
.fn-carousel-slide.is-selected .fn-call-card {
    border-color: var(--fn-brand);
    box-shadow:
        0 0 0 2px var(--fn-brand-soft),
        0 1px 0 rgba(255,255,255,0.5) inset,
        0 14px 36px -8px rgba(49, 58, 70, .28),
        0 4px 12px -4px rgba(0, 0, 0, .10);
}


/* ─────────────────────────────────────────────────────────────────────────
 * Call card header — pulse-dot ACTIVE/CLOSED/EARLIER badge + time.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-call-header {
    padding: .6rem .85rem;
    background: linear-gradient(135deg, rgba(176,58,46,.10), rgba(176,58,46,.03));
    border-bottom: 1px solid var(--lg-divider);
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-shrink: 0;
}
.fn-call-header.older  { background: var(--lg-surface-subtle); }
.fn-call-header.closed { background: var(--lg-surface-subtle); }

.fn-call-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    background: var(--fn-accent);
    color: #fff;
    font-size: .65rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .06em;
    padding: .25rem .55rem;
    border-radius: 999px;
    flex-shrink: 0;
}
.fn-call-badge::before {
    content: '';
    width: .35rem;
    height: .35rem;
    border-radius: 50%;
    background: #fff;
    animation: fnPulse 1.4s infinite;
}
.fn-call-badge.older  { background: var(--fn-text-muted); }
.fn-call-badge.older::before  { animation: none; }
.fn-call-badge.closed { background: var(--fn-text-muted); }
.fn-call-badge.closed::before { animation: none; }

@keyframes fnPulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

.fn-call-time {
    font-size: .78rem;
    color: var(--fn-text-muted);
    font-weight: 600;
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Call body — incident type, address, units, message.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-call-body {
    padding: .85rem .95rem;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    min-width: 0;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}
.fn-call-body > * { flex-shrink: 0; }

.fn-call-type {
    /* Scales down on narrow screens. Floor at .95rem, ceiling 1.25rem.
       Final guard: nowrap+ellipsis if it still overflows. */
    font-size: clamp(.95rem, 4.2vw, 1.25rem);
    font-weight: 900;
    line-height: 1.15;
    color: var(--fn-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Preplan alert banner — solid red CTA at top of call body when a preplan
 * exists for the address. Solid (not glass) because action affordance.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-call-preplan-banner {
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    width: 100%;
    text-align: left;
    font-family: inherit;
    background-image: var(--lg-fill-danger);
    color: #fff;
    border-radius: var(--lg-r-sm);
    padding: .65rem .75rem;
    display: flex;
    align-items: center;
    gap: .65rem;
    cursor: pointer;
    box-shadow: 0 1px 0 rgba(255,255,255,.18) inset,
                0 6px 16px -6px rgba(176, 58, 46, .55),
                0 2px 6px -2px rgba(0,0,0,.15);
    transition: filter .12s ease, transform .1s ease;
    position: relative;
    overflow: hidden;
    flex: 0 0 auto;
}
.fn-call-preplan-banner.secure-only {
    background-image: linear-gradient(135deg, #0b95ad 0%, #086c80 100%);
    box-shadow: 0 1px 0 rgba(255,255,255,.18) inset,
                0 6px 16px -6px rgba(11, 142, 166, .55),
                0 2px 6px -2px rgba(0,0,0,.15);
}
.fn-call-preplan-banner:active {
    transform: scale(.985);
    filter: brightness(.92);
}
.fn-call-preplan-banner-icon {
    font-size: 1.45rem;
    line-height: 1;
    flex-shrink: 0;
    animation: fnPreplanPulse 2.4s ease-in-out infinite;
}
@keyframes fnPreplanPulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .55; }
}
.fn-call-preplan-banner-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .1rem;
}
.fn-call-preplan-banner-title {
    font-size: .82rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .05em;
    line-height: 1.1;
}
.fn-call-preplan-banner-sub {
    font-size: .78rem;
    font-weight: 600;
    opacity: .92;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fn-call-preplan-banner-arrow {
    font-size: 1.4rem;
    line-height: 1;
    opacity: .85;
    flex-shrink: 0;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Section blocks — label (small caps with brand tab) + value.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-call-section {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    min-width: 0;
}
.fn-call-section .label {
    font-size: .65rem;
    font-weight: 800;
    text-transform: uppercase;
    color: var(--fn-text-muted);
    letter-spacing: .04em;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
}
.fn-call-section .label::before {
    content: '';
    width: 3px;
    height: 11px;
    background: var(--fn-brand);
    border-radius: 2px;
}
.fn-call-section .value {
    font-size: .92rem;
    font-weight: 600;
    color: var(--fn-text);
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}
.fn-call-section .value.message {
    font-size: .92rem;
    line-height: 1.5;
    font-weight: 500;
    max-height: 5.5em;
    white-space: normal;
    overflow-y: auto;
    overflow-x: hidden;
    text-overflow: clip;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    word-break: break-word;
    overflow-wrap: anywhere;
    background-color: var(--lg-surface-subtle);
    border: 1px solid var(--lg-edge);
    border-radius: var(--lg-r-sm);
    padding: .4rem .55rem;
    flex-shrink: 0;
}
.fn-call-section .value.message::-webkit-scrollbar {
    width: 4px;
}
.fn-call-section .value.message::-webkit-scrollbar-thumb {
    background: var(--lg-edge-strong);
    border-radius: 2px;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Units list — small brand-coloured pills, horizontally scrollable.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-units-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: nowrap;
    gap: .35rem;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
}
.fn-units-list::-webkit-scrollbar { display: none; }
.fn-units-list li {
    background-image: var(--lg-fill-primary);
    color: #fff;
    border-radius: .4rem;
    padding: .28rem .6rem;
    font-weight: 800;
    font-size: .82rem;
    white-space: nowrap;
    flex-shrink: 0;
    box-shadow: 0 1px 0 rgba(255,255,255,.15) inset,
                0 1px 3px rgba(0,0,0,.1);
}


/* ─────────────────────────────────────────────────────────────────────────
 * "YOUR RESPONSE" SUMMARY BLOCK — replaces the old top-of-screen status
 * bar. Now lives inside .fn-call-response-box together with the response
 * buttons, so the two read as one bordered unit (matches the user's
 * design screenshot). Two-column inner layout:
 *
 *   Left:  person icon  +  heading text  +  subtitle
 *   Right: one circle per response type, count of respondents inside
 *
 * The heading text defaults to "YOUR RESPONSE" (muted) and flips to the
 * selected response's label (coloured to its type) once the user taps
 * a button. Circle counts come from the focused call's data.responses;
 * other carousel slides render with em-dash placeholders so the layout
 * doesn't shift when the user swipes to a different card.
 * ──────────────────────────────────────────────────────────────────────── */

/* Outer wrapper that holds BOTH the summary row and the response grid.
   Owns the soft border + tinted background + outer margin; the children
   now sit transparent on top of it. */
.fn-call-response-box {
    margin: .35rem .85rem .85rem;
    padding: .5rem;
    background-color: var(--lg-surface-subtle);
    border: 1px solid rgba(15, 23, 42, 0.12);
    border-radius: var(--lg-r-md);
    display: flex;
    flex-direction: column;
    gap: .5rem;
    flex-shrink: 0;
    box-sizing: border-box;
    /* Subtle inner highlight so the box reads as a single elevated
       surface against the card. Matches the .fn-call-card specular
       treatment, minus the heavy shadow. */
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
}

.fn-call-myresp {
    padding: .15rem .25rem .15rem .15rem;
    display: flex;
    align-items: center;
    gap: .65rem;
    flex-shrink: 0;
    min-height: 2.5rem;
    box-sizing: border-box;
    /* No standalone border/background/margin — the .fn-call-response-box
       wrapper handles all of that now. */
}

.fn-call-myresp-left {
    display: flex;
    align-items: center;
    gap: .55rem;
    flex: 1 1 auto;
    min-width: 0;
}

.fn-call-myresp-icon {
    font-size: 1.2rem;
    color: var(--fn-text-muted);
    flex-shrink: 0;
}

/* Heading: bold, all-caps, slightly tracked. Defaults to muted grey;
   when a response is selected, .fn-call-myresp-heading.<color> swaps
   in the type's accent for instant "I know what I picked" feedback.
   Sits directly next to the icon — no longer wrapped in a column
   layout since the subtitle line was removed. */
.fn-call-myresp-heading {
    font-weight: 800;
    font-size: .92rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--fn-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    flex: 1 1 auto;
    line-height: 1.1;
    transition: color .15s ease;
}
.fn-call-myresp-heading.success { color: #198754; }
.fn-call-myresp-heading.danger  { color: var(--fn-accent); }
.fn-call-myresp-heading.warning { color: #d97706; }
.fn-call-myresp-heading.info    { color: #0d6efd; }
.fn-call-myresp-heading.purple  { color: #7c3aed; }
.fn-call-myresp-heading.teal    { color: #0d9488; }
.fn-call-myresp-heading.pink    { color: #db2777; }
.fn-call-myresp-heading.dark    { color: #1f2937; }
.fn-call-myresp-heading.gray    { color: #6b7280; }

/* Count-circles row. One per response type, coloured by type. The
   circle holds dark-on-tint count text — placeholder "—" for the
   off-screen-card case where data.responses isn't this card's.
   max-width: 60% so a wall of circles can't crowd the heading text. */
.fn-call-myresp-circles {
    display: flex;
    align-items: center;
    gap: .35rem;
    flex: 0 0 auto;
    max-width: 60%;
    overflow: hidden;
}

.fn-call-myresp-circle {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
    color: var(--fn-text);
    flex-shrink: 0;
    /* Soft-tinted background + matching tinted border keeps the circles
       readable on either a light or dark card surface. Each .color
       modifier below sets both. Slightly stronger fill than before
       since the circles now sit on the response-box's tinted backdrop
       — they'd otherwise wash into it. */
    background-color: rgba(255, 255, 255, .85);
    border: 1px solid var(--lg-edge);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .08);
}

.fn-call-myresp-circle.success { background-color: rgba(25, 135, 84,  .22); border-color: rgba(25, 135, 84,  .40); color: #0f5132; }
.fn-call-myresp-circle.danger  { background-color: rgba(176, 58, 46,  .22); border-color: rgba(176, 58, 46,  .40); color: #842029; }
.fn-call-myresp-circle.warning { background-color: rgba(217, 119, 6,  .24); border-color: rgba(217, 119, 6,  .40); color: #7a3e00; }
.fn-call-myresp-circle.info    { background-color: rgba(13, 110, 253, .22); border-color: rgba(13, 110, 253, .40); color: #084298; }
.fn-call-myresp-circle.purple  { background-color: rgba(124, 58, 237, .22); border-color: rgba(124, 58, 237, .40); color: #4a1d96; }
.fn-call-myresp-circle.teal    { background-color: rgba(13, 148, 136, .22); border-color: rgba(13, 148, 136, .40); color: #0b5a52; }
.fn-call-myresp-circle.pink    { background-color: rgba(219, 39, 119, .22); border-color: rgba(219, 39, 119, .40); color: #831843; }
.fn-call-myresp-circle.dark    { background-color: rgba(31, 41, 55,   .18); border-color: rgba(31, 41, 55,   .35); color: #1f2937; }
.fn-call-myresp-circle.gray    { background-color: rgba(107, 114, 128, .18); border-color: rgba(107, 114, 128, .35); color: #374151; }

/* Tight screens: shrink the circles a hair so 4+ response types still
   fit alongside the heading text without crowding. */
@media (max-width: 380px) {
    .fn-call-myresp-circles { gap: .28rem; }
    .fn-call-myresp-circle  { width: 1.75rem; height: 1.75rem; font-size: .78rem; }
    .fn-call-response-box   { padding: .4rem; gap: .4rem; }
    .fn-call-myresp         { gap: .5rem; }
}


/* ─────────────────────────────────────────────────────────────────────────
 * RESPONSE BUTTON GRID — the "tap to respond" buttons. SOLID coloured
 * fills (Liquid Glass keeps action buttons solid for unambiguous
 * affordance), but pressed/is-mine states get spring + inner highlight.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-resp-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .4rem;
    /* Padding zeroed out — the .fn-call-response-box wrapper provides
       the outer padding now. */
    padding: 0;
    flex-shrink: 0;
}

.fn-resp-btn {
    border: 0;
    /* Was --lg-r-sm (0.65rem). Bumped to --lg-r-md (1rem) for a
       softer, more pill-like look matching the rest of the redesign. */
    border-radius: var(--lg-r-md);
    color: #fff;
    background: var(--fn-text-muted);
    font-family: inherit;
    font-weight: 800;
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .02em;
    padding: .55rem .25rem;
    min-height: 3rem;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .2rem;
    line-height: 1.05;
    transition: filter .12s, transform .1s, opacity .15s, box-shadow .15s;
    box-shadow: 0 1px 0 rgba(255,255,255,.20) inset,
                0 2px 6px rgba(0,0,0,.18);
    overflow: hidden;
    position: relative;
}
.fn-resp-btn span {
    /* fnFitRespButtons() sets an inline font-size — largest that fits.
       Don't ellipsis here; auto-fit avoids truncation by design. */
    white-space: nowrap;
    overflow: hidden;
    max-width: 100%;
    display: block;
    text-align: center;
}
.fn-resp-btn:active:not(:disabled):not(.is-mine) {
    transform: scale(.96);
    filter: brightness(.92);
}
.fn-resp-btn:disabled { cursor: not-allowed; }
.fn-resp-btn .mdi { font-size: 1.1rem; line-height: 1; }

.fn-resp-btn.success { background: #198754; }
.fn-resp-btn.danger  { background: var(--fn-accent); }
.fn-resp-btn.warning { background: #d97706; }
.fn-resp-btn.info    { background: #0d6efd; }
.fn-resp-btn.purple  { background: #7c3aed; }
.fn-resp-btn.teal    { background: #0d9488; }
.fn-resp-btn.pink    { background: #db2777; }
.fn-resp-btn.dark    { background: #1f2937; }
.fn-resp-btn.gray    { background: #6b7280; }

/* User's own response — dimmed + checkmark badge. */
.fn-resp-btn.is-mine {
    cursor: default;
    opacity: .55;
    box-shadow: inset 0 0 0 2px rgba(255,255,255,.5),
                0 1px 3px rgba(0,0,0,.1);
}
.fn-resp-btn.is-mine::after {
    content: '';
    position: absolute;
    top: .3rem;
    right: .3rem;
    width: 1.05rem;
    height: 1.05rem;
    background: rgba(255,255,255,.95);
    border-radius: 50%;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24'><path fill='%23222' d='M9,16.17L4.83,12L3.41,13.41L9,19L21,7L19.59,5.59L9,16.17Z'/></svg>");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 75%;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Empty state — "no active calls".
 * ──────────────────────────────────────────────────────────────────────── */
.fn-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 3rem 1.5rem 2rem;
    color: var(--fn-text-muted);
}
.fn-empty-icon {
    font-size: 3.5rem;
    line-height: 1;
    opacity: .35;
    color: var(--fn-text);
    margin-bottom: .25rem;
}
.fn-empty-title {
    font-weight: 800;
    font-size: 1.05rem;
    color: var(--fn-text);
    margin: .5rem 0 .35rem;
}
.fn-empty-sub {
    font-size: .85rem;
    color: var(--fn-text-muted);
    line-height: 1.45;
    max-width: 22rem;
}


/* ─────────────────────────────────────────────────────────────────────────
 * In-app confirmation modal — strong frosted glass card on a dim overlay.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-confirm-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .55);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
}
.fn-confirm-overlay.active {
    opacity: 1;
    pointer-events: auto;
}
.fn-confirm-card {
    background-color: var(--lg-surface-strong);
    backdrop-filter: var(--lg-blur-strong);
    -webkit-backdrop-filter: var(--lg-blur-strong);
    border: 1px solid var(--lg-edge-strong);
    color: var(--fn-text);
    border-radius: var(--lg-r-lg);
    max-width: 22rem;
    width: 100%;
    padding: 1.1rem 1.1rem .85rem;
    box-shadow: var(--lg-shadow-strong);
    transform: scale(.92);
    transition: transform .2s ease;
}
.fn-confirm-overlay.active .fn-confirm-card { transform: scale(1); }

.fn-confirm-title {
    font-weight: 800;
    font-size: 1.05rem;
    margin: 0 0 .5rem;
    line-height: 1.3;
}
.fn-confirm-msg {
    font-size: .92rem;
    line-height: 1.45;
    color: var(--fn-text-muted);
    margin: 0 0 .9rem;
}
.fn-confirm-msg strong {
    color: var(--fn-text);
    font-weight: 800;
}
.fn-confirm-actions {
    display: flex;
    gap: .55rem;
}
.fn-confirm-btn {
    flex: 1;
    padding: .7rem .5rem;
    border: 0;
    border-radius: var(--lg-r-sm);
    font-family: inherit;
    font-weight: 800;
    font-size: .9rem;
    cursor: pointer;
    line-height: 1;
}
.fn-confirm-btn.cancel {
    background-color: var(--lg-surface-subtle);
    color: var(--fn-text);
    border: 1px solid var(--lg-edge);
    backdrop-filter: var(--lg-blur-subtle);
    -webkit-backdrop-filter: var(--lg-blur-subtle);
}
.fn-confirm-btn.confirm {
    background-image: var(--lg-fill-primary);
    color: #fff;
}
.fn-confirm-btn:active { filter: brightness(.92); }



/* ==========================================================================
   Source: demo/assets/css/response.css
   ========================================================================== */

.fn-resp-call-summary {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .7rem;
    padding: .65rem .85rem;
    margin-bottom: .75rem;
    display: flex;
    align-items: center;
    gap: .55rem;
}
.fn-resp-call-summary .icon {
    width: 2rem; height: 2rem;
    border-radius: .45rem;
    background: var(--fn-accent-soft);
    color: var(--fn-accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.fn-resp-call-summary .icon .mdi { font-size: 1.15rem; }
.fn-resp-call-summary .info { min-width: 0; flex: 1; }
.fn-resp-call-summary .type {
    font-weight: 800;
    font-size: 1rem;
    color: var(--fn-text);
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fn-resp-call-summary .addr {
    font-size: .8rem;
    color: var(--fn-text-muted);
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-top: .15rem;
}

.fn-resp-group {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .7rem;
    overflow: hidden;
    margin-bottom: .65rem;
}
.fn-resp-group-header {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .55rem .85rem;
    background: var(--fn-tertiary-bg);
    border-bottom: 1px solid var(--fn-card-border);
}
.fn-resp-group-pill {
    width: 1.7rem; height: 1.7rem;
    border-radius: .45rem;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.fn-resp-group-pill .mdi { font-size: 1rem; }
.fn-resp-group-pill.success { background: #198754; }
.fn-resp-group-pill.danger  { background: var(--fn-accent); }
.fn-resp-group-pill.warning { background: #d97706; }
.fn-resp-group-pill.info    { background: #0d6efd; }
.fn-resp-group-pill.purple  { background: #7c3aed; }
.fn-resp-group-pill.teal    { background: #0d9488; }
.fn-resp-group-pill.pink    { background: #db2777; }
.fn-resp-group-pill.dark    { background: #1f2937; }
.fn-resp-group-pill.gray    { background: #6b7280; }
.fn-resp-group-label {
    font-weight: 800;
    font-size: .85rem;
    color: var(--fn-text);
    text-transform: uppercase;
    letter-spacing: .03em;
    flex: 1;
    min-width: 0;
}
.fn-resp-group-count {
    font-weight: 800;
    font-size: .8rem;
    color: var(--fn-text-muted);
    background: var(--fn-card-bg);
    padding: .2rem .5rem;
    border-radius: 999px;
    border: 1px solid var(--fn-card-border);
    flex-shrink: 0;
}

.fn-resp-row {
    display: flex;
    align-items: center;
    gap: .55rem;
    padding: .55rem .85rem;
    border-bottom: 1px solid var(--fn-card-border);
}
.fn-resp-row:last-child { border-bottom: 0; }
.fn-resp-row.is-mine { background: rgba(13,110,253,.06); }

.fn-resp-name {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .15rem;
}
.fn-resp-name .name {
    font-weight: 700;
    font-size: .95rem;
    color: var(--fn-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fn-resp-name .ff {
    font-size: .72rem;
    color: var(--fn-text-muted);
    font-weight: 600;
}
.fn-resp-name .ff.you {
    color: #0d6efd;
    font-weight: 800;
}

/* ETA pill — Bootstrap-style subtle success green.
   Pale tinted background, dark green text, soft border.
   Reads as "informational success" without being loud. */
.fn-resp-eta {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    background: #d1e7dd;          /* Bootstrap success-subtle bg */
    color: #0a3622;               /* Bootstrap success-emphasis text */
    border: 1px solid #a3cfbb;    /* Bootstrap success-border-subtle */
    padding: .28rem .5rem;
    border-radius: .4rem;
    font-size: .8rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    flex-shrink: 0;
    letter-spacing: .01em;
}
.fn-resp-eta .mdi {
    font-size: .9rem;
    opacity: .85;
}
[data-bs-theme="dark"] .fn-resp-eta {
    background: rgba(25, 135, 84, .18);
    color: #75d8a6;
    border-color: rgba(25, 135, 84, .35);
}

.fn-resp-time {
    font-size: .72rem;
    color: var(--fn-text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    flex-shrink: 0;
}

.fn-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 3rem 1.5rem 2rem;
    color: var(--fn-text-muted);
}
.fn-empty-icon {
    font-size: 4rem;
    line-height: 1;
    opacity: .35;
    color: var(--fn-text);
    margin-bottom: .25rem;
}
.fn-empty-title {
    font-weight: 800;
    font-size: 1.15rem;
    color: var(--fn-text);
    margin: .5rem 0 .35rem;
}
.fn-empty-sub {
    font-size: .9rem;
    color: var(--fn-text-muted);
    line-height: 1.45;
    max-width: 22rem;
}



/* ==========================================================================
   Source: demo/assets/css/address.css
   ========================================================================== */

/* ============================================================================
 * address.css
 * ----------------------------------------------------------------------------
 * Address tab — Google Map + Street View, hydrants chip, what3words chip,
 * map launch buttons. Combines:
 *
 *   1. Existing /response/assets/css/address.css
 *   2. Inline <style> block extracted from /response/pages/address.php
 *      (the .fn-w3w-chip rules)
 *
 * Restyled with Liquid Glass tokens where appropriate. The map wrap stays
 * with a solid background since the map tiles fill it.
 *
 * Load AFTER liquid-glass.css.
 * ========================================================================= */


/* ─────────────────────────────────────────────────────────────────────────
 * Stage — vertical flex container that fills the page-host content area.
 * Map takes the available space; buttons + chips sit below.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-addr-stage {
    display: flex;
    flex-direction: column;
    /* Gap 0.7rem between items (was 0.5). User said too crammed —
       extra breathing between map, address text, hydrants chip, and
       map buttons. */
    gap: .7rem;
    /* Vertical padding tuned for equal-gap layout:
         - top 0.25rem: small breathing below the status bar — matches
           the gap from AVAILABLE to the call card on the home screen,
           so AVAILABLE → content has the same gap on both screens
         - bottom 0: buttons (last item) sit AT stage bottom, which the
           page--full height calc places exactly 0.5rem above tabbar
           top — same as the gap between every other pair of items */
    padding: 0.25rem .85rem 0;
    height: 100%;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Map wrap — contains <iframe>/canvas map and street-view panorama.
 * Solid surface, not glass — the map tiles cover the entire area.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-map-wrap {
    position: relative;
    flex: 1 1 0;
    min-height: 12rem;
    border-radius: var(--lg-r-md);
    overflow: hidden;
    border: 1px solid var(--lg-edge);
    background: var(--fn-tertiary-bg);
    box-shadow: var(--lg-shadow);
}

#fnMap, #fnPano {
    width: 100%;
    height: 100%;
    min-height: 12rem;
}
#fnPano { display: none; }
.fn-map-wrap.streetview #fnMap { display: none; }
.fn-map-wrap.streetview #fnPano { display: block; }


/* ─────────────────────────────────────────────────────────────────────────
 * Street-view toggle — floats over the top-right of the map. Glass pill
 * so it reads as a control distinct from the map content.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-sv-toggle {
    position: absolute;
    top: .55rem;
    right: .55rem;
    z-index: 5;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    background: rgba(255, 255, 255, .96);
    color: #1a1a1a;
    border: 0;
    border-radius: 999px;
    padding: .45rem .75rem;
    font-weight: 700;
    font-size: .82rem;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
}
.fn-sv-toggle .mdi { font-size: 1rem; }
.fn-sv-toggle.disabled {
    opacity: .55;
    cursor: not-allowed;
}
.fn-map-wrap.streetview .fn-sv-toggle {
    background: #1a1a1a;
    color: #fff;
}
[data-bs-theme="dark"] .fn-sv-toggle {
    background: rgba(40, 44, 52, .96);
    color: #fff;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Address text strip beneath the map.
 * NOTE: .fn-map-coords (the lat/long sub-line) is hidden — the user
 * doesn't need GPS coordinates surfaced; the map+address are enough.
 * The element still exists in the DOM so any JS that targets it keeps
 * working, it just doesn't render.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-map-address {
    flex: 0 0 auto;
    font-size: .95rem;
    color: var(--fn-text-muted);
    text-align: center;
    line-height: 1.35;
    padding: 0 .25rem;
}
.fn-map-address strong {
    color: var(--fn-text);
    font-weight: 700;
}
.fn-map-coords {
    display: none;  /* lat/long not shown — was distracting */
}


/* ─────────────────────────────────────────────────────────────────────────
 * Map action buttons — Google + Apple maps launchers.
 * Solid coloured fills (action affordance), but spring + brightness on
 * press matches the Liquid Glass interaction language elsewhere.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-map-actions {
    flex: 0 0 auto;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .4rem;
}
.fn-map-actions.single-col {
    grid-template-columns: 1fr;
}

.fn-map-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    padding: .5rem .55rem;
    min-height: 2.5rem;
    /* Was --lg-r-sm (0.65rem). Bumped to 1rem to match home response
       buttons and preplan action buttons. */
    border-radius: 1rem;
    font-weight: 800;
    font-size: .85rem;
    letter-spacing: .02em;
    text-decoration: none;
    border: 0;
    cursor: pointer;
    white-space: nowrap;
    line-height: 1;
    box-shadow: 0 1px 0 rgba(255,255,255,.20) inset,
                0 2px 6px rgba(0,0,0,.18);
    transition: filter .12s var(--lg-ease),
                transform .1s var(--lg-ease);
    box-sizing: border-box;
}
.fn-map-btn:active {
    transform: scale(.96);
    filter: brightness(.92);
}
.fn-map-btn .mdi { font-size: 1.1rem; line-height: 1; }
.fn-map-btn.google { background: #4285F4; color: #fff; }
.fn-map-btn.apple  { background: #1a1a1a; color: #fff; }
[data-bs-theme="dark"] .fn-map-btn.apple { background: #383838; }


/* ─────────────────────────────────────────────────────────────────────────
 * Hydrants info chip — red-themed strip between address and buttons.
 * Renders distance to nearest hydrant + count within 200m; flips to a
 * filled-red "warning" state when no hydrants are within 200m so crews
 * know they may have to draft or shuttle water.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-hydrants-info {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    width: 100%;
    box-sizing: border-box;
    background: rgba(220, 38, 38, .10);
    color: #b91c1c;
    border: 1px solid rgba(220, 38, 38, .30);
    border-radius: var(--lg-r-sm);
    padding: .5rem .85rem;
    min-height: 2.5rem;
    font-size: .85rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: .02em;
    transition: background .15s, color .15s, border-color .15s;
}
.fn-hydrants-info[hidden] { display: none !important; }
.fn-hydrants-info .mdi { font-size: 1.1rem; }
.fn-hydrants-info.warn {
    background: var(--fn-accent);
    color: #fff;
    border-color: var(--fn-accent);
}
.fn-hydrants-info.loading {
    background: var(--lg-surface-subtle);
    color: var(--fn-text-muted);
    border-color: var(--lg-edge);
    font-weight: 600;
}
[data-bs-theme="dark"] .fn-hydrants-info {
    background: rgba(220, 38, 38, .18);
    color: #ff8a8a;
    border-color: rgba(220, 38, 38, .38);
}
[data-bs-theme="dark"] .fn-hydrants-info.warn {
    background: var(--fn-accent);
    color: #fff;
    border-color: var(--fn-accent);
}


/* ─────────────────────────────────────────────────────────────────────────
 * what3words auto-detected chip (extracted from settings.php inline).
 * Renders when call data includes a /// address. Tapping opens the w3w
 * app via Universal Links on iOS, falls back to the web page.
 * ──────────────────────────────────────────────────────────────────────── */
#fnAddrRoot .fn-w3w-chip {
    /* Same sizing rules as .fn-hydrants-info / .fn-map-btn so the chip
       + hydrants chip + map buttons read as one coherent action stack. */
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: .55rem;
    width: 100%;
    box-sizing: border-box;
    min-height: 2.5rem;
    padding: .5rem .85rem;
    background: rgba(225, 31, 38, .07);
    border: 1px solid rgba(225, 31, 38, .22);
    border-radius: var(--lg-r-sm);
    color: inherit;
    text-decoration: none;
    font-family: inherit;
    text-align: left;
    -webkit-tap-highlight-color: transparent;
    transition: background .15s var(--lg-ease),
                transform .1s var(--lg-ease);
}
#fnAddrRoot .fn-w3w-chip:active {
    transform: scale(0.99);
    background: rgba(225, 31, 38, .12);
}
#fnAddrRoot .fn-w3w-chip .fn-w3w-prefix {
    color: #E11F26;
    font-weight: 800;
    letter-spacing: -1px;
    font-size: 1rem;
    line-height: 1;
    flex-shrink: 0;
}
#fnAddrRoot .fn-w3w-chip .fn-w3w-words {
    flex: 1;
    font-weight: 700;
    font-size: .92rem;
    word-break: break-word;
    line-height: 1.25;
}
#fnAddrRoot .fn-w3w-chip-icon {
    color: var(--fn-text-muted);
    flex-shrink: 0;
    font-size: 1.05rem;
}
[data-bs-theme="dark"] #fnAddrRoot .fn-w3w-chip {
    background: rgba(225, 31, 38, .14);
    border-color: rgba(225, 31, 38, .35);
}


/* ─────────────────────────────────────────────────────────────────────────
 * Google Maps InfoWindow chrome overrides — hydrant marker popups.
 *
 * Modern Google Maps InfoWindow (2024+) has THREE layers, not two:
 *   .gm-style-iw-c    → outer white card wrapper
 *   .gm-style-iw-chr  → close-button chrome ROW (~32px, holds the X)
 *   .gm-style-iw-d    → content scroll container (where our HTML goes)
 *
 * The .gm-style-iw-chr row reserves its own height at the top of the
 * card. Adjusting .gm-style-iw-c padding alone won't move the title up
 * — content still starts BELOW the chrome row. To make the title sit
 * inline with the X we have to collapse the chrome row to height 0
 * and re-anchor the X via absolute positioning on the close button.
 *
 * Targeting Google's class names is brittle (they can rename in API
 * updates) but it's the only way — InfoWindow chrome isn't reachable
 * via our own class names.
 * ──────────────────────────────────────────────────────────────────────── */

/* Collapse the close-button row so it stops reserving vertical space. */
.gm-style-iw-chr {
    min-height: 0 !important;
    height: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    border: 0 !important;
    overflow: visible !important;  /* keep X visible even though height=0 */
}

/* Re-anchor the X button to top-right of the card itself (was inside the
   collapsed chrome row). 4px offset matches Google's normal positioning. */
.gm-style-iw-chr .gm-ui-hover-effect,
.gm-style .gm-ui-hover-effect {
    position: absolute !important;
    top: 4px !important;
    right: 4px !important;
    z-index: 2 !important;
}

/* Wrapper padding: top breathing + right room for the X + normal sides */
.gm-style .gm-style-iw-c {
    padding: 8px 36px 10px 12px !important;
}

/* Inner scroll container — kill its padding/overflow so our content
   fills the wrapper edge-to-edge. */
.gm-style .gm-style-iw-d {
    overflow: hidden !important;
    padding: 0 !important;
    max-height: none !important;
}



/* ==========================================================================
   Source: demo/assets/css/preplan.css
   ========================================================================== */

.fn-preplan-controls {
    display: flex;
    flex-direction: column;
    gap: .65rem;
    margin-bottom: .65rem;
}

/* Each search input is wrapped in a "field" with a small label above */
.fn-preplan-field {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    width: 100%;
    box-sizing: border-box;
}

/* Top search fields must stay full width like the range/results cards */
.fn-preplan-controls > .fn-preplan-field {
    padding: 0;
    border-bottom: 0;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

.fn-preplan-field-head {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--fn-text-muted);
    padding-left: .15rem;
}

.fn-preplan-field-head .mdi {
    font-size: .9rem;
}

/* Tiny pill that confirms the currently-active Google search anchor */
.fn-preplan-google-anchor {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    align-self: flex-start;
    font-size: .7rem;
    font-weight: 700;
    color: #0a4d6a;
    background: rgba(13, 202, 240, .18);
    border: 1px solid rgba(13, 202, 240, .45);
    padding: .2rem .55rem;
    border-radius: 999px;
    line-height: 1.25;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fn-preplan-google-anchor[hidden] {
    display: none;
}

.fn-preplan-google-anchor .mdi {
    font-size: .85rem;
    flex-shrink: 0;
}

[data-bs-theme="dark"] .fn-preplan-google-anchor {
    color: #7ee0f5;
    background: rgba(13, 202, 240, .12);
    border-color: rgba(13, 202, 240, .35);
}

.fn-preplan-search-row {
    position: relative;
    display: block;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

.fn-preplan-search-icon {
    position: absolute;
    left: .65rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--fn-text-muted);
    font-size: 1.15rem;
    pointer-events: none;
}

.fn-preplan-search {
    display: block;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    margin: 0;
    padding: .65rem 2.4rem .65rem 2.3rem;
    border-radius: .55rem;
    border: 1px solid var(--fn-card-border);
    background: var(--fn-card-bg);
    color: var(--fn-text);
    font-family: inherit;
    font-size: .95rem;
    line-height: 1;
    -webkit-appearance: none;
    appearance: none;
    -webkit-box-sizing: border-box;
}

.fn-preplan-search:focus {
    outline: none;
    border-color: var(--fn-brand);
    box-shadow: 0 0 0 3px var(--fn-brand-soft);
}

.fn-preplan-search-clear {
    position: absolute;
    right: .35rem;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: 0;
    color: var(--fn-text-muted);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    padding: .35rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fn-preplan-search-clear[hidden] {
    display: none;
}

.fn-preplan-range {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .65rem;
    padding: .65rem .8rem .55rem;
    transition: opacity .2s;
    box-sizing: border-box;
    width: 100%;
}

.fn-preplan-range.disabled {
    opacity: .55;
}

.fn-preplan-range-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: .35rem;
}

.fn-preplan-range-label {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: .8rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--fn-text-muted);
}

.fn-preplan-range-label .mdi {
    font-size: 1rem;
}

.fn-preplan-range-value {
    font-weight: 800;
    font-size: .95rem;
    color: var(--fn-brand);
    font-variant-numeric: tabular-nums;
}

[data-bs-theme="dark"] .fn-preplan-range-value {
    color: #c5d0db;
}

.fn-preplan-range-slider {
    width: 100%;
    margin: .15rem 0 .25rem;
    -webkit-appearance: none;
    appearance: none;
    height: .35rem;
    border-radius: 999px;
    background: var(--fn-tertiary-bg);
    cursor: pointer;
}

.fn-preplan-range-slider:disabled {
    cursor: not-allowed;
}

.fn-preplan-range-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--fn-brand);
    cursor: pointer;
    border: 2px solid #fff;
    box-shadow: 0 1px 4px rgba(0,0,0,.25);
}

.fn-preplan-range-slider::-moz-range-thumb {
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--fn-brand);
    cursor: pointer;
    border: 2px solid #fff;
    box-shadow: 0 1px 4px rgba(0,0,0,.25);
}

.fn-preplan-range-bounds {
    display: flex;
    justify-content: space-between;
    font-size: .7rem;
    color: var(--fn-text-muted);
    margin-top: -.1rem;
}

.fn-preplan-range-note {
    margin-top: .35rem;
    font-size: .75rem;
    color: var(--fn-text-muted);
    font-style: italic;
}

.fn-preplan-range-note[hidden] {
    display: none;
}

.fn-preplan-status {
    font-size: .8rem;
    color: var(--fn-text-muted);
    margin: .2rem 0 .5rem;
    min-height: 1.1em;
}

.fn-preplan-results {
    display: flex;
    flex-direction: column;
    gap: .55rem;
}

.fn-preplan-card {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .75rem;
    padding: .75rem .85rem;
    box-shadow: 0 1px 3px rgba(0,0,0,.04);
    display: flex;
    flex-direction: column;
    gap: .55rem;
}

.fn-preplan-card-head {
    display: flex;
    flex-direction: column;
    gap: .15rem;
}

.fn-preplan-card-name {
    font-weight: 800;
    font-size: 1.02rem;
    color: var(--fn-text);
    line-height: 1.2;
    word-wrap: break-word;
}

.fn-preplan-card-addr {
    font-size: .85rem;
    color: var(--fn-text-muted);
    line-height: 1.3;
    word-wrap: break-word;
}

.fn-preplan-card-distance {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    align-self: flex-start;
    font-size: .72rem;
    font-weight: 800;
    color: #fff;
    background: var(--fn-brand);
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: .25rem .6rem .28rem;
    border-radius: 999px;
    margin-top: .25rem;
    line-height: 1.2;
    box-shadow: 0 1px 2px rgba(0,0,0,.12);
}

.fn-preplan-card-distance .mdi {
    font-size: .9rem;
}

.fn-preplan-card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}

.fn-preplan-action-btn {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    border-radius: .5rem;
    padding: .55rem .65rem;
    font-family: inherit;
    font-weight: 800;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .02em;
    line-height: 1.05;
    cursor: pointer;
    color: #fff;
    background: var(--fn-brand);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .3rem;
    box-shadow: 0 1px 3px rgba(0,0,0,.12);
    transition: filter .12s, transform .1s;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fn-preplan-action-btn:active {
    transform: scale(.96);
    filter: brightness(.92);
}

.fn-preplan-action-btn .mdi {
    font-size: .95rem;
}

/* Hazards: same red as other "warning/danger" buttons across the app */
.fn-preplan-action-btn.hazards {
    background: var(--fn-accent);
    color: #fff;
}

/* Secure: bootstrap-info-feel cyan. Bright background needs dark text
   for readable contrast (white on cyan fails WCAG). */
.fn-preplan-action-btn.secure {
    background: #0dcaf0;
    color: #fff;
}

.fn-preplan-action-btn.full {
    background: var(--fn-brand);
    color: #fff;
}

.fn-preplan-empty {
    text-align: center;
    padding: 2.5rem 1rem;
    color: var(--fn-text-muted);
}

.fn-preplan-empty .mdi {
    font-size: 2.8rem;
    opacity: .3;
    color: var(--fn-text);
    display: block;
    margin-bottom: .35rem;
}

.fn-preplan-empty-title {
    font-weight: 800;
    color: var(--fn-text);
    margin-bottom: .25rem;
}

.fn-preplan-empty-sub {
    font-size: .85rem;
    line-height: 1.45;
}

/* ── Modal ──────────────────────────────────────────────────
   Modal sits BETWEEN the FN top chrome and the tab bar so the
   header is fully visible AND the navigation tabs stay
   visible/tappable below it. */
.fn-preplan-modal {
    position: fixed;
    top: calc(var(--fn-top-chrome-h) + .25rem);
    left: 0;
    right: 0;
    /* Bottom ends above the tab bar (and any iOS bottom safe area)
       with extra breathing room so the modal isn't pressed against
       the navigation tabs. */
    bottom: calc(var(--fn-tabbar-h) + var(--fn-safe-bottom) + .75rem);
    background: rgba(0,0,0,.55);
    z-index: 250;
    display: flex;
    align-items: stretch;
    justify-content: center;
    padding: .6rem;
    box-sizing: border-box;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
}

.fn-preplan-modal[hidden] {
    display: none;
}

.fn-preplan-modal.active {
    opacity: 1;
    pointer-events: auto;
}

.fn-preplan-modal-card {
    position: relative;
    background: var(--fn-body-bg);
    color: var(--fn-text);
    width: 100%;
    max-width: 640px;
    border-radius: .85rem;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 16px 50px rgba(0,0,0,.4);
    transform: scale(.96) translateY(.5rem);
    transition: transform .22s cubic-bezier(.2,.8,.2,1);
    box-sizing: border-box;
}

.fn-preplan-modal.active .fn-preplan-modal-card {
    transform: scale(1) translateY(0);
}

.fn-preplan-modal-head {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .85rem .95rem;
    border-bottom: 1px solid var(--fn-card-border);
    background: var(--fn-card-bg);
    flex-shrink: 0;
    transition: background .2s;
}

/* Themed modal headers — match the action button colors so the modal
   carries the same visual identity as whichever button opened it.
   Colors are theme-independent so dark mode just works. */
.fn-preplan-modal-card.theme-hazards .fn-preplan-modal-head {
    background: var(--fn-accent);
    border-bottom-color: rgba(0,0,0,.18);
}

.fn-preplan-modal-card.theme-secure .fn-preplan-modal-head {
    background: #0dcaf0;
    border-bottom-color: rgba(0,0,0,.18);
}

.fn-preplan-modal-card.theme-full .fn-preplan-modal-head {
    background: var(--fn-brand);
    border-bottom-color: rgba(0,0,0,.25);
}

/* Title/sub text colors per theme — white on red & navy, dark on cyan
   (cyan needs dark text for contrast). */
.fn-preplan-modal-card.theme-hazards .fn-preplan-modal-title,
.fn-preplan-modal-card.theme-full .fn-preplan-modal-title {
    color: #fff;
}

.fn-preplan-modal-card.theme-hazards .fn-preplan-modal-sub,
.fn-preplan-modal-card.theme-full .fn-preplan-modal-sub {
    color: rgba(255,255,255,.85);
}

.fn-preplan-modal-card.theme-secure .fn-preplan-modal-title {
    color: #fff;
}

.fn-preplan-modal-card.theme-secure .fn-preplan-modal-sub {
    color: rgba(255, 255, 255, .85);
}

.fn-preplan-modal-title-wrap {
    flex: 1;
    min-width: 0;
}

.fn-preplan-modal-title {
    font-weight: 800;
    font-size: 1.1rem;
    line-height: 1.2;
    color: var(--fn-text);
    overflow: hidden;
    text-overflow: ellipsis;
}

.fn-preplan-modal-sub {
    font-size: .8rem;
    color: var(--fn-text-muted);
    line-height: 1.3;
    margin-top: .15rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.fn-preplan-modal-filter {
    position: relative;
    padding: .55rem .85rem;
    border-bottom: 1px solid var(--fn-card-border);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: .4rem;
}

.fn-preplan-modal-filter[hidden] {
    display: none;
}

.fn-preplan-modal-filter .mdi {
    color: var(--fn-text-muted);
    font-size: 1.1rem;
}

.fn-preplan-modal-filter-input {
    flex: 1;
    padding: .45rem .55rem;
    border-radius: .5rem;
    border: 1px solid var(--fn-card-border);
    background: var(--fn-card-bg);
    color: var(--fn-text);
    font-family: inherit;
    font-size: .9rem;
    -webkit-appearance: none;
    appearance: none;
}

.fn-preplan-modal-filter-input:focus {
    outline: none;
    border-color: var(--fn-brand);
    box-shadow: 0 0 0 2px var(--fn-brand-soft);
}

.fn-preplan-modal-body {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    flex: 1 1 0;
    min-height: 0;
    /* Bottom padding so the floating close FAB doesn't cover the
       last item when scrolled to the end */
    padding: .35rem 0 4rem;
}

/* Modal detail rows only.
   This was previously using .fn-preplan-field globally, which also
   affected the two search inputs at the top and made them appear narrower. */
#fnPreplanModalBody .fn-preplan-field {
    padding: .55rem .95rem .6rem;
    border-bottom: 1px solid var(--fn-card-border);
}

#fnPreplanModalBody .fn-preplan-field:last-child {
    border-bottom: 0;
}

#fnPreplanModalBody .fn-preplan-field[hidden] {
    display: none;
}

.fn-preplan-field-label {
    font-size: .68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--fn-text-muted);
    margin-bottom: .15rem;
    display: inline-flex;
    align-items: center;
    gap: .25rem;
}

.fn-preplan-field-label::before {
    content: '';
    width: 3px;
    height: 10px;
    background: var(--fn-brand);
    border-radius: 2px;
}

.fn-preplan-field-value {
    font-size: .95rem;
    line-height: 1.45;
    color: var(--fn-text);
    word-break: break-word;
    white-space: pre-wrap;
}

.fn-preplan-modal-prose {
    padding: 1rem 1rem 4rem;   /* extra bottom for the FAB */
    font-size: 1rem;
    line-height: 1.55;
    color: var(--fn-text);
    white-space: pre-wrap;
    word-break: break-word;
}

/* Google Places Autocomplete dropdown — lift above the FN tab bar
   (z-index 100) but stay below our modal (z-index 250). Theme for
   dark mode so it doesn't look like a foreign white box. */
.pac-container {
    z-index: 200 !important;
    border-radius: .5rem;
    box-shadow: 0 8px 24px rgba(0,0,0,.18), 0 1px 4px rgba(0,0,0,.08);
    margin-top: .25rem;
    font-family: inherit;
}

[data-bs-theme="dark"] .pac-container {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
}

[data-bs-theme="dark"] .pac-item {
    background: var(--fn-card-bg);
    color: var(--fn-text);
    border-top-color: var(--fn-card-border);
}

[data-bs-theme="dark"] .pac-item:hover,
[data-bs-theme="dark"] .pac-item-selected {
    background: var(--fn-tertiary-bg);
}

[data-bs-theme="dark"] .pac-item-query,
[data-bs-theme="dark"] .pac-matched {
    color: var(--fn-text);
}

/* Persistent bottom-right close FAB — sits over the modal body
   so it's always reachable regardless of scroll position. */
.fn-preplan-modal-fab-close {
    position: absolute;
    right: .85rem;
    bottom: .85rem;
    width: 3.2rem;
    height: 3.2rem;
    border-radius: 50%;
    background: var(--fn-brand);
    color: #fff;
    border: 0;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    box-shadow: 0 4px 14px rgba(0,0,0,.3), 0 1px 4px rgba(0,0,0,.18);
    z-index: 5;
    transition: transform .12s, filter .12s;
}

.fn-preplan-modal-fab-close:active {
    transform: scale(.93);
    filter: brightness(.9);
}

.fn-preplan-modal-fab-close .mdi {
    font-size: 1.55rem;
    line-height: 1;
}

/* FAB color follows the modal theme so it matches the header.
   Cyan needs a dark icon for contrast (same rule as the button). */
.fn-preplan-modal-card.theme-hazards .fn-preplan-modal-fab-close {
    background: var(--fn-accent);
    color: #fff;
}

.fn-preplan-modal-card.theme-secure .fn-preplan-modal-fab-close {
    background: #0dcaf0;
    color: #fff;
}

.fn-preplan-modal-card.theme-full .fn-preplan-modal-fab-close {
    background: var(--fn-brand);
    color: #fff;
}



/* ==========================================================================
   Source: demo/assets/css/settings.css
   ========================================================================== */

/* ============================================================================
 * settings.css
 * ----------------------------------------------------------------------------
 * Settings tab — section cards, segmented controls, dropdowns, link rows,
 * sign-out button. Combines what used to live in two places:
 *
 *   1. The original /response/assets/css/settings.css (which was already
 *      linked).
 *   2. The inline <style> block in /response/pages/settings.php (extra
 *      polish rules that loaded after).
 *
 * Both are now merged here. Restyled in Liquid Glass.
 *
 * Key change: the segmented controls (Theme / Header color / Tab bar color
 * / Font size / Metric+Imperial / etc.) used to use --fn-card-bg as the
 * active-button background. In dark mode that's #23272C, which is nearly
 * identical to the container's --fn-tertiary-bg #2A2F35 — there was no
 * visible difference between active and inactive. Now the active button
 * gets the brand-pill treatment (solid slate light, lighter slate dark,
 * white text either way) so it matches the tabbar's "you are here" pill.
 *
 * Load AFTER liquid-glass.css.
 * ========================================================================= */


/* ─────────────────────────────────────────────────────────────────────────
 * Section + title (e.g. "Display", "Calls", "Activity")
 * ──────────────────────────────────────────────────────────────────────── */
.fn-set-section {
    margin-bottom: .85rem;
}
.fn-set-title {
    font-size: .68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--fn-text-muted);
    margin: 0 0 .35rem .25rem;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Settings card — frosted glass surface that groups related rows.
 * Cards stack vertically; multiple per page; each renders backdrop-filter.
 * Performance is fine because they're not animated.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-set-card {
    background-color: var(--lg-surface);
    backdrop-filter: var(--lg-blur);
    -webkit-backdrop-filter: var(--lg-blur);
    border: 1px solid var(--lg-edge);
    border-radius: var(--lg-r-md);
    box-shadow: var(--lg-shadow);
    overflow: hidden;
}

.fn-set-row {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .55rem .75rem;
    border-bottom: 1px solid var(--lg-divider);
    min-height: 2.4rem;
}
.fn-set-row:last-child {
    border-bottom: 0;
}

.fn-set-label {
    font-weight: 600;
    font-size: .88rem;
    color: var(--fn-text);
    flex-shrink: 0;
}
.fn-set-value {
    margin-left: auto;
    color: var(--fn-text-muted);
    font-weight: 600;
    font-size: .88rem;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Hint banner — info / advisory note under a row. Tinted strip at the
 * bottom of a card. The blue-tint variant is the default; the danger
 * variant is for stronger "heads-up" advisories (red tint).
 *
 * Rules in here merged from settings.php's inline <style> block.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-set-hint {
    padding: .35rem .75rem .55rem;
    border-top: 1px solid var(--lg-divider);
    background: var(--lg-surface-subtle);
    color: var(--fn-text-muted);
    font-size: .77rem;
    line-height: 1.35;
    display: flex;
    align-items: flex-start;
    gap: .35rem;
}
.fn-set-hint .mdi {
    font-size: .95rem;
    flex-shrink: 0;
    line-height: 1.4;
    opacity: .85;
}

/* Info-tinted variant (was inline in settings.php). Light blue wash;
   the icon picks up a brand-ish slate. */
#fnSettingsRoot .fn-set-card > .fn-set-hint {
    background: rgba(13, 110, 253, .07);
    color: var(--fn-text-muted);
    border-top: 1px solid var(--lg-divider);
    border-radius: 0;
    margin: 0;
    padding: .6rem .9rem;
    display: flex;
    align-items: center;
    gap: .45rem;
    font-size: .78rem;
    line-height: 1.4;
}
#fnSettingsRoot .fn-set-card > .fn-set-hint:last-child {
    border-bottom-left-radius: inherit;
    border-bottom-right-radius: inherit;
}
#fnSettingsRoot .fn-set-card > .fn-set-hint .mdi {
    color: var(--fn-brand);
    opacity: .85;
    font-size: 1rem;
    flex-shrink: 0;
}
[data-bs-theme="dark"] #fnSettingsRoot .fn-set-card > .fn-set-hint {
    background: rgba(13, 110, 253, .14);
}
[data-bs-theme="dark"] #fnSettingsRoot .fn-set-card > .fn-set-hint .mdi {
    color: #6ea3ff;     /* lighter blue so the icon shows against dark */
}

/* Danger-tinted variant — stronger advisory (red wash). */
#fnSettingsRoot .fn-set-card > .fn-set-hint-danger {
    background: rgba(220, 53, 69, .08);
    color: var(--fn-text-muted);
    border-top: 1px solid var(--lg-divider);
    border-radius: 0;
    margin: 0;
    padding: .6rem .9rem;
    display: flex;
    align-items: center;
    gap: .45rem;
    font-size: .78rem;
    line-height: 1.4;
}
#fnSettingsRoot .fn-set-card > .fn-set-hint-danger:last-child {
    border-bottom-left-radius: inherit;
    border-bottom-right-radius: inherit;
}
#fnSettingsRoot .fn-set-card > .fn-set-hint-danger .mdi {
    color: #dc3545;
    opacity: .9;
    font-size: 1rem;
    flex-shrink: 0;
}
[data-bs-theme="dark"] #fnSettingsRoot .fn-set-card > .fn-set-hint-danger {
    background: rgba(220, 53, 69, .16);
}
[data-bs-theme="dark"] #fnSettingsRoot .fn-set-card > .fn-set-hint-danger .mdi {
    color: #ff6b78;
}


/* ─────────────────────────────────────────────────────────────────────────
 * SEGMENTED CONTROL — Theme / Header / Tab bar / Font size etc.
 *
 * NEW: Active button uses the brand-pill treatment (solid slate light,
 * lighter slate dark, white text/icons either way) matching the tabbar's
 * active pill. Previously the active background was --fn-card-bg, which
 * in dark mode rendered identically to the container — there was no
 * visible "I am selected" cue.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-segmented {
    margin-left: auto;
    display: inline-flex;
    background-color: var(--lg-surface-subtle);
    backdrop-filter: var(--lg-blur-subtle);
    -webkit-backdrop-filter: var(--lg-blur-subtle);
    border: 1px solid var(--lg-edge);
    border-radius: var(--lg-r-sm);
    padding: .15rem;
    gap: .15rem;
}
.fn-segmented button {
    background: transparent;
    border: 0;
    color: var(--fn-text-muted);
    padding: .35rem .6rem;
    font-weight: 700;
    font-size: .78rem;
    border-radius: calc(var(--lg-r-sm) - .2rem);
    cursor: pointer;
    transition: background-color .18s var(--lg-ease),
                color .18s var(--lg-ease),
                box-shadow .18s var(--lg-ease);
    font-family: inherit;
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    line-height: 1;
}
.fn-segmented button.active {
    /* Brand-pill treatment — same tokens the tabbar's active pill uses,
       so the design language is consistent. White text on the slate
       background reads unambiguously in both light and dark mode. */
    background-color: var(--lg-tabbar-pill-bg);
    color: var(--lg-tabbar-pill-fg);
    box-shadow: var(--lg-tabbar-pill-shadow);
}


/* ─────────────────────────────────────────────────────────────────────────
 * Color dot — inline swatch inside segmented buttons (Header color row,
 * Tab bar color row). Border had hardcoded rgba(0,0,0,.15) which was
 * invisible against the new brand-slate active button. Token now picks
 * up a theme-appropriate edge.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-color-dot {
    display: inline-block;
    width: .65rem;
    height: .65rem;
    border-radius: 50%;
    border: 1px solid var(--lg-edge-strong);
    flex-shrink: 0;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .12);
}
[data-bs-theme="dark"] .fn-color-dot {
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .15);
}


/* ─────────────────────────────────────────────────────────────────────────
 * Dropdown — used for "Show calls from the past" and similar.
 * Frosted glass surface so it matches the card it sits in.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-set-select {
    margin-left: auto;
    appearance: none;
    -webkit-appearance: none;
    background-color: var(--lg-surface-subtle);
    backdrop-filter: var(--lg-blur-subtle);
    -webkit-backdrop-filter: var(--lg-blur-subtle);
    color: var(--fn-text);
    border: 1px solid var(--lg-edge);
    border-radius: var(--lg-r-sm);
    padding: .35rem 1.85rem .35rem .6rem;
    font-size: .82rem;
    font-weight: 700;
    cursor: pointer;
    /* Chevron stroke colour picked from currentColor so it follows
       --fn-text — invisible in dark mode no more. */
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='none' stroke='%236B7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M1 1l5 5 5-5'/></svg>");
    background-repeat: no-repeat;
    background-position: right .55rem center;
}
[data-bs-theme="dark"] .fn-set-select {
    /* Inline chevron uses %236B7280 stroke — readable in dark too,
       but swap to a lighter gray for higher contrast. */
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='none' stroke='%239099A4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M1 1l5 5 5-5'/></svg>");
}


/* ─────────────────────────────────────────────────────────────────────────
 * Navigation link rows — Call History / Manage Accounts / Clear cache.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-set-link {
    display: flex;
    align-items: center;
    gap: .55rem;
    padding: .85rem 1rem;
    border-bottom: 1px solid var(--lg-divider);
    color: var(--fn-text);
    text-decoration: none;
    font-weight: 600;
    font-size: .9rem;
    cursor: pointer;
    min-height: 2.4rem;
    transition: background-color .15s var(--lg-ease);
}
.fn-set-link:last-child {
    border-bottom: 0;
}
.fn-set-link:active {
    background: var(--lg-pressed);
}
.fn-set-link > .mdi:first-child {
    font-size: 1.1rem;
    color: var(--fn-text-muted);
    flex-shrink: 0;
}
.fn-set-link span {
    flex: 1 1 auto;
}
.fn-set-chev {
    margin-left: auto;
    opacity: .5;
    flex-shrink: 0;
}

/* Button rendered as a link row (e.g. Clear cached app data). */
.fn-set-link-btn {
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--lg-divider);
    text-align: left;
    font-family: inherit;
}
.fn-set-link-btn:last-child {
    border-bottom: 0;
}

/* Monospace version label inside the Clear-cache button. */
.fn-set-version {
    flex: 0 0 auto;
    margin-left: auto;
    padding-right: .35rem;
    font-size: .68rem;
    font-weight: 500;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    color: var(--fn-text-muted);
    opacity: .8;
}
.fn-set-version:empty {
    display: none;
}


/* ─────────────────────────────────────────────────────────────────────────
 * Sign-out button — solid red CTA at the bottom. Stays solid (no glass)
 * because action affordance.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-set-signout {
    width: 100%;
    background-image: var(--lg-fill-danger);
    color: #fff;
    border: 0;
    border-radius: var(--lg-r-sm);
    padding: .7rem;
    font-weight: 800;
    font-size: .95rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    box-shadow: 0 1px 0 rgba(255,255,255,.18) inset,
                0 4px 12px -4px rgba(176, 58, 46, .45),
                0 2px 6px -2px rgba(0,0,0,.15);
    font-family: inherit;
    transition: filter .12s var(--lg-ease), transform .1s var(--lg-ease);
}
.fn-set-signout:active {
    filter: brightness(.9);
    transform: scale(.98);
}
.fn-set-signout .mdi {
    font-size: 1.1rem;
}



/* ==========================================================================
   Source: demo/assets/css/dashboard.css
   ========================================================================== */

/* ============================================================
 * FireNotify — Dashboard (Liquid Glass)
 *
 * Drop-in replacement for the wall-display station dashboard
 * served at /response/dashboard.php. The same selectors and
 * variable namespace from the previous build are preserved so
 * the dashboard's JS keeps working untouched; only the visual
 * treatment changes.
 *
 * Treatment notes:
 *   - Deep gradient body with a slow drift on the brand-red
 *     ember layer, so the dashboard never feels static even
 *     when "Standing By."
 *   - Every card is a frosted-glass surface (backdrop-filter
 *     blur + low-alpha white tint) floating over the gradient.
 *   - Brand red (#c0282d) is the single accent — it sits on
 *     the topbar bell, "Active" badge, alert flash, and the
 *     idle progress bar. Status colors (success/danger/etc)
 *     are reserved for responder state.
 *   - Designed for wall displays at viewing distances of 6-10
 *     feet: large type, high contrast, motion only where it
 *     conveys information.
 * ========================================================= */

:root {
    /* Background layers */
    --d-bg-base:       #07090d;
    --d-bg-mid:        #0e1218;
    --d-bg-glow:       rgba(192, 40, 45, 0.28);
    --d-bg-glow-2:     rgba(60, 100, 200, 0.12);

    /* Frosted glass surfaces */
    --d-surface:       rgba(255, 255, 255, 0.04);
    --d-surface-2:     rgba(255, 255, 255, 0.06);
    --d-surface-3:     rgba(255, 255, 255, 0.09);
    --d-surface-hover: rgba(255, 255, 255, 0.08);
    --d-border:        rgba(255, 255, 255, 0.10);
    --d-border-strong: rgba(255, 255, 255, 0.18);

    /* Type ramp */
    --d-text:    rgba(255, 255, 255, 0.95);
    --d-text-2:  rgba(255, 255, 255, 0.68);
    --d-text-3:  rgba(255, 255, 255, 0.42);

    /* Brand + status palette */
    --d-brand:     #c0282d;
    --d-brand-2:   #ff6b6b;
    --d-accent:    #ef4444;
    --d-success:   #10b981;
    --d-warning:   #f59e0b;
    --d-info:      #3b82f6;
    --d-purple:    #a855f7;
    --d-teal:      #14b8a6;
    --d-pink:      #ec4899;
    --d-dark:      #475569;
    --d-gray:      #94a3b8;

    /* Topbar */
    --d-topbar-bg: linear-gradient(135deg,
        rgba(192, 40, 45, 0.92) 0%,
        rgba(135, 30, 35, 0.92) 60%,
        rgba(60, 18, 22, 0.92) 100%);
    --d-topbar-fg: #ffffff;

    /* Tinted card backgrounds — used on top of the glass to
       hint at semantic meaning without overwhelming. */
    --d-call-tint:    radial-gradient(1200px 320px at 0% 0%,
                          rgba(239, 68, 68, 0.10), transparent 65%);
    --d-resp-tint:    radial-gradient(1000px 280px at 100% 0%,
                          rgba(59, 130, 246, 0.07), transparent 60%);
    --d-standby-tint: radial-gradient(800px 200px at 50% 0%,
                          rgba(59, 130, 246, 0.10), transparent 70%);
    --d-resp-head-bg: rgba(59, 130, 246, 0.07);
    --d-summary-bg:   linear-gradient(180deg,
                          rgba(255, 255, 255, 0.025),
                          rgba(255, 255, 255, 0));

    /* Responder-cell tints — each color group has a subtle
       fill, a stronger border for the icon, and a clean text
       color. Picking the right tone for "low-info but visible
       from across the room" is the whole game. */
    --d-cell-success: rgba(16, 185, 129, 0.13);
    --d-cell-danger:  rgba(239, 68, 68, 0.13);
    --d-cell-warning: rgba(245, 158, 11, 0.13);
    --d-cell-info:    rgba(59, 130, 246, 0.13);
    --d-cell-purple:  rgba(168, 85, 247, 0.13);
    --d-cell-teal:    rgba(20, 184, 166, 0.13);
    --d-cell-pink:    rgba(236, 72, 153, 0.13);
    --d-cell-dark:    rgba(71, 85, 105, 0.20);
    --d-cell-gray:    rgba(148, 163, 184, 0.16);

    --d-head-height:  4.25rem;
    --d-radius:       1.1rem;
    --d-radius-sm:    .65rem;
    --d-card-head-height: 3.25rem;

    /* Pill / badge text colors. Hard-coded pale shades only work
       on dark backgrounds — in light mode they're invisible. By
       routing through these vars we get correct contrast in
       both modes. Dark-mode values are the same pale tints we
       had before; light-mode values (in the @media block below)
       switch to the deepest stop of each ramp so the text reads
       like a label, not a watermark. */
    --d-pill-success-text: #a7f3d0;
    --d-pill-danger-text:  #fecaca;
    --d-pill-warning-text: #fde68a;
    --d-pill-info-text:    #bfdbfe;
    --d-pill-purple-text:  #e9d5ff;
    --d-pill-teal-text:    #99f6e4;
    --d-pill-pink-text:    #fbcfe8;
    --d-pill-dark-text:    #cbd5e1;
    --d-pill-gray-text:    #e2e8f0;

    --d-tab-active-text:   #bfdbfe;
    --d-tab-active-bg:     rgba(59, 130, 246, 0.18);

    --d-units-text:        #dbeafe;
    --d-units-bg:          rgba(59, 130, 246, 0.18);
    --d-units-border:      rgba(59, 130, 246, 0.32);

    --d-cell-eta-text:     #ffffff;
    --d-cell-eta-bg:       rgba(0, 0, 0, 0.25);
}

/* Light-mode override for the rare case the dashboard is run
   on a daytime display where dark mode hurts. Backdrop-filter
   still applies — frosted glass works on light backgrounds too. */
@media (prefers-color-scheme: light) {
    :root {
        /* Body is pure white in light mode so the .d-main grid gap
           between cards shows the same color as the cards themselves.
           Previously the body was light-grey-blue (#eef1f6), which
           the grid gap revealed as visible darker channels running
           between the cards. White-on-white means: gap and cards are
           the same color, so the gap reads as deliberate spacing
           rather than a strip of "something behind." Card definition
           comes from their 1px border and rounded corner. */
        --d-bg-base:       #ffffff;
        --d-bg-mid:        #ffffff;
        --d-bg-glow:       rgba(192, 40, 45, 0.025);
        --d-bg-glow-2:     rgba(60, 100, 200, 0.020);

        --d-surface:       rgba(255, 255, 255, 0.96);
        --d-surface-2:     rgba(248, 250, 252, 0.88);
        --d-surface-3:     rgba(248, 250, 252, 0.95);
        --d-surface-hover: rgba(255, 255, 255, 1);
        --d-border:        rgba(15, 23, 42, 0.10);
        --d-border-strong: rgba(15, 23, 42, 0.18);

        --d-text:    rgba(15, 23, 42, 0.92);
        --d-text-2:  rgba(15, 23, 42, 0.62);
        --d-text-3:  rgba(15, 23, 42, 0.40);

        --d-call-tint:    radial-gradient(1200px 320px at 0% 0%,
                              rgba(192, 40, 45, 0.06), transparent 65%);
        --d-resp-tint:    radial-gradient(1000px 280px at 100% 0%,
                              rgba(59, 130, 246, 0.05), transparent 60%);
        --d-standby-tint: radial-gradient(800px 200px at 50% 0%,
                              rgba(59, 130, 246, 0.06), transparent 70%);
        --d-resp-head-bg: rgba(59, 130, 246, 0.05);
        --d-summary-bg:   linear-gradient(180deg,
                              rgba(15, 23, 42, 0.02),
                              rgba(15, 23, 42, 0));

        --d-cell-success: rgba(16, 185, 129, 0.12);
        --d-cell-danger:  rgba(192, 40, 45, 0.10);
        --d-cell-warning: rgba(245, 158, 11, 0.16);
        --d-cell-info:    rgba(59, 130, 246, 0.10);
        --d-cell-purple:  rgba(168, 85, 247, 0.10);
        --d-cell-teal:    rgba(20, 184, 166, 0.12);
        --d-cell-pink:    rgba(236, 72, 153, 0.10);
        --d-cell-dark:    rgba(71, 85, 105, 0.14);
        --d-cell-gray:    rgba(148, 163, 184, 0.18);

        /* Light-mode pill text — use the deepest stop of each
           color so the label reads sharply on the faint
           background tint. Pale tints (from dark mode) read as
           invisible watermarks here. */
        --d-pill-success-text: #065f46;  /* emerald-900 */
        --d-pill-danger-text:  #7f1d1d;  /* red-900 */
        --d-pill-warning-text: #78350f;  /* amber-900 */
        --d-pill-info-text:    #1e3a8a;  /* blue-900 */
        --d-pill-purple-text:  #581c87;  /* purple-900 */
        --d-pill-teal-text:    #134e4a;  /* teal-900 */
        --d-pill-pink-text:    #831843;  /* pink-900 */
        --d-pill-dark-text:    #1e293b;  /* slate-800 */
        --d-pill-gray-text:    #334155;  /* slate-700 */

        --d-tab-active-text:   #1e3a8a;
        --d-tab-active-bg:     rgba(59, 130, 246, 0.12);

        --d-units-text:        #1e3a8a;
        --d-units-bg:          rgba(59, 130, 246, 0.12);
        --d-units-border:      rgba(59, 130, 246, 0.30);

        --d-cell-eta-text:     #ffffff;
        --d-cell-eta-bg:       rgba(15, 23, 42, 0.55);
    }
}

/* ── Base ──────────────────────────────────────────────── */
* { box-sizing: border-box; }

html, body {
    height: 100%; width: 100%; margin: 0;
    color: var(--d-text);
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif;
    overflow: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-feature-settings: 'cv11', 'ss01', 'ss03';
}

/* The "stage" — full-viewport gradient with two drifting
   ember layers. ::before is the static base gradient; ::after
   carries the slow-drifting brand-red glow that gives the
   dashboard a sense of life without animating actual content. */
body {
    background: var(--d-bg-base);
    position: relative;
    isolation: isolate;
}
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -2;
    background:
        radial-gradient(ellipse 80% 60% at 80% 0%,
            var(--d-bg-glow) 0%, transparent 55%),
        radial-gradient(ellipse 70% 50% at 0% 100%,
            var(--d-bg-glow-2) 0%, transparent 55%),
        linear-gradient(180deg,
            var(--d-bg-base) 0%,
            var(--d-bg-mid) 60%,
            var(--d-bg-base) 100%);
}
body::after {
    /* Slow-drifting ember layer — 60s rotation pulls the warm
       light around the screen so the dashboard never looks
       like a frozen poster. Pointer-events none + z-index -1
       keep it strictly visual. */
    content: '';
    position: fixed;
    inset: -20%;
    z-index: -1;
    background: radial-gradient(circle at 30% 40%,
        rgba(192, 40, 45, 0.10) 0%,
        transparent 35%);
    animation: dEmberDrift 60s ease-in-out infinite alternate;
    pointer-events: none;
}
@keyframes dEmberDrift {
    0%   { transform: translate(0, 0)        rotate(0deg); }
    50%  { transform: translate(8%, -4%)     rotate(15deg); }
    100% { transform: translate(-6%, 6%)     rotate(-10deg); }
}

/* Hide the drifting ember layer in light mode. The warm rotation
   looks gorgeous on a dark base but on a light gradient it just
   creates a patchy pink fog that bleeds through the gaps between
   cards. Same goes for backdrop-filter on cards in light mode —
   blurring 96%-opaque white over a near-white background is wasted
   GPU work and produces a faintly muddy halo. Flat solid surfaces
   read cleaner. */
@media (prefers-color-scheme: light) {
    body::after { display: none; }
    body::before {
        background: var(--d-bg-base);
    }
    /* No outer box-shadow on cards in light mode. Every shadow
       attempt — directional, negative-spread, asymmetric — still
       bled enough into the gap between cards that two adjacent
       cards' shadows summed into a visible muddy strip down the
       middle. And card shadows reaching the screen edges were
       what made the four screen corners look subtly darker than
       the rest of the body. Card definition now comes purely
       from: a 1px border, a 1.1rem rounded corner, and a 96%-
       opaque white surface against the light-grey body. The
       inner highlight on the top edge keeps the Liquid Glass
       "lit edge" feel without putting any pigment outside the
       card itself. */
    .d-card {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        border-color: rgba(15, 23, 42, 0.12);
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95);
    }
    /* Topbar's wide red shadow was casting 32px in every direction
       — that's what was tinting the top corners of the screen pink.
       In light mode, replace it with a tight 1px hairline below
       the topbar that reads as a divider, not a glow. */
    .d-topbar {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        box-shadow:
            0 1px 0 rgba(15, 23, 42, 0.06),
            inset 0 1px 0 rgba(255, 255, 255, 0.16);
    }
}

/* ── Layout shell ──────────────────────────────────────── */
.d-shell {
    display: grid;
    grid-template-rows: auto 1fr;
    height: 100vh; width: 100vw;
    gap: 1rem;
    padding: 1rem 1.25rem 1.25rem;
    overflow: hidden;
    position: relative;
    z-index: 1;
}

/* ── Topbar — brand-red frosted strip ──────────────────── */
.d-topbar {
    display: flex;
    align-items: center;
    gap: 1rem;
    height: var(--d-head-height);
    padding: 0 1.25rem;
    background: var(--d-topbar-bg);
    color: var(--d-topbar-fg);
    border-radius: var(--d-radius);
    border: 1px solid rgba(255, 255, 255, 0.08);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    box-shadow:
        0 12px 32px rgba(192, 40, 45, 0.22),
        inset 0 1px 0 rgba(255, 255, 255, 0.12);
    position: relative;
    overflow: hidden;
}
.d-topbar::before {
    /* Hairline highlight along the top edge — the
       characteristic Liquid Glass "lit edge" look. */
    content: '';
    position: absolute;
    top: 0; left: 8%; right: 8%;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        rgba(255, 255, 255, 0.50),
        transparent);
    pointer-events: none;
}

.d-brand {
    display: flex; align-items: center; gap: .55rem;
    font-size: 1.32rem;
    font-weight: 800;
    letter-spacing: 0.005em;
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}
.d-brand .mdi {
    font-size: 1.7rem;
    line-height: 1;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.25));
}

.d-station {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .35rem .75rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.14);
    border: 1px solid rgba(255, 255, 255, 0.22);
    font-size: .95rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #fff;
}
.d-station .mdi { font-size: 1.05rem; line-height: 1; }

.d-spacer { flex: 1; }

.d-status {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .35rem .75rem;
    border-radius: 999px;
    background: rgba(16, 185, 129, 0.18);
    border: 1px solid rgba(16, 185, 129, 0.40);
    font-size: .85rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #d1fae5;
    transition: background .2s, border-color .2s, color .2s;
}
.d-status .dot {
    width: .55rem; height: .55rem;
    border-radius: 50%;
    background: #10b981;
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.55);
    animation: dLivePulse 1.6s ease-in-out infinite;
}
.d-status.offline {
    background: rgba(245, 158, 11, 0.18);
    border-color: rgba(245, 158, 11, 0.45);
    color: #fde68a;
}
.d-status.offline .dot {
    background: #f59e0b;
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.55);
}
@keyframes dLivePulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.55); }
    50%      { box-shadow: 0 0 0 8px rgba(16, 185, 129, 0); }
}

.d-clock {
    font-variant-numeric: tabular-nums;
    font-size: 1.45rem;
    font-weight: 800;
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    letter-spacing: .02em;
    min-width: 9.5rem;
    text-align: right;
}

/* ── Main grid — three frosted cards ────────────────────
   Default split is wide-friendly:
     Call (1.5fr) | Responders (1.5fr) | Idle (1fr collapsed)
   When .is-idle is set, the call card collapses to a small
   "Standing By" panel and the idle feed grows to take the
   center stage. */
.d-main {
    display: grid;
    grid-template-columns: 1.5fr 1.5fr 1fr;
    gap: 1rem;
    min-height: 0;
    overflow: hidden;
}
.d-main.is-idle {
    grid-template-columns: 1fr 1fr 2fr;
}

/* ── Card base — frosted glass surface ─────────────────── */
.d-card {
    position: relative;
    background: var(--d-surface);
    border: 1px solid var(--d-border);
    border-radius: var(--d-radius);
    backdrop-filter: blur(24px) saturate(160%);
    -webkit-backdrop-filter: blur(24px) saturate(160%);
    box-shadow:
        0 20px 50px rgba(0, 0, 0, 0.35),
        0 2px 8px rgba(0, 0, 0, 0.15),
        inset 0 1px 0 rgba(255, 255, 255, 0.07);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    min-height: 0;
}
.d-card::after {
    /* Subtle highlight along the top edge — same Liquid Glass
       lit-edge motif as the topbar. */
    content: '';
    position: absolute;
    top: 0; left: 10%; right: 10%;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        rgba(255, 255, 255, 0.18),
        transparent);
    pointer-events: none;
}

/* ── Call card ─────────────────────────────────────────── */
.d-call {
    background-image: var(--d-call-tint);
}
.d-call-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex: 1;
    text-align: center;
    padding: 2rem;
    background: var(--d-standby-tint);
}
.d-call-empty .icon-wrap {
    width: 5.5rem; height: 5.5rem;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.10);
    display: flex; align-items: center; justify-content: center;
    margin-bottom: 1.1rem;
}
.d-call-empty .icon-wrap .mdi {
    font-size: 2.8rem;
    color: var(--d-text-2);
}
.d-call-empty .title {
    font-size: 1.85rem;
    font-weight: 800;
    color: var(--d-text);
    margin-bottom: .4rem;
    letter-spacing: -0.01em;
}
.d-call-empty .sub {
    font-size: 1rem;
    color: var(--d-text-2);
    max-width: 28ch;
    line-height: 1.4;
}

.d-call-active {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}
.d-call-head {
    display: flex; align-items: center; justify-content: space-between;
    min-height: var(--d-card-head-height);
    padding: 0 1.2rem;
    border-bottom: 1px solid var(--d-border);
    flex-shrink: 0;
    background: rgba(239, 68, 68, 0.07);
}
.badge-newest {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .3rem .7rem .32rem;
    border-radius: 999px;
    background: var(--d-brand);
    color: #fff;
    font-size: .72rem;
    font-weight: 900;
    letter-spacing: .12em;
    text-transform: uppercase;
    box-shadow: 0 2px 10px rgba(192, 40, 45, 0.45);
}
.badge-newest.is-active {
    animation: dBadgePulse 2.4s ease-in-out infinite;
}
.badge-newest.is-call {
    background: var(--d-dark);
    box-shadow: none;
}
@keyframes dBadgePulse {
    0%, 100% { box-shadow: 0 2px 10px rgba(192, 40, 45, 0.45); }
    50%      { box-shadow: 0 2px 18px rgba(192, 40, 45, 0.75),
                            0 0 0 6px rgba(192, 40, 45, 0.10); }
}
.age {
    display: inline-flex; align-items: center; gap: .3rem;
    font-size: .92rem;
    font-weight: 700;
    color: var(--d-text-2);
    font-variant-numeric: tabular-nums;
}
.age .mdi { font-size: 1.05rem; line-height: 1; }

.d-call-body {
    flex: 1;
    overflow-y: auto;
    padding: 1.1rem 1.3rem 1.3rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}
.d-call-type {
    font-size: 2.4rem;
    font-weight: 900;
    line-height: 1.1;
    color: var(--d-text);
    letter-spacing: -0.02em;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
.d-call-time {
    font-size: .92rem;
    color: var(--d-text-2);
    margin-top: .35rem;
    font-variant-numeric: tabular-nums;
}

.d-call-section {
    padding: .7rem .9rem .8rem;
    background: var(--d-surface-2);
    border: 1px solid var(--d-border);
    border-radius: var(--d-radius-sm);
}
.d-call-section .label {
    font-size: .68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--d-text-3);
    margin-bottom: .3rem;
}
.d-call-section .value {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--d-text);
    line-height: 1.4;
    word-break: break-word;
}
.d-call-section .value.message {
    font-weight: 500;
    color: var(--d-text-2);
    font-size: .95rem;
}

.d-units-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}
.d-units-list li {
    display: inline-flex; align-items: center;
    padding: .25rem .6rem .28rem;
    border-radius: 999px;
    background: var(--d-units-bg);
    border: 1px solid var(--d-units-border);
    color: var(--d-units-text);
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .04em;
    font-variant-numeric: tabular-nums;
}

.d-other-calls {
    margin-top: .25rem;
    padding: .7rem .9rem .8rem;
    background: var(--d-surface);
    border: 1px solid var(--d-border);
    border-radius: var(--d-radius-sm);
}
.d-other-calls .label {
    font-size: .68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--d-text-3);
    margin-bottom: .35rem;
}
.d-other-call-row {
    display: flex; justify-content: space-between; align-items: center;
    padding: .35rem 0;
    border-bottom: 1px solid var(--d-border);
    font-size: .9rem;
}
.d-other-call-row:last-child { border-bottom: 0; }
.d-other-call-row .type { color: var(--d-text); font-weight: 600; }
.d-other-call-row .time { color: var(--d-text-3); font-size: .8rem; font-variant-numeric: tabular-nums; }

/* ── Responders card ───────────────────────────────────── */
.d-resp {
    background-image: var(--d-resp-tint);
}
.d-resp-head {
    display: flex; align-items: center; justify-content: space-between;
    min-height: var(--d-card-head-height);
    padding: 0 1.2rem;
    border-bottom: 1px solid var(--d-border);
    background: var(--d-resp-head-bg);
    flex-shrink: 0;
}
.d-resp-head .title {
    display: inline-flex; align-items: center; gap: .5rem;
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--d-text);
    letter-spacing: -0.005em;
}
.d-resp-head .title .mdi {
    font-size: 1.3rem;
    line-height: 1;
    color: var(--d-info);
}
.d-resp-head .count {
    font-size: .85rem;
    font-weight: 700;
    color: var(--d-text-2);
    font-variant-numeric: tabular-nums;
}

.d-resp-summary {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    padding: .65rem 1.2rem .35rem;
    background: var(--d-summary-bg);
    flex-shrink: 0;
}
.d-resp-summary:empty { display: none; }

.d-resp-pill {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .28rem .65rem .3rem;
    border-radius: 999px;
    font-size: .78rem;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
    background: var(--d-cell-info);
    border: 1px solid rgba(59, 130, 246, 0.30);
    color: var(--d-pill-info-text);
    font-variant-numeric: tabular-nums;
}
.d-resp-pill .mdi { font-size: .9rem; line-height: 1; }
.d-resp-pill.success { background: var(--d-cell-success);
    border-color: rgba(16, 185, 129, 0.30); color: var(--d-pill-success-text); }
.d-resp-pill.danger  { background: var(--d-cell-danger);
    border-color: rgba(239, 68, 68, 0.30);  color: var(--d-pill-danger-text); }
.d-resp-pill.warning { background: var(--d-cell-warning);
    border-color: rgba(245, 158, 11, 0.32); color: var(--d-pill-warning-text); }
.d-resp-pill.info    { background: var(--d-cell-info);
    border-color: rgba(59, 130, 246, 0.30); color: var(--d-pill-info-text); }
.d-resp-pill.purple  { background: var(--d-cell-purple);
    border-color: rgba(168, 85, 247, 0.30); color: var(--d-pill-purple-text); }
.d-resp-pill.teal    { background: var(--d-cell-teal);
    border-color: rgba(20, 184, 166, 0.30); color: var(--d-pill-teal-text); }
.d-resp-pill.pink    { background: var(--d-cell-pink);
    border-color: rgba(236, 72, 153, 0.30); color: var(--d-pill-pink-text); }
.d-resp-pill.dark    { background: var(--d-cell-dark);
    border-color: rgba(71, 85, 105, 0.40);  color: var(--d-pill-dark-text); }
.d-resp-pill.gray    { background: var(--d-cell-gray);
    border-color: rgba(148, 163, 184, 0.34); color: var(--d-pill-gray-text); }
.d-resp-pill.no-response {
    background: var(--d-cell-gray);
    border-color: rgba(148, 163, 184, 0.34);
    color: var(--d-pill-gray-text);
}

.d-resp-grid {
    flex: 1;
    overflow: hidden;
    padding: .65rem 1.2rem 1rem;
    display: grid;
    gap: .55rem;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    align-content: start;
}
.d-resp-grid[data-density="medium"] {
    gap: .45rem;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
}
.d-resp-grid[data-density="high"] {
    gap: .35rem;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
}
.d-resp-grid[data-density="high"] .d-resp-cell {
    padding: .4rem .55rem;
    font-size: .82rem;
}
.d-resp-grid[data-density="high"] .cell-icon {
    font-size: 1.05rem;
}

.d-resp-empty-wrap {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 8rem;
}
.d-resp-empty {
    display: inline-flex; align-items: center; gap: .55rem;
    padding: .85rem 1.25rem;
    border-radius: var(--d-radius-sm);
    background: var(--d-surface-2);
    border: 1px dashed var(--d-border-strong);
    color: var(--d-text-2);
    font-size: .95rem;
    font-weight: 600;
}
.d-resp-empty .mdi { font-size: 1.3rem; color: var(--d-text-3); }

.d-resp-sep {
    grid-column: 1 / -1;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        var(--d-border-strong),
        transparent);
    margin: .25rem 0;
}

.d-resp-cell {
    display: flex; align-items: center; gap: .55rem;
    padding: .55rem .7rem;
    border-radius: var(--d-radius-sm);
    background: var(--d-cell-info);
    border: 1px solid rgba(59, 130, 246, 0.22);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    min-width: 0;
    transition: background .15s, transform .12s;
}
.d-resp-cell .cell-icon {
    font-size: 1.4rem;
    color: var(--d-info);
    flex-shrink: 0;
    line-height: 1;
}
.d-resp-cell .cell-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.15;
}
.d-resp-cell .cell-ff {
    font-size: .85rem;
    font-weight: 800;
    color: var(--d-text);
    font-variant-numeric: tabular-nums;
}
.d-resp-cell .cell-name {
    font-size: .75rem;
    color: var(--d-text-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.d-resp-cell .cell-eta {
    margin-left: auto;
    padding: .2rem .55rem .22rem;
    border-radius: 999px;
    background: var(--d-cell-eta-bg);
    color: var(--d-cell-eta-text);
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .04em;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

/* Per-color responder cell variants. Each one swaps:
     - background tint
     - border color (more saturated)
     - icon color (full saturation) */
.d-resp-cell.success { background: var(--d-cell-success);
    border-color: rgba(16, 185, 129, 0.32); }
.d-resp-cell.success .cell-icon { color: var(--d-success); }
.d-resp-cell.danger  { background: var(--d-cell-danger);
    border-color: rgba(239, 68, 68, 0.32); }
.d-resp-cell.danger  .cell-icon { color: var(--d-accent); }
.d-resp-cell.warning { background: var(--d-cell-warning);
    border-color: rgba(245, 158, 11, 0.34); }
.d-resp-cell.warning .cell-icon { color: var(--d-warning); }
.d-resp-cell.info    { background: var(--d-cell-info);
    border-color: rgba(59, 130, 246, 0.32); }
.d-resp-cell.info    .cell-icon { color: var(--d-info); }
.d-resp-cell.purple  { background: var(--d-cell-purple);
    border-color: rgba(168, 85, 247, 0.32); }
.d-resp-cell.purple  .cell-icon { color: var(--d-purple); }
.d-resp-cell.teal    { background: var(--d-cell-teal);
    border-color: rgba(20, 184, 166, 0.32); }
.d-resp-cell.teal    .cell-icon { color: var(--d-teal); }
.d-resp-cell.pink    { background: var(--d-cell-pink);
    border-color: rgba(236, 72, 153, 0.32); }
.d-resp-cell.pink    .cell-icon { color: var(--d-pink); }
.d-resp-cell.dark    { background: var(--d-cell-dark);
    border-color: rgba(71, 85, 105, 0.42); }
.d-resp-cell.dark    .cell-icon { color: #cbd5e1; }
.d-resp-cell.gray    { background: var(--d-cell-gray);
    border-color: rgba(148, 163, 184, 0.36); }
.d-resp-cell.gray    .cell-icon { color: var(--d-gray); }

/* ── Idle / Training feed card ─────────────────────────── */
.d-idle {
    background-image: var(--d-standby-tint);
}
.d-idle-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .85rem;
    min-height: var(--d-card-head-height);
    padding: 0 1.2rem;
    border-bottom: 1px solid var(--d-border);
    flex-shrink: 0;
}
.d-idle-tabs {
    display: none;
}
.d-idle-tab {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .28rem .65rem .3rem;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
    background: var(--d-surface-2);
    border: 1px solid var(--d-border);
    color: var(--d-text-3);
}
.d-idle-tab .mdi { font-size: .85rem; }
.d-idle-tab.active {
    background: var(--d-tab-active-bg);
    border-color: rgba(59, 130, 246, 0.40);
    color: var(--d-tab-active-text);
    box-shadow: 0 0 0 1px rgba(59, 130, 246, 0.10),
                0 2px 8px rgba(59, 130, 246, 0.20);
}
.d-idle-title-wrap {
    min-width: 0;
    margin-bottom: 0;
}
.kicker {
    font-size: .7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--d-text-3);
    margin-bottom: .25rem;
}
.d-idle-title-wrap .title {
    font-size: 1.05rem;
    font-weight: 800;
    color: var(--d-text);
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.d-idle-meta {
    display: inline-flex; align-items: center; gap: .35rem;
    padding: .25rem .65rem .27rem;
    border-radius: 999px;
    background: var(--d-surface-2);
    border: 1px solid var(--d-border);
    font-size: .78rem;
    font-weight: 700;
    color: var(--d-text-2);
    font-variant-numeric: tabular-nums;
}
.d-idle-meta .mdi { font-size: .9rem; line-height: 1; }

.d-idle-feed {
    flex: 1;
    overflow: hidden;
    display: flex;
    gap: 1rem;
    padding: 1.2rem 1.2rem .9rem;
}
.d-idle-icon {
    flex-shrink: 0;
    width: 4.5rem; height: 4.5rem;
    border-radius: 1rem;
    display: flex; align-items: center; justify-content: center;
    background: var(--d-cell-info);
    border: 1px solid rgba(59, 130, 246, 0.30);
}
.d-idle-icon .mdi {
    font-size: 2.4rem;
    color: var(--d-info);
}
/* Idle icon color variants — match training/safety priority colors */
.d-idle-icon.red    { background: var(--d-cell-danger);
    border-color: rgba(239, 68, 68, 0.36); }
.d-idle-icon.red    .mdi { color: var(--d-accent); }
.d-idle-icon.yellow { background: var(--d-cell-warning);
    border-color: rgba(245, 158, 11, 0.38); }
.d-idle-icon.yellow .mdi { color: var(--d-warning); }
.d-idle-icon.green  { background: var(--d-cell-success);
    border-color: rgba(16, 185, 129, 0.36); }
.d-idle-icon.green  .mdi { color: var(--d-success); }
.d-idle-icon.blue   { background: var(--d-cell-info);
    border-color: rgba(59, 130, 246, 0.36); }
.d-idle-icon.blue   .mdi { color: var(--d-info); }
.d-idle-icon.purple { background: var(--d-cell-purple);
    border-color: rgba(168, 85, 247, 0.36); }
.d-idle-icon.purple .mdi { color: var(--d-purple); }

.d-idle-content {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: .35rem;
}
.d-idle-category {
    font-size: .72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .12em;
    color: var(--d-text-3);
}
.d-idle-feed-title {
    font-size: 1.55rem;
    font-weight: 800;
    color: var(--d-text);
    line-height: 1.2;
    letter-spacing: -0.01em;
    /* Allow up to ~3 lines before truncating; long messages
       become more readable on a wall display this way. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.d-idle-feed-detail {
    font-size: 1rem;
    line-height: 1.45;
    color: var(--d-text-2);
    /* 4 lines max for the body text. */
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.d-idle-sources {
    margin-top: .35rem;
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}
.d-idle-sources span {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .2rem .55rem .22rem;
    border-radius: 999px;
    background: var(--d-surface-2);
    border: 1px solid var(--d-border);
    font-size: .72rem;
    font-weight: 700;
    color: var(--d-text-2);
}
.d-idle-sources .mdi { font-size: .85rem; line-height: 1; }

.d-idle-foot {
    flex-shrink: 0;
    padding: .65rem 1.2rem 1rem;
    border-top: 1px solid var(--d-border);
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: .85rem;
    background: var(--d-summary-bg);
}
.d-idle-foot .count {
    font-size: .82rem;
    font-weight: 700;
    color: var(--d-text-2);
    font-variant-numeric: tabular-nums;
}
.d-idle-foot .hint {
    font-size: .78rem;
    color: var(--d-text-3);
    font-style: italic;
    text-align: right;
}
.d-idle-progress {
    height: 6px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    overflow: hidden;
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.18);
}
.d-idle-progress-bar {
    height: 100%;
    background: linear-gradient(90deg, var(--d-brand), var(--d-brand-2));
    border-radius: 999px;
    transition: width .8s ease-out;
    box-shadow: 0 0 8px rgba(192, 40, 45, 0.45);
}

/* ── New-call flash overlay ────────────────────────────── */
/* Full-screen border glow + brief brand-red wash when a new
   call arrives. Big and dramatic by design — this is the one
   thing that absolutely must be noticed from across the bay. */
.d-alert-flash {
    position: fixed;
    inset: 0;
    z-index: 1000;
    pointer-events: none;
    opacity: 0;
    background:
        radial-gradient(ellipse 80% 60% at 50% 50%,
            rgba(192, 40, 45, 0) 50%,
            rgba(192, 40, 45, 0.35) 100%);
    box-shadow: inset 0 0 0 0 rgba(239, 68, 68, 0.9);
    transition: opacity .25s ease;
}
.d-alert-flash.active {
    opacity: 1;
    animation: dAlertFlashPulse 1.5s ease-out infinite;
}
@keyframes dAlertFlashPulse {
    0%, 100% {
        box-shadow:
            inset 0 0 0 12px rgba(239, 68, 68, 0.85),
            inset 0 0 60px 30px rgba(239, 68, 68, 0.30);
    }
    50% {
        box-shadow:
            inset 0 0 0 6px rgba(239, 68, 68, 0.55),
            inset 0 0 80px 50px rgba(239, 68, 68, 0.15);
    }
}


/* ── Light-mode cleanup — remove muddy card gaps ─────────
   The grid gap shows the page behind the cards. In light mode,
   keep the shell, main grid, and cards on the same true-white
   surface and remove outside shadows so adjacent cards do not
   create darker channels between their rounded corners. */
@media (prefers-color-scheme: light) {
    body,
    body::before,
    .d-shell,
    .d-main {
        background: #ffffff !important;
    }

    body::after {
        display: none !important;
    }

    .d-card {
        background-color: #ffffff !important;
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        border: 1px solid rgba(15, 23, 42, 0.12) !important;
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95) !important;
        overflow: hidden;
    }

    .d-call,
    .d-resp,
    .d-idle {
        background-color: #ffffff !important;
    }
}

/* ── Responsive — for smaller secondary displays ────────
   Below 900px the three-column layout collapses to a column
   stack; below 600px the topbar wraps. The dashboard is
   primarily designed for 1080p+ wall displays but a captain
   on an iPad mini in the truck cab should still get value. */
@media (max-width: 900px) {
    .d-main {
        grid-template-columns: 1fr;
        grid-template-rows: auto auto 1fr;
    }
    .d-main.is-idle {
        grid-template-columns: 1fr;
    }
    .d-call-type { font-size: 1.85rem; }
}
@media (max-width: 600px) {
    .d-shell {
        padding: .65rem .75rem .75rem;
        gap: .65rem;
    }
    .d-topbar {
        flex-wrap: wrap;
        height: auto;
        padding: .65rem .85rem;
        gap: .5rem;
    }
    .d-brand { font-size: 1.1rem; }
    .d-brand .mdi { font-size: 1.4rem; }
    .d-clock { font-size: 1.15rem; min-width: 0; }
    .d-call-type { font-size: 1.4rem; }
}

/* ── Print — leave the page styled minimally in case anyone
   ever does a screen capture for an after-action report. */
@media print {
    body::before, body::after { display: none !important; }
    .d-alert-flash { display: none !important; }
    .d-card {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        box-shadow: none !important;
    }
}

/* ============================================================
 * Wall-display operating modes
 *
 * is-active:    newest call is under 1 hour old; show call + responders.
 * is-aged-call: newest call remains visible, but responder window is closed;
 *               show call + training/safety.
 * is-idle:      no call to show; show standing-by + training/safety.
 *
 * This screen is intended for TVs and fixed dashboards. Do not depend on
 * scrolling to reveal important information.
 * ========================================================= */
.d-main.is-active {
    grid-template-columns: minmax(18rem, .85fr) minmax(0, 2.15fr);
}
.d-main.is-active .d-idle {
    display: none;
}

.d-main.is-aged-call {
    grid-template-columns: minmax(22rem, 1fr) minmax(0, 1.25fr);
}
.d-main.is-aged-call .d-resp {
    display: none;
}
.d-main.is-aged-call .d-idle {
    display: flex;
}

.d-main.is-idle {
    grid-template-columns: minmax(18rem, .8fr) minmax(0, 2.2fr);
}
.d-main.is-idle .d-resp {
    display: none;
}
.d-main.is-idle .d-idle {
    display: flex;
}

/* No dashboard scrolling: tighten call details so the card itself fits. */
.d-call-body {
    overflow: hidden;
    gap: .7rem;
    padding: .9rem 1rem 1rem;
}
.d-call-type {
    font-size: clamp(1.55rem, 2.1vw, 2.4rem);
}
.d-call-section {
    padding: .58rem .72rem .65rem;
}
.d-call-section .value {
    font-size: clamp(.86rem, .95vw, 1.05rem);
    line-height: 1.25;
}
.d-call-section .value.message {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.d-other-calls {
    margin: 0 .9rem .9rem;
    padding: .55rem .7rem;
}

/* Responders are the primary display during the first hour. */
.d-main.is-active .d-resp-grid {
    padding: .55rem .8rem .75rem;
    gap: .34rem;
    grid-template-columns: repeat(auto-fill, minmax(8.25rem, 1fr));
    grid-auto-rows: min-content;
    align-content: start;
    overflow: hidden;
}
.d-resp-grid[data-density="medium"] {
    gap: .32rem;
    grid-template-columns: repeat(auto-fill, minmax(8.75rem, 1fr));
}
.d-resp-grid[data-density="high"] {
    gap: .28rem;
    grid-template-columns: repeat(auto-fill, minmax(7.75rem, 1fr));
}
.d-resp-grid[data-density="ultra"] {
    gap: .24rem;
    grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
}

.d-resp-grid[data-density="medium"] .d-resp-cell,
.d-resp-grid[data-density="high"] .d-resp-cell,
.d-resp-grid[data-density="ultra"] .d-resp-cell {
    padding: .31rem .42rem;
    gap: .34rem;
    min-height: 2.32rem;
}
.d-resp-grid[data-density="medium"] .cell-icon,
.d-resp-grid[data-density="high"] .cell-icon,
.d-resp-grid[data-density="ultra"] .cell-icon {
    font-size: .95rem;
}
.d-resp-grid[data-density="medium"] .cell-ff,
.d-resp-grid[data-density="high"] .cell-ff,
.d-resp-grid[data-density="ultra"] .cell-ff {
    font-size: .7rem;
}
.d-resp-grid[data-density="medium"] .cell-name,
.d-resp-grid[data-density="high"] .cell-name,
.d-resp-grid[data-density="ultra"] .cell-name {
    font-size: .62rem;
}
.d-resp-grid[data-density="medium"] .cell-eta,
.d-resp-grid[data-density="high"] .cell-eta,
.d-resp-grid[data-density="ultra"] .cell-eta {
    font-size: .58rem;
    padding: .1rem .28rem;
}

.d-resp-head {
    min-height: var(--d-card-head-height);
    padding: 0 .9rem;
}
.d-resp-summary {
    padding: .45rem .9rem .32rem;
    gap: .28rem;
}
.d-resp-pill {
    padding: .2rem .48rem .22rem;
    font-size: .66rem;
}

/* Visible responder group headers for TV readability. */
.d-resp-group-title {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .6rem;
    margin: .12rem 0 -.05rem;
    padding: .16rem .46rem .18rem;
    border-radius: .42rem;
    background: rgba(255, 255, 255, 0.055);
    border: 1px solid var(--d-border);
    color: var(--d-text-2);
    font-size: .58rem;
    font-weight: 900;
    letter-spacing: .1em;
    line-height: 1;
    text-transform: uppercase;
}
.d-resp-group-title.success { border-color: rgba(16, 185, 129, 0.32); }
.d-resp-group-title.danger  { border-color: rgba(239, 68, 68, 0.32); }
.d-resp-group-title.warning { border-color: rgba(245, 158, 11, 0.34); }
.d-resp-group-title.info    { border-color: rgba(59, 130, 246, 0.32); }
.d-resp-group-title.purple  { border-color: rgba(168, 85, 247, 0.32); }
.d-resp-group-title.teal    { border-color: rgba(20, 184, 166, 0.32); }
.d-resp-group-title.pink    { border-color: rgba(236, 72, 153, 0.32); }
.d-resp-group-title.dark    { border-color: rgba(71, 85, 105, 0.42); }
.d-resp-group-title.gray    { border-color: rgba(148, 163, 184, 0.36); }

/* Training/safety is secondary during aged-call display. */
.d-main.is-aged-call .d-idle-head,
.d-main.is-active .d-idle-head {
    min-height: var(--d-card-head-height);
    padding: 0 .85rem;
}
.d-main.is-aged-call .d-idle-tabs,
.d-main.is-active .d-idle-tabs {
    display: none;
}
.d-main.is-aged-call .d-idle-feed,
.d-main.is-active .d-idle-feed {
    padding: .85rem;
    gap: .7rem;
}
.d-main.is-aged-call .d-idle-icon,
.d-main.is-active .d-idle-icon {
    width: 3.2rem;
    height: 3.2rem;
    border-radius: .75rem;
}
.d-main.is-aged-call .d-idle-icon .mdi,
.d-main.is-active .d-idle-icon .mdi {
    font-size: 1.7rem;
}
.d-main.is-aged-call .d-idle-feed-title,
.d-main.is-active .d-idle-feed-title {
    font-size: clamp(1.05rem, 1.25vw, 1.45rem);
    line-height: 1.15;
    -webkit-line-clamp: 3;
}
.d-main.is-aged-call .d-idle-feed-detail,
.d-main.is-active .d-idle-feed-detail {
    font-size: clamp(.8rem, .9vw, 1rem);
    line-height: 1.28;
    -webkit-line-clamp: 5;
}
.d-main.is-aged-call .d-idle-sources,
.d-main.is-active .d-idle-sources {
    display: none;
}
.d-main.is-aged-call .d-idle-foot,
.d-main.is-active .d-idle-foot {
    padding: .45rem .8rem;
}

/* Light mode needs the same clean white surface across hidden gaps. */
@media (prefers-color-scheme: light) {
    .d-main.is-active,
    .d-main.is-aged-call,
    .d-main.is-idle {
        background: #ffffff !important;
    }
    .d-resp-group-title {
        background: rgba(15, 23, 42, 0.035);
    }
}

@media (max-width: 900px) {
    .d-main.is-active,
    .d-main.is-aged-call,
    .d-main.is-idle {
        grid-template-columns: 1fr;
    }
    .d-main.is-active .d-idle,
    .d-main.is-aged-call .d-resp,
    .d-main.is-idle .d-resp {
        display: none;
    }
}


/* ── Dashboard polish: equal card headers + remove low-value feed chrome ── */
.d-call-head,
.d-resp-head,
.d-idle-head {
    height: var(--d-card-head-height);
    min-height: var(--d-card-head-height);
    max-height: var(--d-card-head-height);
}

.d-idle-meta,
.d-idle-foot .count,
.d-idle-foot .hint {
    display: none !important;
}

.d-idle-foot {
    grid-template-columns: 1fr;
    padding: .45rem .85rem .65rem;
}

.d-main.is-aged-call .d-idle-feed {
    padding: 1rem 1rem .75rem;
}

.d-main.is-aged-call .d-idle-feed-title {
    font-size: clamp(1.25rem, 1.55vw, 1.85rem);
    -webkit-line-clamp: 3;
}

.d-main.is-aged-call .d-idle-feed-detail {
    font-size: clamp(.95rem, 1.05vw, 1.2rem);
    -webkit-line-clamp: 6;
}


/* ============================================================
 * Responder-name wall-display refinement
 *
 * The active responder window must show full names, not clipped
 * fragments. The responder panel gets more width during the
 * first-hour active window, and the grid cells use wider columns
 * with wrapping names.
 * ========================================================= */
.d-main.is-active {
    grid-template-columns: minmax(16rem, .58fr) minmax(0, 2.42fr);
}

.d-main.is-active .d-call-body {
    padding: .78rem .85rem .9rem;
    gap: .55rem;
}

.d-main.is-active .d-call-section {
    padding: .48rem .62rem .55rem;
}

.d-main.is-active .d-call-type {
    font-size: clamp(1.35rem, 1.75vw, 2.05rem);
}

.d-main.is-active .d-resp-grid {
    padding: .52rem .72rem .72rem;
    gap: .30rem;
    grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
}

.d-main.is-active .d-resp-grid[data-density="medium"],
.d-main.is-active .d-resp-grid[data-density="high"],
.d-main.is-active .d-resp-grid[data-density="ultra"] {
    grid-template-columns: repeat(auto-fill, minmax(11.35rem, 1fr));
}

.d-main.is-active .d-resp-grid[data-density="medium"] .d-resp-cell,
.d-main.is-active .d-resp-grid[data-density="high"] .d-resp-cell,
.d-main.is-active .d-resp-grid[data-density="ultra"] .d-resp-cell {
    min-height: 2.55rem;
    padding: .34rem .46rem;
}

.d-main.is-active .d-resp-cell {
    align-items: flex-start;
}

.d-main.is-active .d-resp-cell .cell-text {
    flex: 1 1 auto;
    min-width: 0;
}

.d-main.is-active .d-resp-cell .cell-name {
    display: block;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.12;
    max-height: 2.3em;
}

.d-main.is-active .d-resp-grid[data-density="medium"] .cell-name,
.d-main.is-active .d-resp-grid[data-density="high"] .cell-name,
.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-name {
    font-size: .68rem;
}

.d-main.is-active .d-resp-grid[data-density="medium"] .cell-ff,
.d-main.is-active .d-resp-grid[data-density="high"] .cell-ff,
.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-ff {
    font-size: .68rem;
}

.d-main.is-active .d-resp-cell .cell-eta {
    align-self: center;
}

/* Keep group labels compact so Available remains clearly first without
   burning too much vertical space. */
.d-main.is-active .d-resp-group-title {
    margin: .08rem 0 -.08rem;
    padding: .14rem .42rem .16rem;
}

/* ── Correction: keep call card at the previous active-call width ──
   The responder-name pass made the call column too narrow. During the
   first-hour responder window, preserve the call panel and let responder
   names gain space through wider responder cells, not by squeezing the call. */
.d-main.is-active {
    grid-template-columns: minmax(22rem, .85fr) minmax(0, 2.15fr) !important;
}

.d-main.is-active .d-call-body {
    padding: 1.1rem 1.3rem 1.3rem !important;
    gap: 1rem !important;
}

.d-main.is-active .d-call-section {
    padding: .7rem .9rem .8rem !important;
}

.d-main.is-active .d-call-type {
    font-size: 2.4rem !important;
}

/* Keep responder names readable without stealing width from the call card. */
.d-main.is-active .d-resp-grid {
    padding: .65rem .9rem .9rem !important;
    gap: .38rem !important;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)) !important;
}

.d-main.is-active .d-resp-grid[data-density="medium"],
.d-main.is-active .d-resp-grid[data-density="high"],
.d-main.is-active .d-resp-grid[data-density="ultra"] {
    grid-template-columns: repeat(auto-fill, minmax(12.25rem, 1fr)) !important;
}

.d-main.is-active .d-resp-cell {
    min-height: 2.7rem !important;
    padding: .42rem .55rem !important;
    gap: .42rem !important;
}

.d-main.is-active .d-resp-cell .cell-name {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    line-height: 1.08 !important;
    max-height: 2.2em !important;
}

@media (max-width: 900px) {
    .d-main.is-active {
        grid-template-columns: 1fr !important;
    }
}

/* ============================================================
 * Call-card fit refinement
 *
 * The dashboard is a fixed TV display, so the call card cannot
 * depend on scrolling. Keep the call column width from the prior
 * pass, but reduce the internal type scale and spacing so call
 * details fit. Comments are the only field allowed to truncate,
 * and they are limited to two rows.
 * ========================================================= */
.d-main.is-active {
    grid-template-columns: minmax(22rem, .85fr) minmax(0, 2.15fr) !important;
}

.d-main.is-active .d-call-body,
.d-main.is-aged-call .d-call-body {
    overflow: hidden !important;
    padding: .72rem .88rem .82rem !important;
    gap: .48rem !important;
}

.d-main.is-active .d-call-type,
.d-main.is-aged-call .d-call-type {
    font-size: clamp(1.25rem, 1.35vw, 1.75rem) !important;
    line-height: 1.06 !important;
    letter-spacing: -.015em !important;
    margin: 0 !important;
    overflow-wrap: anywhere;
}

.d-main.is-active .d-call-time,
.d-main.is-aged-call .d-call-time {
    font-size: clamp(.74rem, .78vw, .88rem) !important;
    margin-top: .18rem !important;
}

.d-main.is-active .d-call-section,
.d-main.is-aged-call .d-call-section {
    padding: .42rem .55rem .48rem !important;
    border-radius: .52rem !important;
}

.d-main.is-active .d-call-section .label,
.d-main.is-aged-call .d-call-section .label {
    font-size: .58rem !important;
    letter-spacing: .105em !important;
    margin-bottom: .16rem !important;
}

.d-main.is-active .d-call-section .value,
.d-main.is-aged-call .d-call-section .value {
    font-size: clamp(.78rem, .82vw, .94rem) !important;
    line-height: 1.16 !important;
}

.d-main.is-active .d-call-section .value.message,
.d-main.is-aged-call .d-call-section .value.message {
    display: -webkit-box !important;
    -webkit-line-clamp: 2 !important;
    -webkit-box-orient: vertical !important;
    overflow: hidden !important;
    line-height: 1.18 !important;
}

.d-main.is-active .d-units-list,
.d-main.is-aged-call .d-units-list {
    gap: .24rem !important;
}

.d-main.is-active .d-units-list li,
.d-main.is-aged-call .d-units-list li {
    padding: .16rem .42rem .18rem !important;
    font-size: .68rem !important;
    line-height: 1.05 !important;
}

.d-main.is-active .d-other-calls,
.d-main.is-aged-call .d-other-calls {
    margin: 0 .72rem .72rem !important;
    padding: .42rem .55rem !important;
}

.d-main.is-active .d-other-calls .label,
.d-main.is-aged-call .d-other-calls .label {
    font-size: .58rem !important;
    margin-bottom: .2rem !important;
}

.d-main.is-active .d-other-call-row,
.d-main.is-aged-call .d-other-call-row {
    padding: .24rem 0 !important;
    font-size: .76rem !important;
}

.d-main.is-active .d-other-call-row .time,
.d-main.is-aged-call .d-other-call-row .time {
    font-size: .68rem !important;
}

/* On 1080p-height displays, save a bit more vertical space without
   changing the overall card width. */
@media (max-height: 900px) {
    .d-main.is-active .d-call-body,
    .d-main.is-aged-call .d-call-body {
        padding: .58rem .72rem .68rem !important;
        gap: .38rem !important;
    }

    .d-main.is-active .d-call-type,
    .d-main.is-aged-call .d-call-type {
        font-size: clamp(1.12rem, 1.2vw, 1.55rem) !important;
    }

    .d-main.is-active .d-call-section,
    .d-main.is-aged-call .d-call-section {
        padding: .34rem .46rem .39rem !important;
    }
}

/* ============================================================
 * Call-card height tuning
 *
 * Width stays exactly as-is. This restores some vertical scale so
 * the call card uses more of the available TV height while still
 * preventing scroll. Comments remain capped at two lines.
 * ========================================================= */
.d-main.is-active .d-call-body,
.d-main.is-aged-call .d-call-body {
    padding: .95rem 1.05rem 1rem !important;
    gap: .68rem !important;
}

.d-main.is-active .d-call-type,
.d-main.is-aged-call .d-call-type {
    font-size: clamp(1.55rem, 1.62vw, 2.08rem) !important;
    line-height: 1.08 !important;
}

.d-main.is-active .d-call-time,
.d-main.is-aged-call .d-call-time {
    font-size: clamp(.82rem, .86vw, .98rem) !important;
    margin-top: .24rem !important;
}

.d-main.is-active .d-call-section,
.d-main.is-aged-call .d-call-section {
    padding: .58rem .72rem .64rem !important;
    border-radius: .62rem !important;
}

.d-main.is-active .d-call-section .label,
.d-main.is-aged-call .d-call-section .label {
    font-size: .64rem !important;
    margin-bottom: .24rem !important;
}

.d-main.is-active .d-call-section .value,
.d-main.is-aged-call .d-call-section .value {
    font-size: clamp(.9rem, .92vw, 1.06rem) !important;
    line-height: 1.22 !important;
}

.d-main.is-active .d-call-section .value.message,
.d-main.is-aged-call .d-call-section .value.message {
    -webkit-line-clamp: 2 !important;
    line-height: 1.22 !important;
    max-height: calc(1.22em * 2) !important;
}

.d-main.is-active .d-units-list,
.d-main.is-aged-call .d-units-list {
    gap: .32rem !important;
}

.d-main.is-active .d-units-list li,
.d-main.is-aged-call .d-units-list li {
    padding: .22rem .52rem .24rem !important;
    font-size: .76rem !important;
    line-height: 1.08 !important;
}

.d-main.is-active .d-other-calls,
.d-main.is-aged-call .d-other-calls {
    margin: 0 .95rem .95rem !important;
    padding: .52rem .68rem !important;
}

.d-main.is-active .d-other-calls .label,
.d-main.is-aged-call .d-other-calls .label {
    font-size: .64rem !important;
    margin-bottom: .28rem !important;
}

.d-main.is-active .d-other-call-row,
.d-main.is-aged-call .d-other-call-row {
    padding: .3rem 0 !important;
    font-size: .84rem !important;
}

.d-main.is-active .d-other-call-row .time,
.d-main.is-aged-call .d-other-call-row .time {
    font-size: .74rem !important;
}

/* 1080p-height displays still get the larger call card treatment,
   just slightly compressed compared with 4K. */
@media (max-height: 900px) {
    .d-main.is-active .d-call-body,
    .d-main.is-aged-call .d-call-body {
        padding: .78rem .9rem .84rem !important;
        gap: .55rem !important;
    }

    .d-main.is-active .d-call-type,
    .d-main.is-aged-call .d-call-type {
        font-size: clamp(1.38rem, 1.45vw, 1.88rem) !important;
    }

    .d-main.is-active .d-call-section,
    .d-main.is-aged-call .d-call-section {
        padding: .5rem .62rem .56rem !important;
    }

    .d-main.is-active .d-call-section .value,
    .d-main.is-aged-call .d-call-section .value {
        font-size: clamp(.84rem, .86vw, .98rem) !important;
    }
}


/* ============================================================
 * Theme state colours
 *
 * Keep the red Priority4 emergency theme whenever a call is on
 * screen. When there is no call and the dashboard is in idle mode,
 * switch the primary chrome and neutral accents to #1f2937.
 * ============================================================ */
:root {
    --d-idle-base: #1f2937;
    --d-idle-base-2: #111827;
    --d-idle-base-3: #374151;
    --d-idle-glow: rgba(31, 41, 55, 0.34);
}

body.d-mode-idle {
    --d-brand: #1f2937;
    --d-brand-2: #4b5563;
    --d-bg-glow: rgba(31, 41, 55, 0.26);
    --d-bg-glow-2: rgba(75, 85, 99, 0.16);
    --d-topbar-bg: linear-gradient(135deg,
        rgba(31, 41, 55, 0.96) 0%,
        rgba(17, 24, 39, 0.96) 58%,
        rgba(55, 65, 81, 0.96) 100%);
    --d-standby-tint: radial-gradient(800px 220px at 50% 0%,
        rgba(31, 41, 55, 0.18), transparent 72%);
    --d-tab-active-bg: rgba(31, 41, 55, 0.28);
    --d-tab-active-text: #f9fafb;
}

body.d-mode-idle::before {
    background:
        radial-gradient(ellipse 80% 60% at 80% 0%,
            rgba(31, 41, 55, 0.32) 0%, transparent 55%),
        radial-gradient(ellipse 70% 50% at 0% 100%,
            rgba(75, 85, 99, 0.14) 0%, transparent 55%),
        linear-gradient(180deg,
            var(--d-bg-base) 0%,
            var(--d-bg-mid) 60%,
            var(--d-bg-base) 100%);
}

body.d-mode-idle::after {
    background: radial-gradient(circle at 30% 40%,
        rgba(31, 41, 55, 0.16) 0%,
        transparent 36%);
}

body.d-mode-idle .d-topbar {
    background: var(--d-topbar-bg) !important;
    box-shadow:
        0 12px 32px rgba(31, 41, 55, 0.30),
        inset 0 1px 0 rgba(255, 255, 255, 0.12) !important;
}

body.d-mode-idle .d-status {
    background: rgba(255, 255, 255, 0.13);
    border-color: rgba(255, 255, 255, 0.22);
    color: #ffffff;
}

body.d-mode-idle .d-status .dot {
    background: #d1d5db;
    animation: none;
    box-shadow: 0 0 0 4px rgba(209, 213, 219, 0.16);
}

body.d-mode-idle .d-idle-tab.active,
body.d-mode-idle .d-idle-meta,
body.d-mode-idle .d-idle-sources span {
    border-color: rgba(31, 41, 55, 0.34);
}

body.d-mode-idle .d-idle-icon.blue {
    background: rgba(31, 41, 55, 0.20);
    border-color: rgba(31, 41, 55, 0.38);
}

body.d-mode-idle .d-idle-icon.blue .mdi {
    color: #9ca3af;
}

body.d-mode-idle .d-idle-progress-bar {
    background: linear-gradient(90deg, #1f2937, #4b5563) !important;
    box-shadow: 0 0 8px rgba(31, 41, 55, 0.45) !important;
}

/* In light mode the idle dashboard still uses the #1f2937 chrome,
   but the card bodies remain clean white so the rounded corners stay crisp. */
@media (prefers-color-scheme: light) {
    body.d-mode-idle,
    body.d-mode-idle::before,
    body.d-mode-idle .d-shell,
    body.d-mode-idle .d-main {
        background: #ffffff !important;
    }

    body.d-mode-idle .d-topbar {
        background: linear-gradient(135deg, #1f2937 0%, #111827 62%, #374151 100%) !important;
        box-shadow:
            0 1px 0 rgba(15, 23, 42, 0.08),
            inset 0 1px 0 rgba(255, 255, 255, 0.16) !important;
    }

    body.d-mode-idle .d-idle-icon.blue {
        background: rgba(31, 41, 55, 0.10);
        border-color: rgba(31, 41, 55, 0.24);
    }

    body.d-mode-idle .d-idle-icon.blue .mdi {
        color: #1f2937;
    }
}

/* ============================================================
 * TV screen-real-estate pass
 *
 * Current active-call view has the right split, but the content was
 * sitting too high with too much unused vertical space. This pass keeps
 * the call width stable, gives responder rows a little more visual
 * weight, and still leaves capacity for more responders / longer call
 * content without introducing scrolling.
 * ============================================================ */
:root {
    --d-card-head-height: 3.72rem;
}

/* Active view: preserve the call-card width and give the responder panel
   the rest. This keeps the call readable while maintaining room for up to
   the high-20s responder count. */
.d-main.is-active {
    grid-template-columns: minmax(28rem, .9fr) minmax(0, 2.2fr) !important;
    gap: 1rem !important;
}

/* Normalize all visible card headers. */
.d-call-head,
.d-resp-head,
.d-idle-head {
    min-height: var(--d-card-head-height) !important;
}

.d-call-head,
.d-resp-head {
    display: flex !important;
    align-items: center !important;
}

.d-idle-head {
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
}

/* Call card: use more of the vertical space without depending on scroll.
   Comments remain capped elsewhere at two lines. */
.d-main.is-active .d-call-body,
.d-main.is-aged-call .d-call-body {
    padding: 1.08rem 1.08rem 1.05rem !important;
    gap: .76rem !important;
    overflow: hidden !important;
}

.d-main.is-active .d-call-type,
.d-main.is-aged-call .d-call-type {
    font-size: clamp(1.72rem, 1.85vw, 2.3rem) !important;
    line-height: 1.08 !important;
    letter-spacing: -.018em !important;
}

.d-main.is-active .d-call-time,
.d-main.is-aged-call .d-call-time {
    font-size: clamp(.88rem, .9vw, 1rem) !important;
    margin-top: .25rem !important;
}

.d-main.is-active .d-call-section,
.d-main.is-aged-call .d-call-section {
    padding: .68rem .78rem .72rem !important;
    min-height: 3.55rem !important;
    border-radius: .7rem !important;
}

.d-main.is-active .d-call-section .label,
.d-main.is-aged-call .d-call-section .label {
    font-size: .66rem !important;
    margin-bottom: .22rem !important;
}

.d-main.is-active .d-call-section .value,
.d-main.is-aged-call .d-call-section .value {
    font-size: clamp(.94rem, .96vw, 1.08rem) !important;
    line-height: 1.22 !important;
}

.d-main.is-active .d-call-section .value.message,
.d-main.is-aged-call .d-call-section .value.message {
    -webkit-line-clamp: 2 !important;
    max-height: calc(1.22em * 2) !important;
}

.d-main.is-active .d-units-list li,
.d-main.is-aged-call .d-units-list li {
    font-size: .82rem !important;
    padding: .24rem .58rem .26rem !important;
}

.d-main.is-active .d-other-calls,
.d-main.is-aged-call .d-other-calls {
    margin: 0 1.05rem 1.05rem !important;
    padding: .6rem .72rem !important;
}

.d-main.is-active .d-other-call-row,
.d-main.is-aged-call .d-other-call-row {
    padding: .34rem 0 !important;
    font-size: .88rem !important;
}

/* Responder card: slightly larger rows and clearer lanes, while keeping
   enough room for 28+ responders on 1080p/4K displays. */
.d-main.is-active .d-resp-summary {
    padding: .6rem 1rem .34rem !important;
    gap: .42rem !important;
}

.d-main.is-active .d-resp-grid {
    padding: .6rem 1rem 1rem !important;
    gap: .46rem !important;
    grid-template-columns: repeat(auto-fill, minmax(13.75rem, 1fr)) !important;
    align-content: start !important;
    overflow: hidden !important;
}

.d-main.is-active .d-resp-grid[data-density="medium"],
.d-main.is-active .d-resp-grid[data-density="high"],
.d-main.is-active .d-resp-grid[data-density="ultra"] {
    grid-template-columns: repeat(auto-fill, minmax(12.75rem, 1fr)) !important;
}

.d-main.is-active .d-resp-cell {
    min-height: 3.05rem !important;
    padding: .48rem .62rem !important;
    gap: .46rem !important;
    align-items: center !important;
}

.d-main.is-active .d-resp-cell .cell-ff {
    font-size: .78rem !important;
    line-height: 1.08 !important;
}

.d-main.is-active .d-resp-cell .cell-name {
    font-size: .72rem !important;
    line-height: 1.12 !important;
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    max-height: 2.3em !important;
}

.d-main.is-active .d-resp-cell .cell-eta {
    font-size: .7rem !important;
    padding: .18rem .48rem .2rem !important;
}

.d-main.is-active .d-resp-group-title {
    margin: .12rem 0 -.04rem !important;
    padding: .18rem .52rem .2rem !important;
    font-size: .64rem !important;
}

/* If the screen height is tighter, compress only slightly. */
@media (max-height: 900px) {
    .d-main.is-active .d-call-body,
    .d-main.is-aged-call .d-call-body {
        padding: .92rem .94rem .92rem !important;
        gap: .62rem !important;
    }

    .d-main.is-active .d-call-type,
    .d-main.is-aged-call .d-call-type {
        font-size: clamp(1.5rem, 1.58vw, 2rem) !important;
    }

    .d-main.is-active .d-call-section,
    .d-main.is-aged-call .d-call-section {
        min-height: 3.25rem !important;
        padding: .58rem .68rem .62rem !important;
    }

    .d-main.is-active .d-resp-grid {
        gap: .38rem !important;
        grid-template-columns: repeat(auto-fill, minmax(12.9rem, 1fr)) !important;
    }

    .d-main.is-active .d-resp-grid[data-density="medium"],
    .d-main.is-active .d-resp-grid[data-density="high"],
    .d-main.is-active .d-resp-grid[data-density="ultra"] {
        grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)) !important;
    }

    .d-main.is-active .d-resp-cell {
        min-height: 2.78rem !important;
        padding: .4rem .54rem !important;
    }
}

@media (max-width: 900px) {
    .d-main.is-active {
        grid-template-columns: 1fr !important;
    }
}


/* ── Response summary / status lanes polish ───────────────
   The response summary row is driven by response_types from the
   agency-specific table. Make the row use the full card width and
   make the lane headers carry the same status color theme as the
   responder cells. */
.d-main.is-active .d-resp-summary,
.d-resp-summary {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(10.75rem, 1fr)) !important;
    width: 100% !important;
    align-items: stretch !important;
    padding: .56rem 1rem .42rem !important;
    gap: .45rem !important;
}

.d-main.is-active .d-resp-pill,
.d-resp-pill {
    width: 100% !important;
    justify-content: center !important;
    min-height: 1.95rem !important;
    padding: .28rem .6rem .3rem !important;
    font-size: .72rem !important;
    white-space: nowrap !important;
}

.d-resp-pill.no-response {
    background: var(--d-cell-gray) !important;
    border-color: rgba(148, 163, 184, 0.38) !important;
    color: var(--d-pill-gray-text) !important;
}

/* Status lane dividers: keep the same color language as the response
   buttons instead of looking like plain/empty separator lines. */
.d-main.is-active .d-resp-group-title,
.d-resp-group-title {
    border-width: 1px !important;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.18) !important;
}

.d-resp-group-title.success {
    background: var(--d-cell-success) !important;
    border-color: rgba(16, 185, 129, 0.42) !important;
    color: var(--d-pill-success-text) !important;
}
.d-resp-group-title.danger {
    background: var(--d-cell-danger) !important;
    border-color: rgba(239, 68, 68, 0.42) !important;
    color: var(--d-pill-danger-text) !important;
}
.d-resp-group-title.warning {
    background: var(--d-cell-warning) !important;
    border-color: rgba(245, 158, 11, 0.46) !important;
    color: var(--d-pill-warning-text) !important;
}
.d-resp-group-title.info {
    background: var(--d-cell-info) !important;
    border-color: rgba(59, 130, 246, 0.42) !important;
    color: var(--d-pill-info-text) !important;
}
.d-resp-group-title.purple {
    background: var(--d-cell-purple) !important;
    border-color: rgba(168, 85, 247, 0.42) !important;
    color: var(--d-pill-purple-text) !important;
}
.d-resp-group-title.teal {
    background: var(--d-cell-teal) !important;
    border-color: rgba(20, 184, 166, 0.42) !important;
    color: var(--d-pill-teal-text) !important;
}
.d-resp-group-title.pink {
    background: var(--d-cell-pink) !important;
    border-color: rgba(236, 72, 153, 0.42) !important;
    color: var(--d-pill-pink-text) !important;
}
.d-resp-group-title.dark {
    background: var(--d-cell-dark) !important;
    border-color: rgba(71, 85, 105, 0.48) !important;
    color: var(--d-pill-dark-text) !important;
}
.d-resp-group-title.gray,
.d-resp-group-title.no-response {
    background: var(--d-cell-gray) !important;
    border-color: rgba(148, 163, 184, 0.44) !important;
    color: var(--d-pill-gray-text) !important;
}

@media (max-width: 1200px) {
    .d-main.is-active .d-resp-summary,
    .d-resp-summary {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    }
}

/* ── Darker responder status lane dividers ─────────────────
   Stronger tinted backgrounds so AVAILABLE / SCENE /
   UNAVAILABLE divider bars read as real section headers on TV,
   while keeping text contrast high in both light and dark modes. */
.d-main.is-active .d-resp-group-title,
.d-resp-group-title {
    border-width: 1px !important;
    font-weight: 950 !important;
    letter-spacing: .13em !important;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.22),
        0 1px 2px rgba(15,23,42,.06) !important;
}

.d-resp-group-title.success {
    background: rgba(6, 95, 70, 0.18) !important;
    border-color: rgba(6, 95, 70, 0.50) !important;
    color: #064e3b !important;
}
.d-resp-group-title.danger {
    background: rgba(127, 29, 29, 0.16) !important;
    border-color: rgba(127, 29, 29, 0.52) !important;
    color: #7f1d1d !important;
}
.d-resp-group-title.warning {
    background: rgba(146, 64, 14, 0.18) !important;
    border-color: rgba(146, 64, 14, 0.55) !important;
    color: #78350f !important;
}
.d-resp-group-title.info {
    background: rgba(30, 58, 138, 0.16) !important;
    border-color: rgba(30, 58, 138, 0.50) !important;
    color: #1e3a8a !important;
}
.d-resp-group-title.purple {
    background: rgba(88, 28, 135, 0.16) !important;
    border-color: rgba(88, 28, 135, 0.50) !important;
    color: #581c87 !important;
}
.d-resp-group-title.teal {
    background: rgba(19, 78, 74, 0.17) !important;
    border-color: rgba(19, 78, 74, 0.52) !important;
    color: #134e4a !important;
}
.d-resp-group-title.pink {
    background: rgba(131, 24, 67, 0.16) !important;
    border-color: rgba(131, 24, 67, 0.50) !important;
    color: #831843 !important;
}
.d-resp-group-title.dark {
    background: rgba(30, 41, 59, 0.20) !important;
    border-color: rgba(30, 41, 59, 0.55) !important;
    color: #1e293b !important;
}
.d-resp-group-title.gray,
.d-resp-group-title.no-response {
    background: rgba(51, 65, 85, 0.16) !important;
    border-color: rgba(51, 65, 85, 0.50) !important;
    color: #334155 !important;
}

@media (prefers-color-scheme: dark) {
    .d-resp-group-title.success {
        background: rgba(16, 185, 129, 0.24) !important;
        border-color: rgba(16, 185, 129, 0.58) !important;
        color: #d1fae5 !important;
    }
    .d-resp-group-title.danger {
        background: rgba(239, 68, 68, 0.24) !important;
        border-color: rgba(239, 68, 68, 0.58) !important;
        color: #fee2e2 !important;
    }
    .d-resp-group-title.warning {
        background: rgba(245, 158, 11, 0.25) !important;
        border-color: rgba(245, 158, 11, 0.62) !important;
        color: #fef3c7 !important;
    }
    .d-resp-group-title.info {
        background: rgba(59, 130, 246, 0.24) !important;
        border-color: rgba(59, 130, 246, 0.58) !important;
        color: #dbeafe !important;
    }
    .d-resp-group-title.purple {
        background: rgba(168, 85, 247, 0.24) !important;
        border-color: rgba(168, 85, 247, 0.58) !important;
        color: #f3e8ff !important;
    }
    .d-resp-group-title.teal {
        background: rgba(20, 184, 166, 0.24) !important;
        border-color: rgba(20, 184, 166, 0.58) !important;
        color: #ccfbf1 !important;
    }
    .d-resp-group-title.pink {
        background: rgba(236, 72, 153, 0.24) !important;
        border-color: rgba(236, 72, 153, 0.58) !important;
        color: #fce7f3 !important;
    }
    .d-resp-group-title.dark,
    .d-resp-group-title.gray,
    .d-resp-group-title.no-response {
        background: rgba(148, 163, 184, 0.22) !important;
        border-color: rgba(148, 163, 184, 0.54) !important;
        color: #f8fafc !important;
    }
}

/* ============================================================
 * Final state theme override
 * Active response window remains red. Idle and aged-call
 * (non-emergency mode) use #1f2937 / blue-slate chrome.
 * ============================================================ */
body.d-mode-idle,
body.d-mode-aged-call {
    --d-brand: #1f2937;
    --d-brand-2: #475569;
    --d-accent: #1f2937;
    --d-bg-glow: rgba(31, 41, 55, 0.30);
    --d-bg-glow-2: rgba(59, 130, 246, 0.14);
    --d-topbar-bg: linear-gradient(135deg,
        #1f2937 0%,
        #273447 56%,
        #111827 100%);
    --d-call-tint: radial-gradient(1100px 320px at 0% 0%,
        rgba(31, 41, 55, 0.15), transparent 66%);
    --d-standby-tint: radial-gradient(900px 260px at 50% 0%,
        rgba(59, 130, 246, 0.12), transparent 72%);
    --d-tab-active-bg: rgba(31, 41, 55, 0.34);
    --d-tab-active-text: #f8fafc;
}

body.d-mode-idle::before,
body.d-mode-aged-call::before {
    background:
        radial-gradient(ellipse 80% 60% at 80% 0%,
            rgba(31, 41, 55, 0.34) 0%, transparent 55%),
        radial-gradient(ellipse 70% 50% at 0% 100%,
            rgba(59, 130, 246, 0.15) 0%, transparent 55%),
        linear-gradient(180deg,
            var(--d-bg-base) 0%,
            var(--d-bg-mid) 60%,
            var(--d-bg-base) 100%) !important;
}

body.d-mode-idle::after,
body.d-mode-aged-call::after {
    background: radial-gradient(circle at 30% 40%,
        rgba(31, 41, 55, 0.18) 0%,
        transparent 36%) !important;
}

body.d-mode-idle .d-topbar,
body.d-mode-aged-call .d-topbar {
    background: var(--d-topbar-bg) !important;
    box-shadow:
        0 12px 32px rgba(31, 41, 55, 0.30),
        inset 0 1px 0 rgba(255, 255, 255, 0.12) !important;
}

/* Aged-call screen still displays a call, but it is no longer in the
   active responder window, so remove the red emergency header treatment. */
body.d-mode-aged-call .d-call {
    background-image: var(--d-call-tint) !important;
}

body.d-mode-aged-call .d-call-head {
    background: rgba(31, 41, 55, 0.16) !important;
    border-bottom-color: rgba(148, 163, 184, 0.22) !important;
}

body.d-mode-aged-call .badge-newest.is-call {
    background: #1f2937 !important;
    color: #ffffff !important;
    box-shadow: 0 2px 10px rgba(31, 41, 55, 0.32) !important;
}

body.d-mode-idle .d-status,
body.d-mode-aged-call .d-status {
    background: rgba(255, 255, 255, 0.13) !important;
    border-color: rgba(255, 255, 255, 0.22) !important;
    color: #ffffff !important;
}

body.d-mode-idle .d-status .dot,
body.d-mode-aged-call .d-status .dot {
    background: #d1d5db !important;
    animation: none !important;
    box-shadow: 0 0 0 4px rgba(209, 213, 219, 0.16) !important;
}

body.d-mode-idle .d-idle,
body.d-mode-aged-call .d-idle {
    background-image: var(--d-standby-tint) !important;
}

body.d-mode-idle .d-idle-tab.active,
body.d-mode-aged-call .d-idle-tab.active,
body.d-mode-idle .d-idle-meta,
body.d-mode-aged-call .d-idle-meta,
body.d-mode-idle .d-idle-sources span,
body.d-mode-aged-call .d-idle-sources span {
    border-color: rgba(31, 41, 55, 0.34) !important;
}

body.d-mode-idle .d-idle-icon.blue,
body.d-mode-aged-call .d-idle-icon.blue {
    background: rgba(31, 41, 55, 0.20) !important;
    border-color: rgba(31, 41, 55, 0.38) !important;
}

body.d-mode-idle .d-idle-icon.blue .mdi,
body.d-mode-aged-call .d-idle-icon.blue .mdi {
    color: #9ca3af !important;
}

body.d-mode-idle .d-idle-progress-bar,
body.d-mode-aged-call .d-idle-progress-bar {
    background: linear-gradient(90deg, #1f2937, #475569) !important;
    box-shadow: 0 0 8px rgba(31, 41, 55, 0.45) !important;
}

@media (prefers-color-scheme: light) {
    body.d-mode-idle,
    body.d-mode-aged-call,
    body.d-mode-idle::before,
    body.d-mode-aged-call::before,
    body.d-mode-idle .d-shell,
    body.d-mode-aged-call .d-shell,
    body.d-mode-idle .d-main,
    body.d-mode-aged-call .d-main {
        background: #ffffff !important;
    }

    body.d-mode-idle .d-topbar,
    body.d-mode-aged-call .d-topbar {
        background: linear-gradient(135deg, #1f2937 0%, #334155 62%, #111827 100%) !important;
        box-shadow:
            0 1px 0 rgba(15, 23, 42, 0.08),
            inset 0 1px 0 rgba(255, 255, 255, 0.16) !important;
    }

    body.d-mode-aged-call .d-call-head {
        background: rgba(31, 41, 55, 0.08) !important;
        border-bottom-color: rgba(15, 23, 42, 0.12) !important;
    }

    body.d-mode-idle .d-idle-icon.blue,
    body.d-mode-aged-call .d-idle-icon.blue {
        background: rgba(31, 41, 55, 0.10) !important;
        border-color: rgba(31, 41, 55, 0.24) !important;
    }

    body.d-mode-idle .d-idle-icon.blue .mdi,
    body.d-mode-aged-call .d-idle-icon.blue .mdi {
        color: #1f2937 !important;
    }
}

/* ============================================================
 * Final responder lane spacing / divider contrast override
 * - Summary pills stay equal-width across the row.
 * - Add clear breathing room before each next status lane.
 * - Use darker divider bars with high-contrast text.
 * ============================================================ */

.d-main.is-active .d-resp-summary,
.d-resp-summary {
    grid-template-columns: repeat(auto-fit, minmax(10.75rem, 1fr)) !important;
    column-gap: .58rem !important;
    row-gap: .42rem !important;
}

.d-main.is-active .d-resp-pill,
.d-resp-pill {
    min-width: 0 !important;
    text-align: center !important;
}

/* Base lane header sizing. Keep headers compact, but make them read
   like actual section bars instead of thin separator lines. */
.d-main.is-active .d-resp-group-title,
.d-resp-group-title {
    margin: .28rem 0 .42rem !important;
    padding: .24rem .62rem .26rem !important;
    min-height: 1.32rem !important;
    border-radius: .42rem !important;
    border-width: 1px !important;
    font-size: .66rem !important;
    font-weight: 950 !important;
    letter-spacing: .14em !important;
    line-height: 1 !important;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.18),
        0 1px 2px rgba(15,23,42,.10) !important;
}

/* Add the requested spacer between one status group’s content and the
   next status divider. The first AVAILABLE divider stays tucked close
   under the summary row. */
.d-main.is-active .d-resp-grid > .d-resp-group-title:not(:first-child),
.d-resp-grid > .d-resp-group-title:not(:first-child) {
    margin-top: 1.05rem !important;
}

.d-main.is-active .d-resp-grid > .d-resp-group-title:first-child,
.d-resp-grid > .d-resp-group-title:first-child {
    margin-top: .18rem !important;
}

/* Dark section bars — readable on light TV displays and still clear
   in dark mode because text is forced to near-white. */
.d-resp-group-title.success {
    background: linear-gradient(180deg, rgba(6, 95, 70, .98), rgba(5, 78, 61, .98)) !important;
    border-color: rgba(16, 185, 129, .64) !important;
    color: #ecfdf5 !important;
}

.d-resp-group-title.danger {
    background: linear-gradient(180deg, rgba(127, 29, 29, .98), rgba(105, 23, 23, .98)) !important;
    border-color: rgba(239, 68, 68, .64) !important;
    color: #fef2f2 !important;
}

.d-resp-group-title.warning {
    background: linear-gradient(180deg, rgba(146, 64, 14, .98), rgba(120, 53, 15, .98)) !important;
    border-color: rgba(245, 158, 11, .68) !important;
    color: #fffbeb !important;
}

.d-resp-group-title.info {
    background: linear-gradient(180deg, rgba(30, 58, 138, .98), rgba(30, 64, 175, .98)) !important;
    border-color: rgba(59, 130, 246, .64) !important;
    color: #eff6ff !important;
}

.d-resp-group-title.purple {
    background: linear-gradient(180deg, rgba(88, 28, 135, .98), rgba(76, 29, 149, .98)) !important;
    border-color: rgba(168, 85, 247, .64) !important;
    color: #faf5ff !important;
}

.d-resp-group-title.teal {
    background: linear-gradient(180deg, rgba(19, 78, 74, .98), rgba(17, 94, 89, .98)) !important;
    border-color: rgba(20, 184, 166, .64) !important;
    color: #f0fdfa !important;
}

.d-resp-group-title.pink {
    background: linear-gradient(180deg, rgba(131, 24, 67, .98), rgba(112, 26, 117, .98)) !important;
    border-color: rgba(236, 72, 153, .64) !important;
    color: #fdf2f8 !important;
}

.d-resp-group-title.dark,
.d-resp-group-title.gray,
.d-resp-group-title.no-response {
    background: linear-gradient(180deg, rgba(31, 41, 55, .98), rgba(15, 23, 42, .98)) !important;
    border-color: rgba(148, 163, 184, .58) !important;
    color: #f8fafc !important;
}

/* On shorter 1080p-style displays, keep the extra spacing but do not
   let it burn too much vertical room. */
@media (max-height: 900px) {
    .d-main.is-active .d-resp-grid > .d-resp-group-title:not(:first-child),
    .d-resp-grid > .d-resp-group-title:not(:first-child) {
        margin-top: .82rem !important;
    }

    .d-main.is-active .d-resp-group-title,
    .d-resp-group-title {
        margin-bottom: .34rem !important;
        min-height: 1.22rem !important;
        padding-top: .2rem !important;
        padding-bottom: .22rem !important;
    }
}


/* ============================================================
 * FINAL OVERRIDE — responder summary alignment + real spacers
 * ============================================================ */

/* Summary count row: equal width, content horizontally and vertically centered. */
.d-main.is-active .d-resp-summary,
.d-resp-summary {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)) !important;
    align-items: center !important;
    justify-items: stretch !important;
    gap: .5rem !important;
    padding: .62rem 1.1rem .58rem !important;
}

.d-main.is-active .d-resp-pill,
.d-resp-pill {
    width: 100% !important;
    min-height: 2.05rem !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
    line-height: 1 !important;
    padding: .38rem .55rem !important;
}

.d-main.is-active .d-resp-pill .mdi,
.d-resp-pill .mdi {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    line-height: 1 !important;
}

/* Real grid spacer inserted by dashboard.php between status groups.
   Margin alone was not reliable in the CSS grid, so this forces a full-width row. */
.d-resp-group-spacer {
    grid-column: 1 / -1 !important;
    height: .82rem !important;
    min-height: .82rem !important;
    width: 100% !important;
    display: block !important;
}

/* Keep divider/header bars tight to their own content; the spacer now handles the gap. */
.d-main.is-active .d-resp-group-title,
.d-resp-group-title {
    margin: 0 0 .42rem 0 !important;
    min-height: 1.34rem !important;
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    padding: .25rem .65rem .27rem !important;
    line-height: 1 !important;
}

/* First status divider under the summary row. */
.d-main.is-active .d-resp-grid > .d-resp-group-title:first-child,
.d-resp-grid > .d-resp-group-title:first-child {
    margin-top: 0 !important;
}

/* Darker divider bars with readable text. */
.d-resp-group-title.success {
    background: linear-gradient(180deg, #047857 0%, #065f46 100%) !important;
    border-color: rgba(16, 185, 129, .78) !important;
    color: #ecfdf5 !important;
}

.d-resp-group-title.danger {
    background: linear-gradient(180deg, #991b1b 0%, #7f1d1d 100%) !important;
    border-color: rgba(248, 113, 113, .78) !important;
    color: #fef2f2 !important;
}

.d-resp-group-title.warning {
    background: linear-gradient(180deg, #a16207 0%, #78350f 100%) !important;
    border-color: rgba(251, 191, 36, .82) !important;
    color: #fffbeb !important;
}

.d-resp-group-title.info {
    background: linear-gradient(180deg, #1d4ed8 0%, #1e3a8a 100%) !important;
    border-color: rgba(96, 165, 250, .78) !important;
    color: #eff6ff !important;
}

.d-resp-group-title.purple {
    background: linear-gradient(180deg, #7e22ce 0%, #581c87 100%) !important;
    border-color: rgba(192, 132, 252, .78) !important;
    color: #faf5ff !important;
}

.d-resp-group-title.teal {
    background: linear-gradient(180deg, #0f766e 0%, #134e4a 100%) !important;
    border-color: rgba(45, 212, 191, .78) !important;
    color: #f0fdfa !important;
}

.d-resp-group-title.pink {
    background: linear-gradient(180deg, #be185d 0%, #831843 100%) !important;
    border-color: rgba(244, 114, 182, .78) !important;
    color: #fdf2f8 !important;
}

.d-resp-group-title.dark,
.d-resp-group-title.gray,
.d-resp-group-title.no-response {
    background: linear-gradient(180deg, #334155 0%, #1f2937 100%) !important;
    border-color: rgba(148, 163, 184, .72) !important;
    color: #f8fafc !important;
}

@media (max-height: 900px) {
    .d-resp-group-spacer {
        height: .68rem !important;
        min-height: .68rem !important;
    }

    .d-main.is-active .d-resp-summary,
    .d-resp-summary {
        padding-top: .52rem !important;
        padding-bottom: .50rem !important;
    }
}

/* ============================================================
 * HARD FIX: responder status group spacing + summary centering
 * Spacer is now inserted AFTER each group, before the next divider.
 * This makes the visual sequence: divider -> content -> blank space -> divider.
 * ============================================================ */

.d-main.is-active .d-resp-summary,
.d-resp-summary {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(10.75rem, 1fr)) !important;
    align-items: center !important;
    justify-items: stretch !important;
    column-gap: .70rem !important;
    row-gap: .45rem !important;
    padding: .72rem .95rem .70rem !important;
}

.d-main.is-active .d-resp-pill,
.d-resp-pill {
    width: 100% !important;
    height: 2.05rem !important;
    min-height: 2.05rem !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
    gap: .42rem !important;
    margin: 0 !important;
    line-height: 1 !important;
}

.d-resp-grid > .d-resp-group-spacer {
    grid-column: 1 / -1 !important;
    height: 1.18rem !important;
    min-height: 1.18rem !important;
    max-height: 1.18rem !important;
    display: block !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
    pointer-events: none !important;
}

.d-main.is-active .d-resp-group-title,
.d-resp-group-title {
    margin: 0 0 .42rem 0 !important;
    padding: .28rem .70rem .30rem !important;
    min-height: 1.42rem !important;
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
    line-height: 1 !important;
    font-size: .68rem !important;
    font-weight: 950 !important;
    letter-spacing: .15em !important;
    color: #ffffff !important;
}

.d-resp-group-title.success {
    background: linear-gradient(180deg, #047857 0%, #064e3b 100%) !important;
    border-color: rgba(16, 185, 129, .86) !important;
}

.d-resp-group-title.danger {
    background: linear-gradient(180deg, #991b1b 0%, #7f1d1d 100%) !important;
    border-color: rgba(248, 113, 113, .86) !important;
}

.d-resp-group-title.warning {
    background: linear-gradient(180deg, #92400e 0%, #78350f 100%) !important;
    border-color: rgba(251, 191, 36, .88) !important;
}

.d-resp-group-title.info {
    background: linear-gradient(180deg, #1d4ed8 0%, #1e3a8a 100%) !important;
    border-color: rgba(96, 165, 250, .86) !important;
}

.d-resp-group-title.purple {
    background: linear-gradient(180deg, #7e22ce 0%, #581c87 100%) !important;
    border-color: rgba(192, 132, 252, .86) !important;
}

.d-resp-group-title.teal {
    background: linear-gradient(180deg, #0f766e 0%, #134e4a 100%) !important;
    border-color: rgba(45, 212, 191, .86) !important;
}

.d-resp-group-title.pink {
    background: linear-gradient(180deg, #be185d 0%, #831843 100%) !important;
    border-color: rgba(244, 114, 182, .86) !important;
}

.d-resp-group-title.dark,
.d-resp-group-title.gray,
.d-resp-group-title.no-response {
    background: linear-gradient(180deg, #334155 0%, #1f2937 100%) !important;
    border-color: rgba(148, 163, 184, .78) !important;
}

@media (max-height: 900px) {
    .d-resp-grid > .d-resp-group-spacer {
        height: .95rem !important;
        min-height: .95rem !important;
        max-height: .95rem !important;
    }
}


/* ============================================================
 * Station Board aged-call / idle layout
 * Turns the right-side filler card into a useful station board.
 * ========================================================= */
.d-idle-head {
    justify-content: space-between;
    text-align: left;
}

.d-idle-title-wrap {
    margin: 0;
}

.d-idle-title-wrap .title {
    text-align: left;
}

.d-station-board {
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto;
    gap: 1rem;
    padding: 1.15rem 1.2rem 1rem;
}

.d-station-board .d-idle-feed {
    padding: 0;
}

.d-board-feature {
    align-items: flex-start;
    border-radius: calc(var(--d-radius) - .25rem);
    background: linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.015));
    border: 1px solid var(--d-border);
    padding: 1.2rem !important;
}

.d-board-feature .d-idle-icon {
    width: 4.25rem;
    height: 4.25rem;
    border-radius: 1rem;
}

.d-board-feature .d-idle-icon .mdi {
    font-size: 2.25rem;
}

.d-board-feature .d-idle-feed-title {
    font-size: clamp(1.65rem, 2vw, 2.35rem) !important;
    line-height: 1.12 !important;
    -webkit-line-clamp: 3 !important;
}

.d-board-feature .d-idle-feed-detail {
    font-size: clamp(1.05rem, 1.25vw, 1.35rem) !important;
    line-height: 1.35 !important;
    -webkit-line-clamp: 5 !important;
    max-width: 70rem;
}

.d-board-panels {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .8rem;
}

.d-board-panel {
    min-width: 0;
    border-radius: .95rem;
    border: 1px solid var(--d-border);
    background: rgba(255,255,255,.045);
    padding: .85rem .95rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: .32rem;
}

.d-board-panel .panel-label {
    display: flex;
    align-items: center;
    gap: .38rem;
    color: var(--d-text-3);
    font-size: .68rem;
    font-weight: 900;
    letter-spacing: .11em;
    text-transform: uppercase;
}

.d-board-panel .panel-label .mdi {
    font-size: 1rem;
    color: var(--d-info);
}

.d-board-panel .panel-value {
    min-width: 0;
    color: var(--d-text);
    font-size: clamp(1rem, 1.1vw, 1.25rem);
    font-weight: 900;
    line-height: 1.15;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.d-board-panel .panel-sub {
    min-width: 0;
    color: var(--d-text-2);
    font-size: clamp(.78rem, .82vw, .95rem);
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.d-idle-foot {
    padding: 0 .95rem .75rem !important;
    border-top: 0;
    background: transparent;
}

.d-idle-foot .d-idle-progress {
    width: 100%;
}

@media (prefers-color-scheme: light) {
    .d-board-feature,
    .d-board-panel {
        background: rgba(248,250,252,.72);
        border-color: rgba(15,23,42,.11);
    }
}

@media (max-width: 1200px) {
    .d-board-panels {
        grid-template-columns: 1fr;
    }
}


/* ============================================================
 * Station Board v2 — larger useful lower card and left alignment
 * ============================================================ */
.d-idle,
.d-idle * {
    text-align: left;
}

.d-idle-head {
    align-items: flex-start !important;
    justify-content: flex-start !important;
    text-align: left !important;
}

.d-idle-title-wrap,
.d-idle-title-wrap .title,
.d-idle-title-wrap .kicker,
.kicker {
    text-align: left !important;
}

.d-station-board {
    grid-template-rows: minmax(0, 1.15fr) auto;
    gap: 1rem;
}

.d-board-feature {
    align-items: flex-start !important;
    justify-content: flex-start !important;
    text-align: left !important;
    min-height: 0;
}

.d-board-feature .d-idle-content {
    align-items: flex-start !important;
    justify-content: flex-start !important;
    text-align: left !important;
}

.d-board-feature .d-idle-category,
.d-board-feature .d-idle-feed-title,
.d-board-feature .d-idle-feed-detail,
.d-board-feature .d-idle-sources {
    text-align: left !important;
    margin-left: 0 !important;
    margin-right: auto !important;
}

.d-board-feature .d-idle-feed-title {
    max-width: 68rem;
}

.d-board-feature .d-idle-feed-detail {
    max-width: 78rem;
}

.d-board-panels {
    grid-template-columns: 1fr !important;
}

.d-board-last-call {
    min-height: 10rem;
    padding: 1rem 1.1rem 1.1rem !important;
    gap: .85rem;
}

.d-board-last-call .panel-topline {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    min-width: 0;
}

.d-board-last-call .panel-value {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    font-size: clamp(1.15rem, 1.3vw, 1.55rem) !important;
    line-height: 1.12 !important;
}

.d-board-last-call .panel-sub {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
}

.panel-call-age {
    flex-shrink: 0;
    padding: .35rem .7rem;
    border-radius: 999px;
    background: rgba(31, 41, 55, .12);
    border: 1px solid rgba(31, 41, 55, .18);
    color: var(--d-text-2);
    font-size: .82rem;
    font-weight: 900;
    letter-spacing: .03em;
    white-space: nowrap;
}

.d-board-response-counts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
    gap: .55rem;
    width: 100%;
}

.d-board-count-pill {
    min-width: 0;
    min-height: 2.65rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    padding: .55rem .75rem;
    border-radius: 999px;
    background: var(--d-cell-info);
    border: 1px solid rgba(59, 130, 246, .28);
    color: var(--d-pill-info-text);
    font-size: .84rem;
    font-weight: 900;
    letter-spacing: .04em;
    text-transform: uppercase;
    font-variant-numeric: tabular-nums;
}

.d-board-count-pill .mdi {
    font-size: 1rem;
    line-height: 1;
    flex-shrink: 0;
}

.d-board-count-pill .count-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.d-board-count-pill strong {
    font-size: 1rem;
    line-height: 1;
}

.d-board-count-pill.success {
    background: var(--d-cell-success);
    border-color: rgba(16, 185, 129, .36);
    color: var(--d-pill-success-text);
}
.d-board-count-pill.danger {
    background: var(--d-cell-danger);
    border-color: rgba(239, 68, 68, .36);
    color: var(--d-pill-danger-text);
}
.d-board-count-pill.warning {
    background: var(--d-cell-warning);
    border-color: rgba(245, 158, 11, .40);
    color: var(--d-pill-warning-text);
}
.d-board-count-pill.info {
    background: var(--d-cell-info);
    border-color: rgba(59, 130, 246, .36);
    color: var(--d-pill-info-text);
}
.d-board-count-pill.purple {
    background: var(--d-cell-purple);
    border-color: rgba(168, 85, 247, .36);
    color: var(--d-pill-purple-text);
}
.d-board-count-pill.teal {
    background: var(--d-cell-teal);
    border-color: rgba(20, 184, 166, .36);
    color: var(--d-pill-teal-text);
}
.d-board-count-pill.pink {
    background: var(--d-cell-pink);
    border-color: rgba(236, 72, 153, .36);
    color: var(--d-pill-pink-text);
}
.d-board-count-pill.dark {
    background: var(--d-cell-dark);
    border-color: rgba(71, 85, 105, .44);
    color: var(--d-pill-dark-text);
}
.d-board-count-pill.gray,
.d-board-count-pill.no-response {
    background: rgba(148, 163, 184, .18);
    border-color: rgba(100, 116, 139, .34);
    color: var(--d-pill-gray-text);
}

@media (prefers-color-scheme: light) {
    .panel-call-age {
        background: rgba(31, 41, 55, .08);
        border-color: rgba(31, 41, 55, .15);
    }
    .d-board-count-pill.no-response {
        color: #334155;
    }
}

/* ============================================================
   Station board response-count card — vertical count rows
   Gives the Last Call card more height and places each response
   type on its own full-width line so labels like NOT RESPONDED
   do not truncate.
   ============================================================ */

.d-station-board {
    grid-template-rows: minmax(0, 1fr) auto !important;
    gap: 1.1rem !important;
}

.d-board-last-call {
    min-height: 14rem !important;
    padding: 1.15rem 1.25rem 1.25rem !important;
    gap: 1rem !important;
}

.d-board-last-call .panel-topline {
    padding-bottom: .75rem;
    border-bottom: 1px solid rgba(148, 163, 184, .22);
}

.d-board-response-counts {
    display: grid !important;
    grid-template-columns: 1fr !important;
    gap: .55rem !important;
    width: 100%;
}

.d-board-count-pill {
    width: 100%;
    min-height: 2.75rem !important;
    border-radius: .8rem !important;
    justify-content: space-between !important;
    padding: .58rem .85rem !important;
    gap: .65rem !important;
    font-size: .86rem !important;
    letter-spacing: .055em !important;
}

.d-board-count-pill .mdi {
    font-size: 1.05rem !important;
}

.d-board-count-pill .count-label {
    flex: 1;
    min-width: 0;
    overflow: visible !important;
    text-overflow: clip !important;
    white-space: nowrap !important;
}

.d-board-count-pill strong {
    min-width: 2.25rem;
    text-align: right;
    font-size: 1.12rem !important;
    font-weight: 950;
}

/* Use the available height better on large TV-style displays. */
@media (min-width: 1400px) and (min-height: 800px) {
    .d-board-last-call {
        min-height: 15.25rem !important;
    }

    .d-board-count-pill {
        min-height: 3rem !important;
        font-size: .9rem !important;
    }
}

/* ============================================================
 * Station Board header alignment fix
 * Vertically centers the Training & Safety title block inside
 * the card header while keeping all text left-aligned.
 * ============================================================ */
.d-idle-head {
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    justify-content: flex-start !important;
    min-height: var(--d-card-head-height) !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    text-align: left !important;
}

.d-idle-title-wrap {
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
    align-self: stretch !important;
    min-height: var(--d-card-head-height) !important;
    margin: 0 !important;
    text-align: left !important;
}

.d-idle-title-wrap .kicker,
.d-idle-title-wrap .title,
.kicker {
    margin-left: 0 !important;
    margin-right: 0 !important;
    text-align: left !important;
}

.d-idle-title-wrap .kicker,
.kicker {
    margin-top: 0 !important;
    margin-bottom: .22rem !important;
    line-height: 1 !important;
}

.d-idle-title-wrap .title {
    margin: 0 !important;
    line-height: 1.12 !important;
}


/* ============================================================
   Idle footer/progress removed
   The station board has enough useful content without the
   rotating-message progress bar. Keep this hidden even if an
   older PHP template still outputs the element.
   ============================================================ */
.d-idle-foot,
.d-idle-progress,
.d-idle-progress-bar {
    display: none !important;
}

.d-idle {
    padding-bottom: 0;
}

/* ============================================================
   FINAL CAPACITY PASS — active responder board
   - Removes the oversized blank space between status groups.
   - Keeps a small, readable break before the next divider.
   - Tightens high/ultra density so 40 responders can fit on
     1080p/4K wall displays without scrolling.
   ============================================================ */

/* Less vertical waste between AVAILABLE / UNAVAILABLE / SCENE sections. */
.d-main.is-active .d-resp-grid > .d-resp-group-spacer,
.d-resp-grid > .d-resp-group-spacer {
    grid-column: 1 / -1 !important;
    height: .42rem !important;
    min-height: .42rem !important;
    max-height: .42rem !important;
    display: block !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
}

/* Keep dividers tight to their own section. The spacer above now handles separation. */
.d-main.is-active .d-resp-group-title,
.d-resp-group-title {
    margin: 0 0 .24rem 0 !important;
    min-height: 1.26rem !important;
    padding: .20rem .62rem .22rem !important;
    font-size: .64rem !important;
    line-height: 1 !important;
}

/* Summary row: centered, but not oversized. */
.d-main.is-active .d-resp-summary,
.d-resp-summary {
    padding: .58rem .95rem .50rem !important;
    gap: .52rem !important;
    align-items: center !important;
}

.d-main.is-active .d-resp-pill,
.d-resp-pill {
    height: 1.88rem !important;
    min-height: 1.88rem !important;
    padding: .30rem .52rem !important;
    align-items: center !important;
    justify-content: center !important;
}

/* Default active grid uses more columns and less vertical height. */
.d-main.is-active .d-resp-grid {
    padding: .55rem .95rem .85rem !important;
    gap: .38rem !important;
    grid-template-columns: repeat(auto-fill, minmax(11.35rem, 1fr)) !important;
    align-content: start !important;
    overflow: hidden !important;
}

/* High density: used around the current 20s responder count. */
.d-main.is-active .d-resp-grid[data-density="high"] {
    gap: .32rem !important;
    grid-template-columns: repeat(auto-fill, minmax(10.65rem, 1fr)) !important;
}

.d-main.is-active .d-resp-grid[data-density="high"] .d-resp-cell {
    min-height: 2.52rem !important;
    padding: .38rem .52rem !important;
    gap: .40rem !important;
}

.d-main.is-active .d-resp-grid[data-density="high"] .cell-ff {
    font-size: .74rem !important;
}

.d-main.is-active .d-resp-grid[data-density="high"] .cell-name {
    font-size: .68rem !important;
    line-height: 1.08 !important;
    max-height: 2.15em !important;
}

.d-main.is-active .d-resp-grid[data-density="high"] .cell-eta {
    font-size: .66rem !important;
    padding: .15rem .40rem .17rem !important;
}

/* Ultra density: 25+ responders. Built to keep roughly 40 responders visible. */
.d-main.is-active .d-resp-grid[data-density="ultra"] {
    gap: .26rem !important;
    grid-template-columns: repeat(auto-fill, minmax(9.75rem, 1fr)) !important;
}

.d-main.is-active .d-resp-grid[data-density="ultra"] .d-resp-cell {
    min-height: 2.12rem !important;
    padding: .28rem .42rem !important;
    gap: .32rem !important;
    border-radius: .55rem !important;
}

.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-icon {
    font-size: .88rem !important;
}

.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-ff {
    font-size: .66rem !important;
    line-height: 1.05 !important;
}

.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-name {
    font-size: .60rem !important;
    line-height: 1.05 !important;
    max-height: 2.1em !important;
}

.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-eta {
    font-size: .56rem !important;
    padding: .08rem .28rem .10rem !important;
}

.d-main.is-active .d-resp-grid[data-density="ultra"] .d-resp-group-title {
    min-height: 1.08rem !important;
    padding: .16rem .50rem .18rem !important;
    font-size: .56rem !important;
    margin-bottom: .20rem !important;
}

.d-main.is-active .d-resp-grid[data-density="ultra"] > .d-resp-group-spacer {
    height: .30rem !important;
    min-height: .30rem !important;
    max-height: .30rem !important;
}

/* Shorter TV/browser heights need the compact settings earlier. */
@media (max-height: 900px) {
    .d-main.is-active .d-resp-grid > .d-resp-group-spacer,
    .d-resp-grid > .d-resp-group-spacer {
        height: .34rem !important;
        min-height: .34rem !important;
        max-height: .34rem !important;
    }

    .d-main.is-active .d-resp-grid {
        padding-top: .48rem !important;
        padding-bottom: .72rem !important;
        gap: .30rem !important;
    }

    .d-main.is-active .d-resp-grid[data-density="high"] {
        grid-template-columns: repeat(auto-fill, minmax(10.25rem, 1fr)) !important;
        gap: .26rem !important;
    }

    .d-main.is-active .d-resp-grid[data-density="high"] .d-resp-cell {
        min-height: 2.34rem !important;
        padding: .32rem .46rem !important;
    }

    .d-main.is-active .d-resp-grid[data-density="ultra"] {
        grid-template-columns: repeat(auto-fill, minmax(9.35rem, 1fr)) !important;
        gap: .22rem !important;
    }

    .d-main.is-active .d-resp-grid[data-density="ultra"] .d-resp-cell {
        min-height: 1.98rem !important;
        padding: .24rem .38rem !important;
    }
}

/* ============================================================
   Dynamic responder fit
   Start with the comfortable card sizing, then dashboard.php
   measures the real rendered height and steps through these
   densities only when the responder area would overflow.
   ============================================================ */
.d-main.is-active .d-resp-grid {
    --resp-cell-min: 15.5rem;
    grid-template-columns: repeat(auto-fill, minmax(var(--resp-cell-min), 1fr)) !important;
    gap: .42rem .55rem !important;
    padding: .72rem 1rem .9rem !important;
    align-content: start !important;
    overflow: hidden !important;
}

.d-main.is-active .d-resp-grid[data-density="low"] {
    --resp-cell-min: 15.5rem;
}

.d-main.is-active .d-resp-grid[data-density="medium"] {
    --resp-cell-min: 13.75rem;
    gap: .36rem .48rem !important;
}

.d-main.is-active .d-resp-grid[data-density="high"] {
    --resp-cell-min: 12rem;
    gap: .32rem .42rem !important;
}

.d-main.is-active .d-resp-grid[data-density="ultra"] {
    --resp-cell-min: 10.75rem;
    gap: .26rem .34rem !important;
}

.d-main.is-active .d-resp-grid[data-density="micro"] {
    --resp-cell-min: 9.25rem;
    gap: .22rem .28rem !important;
}

/* Comfortable default. */
.d-main.is-active .d-resp-grid[data-density="low"] .d-resp-cell {
    min-height: 3.25rem !important;
    padding: .48rem .65rem !important;
    gap: .5rem !important;
}
.d-main.is-active .d-resp-grid[data-density="low"] .cell-icon { font-size: 1.15rem !important; }
.d-main.is-active .d-resp-grid[data-density="low"] .cell-ff { font-size: .86rem !important; }
.d-main.is-active .d-resp-grid[data-density="low"] .cell-name { font-size: .74rem !important; line-height: 1.05 !important; }
.d-main.is-active .d-resp-grid[data-density="low"] .cell-eta { font-size: .72rem !important; padding: .16rem .45rem !important; }

/* Step 1: keep names, only tighten width/spacing. */
.d-main.is-active .d-resp-grid[data-density="medium"] .d-resp-cell {
    min-height: 3rem !important;
    padding: .42rem .56rem !important;
    gap: .44rem !important;
}
.d-main.is-active .d-resp-grid[data-density="medium"] .cell-icon { font-size: 1.08rem !important; }
.d-main.is-active .d-resp-grid[data-density="medium"] .cell-ff { font-size: .82rem !important; }
.d-main.is-active .d-resp-grid[data-density="medium"] .cell-name { font-size: .70rem !important; line-height: 1.04 !important; }
.d-main.is-active .d-resp-grid[data-density="medium"] .cell-eta { font-size: .68rem !important; padding: .14rem .40rem !important; }

/* Step 2: still readable on a TV, but more rows/columns fit. */
.d-main.is-active .d-resp-grid[data-density="high"] .d-resp-cell {
    min-height: 2.72rem !important;
    padding: .36rem .48rem !important;
    gap: .38rem !important;
}
.d-main.is-active .d-resp-grid[data-density="high"] .cell-icon { font-size: 1rem !important; }
.d-main.is-active .d-resp-grid[data-density="high"] .cell-ff { font-size: .78rem !important; }
.d-main.is-active .d-resp-grid[data-density="high"] .cell-name { font-size: .66rem !important; line-height: 1.02 !important; }
.d-main.is-active .d-resp-grid[data-density="high"] .cell-eta { font-size: .64rem !important; padding: .12rem .35rem !important; }

/* Step 3: only used when the grid is running out of height. */
.d-main.is-active .d-resp-grid[data-density="ultra"] .d-resp-cell {
    min-height: 2.35rem !important;
    padding: .30rem .40rem !important;
    gap: .30rem !important;
}
.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-icon { font-size: .92rem !important; }
.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-ff { font-size: .72rem !important; }
.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-name { font-size: .60rem !important; line-height: 1 !important; }
.d-main.is-active .d-resp-grid[data-density="ultra"] .cell-eta { font-size: .58rem !important; padding: .10rem .30rem !important; }

/* Last resort for very large response counts. This keeps the numbers visible
   without forcing scrolling. Full names remain available in each cell title. */
.d-main.is-active .d-resp-grid[data-density="micro"] .d-resp-cell,
.d-main.is-active .d-resp-grid.is-at-min-density .d-resp-cell {
    min-height: 2.05rem !important;
    padding: .24rem .34rem !important;
    gap: .24rem !important;
}
.d-main.is-active .d-resp-grid[data-density="micro"] .cell-icon,
.d-main.is-active .d-resp-grid.is-at-min-density .cell-icon { font-size: .82rem !important; }
.d-main.is-active .d-resp-grid[data-density="micro"] .cell-ff,
.d-main.is-active .d-resp-grid.is-at-min-density .cell-ff { font-size: .68rem !important; }
.d-main.is-active .d-resp-grid[data-density="micro"] .cell-name,
.d-main.is-active .d-resp-grid.is-at-min-density .cell-name { display: none !important; }
.d-main.is-active .d-resp-grid[data-density="micro"] .cell-eta,
.d-main.is-active .d-resp-grid.is-at-min-density .cell-eta { font-size: .54rem !important; padding: .08rem .25rem !important; }

/* Group spacing: small, deliberate space. The JS spacer is still present, but
   it should never create a huge empty band. */
.d-main.is-active .d-resp-grid > .d-resp-group-spacer,
.d-resp-grid > .d-resp-group-spacer {
    grid-column: 1 / -1 !important;
    height: .48rem !important;
    min-height: .48rem !important;
    margin: 0 !important;
    padding: 0 !important;
}
.d-main.is-active .d-resp-grid[data-density="high"] > .d-resp-group-spacer,
.d-main.is-active .d-resp-grid[data-density="ultra"] > .d-resp-group-spacer,
.d-main.is-active .d-resp-grid[data-density="micro"] > .d-resp-group-spacer {
    height: .28rem !important;
    min-height: .28rem !important;
}

.d-main.is-active .d-resp-group-title {
    min-height: 1.32rem !important;
    height: 1.32rem !important;
    margin: .05rem 0 .12rem !important;
    padding: .12rem .55rem !important;
    align-items: center !important;
}
.d-main.is-active .d-resp-grid[data-density="ultra"] .d-resp-group-title,
.d-main.is-active .d-resp-grid[data-density="micro"] .d-resp-group-title {
    min-height: 1.12rem !important;
    height: 1.12rem !important;
    font-size: .56rem !important;
    padding: .08rem .42rem !important;
}



/* ==========================================================================
   Source: demo/assets/css/accounts-admin.css
   ========================================================================== */

:root {
    --fn-brand:        #313a46;
    --fn-brand-soft:   rgba(49, 58, 70, .10);
    --fn-accent:       #B03A2E;
    --fn-accent-soft:  rgba(176, 58, 46, .10);
    --fn-header-bg:    var(--fn-brand);
    --fn-safe-top:     max(env(safe-area-inset-top, 0px), 2.75rem);
    --fn-safe-bottom:  max(env(safe-area-inset-bottom, 0px), .5rem);
}

:root,
[data-bs-theme="light"] {
    --fn-body-bg:        #FFFFFF;
    --fn-card-bg:        #F5F5F7;
    --fn-card-border:    #E3E5E9;
    --fn-text:           #1F2328;
    --fn-text-muted:     #6B7280;
    --fn-tertiary-bg:    #EEF0F3;
    --fn-shadow:         rgba(0,0,0,.06);
}
[data-bs-theme="dark"] {
    --fn-body-bg:        #1a1d21;
    --fn-card-bg:        #23272C;
    --fn-card-border:    #2E343B;
    --fn-text:           #E6E8EB;
    --fn-text-muted:     #9099A4;
    --fn-tertiary-bg:    #2A2F35;
    --fn-shadow:         rgba(0,0,0,.3);
}

* { -webkit-tap-highlight-color: transparent; }

html, body {
    margin: 0;
    background: var(--fn-body-bg);
    color: var(--fn-text);
    font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    -webkit-font-smoothing: antialiased;
}

body {
    padding-top: calc(var(--fn-safe-top) + 3.4rem);
    padding-bottom: calc(var(--fn-safe-bottom) + 1rem);
}

/* Admin top bar — title only, no back button inside it */
.fn-admin-bar {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 50;
    background: var(--fn-header-bg);
    color: #fff;
    padding-top: var(--fn-safe-top);
    box-shadow: 0 2px 8px rgba(0,0,0,.10);
}
.fn-admin-bar-inner {
    display: flex;
    align-items: center;
    padding: .55rem .85rem;
    min-height: 3.4rem;
    box-sizing: border-box;
}
.fn-admin-title {
    font-weight: 800;
    font-size: 1.05rem;
    line-height: 1;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Back link — lives on the page content, top-left, quiet text */
.fn-page-back-link {
    display: inline-flex;
    align-items: center;
    gap: .15rem;
    color: var(--fn-text-muted);
    background: transparent;
    border: 0;
    padding: .35rem .25rem;
    margin: 0 0 .65rem -.25rem;
    font-weight: 700;
    font-size: .9rem;
    text-decoration: none;
    cursor: pointer;
    line-height: 1;
}
.fn-page-back-link:hover, .fn-page-back-link:active {
    color: var(--fn-text);
}
.fn-page-back-link .mdi {
    font-size: 1.2rem;
}

.fn-admin-container {
    max-width: 720px;
    margin: 0 auto;
    padding: .85rem 1rem 1rem;
}

/* Page-specific styles below */

.fn-msg {
    position: relative;
    padding: .65rem 2.5rem .65rem .85rem;
    border-radius: .55rem;
    margin-bottom: .75rem;
    font-size: .88rem;
    font-weight: 600;
}
.fn-msg.success { background: rgba(25,135,84,.12);  color: #0f5132; border: 1px solid rgba(25,135,84,.4); }
.fn-msg.danger  { background: rgba(220,53,69,.12);  color: #842029; border: 1px solid rgba(220,53,69,.4); }
.fn-msg.info    { background: rgba(13,110,253,.10); color: #084298; border: 1px solid rgba(13,110,253,.3); }

.fn-msg-close {
    position: absolute;
    top: 50%;
    right: .4rem;
    transform: translateY(-50%);
    background: transparent;
    border: 0;
    color: currentColor;
    opacity: .55;
    width: 1.8rem; height: 1.8rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center; justify-content: center;
    cursor: pointer;
    padding: 0;
    transition: opacity .12s, background .12s, transform .08s;
}
.fn-msg-close:hover  { opacity: 1; background: rgba(0,0,0,.08); }
.fn-msg-close:active { transform: translateY(-50%) scale(.9); }
.fn-msg-close .mdi { font-size: 1.1rem; line-height: 1; }
[data-bs-theme="dark"] .fn-msg-close:hover { background: rgba(255,255,255,.08); }

[data-bs-theme="dark"] .fn-msg.success { color: #75d8a6; }
[data-bs-theme="dark"] .fn-msg.danger  { color: #ea868f; }
[data-bs-theme="dark"] .fn-msg.info    { color: #6ea8fe; }

.fn-code-reveal {
    background: var(--fn-accent);
    color: #fff;
    padding: 1rem 1.25rem;
    border-radius: .8rem;
    margin-bottom: .85rem;
    text-align: center;
    box-shadow: 0 4px 14px rgba(176,58,46,.25);
}
.fn-code-reveal .label {
    font-size: .72rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .05em; opacity: .8;
}
.fn-code-reveal .code {
    font-family: 'SF Mono','Monaco','Menlo','Consolas',monospace;
    font-size: 2rem; font-weight: 800; letter-spacing: .25em;
    margin: .3rem 0 .15rem;
}
.fn-code-reveal .who { font-size: .85rem; opacity: .9; }
.fn-code-reveal .copy-btn {
    margin-top: .55rem; background: rgba(255,255,255,.18);
    color: #fff; border: 0; border-radius: 999px;
    padding: .35rem .85rem; font-weight: 700; font-size: .8rem; cursor: pointer;
}
.fn-code-reveal .note {
    font-size: .72rem; margin-top: .5rem; opacity: .85; line-height: 1.4;
}

.fn-add-form {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .8rem;
    padding: .85rem 1rem;
    margin-bottom: 1rem;
}
.fn-add-form summary {
    cursor: pointer; font-weight: 700; color: var(--fn-text);
    list-style: none; display: flex; align-items: center; gap: .35rem;
}
.fn-add-form summary::after { content: '＋'; margin-left: auto; font-size: 1.2rem; }
.fn-add-form[open] summary::after { content: '×'; }
.fn-add-form .role-row { margin-top: .85rem; }
.fn-add-form .form-grid {
    display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin-top: .5rem;
}
.fn-add-form .form-grid .full { grid-column: 1 / -1; }
.fn-add-form input, .fn-add-form select {
    width: 100%; padding: .5rem .65rem; border-radius: .5rem;
    border: 1px solid var(--fn-card-border);
    background: var(--fn-body-bg); color: var(--fn-text);
    font-size: .9rem;
}
.fn-add-form button {
    background: var(--fn-brand); color: #fff; border: 0;
    border-radius: .5rem; padding: .55rem 1rem;
    font-weight: 700; cursor: pointer; margin-top: .5rem;
}
.fn-add-form .role-help {
    font-size: .72rem; color: var(--fn-text-muted);
    margin-top: .4rem; line-height: 1.4;
    padding: .5rem .65rem; background: var(--fn-tertiary-bg);
    border-radius: .4rem;
}
.fn-add-form .role-help strong { color: var(--fn-text); }
.fn-add-form .station-help {
    font-size: .72rem; color: var(--fn-text-muted);
    margin-top: .25rem; line-height: 1.4;
}
.fn-add-form .station-help a {
    color: var(--fn-brand); font-weight: 700; text-decoration: underline;
}

.fn-add-form[data-role="Dashboard"] .fields-firefighter { display: none; }

/* ── Search box (above the user list) ───────────────────────── */
.fn-search {
    position: relative;
    margin-bottom: .75rem;
}
.fn-search input {
    width: 100%;
    box-sizing: border-box;
    padding: .65rem .75rem .65rem 2.25rem;
    border-radius: .55rem;
    border: 1px solid var(--fn-card-border);
    background: var(--fn-card-bg);
    color: var(--fn-text);
    font-size: .95rem;
    font-family: inherit;
}
.fn-search input:focus {
    outline: none;
    border-color: var(--fn-brand);
    background: var(--fn-body-bg);
}
.fn-search .mdi-magnify {
    position: absolute;
    left: .65rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--fn-text-muted);
    font-size: 1.15rem;
    pointer-events: none;
}
.fn-search-clear {
    position: absolute;
    right: .35rem;
    top: 50%;
    transform: translateY(-50%);
    background: var(--fn-tertiary-bg);
    border: 0;
    width: 1.7rem; height: 1.7rem;
    border-radius: 50%;
    color: var(--fn-text-muted);
    display: none;
    align-items: center; justify-content: center;
    cursor: pointer;
    padding: 0;
}
.fn-search-clear.is-visible { display: inline-flex; }
.fn-search-clear .mdi { font-size: 1rem; line-height: 1; }

.fn-empty-state {
    text-align: center;
    padding: 1.5rem;
    color: var(--fn-text-muted);
    font-size: .9rem;
}

/* ── User list rows (two-line layout) ───────────────────────── */
/* Line 1: full-width name with FF# / station inline as muted suffix.
   Line 2: role badge on the left, action controls (Code btn + role
   dropdown) pushed to the right with margin-left:auto. */
.fn-user-row {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .65rem;
    padding: .7rem .85rem;
    margin-bottom: .4rem;
    display: flex; flex-direction: column; gap: .5rem;
}
.fn-user-row.disabled { opacity: .55; }

.fn-user-line-1 {
    line-height: 1.3;
    word-break: break-word;
}
.fn-user-name {
    font-weight: 700;
    font-size: .95rem;
    color: var(--fn-text);
}
.fn-user-meta-inline {
    font-size: .8rem;
    color: var(--fn-text-muted);
    font-weight: 500;
}

.fn-user-line-2 {
    display: flex;
    align-items: center;
    gap: .4rem;
}
.fn-user-line-2 .fn-user-actions { margin-left: auto; }

.fn-user-actions { display: flex; gap: .35rem; align-items: center; }
.fn-user-actions form { margin: 0; }
.fn-user-actions button {
    background: var(--fn-tertiary-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .4rem;
    padding: .35rem .55rem;
    font-size: .75rem; font-weight: 700;
    color: var(--fn-text); cursor: pointer;
    display: inline-flex; align-items: center; gap: .25rem;
}
.fn-user-actions button:hover { border-color: var(--fn-brand); }
.fn-user-actions select {
    border: 1px solid var(--fn-card-border);
    border-radius: .4rem; padding: .3rem .4rem;
    font-size: .75rem;
    background: var(--fn-body-bg); color: var(--fn-text);
    font-weight: 700;
}

.fn-role-pill {
    font-size: .65rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .05em;
    padding: .15rem .45rem;
    border-radius: 999px;
    color: #fff;
    display: inline-block;
}
.fn-role-pill.Admin     { background: var(--fn-accent); }
.fn-role-pill.User      { background: #6c757d; }
.fn-role-pill.Disabled  { background: #343a40; }
.fn-role-pill.Dashboard { background: #0d6efd; }



/* ==========================================================================
   Source: demo/assets/css/responses-config.css
   ========================================================================== */

:root {
    --fn-brand:        #313a46;
    --fn-brand-soft:   rgba(49, 58, 70, .10);
    --fn-accent:       #B03A2E;
    --fn-accent-soft:  rgba(176, 58, 46, .10);
    --fn-header-bg:    var(--fn-brand);
    --fn-safe-top:     max(env(safe-area-inset-top, 0px), 2.75rem);
    --fn-safe-bottom:  max(env(safe-area-inset-bottom, 0px), .5rem);
}

:root,
[data-bs-theme="light"] {
    --fn-body-bg:        #FFFFFF;
    --fn-card-bg:        #F5F5F7;
    --fn-card-border:    #E3E5E9;
    --fn-text:           #1F2328;
    --fn-text-muted:     #6B7280;
    --fn-tertiary-bg:    #EEF0F3;
    --fn-shadow:         rgba(0,0,0,.06);
}
[data-bs-theme="dark"] {
    --fn-body-bg:        #1a1d21;
    --fn-card-bg:        #23272C;
    --fn-card-border:    #2E343B;
    --fn-text:           #E6E8EB;
    --fn-text-muted:     #9099A4;
    --fn-tertiary-bg:    #2A2F35;
    --fn-shadow:         rgba(0,0,0,.3);
}

* { -webkit-tap-highlight-color: transparent; }

html, body {
    margin: 0;
    background: var(--fn-body-bg);
    color: var(--fn-text);
    font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    -webkit-font-smoothing: antialiased;
}

body {
    /* Bar now floats at safe-top + 0.45rem with internal min-height
       3.4rem; content needs to clear safe-top + ~4.4rem total. */
    padding-top: calc(var(--fn-safe-top) + 4.4rem);
    padding-bottom: calc(var(--fn-safe-bottom) + 1rem);
}

/* Safe-area shading at the very top — same idea as the main app's
   liquid-glass.css body::before. Light fade so iOS time/wifi/battery
   stays readable on the light body. */
body::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--fn-safe-top);
    background: linear-gradient(to bottom,
        rgba(15, 17, 21, 0.70) 0%,
        rgba(15, 17, 21, 0.25) 65%,
        transparent           100%);
    z-index: 1;
    pointer-events: none;
}

/* Admin top bar — branded hero with bell, brand, subtitle, user/station.
   Floating glass island — matches the main app's hero. Side margins
   0.3rem from screen edge, 0.45rem below safe-area, all four corners
   rounded, soft drop shadow. */
.fn-admin-bar {
    position: fixed;
    top: calc(var(--fn-safe-top) + 0.45rem);
    left: 0.3rem;
    right: 0.3rem;
    z-index: 50;
    background: var(--fn-header-bg);
    color: #fff;
    border-radius: 1rem;
    box-shadow: 0 14px 36px -10px rgba(0,0,0,.28),
                0 4px 12px -4px rgba(0,0,0,.14);
    overflow: hidden;
}
.fn-admin-bar-inner {
    display: flex;
    align-items: center;
    gap: .55rem;
    padding: .55rem .55rem;
    min-height: 3.4rem;
    box-sizing: border-box;
}
.fn-admin-bell {
    width: 2.2rem;
    height: 2.2rem;
    border-radius: .55rem;
    background: rgba(255,255,255,.16);
    color: #fff;
    border: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    text-decoration: none;
    flex-shrink: 0;
}
.fn-admin-bell:active { transform: scale(.95); }
.fn-admin-bell .mdi { font-size: 1.2rem; }
.fn-admin-brand-wrap {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.fn-admin-brand {
    font-weight: 800;
    font-size: 1rem;
    line-height: 1.1;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fn-admin-subtitle {
    font-size: .78rem;
    font-weight: 500;
    color: rgba(255,255,255,.78);
    line-height: 1.2;
}
.fn-admin-title {
    font-weight: 800;
    font-size: 1.05rem;
    line-height: 1;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fn-admin-id {
    display: inline-flex;
    background: rgba(255,255,255,.10);
    border-radius: .5rem;
    overflow: hidden;
    flex-shrink: 0;
}
.fn-admin-id-cell {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .35rem .5rem;
    font-size: .78rem;
    font-weight: 700;
    color: #fff;
    line-height: 1;
}
.fn-admin-id-cell + .fn-admin-id-cell {
    border-left: 1px solid rgba(255,255,255,.12);
}
.fn-admin-id-cell .mdi {
    font-size: 1rem;
    opacity: .85;
}

/* Back link — on page content, top-left, quiet */
.fn-page-back-link {
    display: inline-flex;
    align-items: center;
    gap: .15rem;
    color: var(--fn-text-muted);
    background: transparent;
    border: 0;
    padding: .35rem .25rem;
    margin: 0 0 .65rem -.25rem;
    font-weight: 700;
    font-size: .9rem;
    text-decoration: none;
    cursor: pointer;
    line-height: 1;
}
.fn-page-back-link:hover, .fn-page-back-link:active {
    color: var(--fn-text);
}
.fn-page-back-link .mdi {
    font-size: 1.2rem;
}

.fn-admin-container {
    max-width: 720px;
    margin: 0 auto;
    padding: .85rem 1rem 1rem;
}


.fn-section-title {
    font-size: .72rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .04em;
    color: var(--fn-text-muted);
    margin: 1.1rem 0 .5rem;
}

.fn-rt-panel {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .8rem;
    padding: 1rem;
    margin-bottom: .8rem;
}

.fn-field { margin-bottom: .8rem; }
.fn-field-label {
    font-size: .72rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .04em;
    color: var(--fn-text-muted);
    margin-bottom: .35rem;
    display: flex; align-items: center; gap: .3rem;
}
.fn-field-label .count {
    font-weight: 600; font-size: .7rem;
    color: var(--fn-text-muted); margin-left: auto;
}
.fn-field-label .count.over { color: var(--fn-accent); font-weight: 800; }

.fn-text-input {
    width: 100%;
    padding: .55rem .7rem;
    border-radius: .5rem;
    border: 1px solid var(--fn-card-border);
    background: var(--fn-body-bg);
    color: var(--fn-text);
    font-size: 1rem;
    font-weight: 700;
}
.fn-text-input:focus { outline: 0; border-color: var(--fn-brand); }
.fn-text-input:disabled {
    background: var(--fn-tertiary-bg);
    color: var(--fn-text-muted);
    cursor: not-allowed;
}

.fn-color-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr));
    gap: .4rem;
}
.fn-color-option {
    cursor: pointer;
    aspect-ratio: 1;
    border-radius: .5rem;
    border: 3px solid transparent;
    display: flex; align-items: center; justify-content: center;
    color: #fff;
    transition: transform .1s, border-color .15s;
    position: relative;
    box-shadow: 0 1px 3px rgba(0,0,0,.1);
}
.fn-color-option:hover { transform: scale(1.05); }
.fn-color-option .mdi {
    font-size: 1.4rem;
    opacity: 0;
    transition: opacity .15s;
}
.fn-color-option.selected .mdi { opacity: 1; }
.fn-color-option.selected {
    border-color: rgba(255,255,255,.6);
    box-shadow: 0 0 0 3px var(--fn-brand), 0 1px 3px rgba(0,0,0,.15);
}

.fn-icon-search {
    margin-bottom: .5rem;
    width: 100%;
    padding: .45rem .7rem;
    border-radius: .5rem;
    border: 1px solid var(--fn-card-border);
    background: var(--fn-body-bg);
    color: var(--fn-text);
    font-size: .9rem;
}

.fn-icon-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(2.6rem, 1fr));
    gap: .35rem;
    max-height: 14rem;
    overflow-y: auto;
    padding: .35rem;
    border: 1px solid var(--fn-card-border);
    border-radius: .55rem;
    background: var(--fn-body-bg);
}
.fn-icon-option {
    cursor: pointer;
    aspect-ratio: 1;
    border-radius: .4rem;
    background: var(--fn-tertiary-bg);
    border: 2px solid transparent;
    display: flex; align-items: center; justify-content: center;
    color: var(--fn-text);
    transition: background .15s, border-color .15s;
}
.fn-icon-option:hover { background: var(--fn-brand-soft); }
.fn-icon-option.selected {
    border-color: var(--fn-brand);
    background: var(--fn-brand-soft);
}
.fn-icon-option .mdi { font-size: 1.4rem; }
.fn-icon-option.hidden { display: none; }

.fn-preview {
    margin-top: .85rem;
    padding: .75rem;
    background: var(--fn-tertiary-bg);
    border-radius: .55rem;
    display: flex; align-items: center; gap: .5rem;
}
.fn-preview-label {
    font-size: .7rem; font-weight: 800;
    text-transform: uppercase; color: var(--fn-text-muted);
    letter-spacing: .04em;
}
.fn-preview-btn {
    flex: 1;
    min-height: 3.2rem;
    padding: .45rem .5rem;
    border-radius: .55rem;
    color: #fff;
    display: inline-flex;
    flex-direction: column;
    align-items: center; justify-content: center;
    gap: .15rem;
    font-weight: 800;
    line-height: 1.05;
    text-align: center;
}
.fn-preview-btn .mdi { font-size: 1.35rem; line-height: 1; }
.fn-preview-btn .lbl {
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.fn-actions {
    display: flex; gap: .5rem; margin-top: .85rem;
}
.fn-btn {
    border: 0; border-radius: .5rem;
    padding: .55rem 1rem; font-weight: 700; cursor: pointer;
    font-size: .9rem;
}
.fn-btn-primary { background: var(--fn-brand); color: #fff; flex: 1; }
.fn-btn-secondary {
    background: var(--fn-tertiary-bg);
    border: 1px solid var(--fn-card-border);
    color: var(--fn-text);
}

.fn-protected-note {
    background: rgba(13,110,253,.08);
    border: 1px solid rgba(13,110,253,.25);
    color: var(--fn-text);
    font-size: .78rem;
    padding: .4rem .65rem;
    border-radius: .4rem;
    margin-top: .5rem;
    display: flex; align-items: center; gap: .35rem;
}
.fn-protected-note .mdi { color: #0d6efd; }

.fn-rt-row {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .55rem;
    padding: .55rem .75rem;
    margin-bottom: .4rem;
    display: flex; align-items: center; gap: .65rem;
    position: relative;
}
.fn-rt-row.protected {
    background: rgba(13,110,253,.05);
    border-color: rgba(13,110,253,.2);
}
.fn-rt-color-pill {
    width: 2rem; height: 2rem;
    border-radius: .45rem;
    display: inline-flex;
    align-items: center; justify-content: center;
    color: #fff; flex-shrink: 0;
}
.fn-rt-color-pill .mdi { font-size: 1.25rem; }
.fn-rt-meta { flex: 1; min-width: 0; }
.fn-rt-label {
    font-weight: 800; color: var(--fn-text); font-size: 1rem;
    display: flex; align-items: center; gap: .35rem;
    flex-wrap: wrap;
}
.fn-rt-icon-name { font-size: .7rem; color: var(--fn-text-muted); font-family: monospace; }
.fn-rt-station {
    font-size: .65rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .04em;
    background: var(--fn-brand-soft); color: var(--fn-brand);
    padding: .15rem .4rem; border-radius: 999px;
}
.fn-rt-protected-badge {
    font-size: .65rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: .04em;
    background: rgba(13,110,253,.15);
    color: #0d6efd;
    padding: .15rem .4rem; border-radius: 999px;
    display: inline-flex; align-items: center; gap: .2rem;
}
.fn-rt-protected-badge .mdi { font-size: .8rem; }
.fn-rt-actions { display: flex; gap: .35rem; }
.fn-rt-actions button {
    background: var(--fn-tertiary-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .4rem;
    padding: .35rem .55rem;
    font-size: .75rem; font-weight: 700;
    color: var(--fn-text);
    cursor: pointer;
}
.fn-rt-actions button:hover { border-color: var(--fn-brand); }
.fn-rt-actions button.danger:hover { border-color: var(--fn-accent); color: var(--fn-accent); }
.fn-rt-actions button:disabled {
    opacity: .35;
    cursor: not-allowed;
}
.fn-rt-actions button:disabled:hover {
    border-color: var(--fn-card-border);
    color: var(--fn-text);
}


/* ─────────────────────────────────────────────────────────────────────────
 * SCROLL UNLOCK — override liquid-glass.css's `html, body { overflow:
 * hidden; height: 100% }`. That rule is correct for the SPA shell
 * (index.php), where scrolling happens inside the .fn-page-host
 * container. THIS page is a standalone route with no inner scroll
 * container — without the override below, the body is locked at viewport
 * height and the Existing-buttons list past the fold is unreachable.
 *
 * `!important` here is deliberate: there's a touch-device @media query
 * in liquid-glass.css that re-applies `overflow: hidden` with the same
 * selector + identical specificity, so source order alone can lose on
 * iOS Safari. Forcing the values guarantees this page scrolls in every
 * browser / device combination.
 * ──────────────────────────────────────────────────────────────────────── */
html, body {
    overflow: visible !important;
    height:   auto    !important;
}
@media (hover: none) and (pointer: coarse) {
    html, body {
        overflow: visible !important;
        height:   auto    !important;
        position: static  !important;
    }
}



/* ==========================================================================
   Source: demo/assets/css/login.css
   ========================================================================== */

body {
    background: #313a46;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    margin: 0;
}
.login-card {
    background: #fff;
    border-radius: 1rem;
    padding: 1.6rem;
    max-width: 400px;
    width: 100%;
    box-shadow: 0 18px 40px rgba(0,0,0,.25);
}
.login-icon {
    width: 3.2rem;
    height: 3.2rem;
    border-radius: 1rem;
    background: #313a46;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.8rem;
    margin-bottom: 1rem;
}
.login-card h4 { margin: 0 0 .25rem; font-weight: 800; }
.login-card p  { margin: 0 0 1.2rem; color: #6c757d; font-size: .9rem; }

.fn-code-input {
    font-family: 'SF Mono', 'Monaco', 'Menlo', 'Consolas', monospace;
    font-size: 1.4rem;
    font-weight: 700;
    text-align: center;
    letter-spacing: .25em;
    padding: .85rem;
}
.fn-code-input::placeholder {
    color: #ced4da;
    letter-spacing: .25em;
}

.btn-fn-primary {
    background: #313a46;
    color: #fff;
    border: 0;
    border-radius: 999px;
    padding: .85rem 1rem;
    font-weight: 800;
    font-size: 1rem;
    width: 100%;
    transition: filter .15s;
}
.btn-fn-primary:hover { filter: brightness(1.15); color: #fff; }
.btn-fn-primary:disabled { opacity: .5; }


/* ─────────────────────────────────────────────────────────────────────────
 * Demo button — floats in the bottom-right corner of the login page,
 * pointing at /response/demo/. Exists primarily so Apple App Review
 * reviewers (who don't have a real department access code) can launch
 * a stubbed read-only build of the app and evaluate it.
 *
 * Style: glass pill on the dark slate body. Reads as a clearly secondary
 * action — visible enough to find, subtle enough not to compete with
 * the centered SIGN IN card.
 *
 * Safe-area aware so it doesn't tuck under the home indicator on iPhone
 * or get clipped by the rounded corner of iPad in landscape.
 * ──────────────────────────────────────────────────────────────────────── */
.fn-demo-btn {
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 1rem);
    right:  calc(env(safe-area-inset-right,  0px) + 1rem);
    z-index: 10;

    display: inline-flex;
    align-items: center;
    gap: .4rem;

    padding: .65rem 1.1rem;
    border-radius: 999px;

    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.22);
    backdrop-filter: blur(12px) saturate(140%);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.20);

    text-decoration: none;
    font-weight: 700;
    font-size: .9rem;
    letter-spacing: .03em;
    line-height: 1;

    transition: background .15s, transform .12s, filter .15s;
    -webkit-tap-highlight-color: transparent;
}
.fn-demo-btn:hover,
.fn-demo-btn:focus {
    background: rgba(255, 255, 255, 0.20);
    color: #fff;
    outline: none;
}
.fn-demo-btn:active {
    transform: scale(.96);
    filter: brightness(.92);
}
.fn-demo-btn .mdi {
    font-size: 1.15rem;
    line-height: 1;
}



/* ==========================================================================
   Source: inline <style> in demo/logout.php
   ========================================================================== */

body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; padding: 2rem; text-align: center; color: #333; }

        /* Same demo watermark as the main app, so reviewers see
           "DEMO" even on this brief redirect screen. */
        body::after {
            content: '';
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            pointer-events: none;
            z-index: 100000;
            background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='340' height='220'><text x='170' y='130' font-family='-apple-system,BlinkMacSystemFont,sans-serif' font-size='60' font-weight='900' letter-spacing='2' fill='%23000' fill-opacity='0.08' text-anchor='middle' transform='rotate(-45 170 110)'>DEMO</text></svg>");
            background-repeat: repeat;
            background-position: center;
        }



/* ==========================================================================
   Source: inline <style> in demo/pages/address.php
   ========================================================================== */

/* ── Demo map page styles ─────────────────────────────────
   The demo doesn't load Google Maps. It shows static images
   for the satellite map and the street view, with hydrant
   markers positioned absolutely over the map image.

   The .fn-map-wrap rules in address.css already provide:
     - rounded card, border-radius 1rem
     - aspect ratio + height
     - clipping
   so the image fills that container naturally. */
#fnAddrRoot .fn-demo-map-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    user-select: none;
    -webkit-user-drag: none;
}
#fnAddrRoot .fn-demo-hydrant {
    /* Each hydrant marker is an absolutely-positioned tap
       target over the map image. The percent coordinates
       come from a per-marker `style="top:Y%;left:X%"` attribute
       so adjusting positions is a copy-paste rather than a
       JS change. */
    position: absolute;
    width: 28px;
    height: 30px;
    transform: translate(-50%, -100%);  /* anchor at base, like a pin */
    display: flex;
    align-items: flex-start;
    justify-content: center;
    cursor: pointer;
    z-index: 5;
    -webkit-tap-highlight-color: transparent;
}
#fnAddrRoot .fn-demo-hydrant i {
    color: #c0282d;
    font-size: 26px;
    text-shadow:
        0 0 2px #fff,
        0 0 2px #fff,
        0 0 2px #fff,
        0 1px 3px rgba(0,0,0,.4);
    transition: transform .12s ease;
}
#fnAddrRoot .fn-demo-hydrant:active i {
    transform: scale(0.92);
}
#fnAddrRoot .fn-demo-hydrant.oos i {
    color: #5d6b78;
}
#fnAddrRoot .fn-demo-hydrant-pop {
    /* Lightweight popup that mirrors the look of the Google
       Maps InfoWindow used in prod. Positioned above the
       tapped hydrant. */
    position: absolute;
    z-index: 10;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 8px 32px rgba(0,0,0,.25);
    padding: 8px 36px 10px 12px;
    font-size: .85rem;
    line-height: 1.4;
    color: #1F2328;
    min-width: 200px;
    max-width: 240px;
    transform: translate(-50%, calc(-100% - 10px));  /* above marker */
}
#fnAddrRoot .fn-demo-hydrant-pop .fn-demo-pop-title {
    font-weight: 800;
    font-size: .95rem;
    line-height: 1.5;
    margin: 0 0 .4rem 0;
}
#fnAddrRoot .fn-demo-hydrant-pop .fn-demo-pop-close {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 28px;
    height: 28px;
    border: 0;
    background: transparent;
    color: #6b7280;
    font-size: 1.3rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
}
#fnAddrRoot .fn-demo-hydrant-pop .fn-demo-pop-close:active {
    background: rgba(0,0,0,.06);
}
#fnAddrRoot .fn-demo-hydrant-pop .fn-demo-pop-status-oos {
    color: #b03a2e;
    font-weight: 700;
}
#fnAddrRoot .fn-demo-hydrant-pop .fn-demo-pop-dist {
    color: #6b7280;
    font-size: .78rem;
    margin-top: .25rem;
}
/* Streetview watermark banner is baked into the image. The
   image swap is the entire mechanism. */
#fnAddrRoot .fn-demo-map-wrap {
    position: relative;
    overflow: hidden;
}



/* ==========================================================================
   Source: inline <style> in demo/pages/preplan.php
   ========================================================================== */

/* Demo page layout — pinned status + scrolling results list. Mirrors the
   production preplan layout but without the controls block at top. */
.fn-page--full #fnPreplanRoot {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    min-width: 0;
    width: 100%;
    box-sizing: border-box;
}

.fn-page.fn-page--full.active.fn-preplan-no-results {
    display: block;
    height: auto;
}
.fn-page--full.fn-preplan-no-results #fnPreplanRoot {
    display: block;
    flex: none;
}
.fn-page--full.fn-preplan-no-results .fn-preplan-results {
    flex: none;
    overflow: visible;
}

/* Status row — count banner at the top of the results region. */
.fn-preplan-status {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .3rem;
    font-size: .8rem;
    color: var(--fn-text-muted);
    margin: .35rem 0 .55rem;
    min-height: 1.65rem;
    flex: 0 0 auto;
}
.fn-preplan-status-banner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    width: 100%;
    box-sizing: border-box;
    gap: .55rem;
    background: var(--fn-brand);
    color: #fff;
    border-radius: .6rem;
    padding: .5rem .85rem;
    font-size: .78rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: .015em;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
}
.fn-preplan-status-banner .count {
    font-size: .85rem;
    font-weight: 800;
    flex-shrink: 0;
}
.fn-preplan-status-banner .filter {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-weight: 600;
    color: rgba(255, 255, 255, .92);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fn-preplan-status-banner .filter .mdi {
    font-size: .95rem;
    opacity: .85;
    flex-shrink: 0;
}
.fn-preplan-status-banner .sep {
    opacity: .4;
    font-weight: 400;
    flex-shrink: 0;
}

.fn-preplan-results {
    display: flex;
    flex-direction: column;
    gap: .55rem;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding-bottom: .5rem;
}
.fn-preplan-results::-webkit-scrollbar { width: 4px; }
.fn-preplan-results::-webkit-scrollbar-thumb {
    background: var(--fn-card-border);
    border-radius: 2px;
}

.fn-preplan-card {
    background: var(--fn-card-bg);
    border: 1px solid var(--fn-card-border);
    border-radius: .75rem;
    padding: .75rem .85rem;
    box-shadow: 0 1px 3px rgba(0,0,0,.04);
    display: flex;
    flex-direction: column;
    gap: .55rem;
}
.fn-preplan-card-head {
    display: flex;
    flex-direction: column;
    gap: .15rem;
}
.fn-preplan-card-name {
    font-weight: 800;
    font-size: 1.02rem;
    color: var(--fn-text);
    line-height: 1.2;
    word-wrap: break-word;
}
.fn-preplan-card-addr {
    font-size: .85rem;
    color: var(--fn-text-muted);
    line-height: 1.3;
    word-wrap: break-word;
}
.fn-preplan-card-distance {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    align-self: flex-start;
    font-size: .72rem;
    font-weight: 800;
    color: #fff;
    background: var(--fn-brand);
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: .25rem .6rem .28rem;
    border-radius: 999px;
    margin-top: .25rem;
    line-height: 1.2;
    box-shadow: 0 1px 2px rgba(0,0,0,.12);
}
.fn-preplan-card-distance .mdi { font-size: .9rem; }
.fn-preplan-card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}
.fn-preplan-action-btn {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    border-radius: 1rem;
    padding: .55rem .65rem;
    font-family: inherit;
    font-weight: 800;
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .02em;
    line-height: 1.05;
    cursor: pointer;
    color: #fff;
    background: var(--fn-brand);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .3rem;
    box-shadow: 0 1px 3px rgba(0,0,0,.12);
    transition: filter .12s, transform .1s;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.fn-preplan-action-btn:active { transform: scale(.96); filter: brightness(.92); }
.fn-preplan-action-btn .mdi { font-size: .95rem; }
.fn-preplan-action-btn.hazards { background: var(--fn-accent); color: #fff; }
.fn-preplan-action-btn.secure  { background: #0dcaf0; color: #fff; }
.fn-preplan-action-btn.full    { background: var(--fn-brand); color: #fff; }

.fn-preplan-empty {
    text-align: center;
    padding: .85rem 1rem 1.25rem;
    color: var(--fn-text-muted);
}
.fn-preplan-empty .mdi {
    font-size: 2.1rem;
    opacity: .3;
    color: var(--fn-text);
    display: block;
    margin-bottom: .15rem;
}
.fn-preplan-empty-title { font-weight: 800; color: var(--fn-text); margin-bottom: .25rem; }
.fn-preplan-empty-sub { font-size: .85rem; line-height: 1.45; }

/* Modal — copied verbatim from production. */
.fn-preplan-modal {
    position: fixed;
    top: 0; left: 0; right: 0;
    bottom: calc(var(--fn-tabbar-h) + var(--fn-safe-bottom) + 0.45rem);
    background-color: rgba(255, 255, 255, 0.30);
    backdrop-filter: blur(28px) saturate(180%);
    -webkit-backdrop-filter: blur(28px) saturate(180%);
    z-index: 250;
    display: flex;
    align-items: stretch;
    justify-content: center;
    padding: calc(var(--fn-safe-top) + 0.45rem + var(--fn-top-chrome-h) + 0.25rem)
             0.6rem 0.6rem;
    box-sizing: border-box;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
}
[data-bs-theme="dark"] .fn-preplan-modal { background-color: rgba(15, 17, 21, 0.45); }
.fn-preplan-modal[hidden] { display: none; }
.fn-preplan-modal.active { opacity: 1; pointer-events: auto; }
.fn-preplan-modal-card {
    position: relative;
    background: var(--fn-body-bg);
    color: var(--fn-text);
    width: 100%;
    max-width: 640px;
    border-radius: .85rem;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 16px 50px rgba(0,0,0,.4);
    transform: scale(.96) translateY(.5rem);
    transition: transform .22s cubic-bezier(.2,.8,.2,1);
    box-sizing: border-box;
}
.fn-preplan-modal.active .fn-preplan-modal-card { transform: scale(1) translateY(0); }
.fn-preplan-modal-head {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .85rem .95rem;
    border-bottom: 1px solid var(--fn-card-border);
    background: var(--fn-card-bg);
    flex-shrink: 0;
    transition: background .2s;
}
.fn-preplan-modal-card.theme-hazards .fn-preplan-modal-head { background: var(--fn-accent); border-bottom-color: rgba(0,0,0,.18); }
.fn-preplan-modal-card.theme-secure  .fn-preplan-modal-head { background: #0dcaf0; border-bottom-color: rgba(0,0,0,.18); }
.fn-preplan-modal-card.theme-full    .fn-preplan-modal-head { background: var(--fn-brand); border-bottom-color: rgba(0,0,0,.25); }
.fn-preplan-modal-card.theme-hazards .fn-preplan-modal-title,
.fn-preplan-modal-card.theme-full    .fn-preplan-modal-title { color: #fff; }
.fn-preplan-modal-card.theme-hazards .fn-preplan-modal-sub,
.fn-preplan-modal-card.theme-full    .fn-preplan-modal-sub   { color: rgba(255,255,255,.85); }
.fn-preplan-modal-card.theme-secure  .fn-preplan-modal-title { color: #fff; }
.fn-preplan-modal-card.theme-secure  .fn-preplan-modal-sub   { color: rgba(255, 255, 255, .85); }
.fn-preplan-modal-title-wrap { flex: 1; min-width: 0; }
.fn-preplan-modal-title { font-weight: 800; font-size: 1.1rem; line-height: 1.2; color: var(--fn-text); overflow: hidden; text-overflow: ellipsis; }
.fn-preplan-modal-sub { font-size: .8rem; color: var(--fn-text-muted); line-height: 1.3; margin-top: .15rem; overflow: hidden; text-overflow: ellipsis; }
.fn-preplan-modal-filter {
    position: relative;
    padding: .55rem .85rem;
    border-bottom: 1px solid var(--fn-card-border);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: .4rem;
}
.fn-preplan-modal-filter[hidden] { display: none; }
.fn-preplan-modal-filter .mdi { color: var(--fn-text-muted); font-size: 1.1rem; }
.fn-preplan-modal-filter-input {
    flex: 1;
    padding: .45rem .55rem;
    border-radius: .5rem;
    border: 1px solid var(--fn-card-border);
    background: var(--fn-card-bg);
    color: var(--fn-text);
    font-family: inherit;
    font-size: .9rem;
    -webkit-appearance: none;
    appearance: none;
}
.fn-preplan-modal-filter-input:focus {
    outline: none;
    border-color: var(--fn-brand);
    box-shadow: 0 0 0 2px var(--fn-brand-soft);
}
.fn-preplan-modal-body {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    flex: 1 1 0;
    min-height: 0;
    padding: .35rem 0 4rem;
}
#fnPreplanModalBody .fn-preplan-field {
    padding: .55rem .95rem .6rem;
    border-bottom: 1px solid var(--fn-card-border);
}
#fnPreplanModalBody .fn-preplan-field:last-child { border-bottom: 0; }
#fnPreplanModalBody .fn-preplan-field[hidden] { display: none; }
.fn-preplan-field-label {
    font-size: .68rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--fn-text-muted);
    margin-bottom: .15rem;
    display: inline-flex;
    align-items: center;
    gap: .25rem;
}
.fn-preplan-field-label::before {
    content: '';
    width: 3px;
    height: 10px;
    background: var(--fn-brand);
    border-radius: 2px;
}
.fn-preplan-field-value {
    font-size: .95rem;
    line-height: 1.45;
    color: var(--fn-text);
    word-break: break-word;
    white-space: pre-wrap;
}
.fn-preplan-modal-prose {
    padding: 1rem 1rem 4rem;
    font-size: 1rem;
    line-height: 1.55;
    color: var(--fn-text);
    white-space: pre-wrap;
    word-break: break-word;
}
.fn-preplan-modal-fab-close {
    position: absolute;
    right: .85rem;
    bottom: .85rem;
    width: 3.2rem;
    height: 3.2rem;
    border-radius: 50%;
    background: var(--fn-brand);
    color: #fff;
    border: 0;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    box-shadow: 0 4px 14px rgba(0,0,0,.3), 0 1px 4px rgba(0,0,0,.18);
    z-index: 5;
    transition: transform .12s, filter .12s;
}
.fn-preplan-modal-fab-close:active { transform: scale(.93); filter: brightness(.9); }
.fn-preplan-modal-fab-close .mdi { font-size: 1.55rem; line-height: 1; }
.fn-preplan-modal-card.theme-hazards .fn-preplan-modal-fab-close { background: var(--fn-accent); color: #fff; }
.fn-preplan-modal-card.theme-secure  .fn-preplan-modal-fab-close { background: #0dcaf0; color: #fff; }
.fn-preplan-modal-card.theme-full    .fn-preplan-modal-fab-close { background: var(--fn-brand); color: #fff; }

@media (min-width: 600px) {
    .fn-preplan-modal {
        left: 1rem;
        right: 1rem;
        top: 0;
        bottom: calc(var(--fn-tabbar-h) + var(--fn-safe-bottom) + 0.45rem);
        max-width: none;
        padding: calc(var(--fn-safe-top) + 0.45rem + var(--fn-top-chrome-h) + 1rem)
                 1rem 1rem;
        transform: none;
    }
    .fn-preplan-modal-card { max-width: none; height: 100%; }
}


/* ==========================================================================
   Source: inline <style> in demo/index.php
   ========================================================================== */

/* ─────────────────────────────────────────────────────────────
/* DEMO MODE: diagonal "DEMO" watermark across every screen. */
body::after {
    content: '';
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    pointer-events: none;
    z-index: 100000;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='340' height='220'><text x='170' y='130' font-family='-apple-system,BlinkMacSystemFont,sans-serif' font-size='60' font-weight='900' letter-spacing='2' fill='%23000' fill-opacity='0.08' text-anchor='middle' transform='rotate(-45 170 110)'>DEMO</text></svg>");
    background-repeat: repeat;
    background-position: center;
}
[data-bs-theme="dark"] body::after {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='340' height='220'><text x='170' y='130' font-family='-apple-system,BlinkMacSystemFont,sans-serif' font-size='60' font-weight='900' letter-spacing='2' fill='%23fff' fill-opacity='0.09' text-anchor='middle' transform='rotate(-45 170 110)'>DEMO</text></svg>");
}
.fn-demo-hero-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
}

.fn-demo-contact-btn,
.fn-demo-exit-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    padding: 0.4rem 0.75rem;
    font-family: inherit;
    font-weight: 700;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
    line-height: 1;
    border-radius: 999px;
    border: 0;
    cursor: pointer;
    white-space: nowrap;
    -webkit-tap-highlight-color: transparent;
    position: relative;
    z-index: 100001;
    transition: background .14s ease, transform .08s ease, box-shadow .14s ease;
}

.fn-demo-contact-btn {
    color: #fff !important;
    background: rgba(255, 255, 255, 0.12);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
}
.fn-demo-contact-btn:hover {
    background: rgba(255, 255, 255, 0.22);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.45);
}
.fn-demo-contact-btn:active {
    transform: scale(0.95);
    background: rgba(255, 255, 255, 0.30);
}

.fn-demo-exit-btn {
    color: #fff !important;
    background: linear-gradient(180deg, #ef4444 0%, #dc2626 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.22),
        0 3px 6px -2px rgba(220, 38, 38, 0.45);
}
.fn-demo-exit-btn:hover {
    background: linear-gradient(180deg, #dc2626 0%, #b91c1c 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.22),
        0 3px 6px -2px rgba(220, 38, 38, 0.45);
}
.fn-demo-exit-btn:active {
    transform: scale(0.95);
    background: linear-gradient(180deg, #b91c1c 0%, #991b1b 100%);
}

.fn-demo-contact-btn .mdi,
.fn-demo-exit-btn .mdi {
    font-size: 0.95rem;
    line-height: 1;
}

/* Narrow phones: shrink padding and label size, then drop the
   labels entirely below 360px so the icons alone remain. */
@media (max-width: 420px) {
    .fn-demo-contact-btn,
    .fn-demo-exit-btn {
        padding: 0.35rem 0.6rem;
        font-size: 0.68rem;
    }
}
@media (max-width: 360px) {
    .fn-demo-contact-btn span,
    .fn-demo-exit-btn span { display: none; }
    .fn-demo-contact-btn,
    .fn-demo-exit-btn { padding: 0.4rem 0.55rem; }
}

/* DEMO MODE: the shared .fn-hero-id pill-background shows
   through the gap between Contact and Exit. Strip it; the
   buttons supply their own visual frame. */
.fn-hero-id {
    background: transparent !important;
    /* If index.css also gives it padding/border that contributes
       to the visible pill, strip those too: */
    padding: 0 !important;
    border: 0 !important;
    box-shadow: none !important;
}



/* ==========================================================================
   Source: inline <style> in demo/index.php
   ========================================================================== */

.fn-demo-intro {
    position: fixed;
    inset: 0;
    z-index: 200000;
    display: none;
    align-items: stretch;
    justify-content: center;
    padding: max(env(safe-area-inset-top, 0px), 1rem)
             1rem
             max(env(safe-area-inset-bottom, 0px), 1rem);
    box-sizing: border-box;
    opacity: 0;
    transition: opacity .25s ease;
}
.fn-demo-intro.active { display: flex; opacity: 1; }
.fn-demo-intro-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 17, 21, 0.55);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
}
.fn-demo-intro-card {
    position: relative;
    width: 100%;
    max-width: 560px;
    margin: auto;
    background: #fff;
    color: #1f2328;
    border-radius: 1.1rem;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
    transform: scale(.94) translateY(.5rem);
    transition: transform .28s cubic-bezier(.2, .8, .2, 1);
    max-height: 100%;
}
.fn-demo-intro.active .fn-demo-intro-card { transform: scale(1) translateY(0); }

.fn-demo-intro-head {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: 1rem 1.1rem;
    background: #c0282d;
    color: #fff;
    flex-shrink: 0;
}
.fn-demo-intro-head > .mdi { font-size: 1.8rem; line-height: 1; flex-shrink: 0; }
.fn-demo-intro-head-text { flex: 1; min-width: 0; }
.fn-demo-intro-title { font-weight: 800; font-size: 1.15rem; line-height: 1.2; }
.fn-demo-intro-sub { font-size: .82rem; opacity: .9; margin-top: .1rem; }
.fn-demo-intro-x {
    appearance: none; -webkit-appearance: none;
    background: rgba(255, 255, 255, 0.18);
    color: #fff; border: 0;
    width: 2.1rem; height: 2.1rem;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; flex-shrink: 0; padding: 0;
    transition: background .15s;
}
.fn-demo-intro-x:hover { background: rgba(255, 255, 255, 0.28); }
.fn-demo-intro-x:active { transform: scale(.93); }
.fn-demo-intro-x .mdi { font-size: 1.2rem; line-height: 1; }

.fn-demo-intro-body {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 1rem 1.1rem .25rem;
}
.fn-demo-intro-lead { margin: 0 0 1rem; font-size: .95rem; line-height: 1.45; color: #44484d; }

.fn-demo-intro-step {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    padding: .7rem 0;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.fn-demo-intro-step:last-of-type { border-bottom: 0; }
.fn-demo-intro-num {
    flex-shrink: 0;
    width: 1.8rem; height: 1.8rem;
    border-radius: 50%;
    background: #c0282d;
    color: #fff;
    font-weight: 800; font-size: .92rem;
    display: flex; align-items: center; justify-content: center;
    line-height: 1;
}
.fn-demo-intro-step-title { font-weight: 800; font-size: .98rem; line-height: 1.25; margin-bottom: .2rem; color: #1f2328; }
.fn-demo-intro-step-body { font-size: .87rem; line-height: 1.45; color: #5d6770; }

.fn-demo-intro-note {
    display: flex;
    gap: .55rem;
    align-items: flex-start;
    margin: 1rem 0 .5rem;
    padding: .7rem .85rem;
    background: rgba(255, 155, 58, 0.10);
    border: 1px solid rgba(255, 155, 58, 0.30);
    border-radius: .6rem;
    font-size: .82rem;
    line-height: 1.4;
    color: #44484d;
}
.fn-demo-intro-note .mdi { font-size: 1.1rem; color: #d97706; flex-shrink: 0; line-height: 1.3; }

.fn-demo-intro-footer {
    padding: .9rem 1.1rem 1.1rem;
    flex-shrink: 0;
    border-top: 1px solid rgba(0, 0, 0, 0.06);
    background: #fafafa;
}
.fn-demo-intro-btn {
    appearance: none; -webkit-appearance: none;
    width: 100%;
    display: flex; align-items: center; justify-content: center;
    gap: .5rem;
    padding: .85rem 1rem;
    background: #c0282d;
    color: #fff;
    font-family: inherit;
    font-weight: 800; font-size: .95rem; letter-spacing: .02em;
    border: 0; border-radius: .75rem;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(192, 40, 45, 0.35);
    transition: background .12s, transform .1s;
}
.fn-demo-intro-btn:hover { background: #a01f24; }
.fn-demo-intro-btn:active { transform: scale(.97); background: #841a1e; }
.fn-demo-intro-btn .mdi { font-size: 1.15rem; }

@media (min-width: 600px) {
    .fn-demo-intro { padding: 2rem; }
}

[data-bs-theme="dark"] .fn-demo-intro-card { background: #1f232a; color: #e6e8eb; }
[data-bs-theme="dark"] .fn-demo-intro-lead { color: #b8bcc1; }
[data-bs-theme="dark"] .fn-demo-intro-step-title { color: #e6e8eb; }
[data-bs-theme="dark"] .fn-demo-intro-step-body { color: #b0b4ba; }
[data-bs-theme="dark"] .fn-demo-intro-step { border-bottom-color: rgba(255, 255, 255, 0.08); }
[data-bs-theme="dark"] .fn-demo-intro-note { color: #c0c4ca; }
[data-bs-theme="dark"] .fn-demo-intro-footer { background: #181b21; border-top-color: rgba(255, 255, 255, 0.08); }


/* ==========================================================================
   App background restore — keep Liquid Glass backdrop after CSS consolidation
   ==========================================================================
   dashboard.css contains global body/body::before rules for the wall display.
   Once all CSS was merged into priority4.css, those dashboard rules were able
   to override the normal app backdrop and leave app/admin pages plain white.
   These rules restore the shared subtle gradient for the main chrome pages. */
body.fn-chrome-page {
    color: var(--fn-text) !important;
    background-color: var(--fn-body-bg) !important;
    background-image:
        radial-gradient(ellipse 80% 65% at 10% 5%,   rgba(120, 145, 195, 0.40), transparent 62%),
        radial-gradient(ellipse 80% 65% at 95% 100%, rgba(220, 130, 110, 0.32), transparent 62%) !important;
    background-attachment: fixed !important;
    background-repeat: no-repeat !important;
    background-size: 100% 100% !important;
    isolation: auto !important;
}

[data-bs-theme="dark"] body.fn-chrome-page {
    background-color: var(--fn-body-bg) !important;
    background-image:
        radial-gradient(ellipse 80% 65% at 10% 5%,   rgba(42, 62, 110, 0.65), transparent 62%),
        radial-gradient(ellipse 80% 65% at 95% 100%, rgba(110, 38, 32, 0.55), transparent 62%) !important;
}

body.fn-chrome-page::before {
    content: "" !important;
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: auto !important;
    height: calc(var(--fn-safe-top) + 1.75rem) !important;
    z-index: 1 !important;
    pointer-events: none !important;
    background:
        linear-gradient(to right,
            transparent 0%,
            transparent 55%,
            rgba(15, 17, 21, 0.18) 100%),
        linear-gradient(to bottom,
            rgba(15, 17, 21, 0.70) 0%,
            rgba(15, 17, 21, 0.55) 25%,
            rgba(15, 17, 21, 0.20) 60%,
            rgba(15, 17, 21, 0.06) 85%,
            transparent 100%) !important;
    animation: none !important;
}

body.fn-chrome-page::after {
    display: none !important;
    content: none !important;
}
