﻿html, body {
    font-family: var(--fs-font-sans);
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}

@media (min-width: 768px) {
    app {
        flex-direction: row;
    }

    .sidebar {
        width: 250px;
        height: 100vh;
        position: sticky;
        top: 0;
    }

    .main .top-row {
        position: sticky;
        top: 0;
    }

    .main > div {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }

    .navbar-toggler {
        display: none;
    }

    .sidebar .collapse {
        /* Never collapse the sidebar for wide screens */
        display: block;
    }

    .table-condensed {
        font-size: 10px;
    }
}


/* ── Service Tracker Route Planner status tokens (guide Aug 11, 2026 + FasCentral UI
   standard rule 1: hex lives ONLY here or in the theme object). The map stop
   bubbles, the Route Breakdown number badges, and the custom-stop magenta
   marker all read these vars, so the three views share ONE color source. */
:root {
    /* The app font stack (9/17). Written here and in BrandFont in Shared/MainLayout.razor, and nowhere
       else; those two are to a font family what this block and the theme object are to a hex. Before this
       existed the hand written pages read the stack from the html rule above while every MudBlazor surface
       fell through to MudBlazor's own Roboto default, so the Snow Tracker and the Service Tracker were in
       two different typefaces and nobody had chosen either. On Windows neither Helvetica face is installed
       and this resolves to Arial, which is what these pages have always actually rendered in. If this line
       changes, change BrandFont with it. */
    --fs-font-sans: 'Helvetica Neue', Helvetica, Arial, sans-serif;

    /* snowma 8/26 (R. Nugent): FasDialog / FasConfirm shell tokens (UI Standard 1.3
       companion block). Derived from the Mud palette where a slot exists; bespoke
       values live ONLY here per standing rule 1. */
    --fs-radius-md: 8px;
    --fs-radius-lg: 14px;
    --fs-gap-sm: 8px;
    --fs-gap-md: 12px;
    --fs-gap-lg: 20px;
    --fs-shadow-dialog: 0 20px 40px rgba(0, 0, 0, .20);
    --fs-shadow-lift: 0 14px 34px rgba(0, 0, 0, .22);   /* snowfit 9/23: the Snow Tracker AI Analyst lift */
    --fs-shadow-bar: 0 1px 3px rgba(0, 0, 0, .18);      /* pagebar 9/23: FasPageBar, the snow pages' top bar */
    --fs-bar-chip-bg: rgba(255, 255, 255, .18);          /* pagebar 9/23: the version tag on that bar */
    --fs-scrim: rgba(17, 24, 39, .45);
    /* histscroll 9/22 (R. Nugent): the site detail drawer's width (Snow Tracker 2.0), read by the drawer
       itself and by FasDialog's BesideDrawer mode, whose backdrop ends at the drawer's left edge so the
       drawer stays live beside the dialog. One number for both edges, so they cannot drift apart.
       panelw 10/13 (R. Nugent, Gate 1 signed off 10/13: "the team would like it to take up more space to the left or the
       ability to expand or contract it"): the drawer now opens at 40% of the screen, never narrower than the old 460px and
       never so wide that Modify Status or Work Orders would open smaller beside it than they did, which keeps 820px to its
       left. A person's own width (the handle on the drawer's edge, or its Widen button) is written over this on <html> by
       wwwroot/js/fas-drawer.js, which reads the four numbers below, so they live only here. Floor plus room is the 1280px
       line where resizing starts, the BesideDrawer line too; a media query cannot read a custom property, so that line is
       written as a number where a stylesheet needs it. */
    --fs-drawer-floor: 460px;
    --fs-drawer-share: 40vw;
    --fs-drawer-room: 820px;
    --fs-drawer-min: 400px;
    --fs-drawer-w: clamp(var(--fs-drawer-floor), var(--fs-drawer-share), calc(100vw - var(--fs-drawer-room)));
    --fs-drawer-scrim: rgba(0, 0, 0, .25);                /* panelw 10/13: the page under the open drawer, as it was inline */
    --fs-shadow-drawer: -4px 0 24px rgba(0, 0, 0, .18);    /* panelw 10/13: the drawer's shadow, as it was inline */
    --fs-drawer-grip-line: #94A3B8;                        /* panelw 10/13: the resize handle's outline (the Gate 1 mock) */
    --fs-drawer-grip-ink: #64748B;                         /* panelw 10/13: its two grip lines */
    --fs-drawer-grip-shadow: 0 1px 4px rgba(0, 0, 0, .2);  /* panelw 10/13: its lift off the page */
    /* navfit 9/23 (R. Nugent): the side menu's colours, read by Shared/NavMenu.razor.css. The background
       follows the Mud palette's Primary (brand colour). Hover and accent are pinned to the menu's own colours
       (10/14): the theme's Secondary/Tertiary were retuned for controls (#159957 / #3B89D8 in MainLayout) and
       must not repaint the menu's hover/active highlight and active-link bar. The inks have no slot either. */
    --fs-nav-bg: var(--mud-palette-primary, #12372E);
    --fs-nav-hover: #1c4a3d;          /* was var(--mud-palette-secondary, #1c4a3d) */
    --fs-nav-accent: #6ee7b7;         /* was var(--mud-palette-tertiary, #6ee7b7) */
    --fs-nav-ink-strong: var(--mud-palette-primary-text, #ffffff);
    --fs-nav-ink: #d7e3de;
    --fs-nav-muted: #8aa79c;
    --fs-warn-bg: #FFF8E1;
    --fs-warn-border: #E6C200;
    --fs-warn-text: #7A5D00;
    --fs-danger-bg: #FDECEA;
    --fs-danger-border: #B91C1C;
    /* snowdocs 9/29 (R. Nugent): FasDocRow's file type badges. Four fills, the same reds, greens and blues the
       status tokens above already use, named for what they mean here so a badge never reads a status token. */
    --fs-doc-pdf: #B91C1C;
    --fs-doc-sheet: #047857;
    --fs-doc-word: #2563EB;
    --fs-doc-other: #6B7280;
    /* addsite 9/29 (R. Nugent): ink on the tertiary mint, the count pill in FasZone. Mass Assign's pill had
       read var(--fs-on-tertiary, #0B241D) since 8/27 with no token behind it, so the fallback was doing the
       work; the theme sets no TertiaryContrastText, and Mud's default there is translucent white. */
    --fs-on-tertiary: #0B241D;
    /* faskpi 9/8 (R. Nugent): FasKpiCard tokens (ADR-0014 wave 1A/1G). The four severity
       pairs are the exact hex the two hand rolled snow KPI copies carried inline in
       SnowTracker20 and SnowMapsCanvas, now defined ONCE. tile = icon background, ink =
       icon color and the Danger subtext. Text tokens are the de facto palette the UI
       Standard theme doc lists (Text secondary, Text muted). shadow-card is Material
       elevation 1, what MudPaper Elevation=1 rendered. */
    --fs-text-secondary: #374151;
    --fs-text-muted: #6B7280;
    --fs-kpi-surface: var(--mud-palette-surface, #ffffff);
    --fs-shadow-card: 0 2px 1px -1px rgba(0, 0, 0, .2), 0 1px 1px 0 rgba(0, 0, 0, .14), 0 1px 3px 0 rgba(0, 0, 0, .12);
    /* mudgrid 8/20: note-indicator + chip tokens so the Mud grid templates carry
       zero inline hex (the classic table's inline styles predate the standard). */
    --stm-note-vendor: #ea580c;
    --stm-note-client: #1d4ed8;
    --stm-note-muted: #d1d5db;
    /* fchips 9/18: the active-filter chip strip. Metrics and colours are the Land
       Tracker .vsp-mlf-chip rule, lifted here as tokens so the new component carries no
       hex of its own (standing rule 1). When ServiceTracker migrates at UI Standard step
       12 its inline hex is deleted and it reads these instead. */
    --fs-chip-bg: #eff6ff;
    --fs-chip-fg: #1e40af;
    --fs-chip-line: #bfdbfe;
    --fs-chip-x: #3b82f6;
    --fs-chip-x-hover: #1e3a8a;
    /* ffs 9/18: focus ring on the open filter box, the Land Tracker .vsp-mlf-box.open glow. */
    --fs-ffs-focus: rgba(18, 55, 46, .15);
    --stm-chip-surface: #ffffff;
    /* mudgrid2: SURVEY filter pellet dots -- same palette as the survey chip borders */
    /* surveypastel 9/1 (R. Nugent): outline colors REVERT to the original production
       palette. The bolder traffic light set read too dark in PROD, and the rating LETTER
       (G/Y/R/N-A) now carries the accessibility ask on its own, so the border is back to
       being a soft secondary cue. Neutral is the hex the chip base rule used before these
       tokens existed. Chips and the SURVEY filter dots share these, so both revert together.
       The left rail concept is SHELVED pending director approval and was never coded. */
    --stm-svy-green: #34d399;
    --stm-svy-yellow: #fbbf24;
    --stm-svy-red: #f87171;
    --stm-svy-neutral: #d1d5db;
    /* surveychip 9/3 (1F/1F-A wave): text + surface steps so the ONE shared rating chip
       (FasSurveyRatingChip) reads every rating color from this block. Borders are the pastel
       revert above; these text/tint values are what the three inline chip copies hardcoded. */
    --stm-svy-green-text: #047857;   --stm-svy-green-bg: #ecfdf5;
    --stm-svy-yellow-text: #a16207;  --stm-svy-yellow-bg: #fffbeb;
    --stm-svy-red-text: #b91c1c;     --stm-svy-red-bg: #fef2f2;
    --stm-svy-neutral-text: #475569; --stm-svy-neutral-bg: #f8fafc;
    /* kpicard 9/3: FasKpiCard severity palette. Values match SnowTracker20's four hand-rolled
       cards exactly so the retrofit is pixel-identical; neutral is for plain counts (1F-A). */
    --fs-kpi-info-fg: #2563EB;    --fs-kpi-info-bg: #DBEAFE;
    /* Selected KPI card (9/11). The card is a filter button, so the reader has to see at a glance
       which one is holding the grid and the map down. The selected colour is the card's OWN severity
       (green complete, amber awaiting, red problem, blue service required), so the ground matches the
       thing that was filtered by; these two are only the fallback for a severity with no palette. */
    --fs-kpi-active-fg: #1D4ED8;  --fs-kpi-active-bg: #EFF6FF;
    --fs-kpi-error-fg: #DC2626;   --fs-kpi-error-bg: #FEE2E2;
    --fs-kpi-warning-fg: #CA8A04; --fs-kpi-warning-bg: #FEF9C3;
    --fs-kpi-success-fg: #16A34A; --fs-kpi-success-bg: #DCFCE7;
    --fs-kpi-neutral-fg: #4B5563; --fs-kpi-neutral-bg: #E5E7EB;
    /* kpiv2 10/23: the KPI Summary Strip's seven card accents (cross-app reference specification, section 8), with the Risk
       Tracker's names and values so a card reads the same in every app. Written out rather than derived from the theme:
       FasCentral's theme success is Mud's default green (#00C853), not the spec's #047857. FasKpiCard v2 reads these; the
       -fg / -bg pairs above stay for everything else that uses them. */
    --fs-kpi-good: #047857;  --fs-kpi-bad: #dc2626;  --fs-kpi-warn: #d97706;  --fs-kpi-cal: #4338ca;
    --fs-kpi-claims: #ea580c;  --fs-kpi-volume: #14B8A6;  --fs-kpi-info: #0369a1;
    /* Ground for an expanded grid row (9/11). Replaces the amber the address block used inline. */
    --fs-rowexp-bg: #F8FAFC;
    --fs-field-fill: #F3F4F6;          /* e50 10/30: grey fill on fields Ops type into (integration compose column) */
    --fs-kpi-label: #374151;      --fs-kpi-sub: #6B7280;
    --stm-status-completed: #2FA66D;
    --stm-status-pending: #F4B400;
    --stm-status-overdue: #E9782E;
    --stm-status-nocheckin: #D64545;
    --stm-status-nofreq: #9D174D;
    --stm-custom-stop: #a855f7;
    --stm-route-accent: #2563eb;
    --stm-rp-brand: #12372E;
    /* fbwave1: dropzone hover/dragover fills = --stm-rp-brand at low opacity */
    --stm-dropzone-hover-fill: rgba(18, 55, 46, 0.06);
    --stm-dropzone-active-fill: rgba(18, 55, 46, 0.14);
    --stm-note-badge-text: #ffffff;
    /* snowmod 9/18: the note-count badge sits on amber (--stm-status-pending), where white
       reads at about 2:1. Its own token so the shared badge-text white above stays correct
       for .stn-photo-vis-*, which sits on dark green. */
    --stm-note-count-text: #1F2937;
    /* groupdelete item 2: per-photo share chip scrim + muted 'hidden' text over thumbnails */
    --stm-photo-vis-scrim: rgba(17, 24, 39, 0.62);
    --stm-photo-vis-offtext: #cbd5e1;
    /* docshare 10/15: FasShareToggle's button shape, the Ops Notes dialog's eye Client button (.stn-vis, inline hex there).
       Its chip shape reads the --stm-photo-vis-* pair above, as the Ops photo chip does. */
    --fs-share-line: #D1D5DB;  --fs-share-off-fg: #6B7280;  --fs-share-on-bg: #EEF4F1;  --fs-share-on-ink: #12372E;
    /* pdfexport: fallbacks for the MudBlazor theme vars the Export-to-PDF dialog reads,
       in case a Mud upgrade renames one. These same three values are the PDF renderer's
       BodyText / MutedText / RuleLine constants (Services/ServiceTrackerPdfExport.cs),
       so the on-screen dialog and the generated file stay one palette. */
    --stm-dlg-text: #111827;
    --stm-dlg-muted: #4B5563;
    --stm-dlg-line: #D8DEDB;
    /* kpiharden: unknown-author note category in the Notes dialog (blank Username rows).
       The avatar keeps the amber the "?" avatar has always rendered with (it was riding
       the vendor color); the bar and UNKNOWN tag are neutral gray so an unclassified
       author no longer reads as vendor-orange. */
    --stm-note-unknown-av: #ea580c;
    --stm-note-unknown-bar: #9ca3af;
    --stm-note-unknown-tag-bg: #e5e7eb;
    --stm-note-unknown-tag-text: #4b5563;
    /* snowclient 9/8 (ADR 0014 wave 1G, R. Nugent): tokens for the client Storm Status view and
       the three house components it introduced (FasStatusPill, FasTimeline, FasPhotoGrid).
       Every hex here already existed inline: the status pill pairs are the .stm-pill/.st-*
       block SnowMapsCanvas and SnowTracker20 both carried, the timeline tones are the KPI
       severity inks so a check-in is the same blue as the Service Required tile, and the
       photo phase badges are the PhaseColor() hex both snow screens hardcoded. */
    --fs-status-completed-bg: #DCFCE7;  --fs-status-completed-fg: #166534;
    --fs-status-followup-bg: #FEF9C3;   --fs-status-followup-fg: #854D0E;
    --fs-status-problem-bg: #FEE2E2;    --fs-status-problem-fg: #B91C1C;
    --fs-status-required-bg: #DBEAFE;   --fs-status-required-fg: #1E40AF;
    --fs-status-none-bg: #F3F4F6;       --fs-status-none-fg: #6B7280;
    /* status2 10/6 (R. Nugent): the STATUS pill's two more tones (FasPillTone.Muted, the darker grey; Clear, no fill
       and a hairline) and the wash a row with an open problem gets, one step lighter than the problem pill. */
    --fs-status-muted-bg: #E5E7EB;      --fs-status-muted-fg: #374151;
    --fs-status-clear-fg: #6B7280;      --fs-status-clear-line: #D1D5DB;
    --fs-row-problem-bg: #FEF2F2;
    --fs-tl-amber: #CA8A04;  --fs-tl-blue: #2563EB;  --fs-tl-green: #16A34A;  --fs-tl-red: #DC2626;  --fs-tl-neutral: #9CA3AF;
    --fs-tl-line: #E5E7EB;
    /* evh 10/8: Snow Tracker 2.0's Event History entries, one card shape: a note (the blue it always had) and an F&S line. */
    --fs-hist-note-bg: #E6F2FF;  --fs-hist-note-line: #BBD9F5;
    --fs-hist-sys-bg: #F9FAFB;   --fs-hist-sys-line: #E5E7EB;
    --fs-hist-text: #1F2937;
    /* notechips 10/29 (Gate 1 signed off 10/29): the comment types' ink and tint (SnowNoteType, FasCommentChips, FasCommentBadge), each pair
       4.5:1 or better for the badge's 10.5px text. User is the Risk Tracker spec's User Comment pair; Status is its neutral pair. */
    --fs-note-user: #1D4ED8;    --fs-note-user-bg: #DBEAFE;
    --fs-note-client: #6D28D9;  --fs-note-client-bg: #EDE9FE;
    --fs-note-weather: #0E7490; --fs-note-weather-bg: #CFFAFE;
    --fs-note-wo: #A84B07;      --fs-note-wo-bg: #FEF3C7;
    --fs-note-status: #475569;  --fs-note-status-bg: #F1F5F9;
    --fs-note-vendor: #BE123C;  --fs-note-vendor-bg: #FFE4E6;
    /* mobilechips 10/29 (Gate 1 signed off 10/29): Mobile, the mobile app's check-ins, in green (R. Nugent: "We can make Mobile
       bubble/color scheme green"), 4.57:1 for the badge's 10.5px text; and System, System Admin's other lines, a neutral a shade
       darker than Status's so the two chips tell apart (the spec keeps machine lines neutral), 11.86:1. */
    --fs-note-mobile: #15803D;  --fs-note-mobile-bg: #DCFCE7;
    --fs-note-system: #1F2937;  --fs-note-system-bg: #E5E7EB;
    /* Map symbols and map controls (mapkey 10/5), read by azmap.js, landlotmap-az.js and fas-map-insets.js: the dark
       edge round every map dot and the inset labels, the white ring of a snow bubble and the hollow site's fill,
       and the Alaska and Hawaii inset frame with the water tint it shows while its tiles load. */
    --fs-map-edge: #111827;  --fs-map-ring: #FFFFFF;  --fs-map-inset-line: #9CA3AF;  --fs-map-inset-bg: #DBEAFE;
    /* mapsix 10/6: the staff snow bubbles wear the STATUS pill's colours (the --fs-tl-* inks above for blue, green and
       amber, --fs-map-ring for Neither open); these two are No Service Required with its follow-up open and done, a
       grey apart as the pill's --fs-status-none and --fs-status-muted are, deep enough to read on the base map. */
    --fs-map-nsr-open: #D1D5DB;  --fs-map-nsr-done: #4B5563;
    /* mapedge 10/14 (R. Nugent: "darker outlines especially to these white neither bubbles"): the ring of the white Neither
       open bubble on the staff snow map, read by azmap.js, its legend dot and the Add sites added bubble; a grey dark
       enough to read on the pale base map, inside the --fs-map-edge outline every tracked bubble now wears. */
    --fs-map-clear-ring: #6B7280;
    /* pinoff 10/9 (R. Nugent): a site to add whose map pin is far from its ZIP, the orange ring on its bubble and in the
       Add sites key (azmap.js), and the note in its popup. */
    --fs-map-pinoff: #EA580C;  --fs-map-pinoff-bg: #FFEDD5;  --fs-map-pinoff-fg: #9A3412;
    /* snowbands 10/26 (R. Nugent; Gate 1 signed off 10/26): the Snow Tracker Map's certified snowfall in six fixed bands of the
       certified total, read by azmap.js for its heat layers and its legend: under 1", 1 to 3", 3.1 to 6", 6.1 to 9", 9.1 to 12"
       and over 12", blue through red, so a light dusting reads light whatever the other sites had. */
    --fs-cst-1: #3B82F6;  --fs-cst-2: #22D3EE;  --fs-cst-3: #A3E635;  --fs-cst-4: #FACC15;  --fs-cst-5: #F97316;  --fs-cst-6: #EF4444;
    /* radararch 10/12 (R. Nugent): on a past date the Weather radar box carries an ARCHIVE tag and Traffic a LIVE ONLY
       tag, on both maps (fas-radar.js). The ramp is Iowa State's own color scale for the archive radar (n0q_ramp.png on
       their mosaic page), every 5 dBZ from 5 to 70, drawn as the bar on the RADAR ARCHIVE legend card. */
    --fs-map-archive-fg: #065F46;  --fs-map-archive-bg: #ECFDF5;  --fs-map-archive-line: #A7F3D0;
    --fs-map-liveonly-fg: var(--fs-text-muted);  --fs-map-liveonly-bg: #F3F4F6;  --fs-map-liveonly-line: var(--fs-tl-line);
    --fs-map-radar-archive-ramp: linear-gradient(to right, #6678A8, #4260A1, #5DACCF, #4AD68F, #0FB613, #0B870F, #095D09,
        #EAD204, #FFB000, #FF0000, #B00000, #FFF5FF, #FC6AFD, #AB00FC);
    /* Survey rating boxes (9/11). The SAME fills the Azure map draws its rating squares with, so a legend
       chip and a map marker are one colour rather than two that drift. G, Y and R are the timeline inks;
       the two greys are the whole point of the pair, separating a survey RATED not applicable from an
       iVueIt inspection that carries no rating at all. */
    --fs-svy-g: #16A34A;   --fs-svy-y: #CA8A04;   --fs-svy-r: #DC2626;
    --fs-svy-na: #6B7280;  --fs-svy-iv: #9CA3AF;  --fs-svy-ot: #D1D5DB;  --fs-svy-fg: #FFFFFF;
    /* Chip ink and tint (9/11). The fills above are what the MAP draws, which is why the two greys are so
       close and why Other type is nearly white: a marker only has to be distinguishable from its neighbour.
       A chip has to carry readable text, so it needs a darker ink and a lighter ground, and the three real
       ratings deliberately reuse the status pill pairs so a red survey chip is the same red the reader
       already reads as bad everywhere else on the screen. */
    --fs-svy-r-bg: #FEE2E2;   --fs-svy-r-fg: #B91C1C;
    --fs-svy-y-bg: #FEF9C3;   --fs-svy-y-fg: #854D0E;
    --fs-svy-g-bg: #DCFCE7;   --fs-svy-g-fg: #166534;
    --fs-svy-na-bg: #F3F4F6;  --fs-svy-na-fg: #4B5563;
    --fs-svy-iv-bg: #F9FAFB;  --fs-svy-iv-fg: #6B7280;
    --fs-svy-ot-bg: #F9FAFB;  --fs-svy-ot-fg: #6B7280;
    --fs-svy-no-bg: #F9FAFB;  --fs-svy-no-fg: #6B7280;
    --fs-photo-before: #6B7280;  --fs-photo-progress: #D97706;  --fs-photo-after: #16A34A;  --fs-photo-tile: #F3F4F6;
    /* oneviewer 9/30: the photo viewer (FasPhotoLightbox), the values the two snow viewers carried inline. */
    --fs-lb-bg: rgba(0,0,0,.88);  --fs-lb-fg: #FFFFFF;  --fs-lb-panel: rgba(255,255,255,.08);  --fs-lb-panel-line: rgba(255,255,255,.16);
    --fs-lb-btn: rgba(255,255,255,.12);  --fs-lb-ok: #34D399;  --fs-lb-shadow: 0 8px 40px rgba(0,0,0,.5);
    --fs-live-bg: #2563EB;  --fs-live-fg: #ffffff;
    --fs-focus-row: #FEF3C7;
    /* erdgrid 10/27: ER Dispatch Manager's own colours, moved out of the page's inline style block unchanged. */
    --fs-erd-accent: #EA6C0C;  --fs-erd-accent-hover: #C85F08;  --fs-erd-accent-soft: #FFF4EC;
    --fs-erd-active-row: #FFE8C7;  --fs-erd-zebra: #EDF7EE;
    /* erdgrid 10/27: ER Dispatch Manager's own colours, moved out of the page's inline style block unchanged. */
    --fs-erd-accent: #EA6C0C;  --fs-erd-accent-hover: #C85F08;  --fs-erd-accent-soft: #FFF4EC;
    --fs-erd-active-row: #FFE8C7;  --fs-erd-zebra: #EDF7EE;
    /* erdgrid 10/27: ER Dispatch Manager's own colours, moved out of the page's inline style block unchanged. */
    --fs-erd-accent: #EA6C0C;  --fs-erd-accent-hover: #C85F08;  --fs-erd-accent-soft: #FFF4EC;
    --fs-erd-active-row: #FFE8C7;  --fs-erd-zebra: #EDF7EE;
    /* erdgrid 10/27: ER Dispatch Manager's own colours, moved out of the page's inline style block unchanged. */
    --fs-erd-accent: #EA6C0C;  --fs-erd-accent-hover: #C85F08;  --fs-erd-accent-soft: #FFF4EC;
    --fs-erd-active-row: #FFE8C7;  --fs-erd-zebra: #EDF7EE;
    --fs-erd-award: #166534;  --fs-erd-award-soft: #F0FDF4;
    --fs-cert-bg: #ECFEFF;  --fs-cert-border: #CFFAFE;  --fs-cert-fg: #0C4A6E;
    --fs-rail-head-bg: #F8FAFC;
    /* Snow Tracker Dates rail (9/17), moved out of that page's inline style block. */
    --fs-rail-line: #EEF1F4;   --fs-rail-hover: #F1F5F9;
    /* Event analysis panel (client AI, 9/10) */
    --fs-ai-bg: #F5F3FF;
    --fs-ai-border: #DDD6FE;
    --fs-ai-fg: #5B21B6;
    --fs-ai-warn-bg: #FEF2F2;
    --fs-ai-warn-border: #FECACA;
    --fs-ai-warn-fg: #B91C1C;
    /* disctiles 9/21: discipline accents for the FasIQ client home tiles, brand palette only.
       Landscaping & Lot = Light Green, Snow = Blue, Quality = F&S Green. Accent use only
       (bars, icons, borders), never body text: Light Green is below text contrast on white. */
    --fs-disc-land: #159957;
    --fs-disc-snow: #3B89D8;
    --fs-disc-quality: #053D14;
    /* wo 10/6 (R. Nugent): the staff doors on Snow Tracker 2.0's WO REC'D and WO OPEN counts. wo2 10/6: a snow work
       order is usually corrective, so open reads in the Problem pill's red and all completed in the Completed pill's
       green, each with a border a shade deeper than its fill. */
    --fs-door-open-bg: var(--fs-status-problem-bg);   --fs-door-open-fg: var(--fs-status-problem-fg);   --fs-door-open-line: #FCA5A5;
    --fs-door-done-bg: var(--fs-status-completed-bg); --fs-door-done-fg: var(--fs-status-completed-fg); --fs-door-done-line: #86EFAC;
    /* intpage 10/16 (ADR-0050): the integration accents, one pair per integration (FasLogoMark and the Integrations
       page read them), and a code face for keys and ids. A new integration adds its pair here, nowhere else. */
    --fs-int-servicechannel: #0E8FB8;
    --fs-int-servicechannel-soft: #E4F7FC;
    --fs-int-sitefotos: #6D4FD8;
    --fs-int-sitefotos-soft: #EFEAFD;
    --fs-font-mono: ui-monospace, 'Cascadia Mono', Consolas, monospace;
}
/* Client view preview badge. Two client screens carry it, so it lives here once (9/10). */
.fas-preview-badge { display: inline-block; border: 1px solid var(--fs-live-fg); color: var(--fs-live-fg);
                     font-size: 10px; font-weight: 700; letter-spacing: .08em; padding: 2px 8px;
                     border-radius: 4px; opacity: .85; white-space: nowrap; margin-left: 10px; }

/* fbwave1: Service Tracker grid Notes column - notepad icon + count badge
   (mirrors the vsp pill/badge pattern: 999px radius, 700 weight, token colors). */
.stm-note-ind { position: relative; display: inline-block; color: var(--stm-rp-brand); font-size: 15px; line-height: 1; padding: 2px 8px 0 0; }
.stm-note-ind-count { position: absolute; top: -7px; right: -4px; background: var(--stm-status-pending); color: var(--stm-note-count-text); border-radius: 999px; padding: 1px 5px; font-size: 10px; font-weight: 700; line-height: 1.2; min-width: 15px; text-align: center; }
/* mudgrid 8/20: tokenized versions of the classic table's inline note-icon styles + chip surface */
.stm-note-vendor.stm-note-vendor { color: var(--stm-note-vendor); font-size: 15px; }
.stm-note-client.stm-note-client { color: var(--stm-note-client); font-size: 15px; }
.stm-note-none.stm-note-none { color: var(--stm-note-muted); font-size: 12px; }
.stm-chip-open { background: var(--stm-chip-surface); cursor: pointer; }
/* mudgrid4 PARITY (corrected diagnosis): the classic table fits all 22 columns because
   width:100% squeezes them to the viewport. The first Mud build overflowed (resize-mode
   column widths) and the columns past the screen edge were CLIPPED, not missing -- and
   the earlier width:max-content rule here locked that overflow in. Squeeze-to-fit like
   the classic table; the outer .vsp-table-scroll remains the scroll surface if anything
   ever does overflow. */
.vsp-table .mud-table-container { overflow: visible; }
.vsp-table table.mud-table-root { width: 100%; }
/* mudgrid5: one-screen fit parity with the classic table. Classic fits 22 columns via
   10px cell padding + wrapping text; Mud adds wider padding, per-header sort icons and
   (SortMode.Multiple) invisible sort-index spans that together force a horizontal
   scrollbar. Compress and wrap; sorting still works, the index numerals are cosmetic. */
/* mudgrid7: match the PROD classic grid exactly (source of truth per R. Nugent).
   Three-deep selectors so these BEAT MudBlazor's stylesheet on specificity, not load
   order (the mudgrid6 two-class rules tied with Mud's and lost -- gray non-bold text).
   Headers: uppercase bold black ~11px like prod, which wraps at two lines naturally.
   Sort icon buttons are hidden entirely -- per the 9.5.0 HeaderCell source the whole
   column label is the click-to-sort target, and reclaiming that reserved width per
   header is what keeps PDir on screen with the nav menu open, exactly like prod. */
.vsp-table .mud-table-root .mud-table-cell { padding: 6px 7px; white-space: normal; overflow-wrap: normal; line-height: 1.3; }  /* mudgrid14: 2px/side trim x22 cols keeps PDir on screen with the nav open */
/* mudgrid8: tbody td selector at (0,3,2) -- the previous (0,3,0) rule TIED with Mud's own
   cell rule and lost on load order, leaving body text gray/normal in most columns. */
.vsp-table .mud-table-root tbody td.mud-table-cell { font-weight: 600; color: var(--stm-dlg-text); font-size: 12.5px; }
.vsp-table .mud-table-root thead th.mud-table-cell { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--stm-dlg-text); }
/* mudgrid8: auto-layout starves columns whose data is short (Days Since = "2"), wrapping
   the header 4 lines; a floor forces the prod-style two-line break. */
/* mudgrid11: floors sized for the NARROWER container (side menu EXPANDED), so the
   date headers hold their 2-line break in both menu states. "LAST SERVICE" at 11.5px
   bold is ~82px + cell padding, so 104px guarantees the pair never splits to 3 lines. */
.vsp-table th.stm-h-dsls { min-width: 104px; }  /* DAYS SINCE / LAST SERVICE + LAST SERVICE / DATE */
.vsp-table th.stm-h-nesd { min-width: 120px; }  /* NEXT EXPECTED / SERVICE DATE */
/* mudgrid8: filter card labels + controls black and bold (per R. Nugent). The card's
   double class beats the page's inline style block, which loads after this sheet. */
.vsp-filter-card.vsp-filter-v2 label { color: var(--stm-dlg-text); font-weight: 700; }
.vsp-filter-card.vsp-filter-v2 .form-select,
.vsp-filter-card.vsp-filter-v2 .form-control,
.vsp-filter-card.vsp-filter-v2 .vsp-mlf-box,
.vsp-filter-card.vsp-filter-v2 .vsp-mlf-ph,
.vsp-filter-card.vsp-filter-v2 .ffs-ph,
.vsp-filter-card.vsp-filter-v2 .vsp-mlf-opt { color: var(--stm-dlg-text); font-weight: 600; }
/* cfb 10/12 (R. Nugent; Gate 1: the Land Ops box): the client bar's Account and Status are FasFilterSelect, the house form
   of the Ops bar's pellet box. These give it the Ops box's height (.vsp-mlf-box, 34px), this bar's label spacing and a
   caret centred on the shorter box; .ffs-ph above reads like the Ops "All". Keyed on the bar's own class and lifted past
   the component's scoped rules by the card classes, because a page's scoped CSS cannot reach a child component's root.
   Tokens only. */
.vsp-filter-card.cfb .ffs { gap: 4px; }
.vsp-filter-card.cfb .ffs-box { min-height: 34px; }
.vsp-filter-card.cfb .ffs-box .ffs-caret { bottom: 11px; }
.vsp-table th .column-header { white-space: normal; }
.vsp-table .mud-sort-index { display: none; }
.vsp-table th .mud-icon-button { display: none; }
/* mudgrid9: the ACTIVELY sorted column shows its direction arrow (classes verified in the
   9.5.0 HeaderCell source: mud-direction-asc/desc are present only while sorted), so the
   reserved-width saving holds everywhere except the one header that earns an arrow. */
.vsp-table th .mud-icon-button.mud-direction-asc,
.vsp-table th .mud-icon-button.mud-direction-desc { display: inline-flex; padding: 0; }
.vsp-table th .mud-icon-button.mud-direction-asc .mud-icon-root,
.vsp-table th .mud-icon-button.mud-direction-desc .mud-icon-root { font-size: 15px; }
.vsp-table .vsp-count-btn { font-size: 12px; padding: 3px 8px; white-space: nowrap; }
.vsp-table .vsp-pill { font-size: 11.5px; padding: 3px 8px; white-space: nowrap; }  /* status pellets (No Checkin etc.) never wrap */
.vsp-table .stm-nowrap { white-space: nowrap; }  /* single-line cells: Store # */
.vsp-table .vsp-survey-chip { font-size: 11.5px; padding: 3px 6px; line-height: 1.25; } /* surveycompact 8/31: PROD sizing restored, initial rating letters keep the box narrow */
/* mudgrid5: survey / service-issue chips keep the classic OUTLINE look. The vendor portal
   dialog's inline style block leaks filled chip styles globally (known scoping bug); this
   three-class selector outranks its two-class rules inside the grid. */
.vsp-table .vsp-survey-chip.stm-chip-open { background: var(--stm-chip-surface); color: var(--stm-dlg-text); cursor: pointer; }
/* mudgrid2: colored pellet dots in the SURVEY filter dropdown (per R. Nugent) */
.stm-svy-dot { display: inline-block; width: 10px; height: 10px; border-radius: 999px; margin-right: 6px; vertical-align: middle; }
.stm-svy-dot.green { background: var(--stm-svy-green); }
.stm-svy-dot.yellow { background: var(--stm-svy-yellow); }
.stm-svy-dot.red { background: var(--stm-svy-red); }
.stm-svy-dot.ivueit { background: var(--stm-rp-brand); }
.stm-svy-dot.none { background: var(--stm-note-muted); }
/* surveychip 9/3: the single survey rating chip for 1F, 1F-A and ServiceTrackerSurveyDialog
   (ADR-0014 reuse-first). Global + class-keyed on purpose -- the chip roots on a plain <span>
   inside many parents, where scoped CSS would not attach. Every color reads --stm-svy-*. */
.fas-svy-chip { display:inline-flex; align-items:center; justify-content:center; box-sizing:border-box;
    font-weight:800; line-height:1; text-align:center; border:1px solid var(--stm-svy-neutral);
    color:var(--stm-svy-neutral-text); background:var(--stm-svy-neutral-bg); }
.fas-svy-chip.green  { border-color:var(--stm-svy-green);  color:var(--stm-svy-green-text);  background:var(--stm-svy-green-bg); }
.fas-svy-chip.yellow { border-color:var(--stm-svy-yellow); color:var(--stm-svy-yellow-text); background:var(--stm-svy-yellow-bg); }
.fas-svy-chip.red    { border-color:var(--stm-svy-red);    color:var(--stm-svy-red-text);    background:var(--stm-svy-red-bg); }
.fas-svy-chip.pill   { min-width:72px; padding:7px 13px; border-radius:999px; font-size:12px; }
.fas-svy-chip.square { width:29px; height:29px; border-radius:6px; font-size:11px; }
.fas-svy-chip.dot    { width:10px; height:10px; border-radius:999px; padding:0; }
.fas-svy-chip.mini   { width:20px; height:20px; border-radius:4px; font-size:9px; }

/* FasSurveyBadge (svyrow 9/14): the SURVEY label plus the rating square in one badge, on the site card, the
   grid row header, the Modify Status dialog and the Service Tracker Map rail. Global on purpose, same reason
   as the chip. Tokens only.
   svybold 9/16 (R. Nugent): the badge now WEARS its rating, outline, ground and ink, so a rail of cards can be
   scanned for reds without reading a word. Every colour is the --fs-svy-* family the MAP draws, so the badge
   beside a map and the pin on it are recognisably one object. States that carry no rating, none, loading and
   unavailable, keep the neutral badge: a grey ring is the honest drawing of an unknown rating. */
.fas-svy-badge { display:inline-flex; align-items:center; gap:5px; border:1px solid var(--fs-tl-line); border-radius:6px;
    padding:2px 7px; background:var(--mud-palette-surface); white-space:nowrap; }
.fas-svy-badge:focus-visible { outline:2px solid var(--mud-palette-primary); outline-offset:2px; }
.fas-svy-badge-label { font-size:9px; font-weight:700; letter-spacing:.08em; color:var(--fs-text-muted); }
.fas-svy-badge-note  { font-size:10.5px; font-weight:600; color:var(--fs-text-muted); }
.fas-svy-badge.unavailable { border-style:dashed; }
/* Clickable only where a page passes OnOpen (svyopen 9/16). The badge already carries its rating, so the
   affordance is the cursor, a lift on hover and the focus ring, not another colour. */
.fas-svy-badge.openable { cursor:pointer; transition:box-shadow .12s ease, transform .12s ease; }
.fas-svy-badge.openable:hover { box-shadow:var(--fs-shadow-card); transform:translateY(-1px); }
/* Each rated badge publishes its own rule, ground and ink; the three rules below read them, so one pattern
   serves six ratings instead of six near copies (the pattern the KPI cards and the legend chips already use). */
.fas-svy-badge.svy-r  { --fsb-line:var(--fs-svy-r);  --fsb-bg:var(--fs-svy-r-bg);  --fsb-fg:var(--fs-svy-r-fg); }
.fas-svy-badge.svy-y  { --fsb-line:var(--fs-svy-y);  --fsb-bg:var(--fs-svy-y-bg);  --fsb-fg:var(--fs-svy-y-fg); }
.fas-svy-badge.svy-g  { --fsb-line:var(--fs-svy-g);  --fsb-bg:var(--fs-svy-g-bg);  --fsb-fg:var(--fs-svy-g-fg); }
.fas-svy-badge.svy-na { --fsb-line:var(--fs-svy-na); --fsb-bg:var(--fs-svy-na-bg); --fsb-fg:var(--fs-svy-na-fg); }
.fas-svy-badge.svy-iv { --fsb-line:var(--fs-svy-iv); --fsb-bg:var(--fs-svy-iv-bg); --fsb-fg:var(--fs-svy-iv-fg); }
.fas-svy-badge.svy-ot { --fsb-line:var(--fs-svy-ot); --fsb-bg:var(--fs-svy-ot-bg); --fsb-fg:var(--fs-svy-ot-fg); }
.fas-svy-badge[class*="svy-"] { border-width:2px; border-color:var(--fsb-line); background:var(--fsb-bg); }
.fas-svy-badge[class*="svy-"] .fas-svy-badge-label { color:var(--fsb-fg); font-weight:800; }
.fas-svy-badge[class*="svy-"]:focus-visible { outline-color:var(--fsb-line); }
.fas-svy-badge-retry { border:0; background:transparent; padding:0 2px; font:inherit; font-size:10.5px; font-weight:700;
    color:var(--mud-palette-primary); cursor:pointer; text-decoration:underline; }

/* Survey rating square (svyland 9/15): the badge exactly as the MAP draws it, solid rating fill with a white
   letter, so the legend chips and the popup line are recognisable as the same object as the pin. Global and
   class keyed because the map popups are plain HTML the JavaScript builds, where scoped CSS cannot reach, and
   FasSurveyLegend reads the same rules so the square is drawn from one place. The map sprite itself reads
   the --fs-svy-* tokens at runtime (fas-survey-layer.js), so a colour change here reaches the pins too. */
.fas-svy-box { display:inline-flex; align-items:center; justify-content:center; min-width:19px; height:15px; padding:0 3px;
    border-radius:3px; font-size:9px; font-weight:800; font-style:normal; line-height:1; letter-spacing:.02em; color:var(--fs-svy-fg); }
.fas-svy-box-g  { background:var(--fs-svy-g); }
.fas-svy-box-y  { background:var(--fs-svy-y); }
.fas-svy-box-r  { background:var(--fs-svy-r); }
.fas-svy-box-na { background:var(--fs-svy-na); }
.fas-svy-box-iv { background:var(--fs-svy-iv); }
.fas-svy-box-ot { background:var(--fs-svy-ot); }
.fas-svy-box-no { background:transparent; border:1px dashed var(--mud-palette-lines-default); }
/* Rail size of the same square, for the SURVEY banner on a site card or a map rail row. */
.fas-svy-box.rail { width:20px; height:20px; min-width:20px; border-radius:4px; font-size:12px; }
.fas-svy-box.rail.wide { font-size:8.5px; letter-spacing:0; }
/* The popup's Last survey line (both maps). */
.fas-svy-pop { margin-top:8px; padding-top:8px; border-top:1px solid var(--fs-tl-line); display:flex; align-items:center; gap:7px; font-size:12px; }
.fas-svy-pop a { display:inline-flex; align-items:center; gap:7px; color:inherit; text-decoration:none; }
.fas-svy-pop .fas-svy-box { width:18px; height:18px; min-width:18px; border-radius:4px; font-size:10px; }
.fas-svy-pop .fas-svy-box.wide { font-size:8px; }
.fas-svy-pop-k { color:var(--fs-text-muted); }
.fas-svy-pop-v { font-weight:600; color:var(--mud-palette-text-primary); }
.fas-svy-pop-m { color:var(--fs-text-muted); opacity:.8; }
.fas-svy-pop-open { color:var(--mud-palette-primary); font-weight:600; margin-left:2px; }

/* FasMapLink (svyrow 9/14): the dark green Open in Map action. Was .stx-map on the grid alone; now one
   rule for the grid row, the site drawer and the Modify Status dialog. */
.fas-maplink { flex:none; display:inline-flex; align-items:center; gap:6px; background:var(--mud-palette-primary);
    color:var(--mud-palette-primary-text); text-decoration:none; font-size:12px; font-weight:600; padding:6px 13px;
    border-radius:var(--fs-radius-md); white-space:nowrap; }
.fas-maplink:hover { filter:brightness(1.12); color:var(--mud-palette-primary-text); }
.fas-maplink:focus-visible { outline:2px solid var(--mud-palette-primary); outline-offset:2px; }
.fas-maplink-icon { display:inline-flex; }
/* addsitemap 9/30: the Add Sites dialog's map door is a button (it may ask first), in the same dress as the link. */
button.fas-maplink { border: 0; cursor: pointer; font-family: inherit; line-height: inherit; }
.fas-maplink .mud-icon-root { font-size:16px; width:16px; height:16px; }
/* surveyidx trend: the last 4 surveys chips row on the index */
.svp-trend { display:flex; gap:5px; align-items:center; }
/* svyorder 10/12 (R. Nugent): the strip says which way it reads. The key sits under the LAST 4 SURVEYS heading, the newest
   chip wears a ring in its own rating colour, and each older chip steps back. Tokens only. */
.svp-trend-key { display:block; margin-top:2px; font-size:10px; font-weight:500; letter-spacing:.02em; text-transform:none;
    color:var(--fs-text-muted); white-space:nowrap; }
.svp-trend .fas-svy-chip.svp-newest { box-shadow:0 0 0 2px currentColor; }
.svp-trend .fas-svy-chip.svp-age-1 { opacity:.78; }
.svp-trend .fas-svy-chip.svp-age-2 { opacity:.6; }
.svp-trend .fas-svy-chip.svp-age-3 { opacity:.45; }
/* svychip 10/12 (R. Nugent, Gate 1: full cues): on the Surveys strip each chip is a button that opens its own survey
   (FasSurveyRatingChip with OnClick). The button sheds the browser's padding, margin and font so it draws as the span
   chip does; then a pointer, an older chip coming up to full strength under the pointer or the keyboard, and a brand
   focus ring outside the newest chip's ring. Tokens only. */
button.fas-svy-chip { padding:0; margin:0; cursor:pointer; font-family:inherit; }
.svp-trend button.fas-svy-chip:hover,
.svp-trend button.fas-svy-chip:focus-visible { opacity:1; }
button.fas-svy-chip:focus-visible { outline:2px solid var(--stm-rp-brand); outline-offset:3px; }
/* ── FasKpiCard v2 (kpiv2 10/23, R. Nugent; Gate 1 signed off 10/23): every KPI card in the Risk Tracker's design, per the KPI
   Summary Strip cross-app reference specification, section 8. MudTooltip round a MudPaper root, with a native button inside when
   the card is clickable. Those roots are Mud components a scoped sheet cannot reach, so their rules are here, keyed on fkc-*, and
   Mud's sheet loads after this one, so a rule on a property Mud also sets repeats its class to win (house gotcha). A 4px accent
   edge down the left; the outline, the icon and the focus ring take the same accent, which the severity picks from the
   --fs-kpi-* accents (Neutral keeps the neutral grey). The label is the standard's uppercase title, set in capitals here so every
   page passes plain words and a screen reader reads them as words. Two choices are FasCentral's own (Gate 1): the label sits on
   a 20px line, where the theme's overline gives it 32px (the card stands 110px tall, not 122px, and a wrapped label stays
   tight), and a pressed card keeps the light tint of its own colour (9/11) under the standard's outline. The card's own plain
   elements are in FasKpiCard.razor.css. Tokens only. */
.fkc-tip { display: block; height: 100%; }
.fkc-card.fkc-card { position: relative; overflow: hidden; height: 100%; border: 2px solid transparent; }
.fkc-card::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--fkc-accent, var(--mud-palette-primary)); }
.fkc-hit { display: block; width: 100%; height: 100%; padding: 13px 15px 13px 18px; border: 0; background: none; color: inherit;
           font: inherit; text-align: left; }
.fkc-clickable .fkc-hit { cursor: pointer; }
.fkc-hit:focus-visible { outline: 2px solid var(--fkc-accent); outline-offset: -4px; }
.fkc-ico { color: var(--fkc-accent); }
.fkc-label.fkc-label { text-transform: uppercase; line-height: 1.66; }
.fkc-card.fkc-active.fkc-active { border-color: var(--fkc-accent, var(--mud-palette-primary));
                                  background-color: var(--fkc-tint, var(--mud-palette-surface)); }
.fkc-info    { --fkc-accent: var(--fs-kpi-info);       --fkc-tint: var(--fs-kpi-info-bg); }
.fkc-success { --fkc-accent: var(--fs-kpi-good);       --fkc-tint: var(--fs-kpi-success-bg); }
.fkc-warning { --fkc-accent: var(--fs-kpi-warn);       --fkc-tint: var(--fs-kpi-warning-bg); }
.fkc-error   { --fkc-accent: var(--fs-kpi-bad);        --fkc-tint: var(--fs-kpi-error-bg); }
.fkc-neutral { --fkc-accent: var(--fs-kpi-neutral-fg); --fkc-tint: var(--fs-kpi-neutral-bg); }
/* surveyidx 9/3: 1F-A survey index page cosmetics (styling source, never inline). */
.svp-page { max-width:1600px; margin:0 auto; padding:16px 12px 40px; }
.svp-eyebrow { letter-spacing:.12em; }
.svp-center { padding:48px; text-align:center; color:var(--stm-dlg-muted); }
.svp-filters { display:flex; align-items:flex-end; gap:12px; flex-wrap:wrap; }
.svp-f-search { min-width:240px; flex:1 1 240px; max-width:360px; }
.svp-f-sel { min-width:190px; }

/* groupdelete item 2: per-photo Client/Vendor share chips on grouped note thumbnails.
   Hover (or keyboard-focus) the thumbnail to reveal; colored green when shared to that
   lane, muted crossed-eye on the dark scrim when hidden. Token colors only (rule 1). */
.stn-photo-wrap { position: relative; display: inline-block; }
.stn-photo-vis { position: absolute; left: 4px; bottom: 4px; display: flex; gap: 3px; opacity: 0; transition: opacity .12s ease-in-out; }
.stn-photo-wrap:hover .stn-photo-vis, .stn-photo-vis:focus-within { opacity: 1; }
.stn-photo-vis-btn { display: inline-flex; align-items: center; gap: 3px; border: 0; border-radius: 999px; padding: 2px 7px; font-size: 10px; font-weight: 700; line-height: 1.4; cursor: pointer; background: var(--stm-photo-vis-scrim); color: var(--stm-photo-vis-offtext); }
.stn-photo-vis-btn:hover { color: var(--stm-note-badge-text); }
.stn-photo-vis-on { background: var(--stm-status-completed); color: var(--stm-note-badge-text); }
/* mudeye 8/26 (R. Nugent): sizing for FasEye (MudIcon) inside the visibility chips.
   Two class selectors on purpose: site.css loads before MudBlazor.min.css in _Host,
   so a single class rule would lose the cascade to Mud's own size and margin defaults.
   Color needs no rule here: Mud fills the svg with currentColor and each chip sets color. */
.stn-vis .fas-eye, .stn-photo-vis-btn .fas-eye, .fshare .fas-eye { font-size: 12px; width: 1em; height: 1em; margin: 0; margin-inline-end: 0; }
/* docshare 10/15 (R. Nugent: "Similar model of document sharing as in Ops Service Tracker"): FasShareToggle, the Ops eye
   share control as one Fas component on a MudElement root, so its rules are global (scoped css cannot reach a Mud root);
   prefix fshare, since fst is FasSectionToggle's.
   .fshare-btn is the Ops Notes dialog's eye Client button and .fshare-chip its eye C photo chip, matched to those, tokens only.
   On a photo tile (FasPhotoGrid .fpg-cell) a shared photo's chip shows on hover or keyboard focus and a hidden photo's chip
   stays on screen, so the exception is visible without hunting (the Ops Check-Ins rule, visfix item 4). */
.fshare { flex: none; display: inline-flex; align-items: center; border-radius: 999px; font-family: inherit; line-height: 1.4; white-space: nowrap; }
.fshare-btn { gap: 4px; padding: 2px 8px; font-size: 11px; font-weight: 600; border: 1px solid var(--fs-share-line); background: var(--mud-palette-surface); color: var(--fs-share-off-fg); }
button.fshare-btn:hover { border-color: var(--fs-share-on-ink); color: var(--fs-share-on-ink); }
.fshare-btn.fshare-on { background: var(--fs-share-on-bg); border-color: var(--fs-share-on-ink); color: var(--fs-share-on-ink); }
.fshare-chip { gap: 3px; padding: 2px 7px; font-size: 10px; font-weight: 700; border: 0; background: var(--stm-photo-vis-scrim); color: var(--stm-photo-vis-offtext); }
button.fshare-chip:hover { color: var(--stm-note-badge-text); }
.fshare-chip.fshare-on { background: var(--stm-status-completed); color: var(--stm-note-badge-text); }
button.fshare { cursor: pointer; }
button.fshare:focus-visible { outline: 2px solid var(--mud-palette-primary); outline-offset: 1px; }
.fpg-cell .fshare-chip { opacity: 0; transition: opacity .12s ease-in-out; }
.fpg-cell:hover .fshare-chip, .fpg-cell:focus-within .fshare-chip, .fpg-cell .fshare-chip:not(.fshare-on) { opacity: 1; }
/* snowma 8/27 (R. Nugent): the Fas button family, promoted from FasConfirm's scoped css
   when the snow assign dialogs became its second and third consumers (rule of two).
   One source: FasConfirm, SnowMassAssignDialog and SnowModifyStatusDialog all read these. */
.fas-btn { border: 1px solid var(--mud-palette-lines-default, #D1D5DB); background: var(--mud-palette-surface, #fff); color: var(--mud-palette-text-primary, #111827); border-radius: var(--fs-radius-md); padding: 7px 14px; font-size: 13px; font-weight: 600; cursor: pointer; }
.fas-btn:hover:not(:disabled) { border-color: var(--mud-palette-primary, #12372E); color: var(--mud-palette-primary, #12372E); }
.fas-btn:disabled { opacity: .5; cursor: default; }
.fas-btn-primary { background: var(--mud-palette-primary, #12372E); border-color: var(--mud-palette-primary, #12372E); color: var(--mud-palette-primary-text, #fff); }
.fas-btn-primary:hover:not(:disabled) { color: var(--mud-palette-primary-text, #fff); filter: brightness(1.12); }
.fas-btn.fas-btn-danger {
    background: var(--mud-palette-error, #B91C1C);
    border-color: var(--mud-palette-error, #B91C1C);
}
/* 11/03: two classes so it beats Ferrandino.styles.css's .fas-btn-primary, which loads later */
/* focusring 11/03 (Eric): a visible ring on the house buttons when reached with Tab (keyboard only; a mouse click shows none). */
.fas-btn:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}
/* erdvs 11/04 (Eric): Search for Vendor results in the Award modal -- one row per vendor; the hovered row and the
   arrow-key row share the same highlight. Tokens only. */
.erd-vs-list {
    max-height: 260px;
    overflow-y: auto;
}

.erd-vs-row {
    padding: 8px 12px;
    font-size: 13px;
    cursor: pointer;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

    .erd-vs-row:last-child {
        border-bottom: none;
    }

    .erd-vs-row:hover, .erd-vs-row.erd-vs-row-active {
        background: var(--mud-palette-primary-hover);
    }

    .erd-vs-row.erd-vs-row-active {
        font-weight: 600;
    }

/* erdvs 11/04 (Eric): Search for Vendor results in the Award modal -- one row per vendor; the hovered row and the
   arrow-key row share the same highlight. Tokens only. */
.erd-vs-list { max-height: 260px; overflow-y: auto; }
.erd-vs-row { padding: 8px 12px; font-size: 13px; cursor: pointer; border-bottom: 1px solid var(--mud-palette-lines-default); }
.erd-vs-row:last-child { border-bottom: none; }
.erd-vs-row:hover, .erd-vs-row.erd-vs-row-active { background: var(--mud-palette-primary-hover); }
.erd-vs-row.erd-vs-row-active { font-weight: 600; }
/* erdfocus 11/04 (Eric): the Award modal's ER Vendor box (read-only; it opens Search for Vendor) shows clearly when it
   has focus -- a light fill as well as Mud's own heavier border. */
.erd-vendor-box .mud-input.mud-input-outlined:focus-within {
    background: var(--mud-palette-primary-hover);
}

    .erd-vendor-box .mud-input.mud-input-outlined:focus-within > .mud-input-outlined-border {
        border-width: 2px;
        border-color: var(--mud-palette-primary);
    }
/* acscroll 11/04 (Eric): a type-ahead list keeps the mouse wheel to itself. At its top or bottom the dialog behind it
   doesn't scroll and drag the list away -- the same feel as Search for Vendor. Add PopoverClass="fas-ac-pop" to a
   MudAutocomplete to opt in. */
.mud-popover.fas-ac-pop, .mud-popover.fas-ac-pop .mud-list {
    overscroll-behavior: contain;
}

/* snowdocs 9/29: the file input MudFileUpload renders over a drop zone (SnowModifyStatusDialog). InputFile is a
   child component root, so its rule lives here; Mud's utilities size and layer it, this makes it invisible and
   gives it the hand cursor, so a click or a drop anywhere on the zone lands on the input natively. */
.fas-file-input { opacity: 0; cursor: pointer; }
/* addsite 9/29: the small variant the zone heads use (Select all, Clear), formerly .smd-mini in Mass Assign. */
.fas-btn-mini { padding: 3px 9px; font-size: 11.5px; }
/* addsite 9/29 (R. Nugent): the rest of the dialog vocabulary the snow doors share, promoted from
   SnowMassAssignDialog.razor.css when Add Sites became its second consumer (rule of two, as the buttons
   above): the footer gate note, the busy block with its title and sub line, the outcome panel with its
   ok, warn and fail lines, list, store run and foot, and the review summary table FasConfirm shows. Plain
   markup authored in each dialog, so global classes reach it without ::deep. The values are the Mass
   Assign rules verbatim; every colour is a token. */
.fas-gate { margin-right: auto; font-size: 12px; color: var(--mud-palette-text-secondary); }
.fas-busy { padding: 26px 8px; }
.fas-busy-title { display: flex; align-items: center; gap: 10px; font-size: 14.5px; font-weight: 700; color: var(--mud-palette-text-primary); margin-bottom: 12px; }
.fas-busy-sub { margin-top: 10px; font-size: 12px; color: var(--mud-palette-text-secondary); }
.fas-out { padding: 6px 2px; }
.fas-out-line { font-size: 13.5px; margin-bottom: 6px; color: var(--mud-palette-text-primary); }
.fas-out-ok { color: var(--mud-palette-success); font-weight: 700; }
.fas-out-warn { color: var(--fs-warn-text); }
.fas-out-fail { color: var(--mud-palette-error); font-weight: 600; }
.fas-out-list { margin: 4px 0 8px 18px; font-size: 12.5px; color: var(--mud-palette-text-primary); }
.fas-out-stores { font-weight: 700; }
.fas-out-foot { margin-top: 10px; font-size: 11.5px; color: var(--mud-palette-text-secondary); }
.fas-summary { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 12.5px; }
.fas-summary td { border-top: 1px solid var(--mud-palette-lines-default); padding: 5px 6px; color: var(--mud-palette-text-primary); }
.fas-summary td:first-child { color: var(--mud-palette-text-secondary); font-size: 10.5px; font-weight: 800; letter-spacing: .4px; text-transform: uppercase; width: 160px; }
/* mudparity 9/22 (R. Nugent): FasNoteBubble now roots on Mud (MudElement > MudBadge > MudIconButton),
   so its rules moved here from Components/Fas/FasNoteBubble.razor.css, which a Mud root can never
   reach (house gotcha: Blazor's scope attribute stops at a child component's root). The numbers are
   the .stm-note-ind / .stm-note-ind-count metrics verbatim, so the Mud build renders where the plain
   one did: a 15px glyph in a 2px 8px 0 0 box, the count at top -7px right -4px of that box, the muted
   12px dot at zero. Mud's own class names sit in every selector on purpose: site.css loads BEFORE
   MudBlazor.min.css in _Host, so on equal specificity Mud wins, and Mud's badge, icon button and icon
   size rules each stack two to four classes (same trick as the FasEye rule above). Every colour is an
   existing --stm-* token (standing rule 1). */
.fnb { display: inline-block; line-height: 1; }
.fnb .mud-badge-root.fnb-badge { display: inline-flex; vertical-align: middle; }
.fnb .mud-icon-button.fnb-btn { padding: 2px 8px 0 0; min-width: 0; min-height: 0; border-radius: 0; background: none; color: var(--stm-rp-brand); line-height: 1; }
.fnb .mud-icon-button.fnb-btn:hover, .fnb .mud-icon-button.fnb-btn:focus-visible { background: none; color: var(--stm-rp-brand); }
.fnb .mud-icon-button.fnb-btn .mud-icon-root { font-size: 15px; width: 15px; height: 15px; }
.fnb .mud-icon-button.fnb-btn.fnb-none, .fnb .mud-icon-button.fnb-btn.fnb-none:hover { color: var(--stm-note-muted); }
.fnb .mud-icon-button.fnb-btn.fnb-none .mud-icon-root { font-size: 12px; width: 12px; height: 12px; }
.fnb .mud-icon-button.fnb-btn.mud-disabled, .fnb .mud-icon-button.fnb-btn:disabled { opacity: .55; cursor: default; color: var(--stm-rp-brand); }
/* The count. fnb-count is repeated on purpose: MudBadge composes its placement classes from the Origin enum at
   runtime, so naming them here is a guess that missed once (the badge fell back to Mud's grey 20px default).
   Repeating our own class lifts specificity past any Mud badge rule without depending on Mud's class names. */
.fnb .mud-badge.fnb-count.fnb-count.fnb-count.fnb-count { top: -7px; right: -4px; left: auto; bottom: auto; transform: none; height: auto; min-width: 15px; padding: 1px 5px; border-radius: 999px; font-size: 10px; font-weight: 700; line-height: 1.2; text-align: center; background: var(--stm-status-pending); color: var(--stm-note-count-text); cursor: pointer; }
/* mudparity 9/22 (R. Nugent): FasStatusPill now roots on Mud (MudElement rendering a span), so its rules
   moved here from Components/Fas/FasStatusPill.razor.css, which a Mud root can never reach (house gotcha:
   Blazor's scope attribute stops at a child component's root). MudElement rather than MudChip by
   decision: a 9.5.0 MudChip adds a container div, a keydown handler and a JS key interceptor per
   instance, and the grid draws one pill per row. The span carries only fsp classes, so no Mud rule
   competes and single class selectors are enough. Metrics are the retired .stm-pill rule verbatim;
   every colour is an --fs-status-* token (standing rule 1). */
.fsp { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 11px; font-weight: 600; white-space: nowrap; line-height: 1.5; }
.fsp-completed { background: var(--fs-status-completed-bg); color: var(--fs-status-completed-fg); }
.fsp-followup  { background: var(--fs-status-followup-bg);  color: var(--fs-status-followup-fg); }
.fsp-problem   { background: var(--fs-status-problem-bg);   color: var(--fs-status-problem-fg); }
.fsp-required  { background: var(--fs-status-required-bg);  color: var(--fs-status-required-fg); }
.fsp-none      { background: var(--fs-status-none-bg);      color: var(--fs-status-none-fg); }
.fsp-muted     { background: var(--fs-status-muted-bg);     color: var(--fs-status-muted-fg); }   /* status2 10/6 */
.fsp-clear     { background: transparent; color: var(--fs-status-clear-fg); box-shadow: inset 0 0 0 1px var(--fs-status-clear-line); }
/* FasClientStatusPill (e50 step 4, 10/30): a client's status from any integration, up to 200 characters, on one line: a width cap,
   an ellipsis, the full text in its tooltip. */
.fsp.fsp-client { max-width: 220px; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; }
/* FasIntegrationSource (e50 10/30): an integration's mark and name. Tinted takes the integration's --fs-int-* colour; Compact
   draws a 16px mark for a meta line. A new integration adds its .fis-tint rule beside its token pair. */
.fis { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; vertical-align: middle; }
.fis.fis-tint.fis-servicechannel { color: var(--fs-int-servicechannel); }
.fis.fis-compact { gap: 4px; }
.fis.fis-compact .flm.flm.flm-small.flm-picture { min-width: 16px; height: 16px; padding: 1px 2px; border-radius: 4px; }
/* navfit 9/23 (R. Nugent): the app bar NavMenu shows under 960px (Shared/NavMenu.razor). It roots on
   MudAppBar, whose own z-index would put it above the slid in menu, so its position is set here keyed on
   its Class. The class is repeated to outrank Mud's app bar and typography rules, which load after this
   file, without naming Mud's generated classes (house gotcha). Colours come from the theme (Color.Primary). */
.fcnav-topbar.fcnav-topbar.fcnav-topbar { position: sticky; top: 0; z-index: 1100; flex-shrink: 0; }
.fcnav-topbar-brand.fcnav-topbar-brand { margin-left: 4px; white-space: nowrap; }
@media (min-width: 960px) {
    .fcnav-topbar.fcnav-topbar.fcnav-topbar { display: none; }
}
/* uipolish audit: grouped-thumbnail pointer cursor moved out of an inline style attr. */
.stn-photo-click { cursor: pointer; }

/* visfix item 4: per-photo CLIENT share chip on the Check-Ins dialog thumbnail strip
   (Components/ServiceTrackerWeeklyCheckinsDialog.razor). REUSES the notes dialog's
   .stn-photo-vis / .stn-photo-vis-btn / .stn-photo-vis-on chip above so both photo strips
   speak one visual language -- only the POSITION changes, because the check-in frame
   already carries its phase badge at bottom-left, so the chip takes top-right. Hover or
   keyboard focus reveals it; a photo currently HIDDEN from the client keeps its chip on
   screen so the exception is visible without hunting. No hex (rule 1 -- the chip's colors
   come from the shared classes), and it lives here rather than in that dialog's inline
   <style> block because Blazor emits those globally (rule 2). */
.stm-ckin-vis { left: auto; right: 3px; bottom: auto; top: 3px; }
.vsp-checkins-photo-frame:hover .stm-ckin-vis, .stm-ckin-vis:focus-within { opacity: 1; }
.stm-ckin-vis.stm-ckin-vis-off { opacity: 1; }

/* pdfexport: "Export to PDF" dialog fact list (Pages/ServiceTracker.razor). Lives here
   rather than in an inline <style> block because Blazor emits those globally (rule 2),
   and reads MudBlazor theme variables so it tracks a rebrand (rule 1 -- no hex). */
.stm-pdfexp-facts { border: 1px solid var(--mud-palette-lines-default, var(--stm-dlg-line)); border-radius: var(--mud-default-borderradius, 4px); padding: 8px 12px; }
.stm-pdfexp-row { display: flex; gap: 12px; align-items: baseline; padding: 3px 0; }
.stm-pdfexp-row + .stm-pdfexp-row { border-top: 1px solid var(--mud-palette-lines-default, var(--stm-dlg-line)); }
.stm-pdfexp-lbl { flex: 0 0 88px; font-size: 12px; font-weight: 700; color: var(--mud-palette-text-secondary, var(--stm-dlg-muted)); text-transform: uppercase; letter-spacing: .3px; }
.stm-pdfexp-val { flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--mud-palette-text-primary, var(--stm-dlg-text)); }

/* ============================================================================
   sfmui: Service Frequency Manager page chrome (Pages/ServiceFrequencyManager.razor).
   Lives here rather than in an inline <style> block because Blazor emits those
   globally (standing rule 2), and reads MudBlazor theme variables so a rebrand
   carries through (standing rule 1 -- no hex outside the theme object / :root).
   ========================================================================== */
.sfm-appbar { display: flex; align-items: center; gap: 12px; background: var(--mud-palette-appbar-background, var(--mud-palette-primary)); color: var(--mud-palette-appbar-text, var(--mud-palette-primary-text)); padding: 0 18px; height: 56px; box-shadow: 0 1px 3px rgba(0, 0, 0, .18); }
.sfm-appbar-logo { height: 34px; max-width: 150px; object-fit: contain; background: var(--mud-palette-surface); border-radius: 6px; padding: 3px 6px; flex: none; }
.sfm-appbar-title { font-size: 18px; font-weight: 600; letter-spacing: .5px; }
.sfm-appbar-spacer { flex: 1 1 auto; }
.sfm-appbar-chip { background: rgba(255, 255, 255, .18); border-radius: 999px; padding: 4px 12px; font-size: 13px; font-weight: 600; }

/* Drill-path breadcrumb + the toolbar row that carries Go Back / Mass Assign. */
.sfm-crumbs { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; min-width: 0; }
.sfm-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; }
.sfm-spacer { flex: 1 1 auto; }

/* Mass-assign date fields: <InputDate> is kept as-is (it binds DateOnly, which
   MudDatePicker does not), so it only gets the surrounding Mud look. */
.sfm-field { display: flex; flex-direction: column; gap: 2px; }
.sfm-field-lbl { color: var(--mud-palette-text-secondary); font-weight: 700; letter-spacing: .3px; text-transform: uppercase; }
.sfm-date { border: 1px solid var(--mud-palette-lines-default); border-radius: var(--mud-default-borderradius, 4px); padding: 7px 8px; font-size: 14px; line-height: 1.2; color: var(--mud-palette-text-primary); background: var(--mud-palette-surface); }

.sfm-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 0; }

/* kpiharden: unknown-author category for the Service Tracker Notes dialog. The dialog
   renders stn-bar stn-cat-@(cat)-bar, stn-avatar stn-cat-@(cat)-av and the stn-pill
   stn-cat-@(cat) tag from AuthorCat(); "unknown" (blank Username) is new. Lives here,
   not in that dialog's inline <style> block (rule 2); token colors only (rule 1).
   Deliberately NO .stn-cat-unknown-dot: unknown has no filter chip -- it appears only
   under the All filter and is excluded from the Vendor/Client/User counts, matching
   the Vendor Activity KPI classifier which never counts blank authors as vendor. */
.stn-cat-unknown-bar { background: var(--stm-note-unknown-bar); }
.stn-cat-unknown-av { background: var(--stm-note-unknown-av); }
.stn-cat-unknown { background: var(--stm-note-unknown-tag-bg); color: var(--stm-note-unknown-tag-text); }

/* ── Snow Tracker Dates rail card (9/17). ONE rule lives here and the reason is the whole point: the card
   is a MudPaper, and Blazor's scope attribute does not attach to a child component's root, so the page's
   scoped sheet cannot reach it and a scoped rule would silently do nothing (house gotcha, same reason the
   Fas survey rules are global). Everything else about the rail sits on plain divs in the page's own
   markup and therefore belongs in Pages/SnowTracker20.razor.css, which is where it is (standing rule 2).

   The card is a column so that ONLY its list scrolls. It used to scroll as one piece, which inside a
   230px rail cost the date range picker the width of a scrollbar and clipped the year off both ends of
   the range (R. Nugent 9/17), and which forced the header to be position sticky just to survive its own
   card scrolling. .mud-paper is named on purpose: MudBlazor's stylesheet loads AFTER this one, so a bare
   class would lose a tie to any future .mud-paper rule. */
.mud-paper.st-rail-card { display: flex; flex-direction: column; max-height: 55vh; overflow: hidden; }
/* railfit 10/6 (R. Nugent: "compact the date listing a bit to make more room for the AI Analyst, or if any of them get
   collapsed have the other dynamically adjust to fill any space"). From 960px up the rail is as tall as the main
   column (SnowTracker20.razor.css, .st-body) and its cards share that height: Dates keeps its content height up to
   three tenths of the rail (its picker and about six dates on a 1080 screen) and scrolls its list past that; AI
   Analyst takes whatever is left and scrolls its body (.stx-ai-wrap); the Status key keeps its own height. A folded
   card is its bar and nothing more, so folding Dates hands its share to the analyst; folding the analyst, or a client
   view with no analyst, hands the rail to Dates (the :has rules). Under 960px the cards sit in a row above the grid
   and keep the rules above and below. */
@media (min-width: 960px) {
    .mud-paper.st-rail-card { flex: 0 0 auto; max-height: 30%; }
    .mud-paper.stx-ai-panel { flex: 1 1 auto; min-height: 120px; }
    .mud-paper.st-rail-key { flex: none; }
    .st-rail:has(.stx-ai-panel.ffc-closed) .mud-paper.st-rail-card,
    .st-rail:not(:has(.stx-ai-panel)) .mud-paper.st-rail-card { flex: 1 1 auto; max-height: none; }
    .st-rail .mud-paper.ffc.ffc-closed { flex: none; min-height: 0; }
}
/* snowfit 9/23 (R. Nugent): the Snow Tracker AI Analyst panel, formerly an inline style string in the page.
   A MudPaper root, so its rules are global (house gotcha). Lifted while a site is selected, so it reads
   as part of the open drawer; under 960px it sits above the grid rather than beside the drawer, where a
   lifted panel would float over the drawer, so there it stays flat. Under 960px the Dates card and this
   panel share the row above the grid, wrapping to one above the other on a phone. */
.mud-paper.stx-ai-panel { overflow: hidden; transition: transform .2s ease, box-shadow .2s ease; }
.mud-paper.stx-ai-panel.stx-ai-lifted { background-color: var(--mud-palette-surface); box-shadow: var(--fs-shadow-lift); transform: translateY(-6px) scale(1.012); position: relative; z-index: 1205; }
@media (max-width: 959.98px) {
    .mud-paper.st-rail-card, .mud-paper.stx-ai-panel { flex: 1 1 280px; min-width: 0; }
    .mud-paper.stx-ai-panel.stx-ai-lifted { transform: none; box-shadow: var(--fs-shadow-card); z-index: auto; }
}

/* ── FasPageBar (pagebar 9/23, R. Nugent): the corporate top bar on Snow Tracker 2.0 and Snow Tracker Map, with
   the values their two copies carried. The root and its toolbar are MudAppBar's own elements, which a scoped
   sheet cannot reach, so every rule for the bar is here, keyed on the classes FasPageBar passes. Mud's sheet
   loads after this one, so the root and the toolbar repeat their own class to win (house gotcha). Colour: the
   green and the white ink are the theme's, through Color.Primary; the shadow and the version tag's ground are
   tokens. Mud positions an app bar and its toolbar for use as a fixed layout bar, lifted to 1300. This bar
   is part of the page, so both stay in the page's flow the way the old bar did: it scrolls with the page,
   sits under the site drawer (1201), the phone menu (1250) and the dialogs, and paints exactly as before. */
.fpb.fpb { position: static; z-index: auto; box-shadow: var(--fs-shadow-bar); }
.fpb-bar.fpb-bar.fpb-bar { position: static; height: 56px; padding: 0 18px; gap: 12px; }
.fpb-logo { height: 34px; max-width: 150px; object-fit: contain; background: var(--mud-palette-surface); border-radius: 6px; padding: 3px 6px; flex: none; }
.fpb-title { font-size: 18px; font-weight: 600; letter-spacing: .5px; color: var(--mud-palette-primary-text); }
.fpb-spacer { flex: 1 1 auto; }
.fpb-version { background: var(--fs-bar-chip-bg); color: var(--mud-palette-primary-text); border-radius: 999px; padding: 4px 12px; font-size: 13px; font-weight: 600; }
.fpb-refresh.fpb-refresh.fpb-refresh .mud-icon-root { width: 24px; height: 24px; font-size: 24px; }   /* mudicons 11/02: 3 + 24 + 3, the old 30px picture */
/* clientlogo 10/8 (R. Nugent): the signed in client's own logo (ClientLogo), a white pill like the F&S logo just before the
   version tag, 4px further off it, as the Service Tracker's sits off its name menu. Under 1280px wide it drops: there the
   page name and the badges need the room, and with the pill the name breaks onto two lines (Gate 1, 10/8). Phones are
   under that too, so the phone layout below never carries it. */
.fpb-client { margin-right: 4px; }
@media (max-width: 1279.98px) { .fpb-client { display: none; } }
/* Phones: the logo and the page name on one line. The prefix and the version tag drop, and any badge or
   back link wraps under them. */
@media (max-width: 599.98px) {
    .fpb-bar.fpb-bar.fpb-bar { height: auto; min-height: 48px; padding: 6px 12px; gap: 8px; flex-wrap: wrap; }
    .fpb-logo { height: 28px; }
    .fpb-title { flex: 1 1 140px; min-width: 0; font-size: 15px; letter-spacing: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .fpb-prefix, .fpb-spacer, .fpb-version { display: none; }
}

/* ── FasFoldCard (railfold 9/29, R. Nugent): a titled card whose body folds to its bar; the Dates and AI Analyst
   cards on Snow Tracker 2.0. MudPaper, MudIcon and MudCollapse are child component roots a scoped sheet cannot
   reach, so every rule is here, keyed on the classes the component passes. The bar carries the values the two
   hand built bars had (6px 10px, bold, theme green, theme ink). The card is a column and the body keeps that
   column going through MudCollapse's grid and wrapper, so a child that scrolls (the Dates list, flex 1 with
   min-height 0) still gets the leftover height; without the last two rules the collapse wrapper would take
   the scroll instead and the whole body would move as one. Mud's sheet loads after this one, so the rules
   that meet one of Mud's repeat their own class to win (house gotcha). */
.ffc.ffc { display: flex; flex-direction: column; overflow: hidden; }
.ffc-bar { flex: none; display: flex; align-items: center; font-weight: 700;
           background: var(--mud-palette-primary); color: var(--mud-palette-primary-text);
           border-radius: var(--fs-radius-md) var(--fs-radius-md) 0 0; }
/* railside 9/30 (R. Nugent): the fold control is the toggle inside the bar. It carries the bar's old padding and
   gap, so a bar with nothing before its title draws exactly as it did. A leading control (Snow Tracker 2.0's
   rail collapse button) sits before the toggle, outside it, so pressing it never folds the card and no button
   sits inside another. The leading control is 26px, inside the bar's 32px, so the bar keeps its height. */
.ffc-toggle { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; padding: 6px 10px;
              cursor: pointer; user-select: none; border-radius: inherit; }
.ffc-toggle:focus-visible { outline: 2px solid var(--mud-palette-primary-text); outline-offset: -3px; }
.ffc-lead { flex: none; display: inline-flex; }
/* The leading control's own box carries its spacing, so a control the page hides (the rail button on a tablet)
   leaves no gap and the title sits where it always has. Repeated class: Mud's button root sets margin 0. */
.ffc-lead.ffc-lead > * { margin: 0 -6px 0 4px; }
.ffc-icon.ffc-icon { font-size: 16px; }
.ffc-title { flex: 1 1 auto; }
.ffc-chev.ffc-chev { flex: none; transition: transform .2s ease; }
.ffc-chev.ffc-folded { transform: rotate(-90deg); }
.ffc-body.ffc-body { flex: 1 1 auto; min-height: 0; }
.ffc-body > .mud-collapse-wrapper > .mud-collapse-wrapper-inner { display: flex; flex-direction: column; min-height: 0; }

/* ── FasRailHead (railhead 10/2, R. Nugent, signed off 10/2): the head bar of a side column that folds to an icon strip,
   with the side menu's hamburger and the column's name; Snow Tracker 2.0's side panel first. MudPaper is a child component
   root a scoped sheet cannot reach, so every rule is here, keyed on the classes the component passes, and Mud's sheet loads
   after this one, so each rule that meets one of Mud's repeats its own class to win (house gotcha). 48px, the strip's
   width, so folded the hamburger sits in the same 44px target the strip's doors use. Theme green and white ink, the side
   menu's. The host places it; its folded look beside the strip is the host's (SnowTracker20.razor.css). */
.frh.frh { display: flex; align-items: center; gap: 2px; height: 48px; padding: 0 2px; flex: none;
           background-color: var(--mud-palette-primary); color: var(--mud-palette-primary-text);
           border-radius: var(--fs-radius-md); }
.frh .frh-btn.frh-btn { padding: 10px; }
.frh-title.frh-title { font-size: 15px; font-weight: 700; line-height: 1; white-space: nowrap; }
.frh-collapsed.frh-collapsed { justify-content: center; }

/* ── The snow photo viewer's layout moved into FasPhotoLightbox.razor.css (oneviewer 9/30), where the one viewer lives. */

/* ── FasRefreshStamp and FasSectionToggle (toolbar 9/30, R. Nugent): the Land Tracker's Refresh and Hide/Show pills on
   Mud primitives. The shape is Mud's own (Variant.Outlined, Size.Small and Mud's rounded-pill utility); these rules
   keep the Land Tracker's sentence case and grey edge, and size the busy spinner to the 18px icon it stands in for.
   The roots are Mud components, so the rules live here keyed on the classes the components pass, and each repeats
   its class to win over Mud's sheet, which loads after this one (house gotcha): Mud colours the edge with two
   classes (.mud-button-outlined.mud-button-outlined-primary), so the grey edge takes three. Tokens only. */
.frs-btn.frs-btn, .fst.fst { text-transform: none; letter-spacing: normal; }
.frs-btn.frs-btn.frs-btn, .fst.fst.fst { border-color: var(--mud-palette-lines-inputs); }
.frs-btn.frs-btn.frs-btn:hover, .fst.fst.fst:hover { border-color: var(--mud-palette-primary); }
.frs-when.frs-when { color: var(--fs-text-muted); white-space: nowrap; }
.frs-spin.frs-spin.frs-spin { width: 18px; height: 18px; }
/* skew 10/26 (R. Nugent): on a narrow phone the Refresh button drops under the time, at the right, rather than running off the
   screen. With room for both on one line nothing changes. */
.frs.frs { flex-wrap: wrap; justify-content: flex-end; row-gap: 4px; }

/* ── FasTestToggle (zzz 10/7, R. Nugent): the Land Tracker's ZZZ flask on Mud's icon button, sized to sit in one row with
   the toolbar's Hide pills (FasSectionToggle, Mud's small outlined button, 30.75px tall): their height, a pill a little
   wider than tall, and their grey edge while the switch is off. On is Mud's own primary fill, with a 1px edge in the
   same colour so the pill keeps its size when it changes state. Each rule repeats its class to win over Mud's sheet,
   which loads after this one (house gotcha). Tokens only. */
.ftt.ftt.ftt { min-height: 30.75px; padding: 0 13px; border-radius: 999px; }
.ftt.ftt.ftt:not(.ftt-on) { border-color: var(--mud-palette-lines-inputs); }
.ftt.ftt.ftt:not(.ftt-on):hover { border-color: var(--mud-palette-primary); }
.ftt.ftt.ftt.ftt-on { border: 1px solid var(--mud-palette-primary); }
.ftt.ftt .mud-icon-root { width: 16px; height: 16px; font-size: 16px; }

/* ── FasMessageAmButton (clientmsg 10/8, R. Nugent): the Client Service Tracker's green paper plane, on Snow Tracker 2.0 and,
   since msgsent 10/13, on the Client Service Tracker itself. The plane is MudIconButton (Filled, Primary), so the green and the
   white glyph are the theme's. A Mud icon button is round; the Service Tracker's is a rounded rectangle, 7px corners and 6px
   by 10px round a 14px glyph, so the button repeats its class to win over Mud's sheet, which loads after this one (house
   gotcha). */
.fma-btn.fma-btn.fma-btn { border-radius: 7px; padding: 6px 10px; }
.fma-btn.fma-btn .mud-icon-root { width: 14px; height: 14px; font-size: 14px; }
/* msgsent 10/13 (R. Nugent; Gate 1 signed off 10/13): the root is a MudElement span (fma) round a MudBadge, the FasNoteBubble
   shape. The count starts at the plane's top right corner and grows to the right, so the glyph stays whole however wide the
   count gets. It is ringed in the surface colour: blue (--fs-kpi-info-fg, the staff side's client note blue) while a note
   waits on F&S, green (--fs-kpi-success-fg) with a check once F&S has acknowledged them all. fma-count is repeated for the
   reason fnb-count is (MudBadge composes its placement classes at runtime); the check is a mask over currentColor, so it
   carries no colour of its own. */
.fma { display: inline-block; line-height: 1; vertical-align: middle; }
.fma .mud-badge-root.fma-badge { display: inline-flex; vertical-align: middle; }
.fma .mud-badge.fma-count.fma-count.fma-count.fma-count { top: -7px; left: calc(100% - 10px); right: auto; bottom: auto; transform: none;
    display: inline-flex; align-items: center; justify-content: center; gap: 2px; box-sizing: content-box; height: 16px; min-width: 8px;
    padding: 0 4px; border-radius: 999px; border: 2px solid var(--mud-palette-surface); font-size: 10.5px; font-weight: 800; line-height: 16px;
    background: var(--fs-kpi-info-fg); color: var(--mud-palette-white); cursor: pointer; }
.fma .mud-badge.fma-count.fma-acked.fma-count.fma-count { background: var(--fs-kpi-success-fg); }
.fma .mud-badge.fma-count.fma-acked::before { content: ""; flex: none; width: 9px; height: 9px; background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") center / contain no-repeat; }

/* ── SnowFollowUpMeter (kpiwo 10/23, Gate 1 signed off 10/23; on MudChip kpimud 10/23, R. Nugent): the follow-up complete pill
   on the title line of Snow Tracker 2.0 and the Snow Tracker Map. Its root is MudChip, which a scoped sheet cannot reach, so the
   pill is here, keyed on the classes the component passes; the inside is in SnowFollowUpMeter.razor.css. The values are the
   signed off plain button's: 3px 10px 3px 7px round a 16px icon, a grey edge that turns green under the pointer, the card
   surface, a green ground and ring while pressed, and the brand focus ring outside. Mud's sheet loads after this one, so each
   rule repeats its class to win (house gotcha): Mud sizes a small chip with two classes and tints a clickable chip's ground on
   hover, focus and press with four, so the ground holds there with five. The pressed ring's three also outrank Bootstrap's
   button:focus:not(:focus-visible) rule, which took the ring away after a click while the meter kept focus. Tokens only. */
.sfu.sfu.sfu { margin: 0; height: auto; padding: 3px 10px 3px 7px; border: 1px solid var(--fs-tl-line); border-radius: 999px;
               background: var(--fs-kpi-surface); font: inherit; line-height: 1; }
.sfu.sfu.sfu:hover { border-color: var(--fs-kpi-success-fg); }
.sfu.sfu.sfu-active { background: var(--fs-kpi-success-bg); outline: 2px solid var(--fs-kpi-success-fg); outline-offset: -2px; }
.sfu.sfu.sfu.sfu:hover, .sfu.sfu.sfu.sfu:focus-visible, .sfu.sfu.sfu.sfu:active { background: var(--fs-kpi-surface); }
.sfu.sfu.sfu.sfu-active:hover, .sfu.sfu.sfu.sfu-active:focus-visible, .sfu.sfu.sfu.sfu-active:active { background: var(--fs-kpi-success-bg); }
.sfu.sfu.sfu:focus-visible { outline: 2px solid var(--mud-palette-primary); outline-offset: 2px; }

/* ── FasFilterChips (fchips 9/18; on Mud primitives chips1 10/1, R. Nugent): the readout of what is filtering a snow
   view, on Snow Tracker 2.0 (in the filter bar, and on its own while the bar is folded) and Snow Tracker Map. MudPaper
   root, MudText label and overflow, a MudElement span per chip with a MudIconButton to remove it, and a text
   MudButton for Clear all. The metrics are the 9/18 strip's, moved here unchanged from FasFilterChips.razor.css,
   because a Mud root takes no scoped styles. Mud's sheet loads after this one, so a rule that meets one of Mud's
   repeats its own class to win (house gotcha). Tokens only. */
.ffch.ffch { display: flex; flex-wrap: wrap; align-items: center; gap: var(--fs-gap-sm);
             padding: 8px 10px; margin-top: var(--fs-gap-sm); border-radius: var(--fs-radius-md); }
/* The label is Subtitle2, the app's small uppercase label scale (.75rem / 700 / .04em from the theme). */
.ffch-cap.ffch-cap { text-transform: uppercase; color: var(--fs-text-muted); line-height: inherit; }
.ffch-chip { display: inline-flex; align-items: center; gap: 5px; max-width: 320px; min-width: 0;
             background: var(--fs-chip-bg); color: var(--fs-chip-fg); border: 1px solid var(--fs-chip-line);
             border-radius: 999px; padding: 3px 9px; font-size: 12px; font-weight: 600; line-height: 1.5; white-space: nowrap; }
.ffch-chip-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* The remove control is a real button now: no padding, the chip's blue, and a ring when it has keyboard focus. The
   Material x is drawn inside a 24 unit box with room round it, so the button is 13px for an x the old one's size,
   and its side margins give back the extra 5px, leaving every chip as wide as it was. */
.ffch-x.ffch-x.ffch-x { flex: none; padding: 0; margin: 0 -2.5px; color: var(--fs-chip-x); background-color: transparent; }
.ffch-x.ffch-x.ffch-x:hover { color: var(--fs-chip-x-hover); background-color: transparent; }
.ffch-x.ffch-x.ffch-x:focus-visible { outline: 2px solid var(--fs-chip-x-hover); outline-offset: 1px; }
.ffch-x.ffch-x .mud-icon-root { font-size: 13px; }
.ffch-more.ffch-more { font-size: 11.5px; color: var(--fs-text-muted); font-style: italic; line-height: inherit; }
.ffch-clear.ffch-clear { margin-left: auto; padding: 0; min-width: 0; font-size: 12px; font-weight: 600; line-height: inherit;
                         letter-spacing: normal; text-transform: none; text-decoration: underline; color: var(--fs-chip-fg); }
.ffch-clear.ffch-clear:hover { color: var(--fs-chip-x-hover); background-color: transparent; text-decoration: underline; }

/* ── FasDocRow (snowdocs 9/29): one file on one line. doctype 11/04: the row roots on a MudElement, so its rules moved here from
   FasDocRow.razor.css unchanged (a Mud root takes no scoped styles). The name shrinks and ellipsizes before anything else on the
   line gives way; the badge fills are the --fs-doc-* tokens. Tokens only. */
.fdr { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 12.5px; min-width: 0; }
.fdr-muted { opacity: .65; }
.fdr-ico { flex: none; display: inline-flex; align-items: center; justify-content: center; min-width: 30px; height: 20px; padding: 0 4px; border-radius: 4px; font-size: 9px; font-weight: 800; letter-spacing: .3px; color: var(--mud-palette-primary-text); }
.fdr-ico-pdf   { background: var(--fs-doc-pdf); }
.fdr-ico-sheet { background: var(--fs-doc-sheet); }
.fdr-ico-word  { background: var(--fs-doc-word); }
.fdr-ico-other { background: var(--fs-doc-other); }
.fdr-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; color: var(--mud-palette-text-primary); text-decoration: none; }
a.fdr-name { color: var(--mud-palette-primary); }
a.fdr-name:hover { text-decoration: underline; }
.fdr-meta { flex: none; font-size: 11px; color: var(--fs-text-muted); white-space: nowrap; }
.fdr-size { flex: none; font-size: 11px; color: var(--fs-text-muted); white-space: nowrap; }
.fdr-status { flex: none; font-size: 11px; color: var(--fs-text-muted); white-space: nowrap; }
.fdr-status-ok { color: var(--mud-palette-success); font-weight: 700; }
.fdr-status-fail { color: var(--mud-palette-error); font-weight: 600; white-space: normal; }
.fdr-x { flex: none; border: 0; background: transparent; color: var(--fs-text-muted); font: inherit; font-size: 16px; line-height: 1; padding: 0 4px; cursor: pointer; }
.fdr-x:hover:not(:disabled) { color: var(--mud-palette-error); }
.fdr-x:disabled { opacity: .4; cursor: default; }

/* ── FasDocType (doctype 11/04, R. Nugent; Gate 1 signed off 11/04, every call A): a file's document type. The chip after a saved
   file's name (a label, or a button with the list for staff with the Documents action), and the select under a waiting file's
   name, whose edge says where its type came from: red, none yet, the window's Save waits; amber, filled in from the file and not
   checked; plain, a person picked it. Mud's sheet loads after this one, so the rules that meet Mud's parts repeat their own
   class or name Mud's to outrank it (house gotcha). Tokens only. */
.fdt-chip { flex: none; display: inline-flex; align-items: center; gap: 1px; padding: 1px 9px; border-radius: 999px; border: 1px solid var(--fs-chip-line);
            background: var(--fs-chip-bg); color: var(--fs-chip-fg); font: inherit; font-size: 11px; font-weight: 600; line-height: 1.5; white-space: nowrap; }
button.fdt-chip { cursor: pointer; padding-right: 3px; }
button.fdt-chip:hover:not(:disabled) { border-color: var(--fs-chip-fg); }
button.fdt-chip:focus-visible { outline: 2px solid var(--mud-palette-primary); outline-offset: 1px; }
button.fdt-chip:disabled { opacity: .5; cursor: default; }
.fdt-chip.fdt-chip-wo { background: var(--fs-note-wo-bg); color: var(--fs-note-wo); border-color: var(--fs-note-wo-bg); }
.fdt-chip.fdt-chip-unset { background: var(--mud-palette-surface); color: var(--fs-text-muted); border: 1px dashed var(--mud-palette-lines-default); }
.fdt-caret.fdt-caret { font-size: 16px; width: 16px; height: 16px; margin: 0; }
.fdr .fdt-menu.fdt-menu { flex: none; }
.mud-menu-item.fdt-item-on.fdt-item-on { font-weight: 700; color: var(--fs-chip-fg); background: var(--fs-chip-bg); }
.fdt-pick.fdt-pick { margin: 0; }
.fdt-pick.fdt-pick .mud-input { font-size: 13px; }
.fdt-pick.fdt-pick .mud-input > input.mud-input-root.mud-input-root-margin-dense { font-size: 13px; padding-top: 8px; padding-bottom: 8px; }
.mud-input-control.fdt-pick > .mud-input-control-input-container > .mud-input-label-inputcontrol { font-size: 13px; }
.fdt-pick.fdt-todo .mud-input.mud-input-outlined .mud-input-outlined-border { border-color: var(--mud-palette-error); border-width: 2px; }
.mud-input-control.fdt-pick.fdt-todo > .mud-input-control-input-container > .mud-input-label-inputcontrol { color: var(--mud-palette-error); }
.fdt-pick.fdt-auto .mud-input.mud-input-outlined .mud-input-outlined-border { border-color: var(--fs-warn-border); border-width: 2px; }
.fdt-pick.fdt-auto .mud-input.mud-input-outlined { background: var(--fs-warn-bg); }

/* ── FasDocDrop (docs1 10/1, R. Nugent): the documents zone on Modify Status and Mass Assign. MudFileUpload carries
   the drop and the picker, and its transparent input (.fas-file-input, above) covers the zone. The look is Modify
   Status's DOCUMENTS zone of 9/29, moved here from SnowModifyStatusDialog.razor.css unchanged, because its parts
   are Mud components now and a Mud root takes no scoped styles. The text parts are MudText, so they take the
   weight and line height around them (inherit) where the old divs did, rather than Mud's type scale. Mud's sheet
   loads after this one, so a rule that meets one of Mud's repeats its own class to win (house gotcha). Tokens only. */
.fdd-zone.fdd-zone { border: 2px dashed var(--fs-text-muted); border-radius: var(--fs-radius-md); padding: 14px 12px;
                     text-align: center; background: var(--mud-palette-background); color: var(--fs-text-muted); }
/* dropblue 10/9 (R. Nugent: "when dragging docs in here want it to highlight blue upon hovering over this drop area"): a file
   over the zone turns it plainly blue, a solid blue edge and a blue fill with the icon and the words in deep blue, in every
   window the zone is in. */
.fdd-zone.fdd-zone-on { border-style: solid; border-color: var(--fs-tl-blue); background: var(--fs-kpi-info-bg); }
.fdd-zone-on .fdd-icon.fdd-icon, .fdd-zone-on .fdd-title.fdd-title, .fdd-zone-on .fdd-sub.fdd-sub { color: var(--fs-chip-fg); }
.fdd-icon.fdd-icon { font-size: 22px; color: var(--fs-text-muted); }
/* e50 10/30 (Julian signed the mock 12:18): the integration compose column's note, files and status read as fields to fill.
   The shrunk label straddles the outline, so its lower half takes the fill and its upper half the card. */
.iwp-compose .mud-input.mud-input-outlined { background: var(--fs-field-fill); border-radius: var(--mud-default-borderradius); }
.iwp-compose .mud-shrink ~ label.mud-input-label-outlined,
.iwp-compose .mud-input:focus-within ~ label.mud-input-label-outlined { background: linear-gradient(to bottom, var(--mud-palette-surface) 50%, var(--fs-field-fill) 50%); }
.iwp-compose .fdd-zone.fdd-zone:not(.fdd-zone-on) { background: var(--fs-field-fill); }
.fdd-title.fdd-title { margin-top: 2px; font-size: 13px; font-weight: 700; line-height: inherit; letter-spacing: normal; color: var(--mud-palette-text-primary); }
.fdd-sub.fdd-sub { display: block; font-size: 11.5px; font-weight: inherit; line-height: inherit; letter-spacing: normal; color: inherit; }
.fdd-list.fdd-list { margin-top: 8px; border-radius: var(--fs-radius-md); padding: 2px 10px; }
.fdd-list .fdr + .fdr { border-top: 1px solid var(--mud-palette-lines-default); }
/* The ready line and the reading line: 12px muted notes, 6px apart, under the list or the zone. */
.fdd-line { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; padding: 6px 2px 0; }
.fdd-note.fdd-note { font-size: 12px; font-weight: inherit; line-height: inherit; letter-spacing: normal; color: var(--fs-text-muted); }
.fdd-strong.fdd-strong { font-weight: 700; color: var(--mud-palette-text-primary); }
.fdd-clear.fdd-clear { padding: 0; min-width: 0; font-size: 12px; font-weight: 700; line-height: inherit; letter-spacing: normal; text-transform: none; }
.fdd-clear.fdd-clear:hover { background-color: transparent; text-decoration: underline; }
.fdd-spin.fdd-spin.fdd-spin { width: 16px; height: 16px; }
.fdd-error.fdd-error { margin-top: 10px; font-size: 12.5px; font-weight: 600; line-height: inherit; letter-spacing: normal; }
/* sharebulk 10/16 (R. Nugent): Share all and Hide all at the head of the list, right aligned over the Client switches they set, in
   Clear's dress. */
.fdd-bulk { display: flex; align-items: center; justify-content: flex-end; gap: 10px; padding: 6px 0 5px; border-bottom: 1px solid var(--mud-palette-lines-default); }
.fdd-bulk-btn.fdd-bulk-btn { padding: 0; min-width: 0; font-size: 12px; font-weight: 700; line-height: inherit; letter-spacing: normal; text-transform: none; }
.fdd-bulk-btn.fdd-bulk-btn:hover { background-color: transparent; text-decoration: underline; }
/* doctype 11/04: the Type line under each waiting file, set in past the badge so it reads as the file's, with its note beside it;
   Type for all at the left of the bulk row, Share all and Hide all still right; the count still to type in the ready line, red. */
.fdd-type { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; padding: 0 0 9px 38px; }
.fdd-type > .mud-select { flex: none; width: 250px; }
.fdd-list .fdd-type + .fdr { border-top: 1px solid var(--mud-palette-lines-default); }
.fdd-type-note.fdd-type-note { font-size: 11.5px; font-weight: 600; line-height: inherit; letter-spacing: normal; }
.fdd-type-todo.fdd-type-todo { color: var(--mud-palette-error); }
.fdd-type-auto.fdd-type-auto { color: var(--fs-warn-text); }
.fdd-todo.fdd-todo { color: var(--mud-palette-error); font-weight: 700; }
.fdd-bulk-type { display: flex; align-items: center; gap: 8px; margin-right: auto; }
.fdd-bulk-type > .mud-select { flex: none; width: 190px; }

/* ---- FasWorkOrderTable (wotrack 9/29) --------------------------------------------------
   The rules a scoped stylesheet cannot deliver. MudTable renders its own table markup, and
   Blazor's scope attribute does not attach to a child component's rendered elements (house
   gotcha), so cell metrics and the open-row tint have to be global, keyed on the .fwo-grid
   wrapper. Same reason and same shape as the .vsp-table block above; the class names were
   confirmed against MudBlazor 9.5.0 as that block already uses them in production.

   Twelve columns inside a 1040px dialog, so the padding is trimmed and the idle sort icons
   are hidden exactly as the Ops grid does, or the chevrons alone eat a column of width.
   Header casing deliberately follows mockup card 1b ("Client PO #", not "CLIENT PO #"),
   which is why there is no text-transform here unlike .vsp-table. Tokens only, no hex. */
.fwo-grid .mud-table-container { overflow: visible; }
.fwo-grid table.mud-table-root { width: 100%; }
.fwo-grid .mud-table-root .mud-table-cell { padding: 5px 6px; white-space: normal; overflow-wrap: normal; line-height: 1.3; vertical-align: top; }
.fwo-grid .mud-table-root tbody td.mud-table-cell { font-size: 12.5px; color: var(--fs-text-secondary); }
.fwo-grid .mud-table-root thead th.mud-table-cell { font-size: 11px; font-weight: 700; letter-spacing: .02em; color: var(--fs-text-secondary); vertical-align: bottom; }
/* MudTable's sort label is NOT MudDataGrid's. The DataGrid (.vsp-table above) wraps its
   icon in .mud-icon-button; MudTable uses .mud-table-sort-label-icon and marks it
   mud-direction-none until the column is actually sorted. Hiding the DataGrid's class here
   did nothing, so every one of twelve headers was paying ~20px for an icon it was not
   using, which is what forced them to three lines. Class names read from MudBlazor.dll. */
.fwo-grid .mud-sort-index { display: none; }
.fwo-grid .mud-table-sort-label .mud-direction-none { display: none; }
.fwo-grid .mud-table-sort-label-icon { font-size: 15px; width: 15px; height: 15px; }

/* wotrack 9/29 render 1: auto layout gave the width to Vendor, which laddered four lines
   deep, and starved Issue / Scope of work, the column ops actually reads. Three header
   labels also wrapped to three lines, failing acceptance criterion 2 (two lines maximum).
   table-layout: fixed plus one width per column settles both: the browser stops guessing,
   and column 4 takes whatever is left, so the scope text gets the room at any dialog size.
   Widths are ch-free pixels chosen against the real header strings at 11px/700. */
.fwo-grid table.mud-table-root { table-layout: fixed; }
/* Percentages, not pixels. Fixed pixels summed to ~1022px against ~1008px usable inside
   a Large dialog, so the auto column collapsed to nothing and the headers overlapped
   (render 2026-09-29). Percentages cannot overflow: they always divide whatever width
   the dialog actually has, at Full, at Large, or with the side menu collapsed. */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(1),
.fwo-grid .mud-table-root td.mud-table-cell:nth-child(1)  { width: 30px; }
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(2)   { width: 7%; }     /* WO # */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(3)   { width: 8%; }     /* Client PO # */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(4)   { width: 20%; }    /* Issue / Scope */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(5)   { width: 7%; }     /* Category */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(6)   { width: 9%; }     /* Date / Time */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(7)   { width: 8%; }     /* Priority */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(8)   { width: 9%; }     /* Status */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(9)   { width: 6%; }     /* In Scope */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(10)  { width: 10%; }    /* SLA Date / Time */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(11)  { width: 7%; }     /* Vendor */
.fwo-grid .mud-table-root th.mud-table-cell:nth-child(12)  { width: 7%; }     /* Assigned AM */
.fwo-grid tbody tr.mud-table-row { cursor: pointer; }
/* Real IDS statuses run long ("PENDING SCHEDULED"). .fsp is nowrap because the snow grid
   it was built for has short ones, so inside THIS grid only, let the pill wrap rather than
   spill over the next column, which is what put "TE" in the In Scope cell at render. */
.fwo-grid td.mud-table-cell .fsp { white-space: normal; }
.fwo-grid tbody tr.fwo-row-open > td.mud-table-cell { background: var(--fs-rowexp-bg); }

/* FasCommStrip (commstrip 10/2, signed off 10/2): the vendor communication rail. The root is a MudStack and
   Mud's own classes carry the buttons, so these rules lift specificity by repeating the house class, never by
   naming Mud's generated classes (site.css loads before MudBlazor.min.css). Tokens only, no new hex. */
.fcs { margin-top: 6px; }
.fcs .fcs-ico.fcs-ico { width: 34px; height: 34px; padding: 0; border-radius: var(--fs-radius-md); border: 1px solid var(--fs-tl-line); color: var(--fs-text-secondary); }
.fcs .fcs-ico.fcs-ico:hover { border-color: var(--mud-palette-primary); color: var(--mud-palette-primary); }
.fcs .fcs-contacts.fcs-contacts { height: 34px; min-width: 0; border-radius: 999px; padding: 0 12px; text-transform: none; font-weight: 700; color: var(--fs-text-secondary); border: 1px solid var(--fs-tl-line); }
.fcs .fcs-contacts.on.on { background: var(--fs-ffs-focus); border-color: var(--mud-palette-primary); color: var(--mud-palette-primary); }
.fcs .fcs-chip.fcs-chip { text-transform: none; border-radius: 999px; border-color: var(--fs-chip-line); background: var(--fs-chip-bg); color: var(--fs-chip-fg); font-size: 12px; font-weight: 600; padding: 2px 10px; }
.fcs .fcs-chip.fcs-chip:hover { border-color: var(--fs-chip-fg); }
.fcs-note { color: var(--fs-text-muted); font-size: 12px; line-height: 1.5; display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; }
.fcs-off { color: var(--fs-warn-text); }
.fcs .fcs-log.fcs-log { text-transform: none; padding: 0 6px; min-width: 0; font-weight: 600; }
.fcs-link { color: var(--fs-chip-fg); text-decoration: none; }
/* railhead 10/2: Compact, the dialogs' strip. Lead (the host's label and the vendor's name) starts the row. */
.fcs.fcs-compact { margin-top: 0; }
.fcs-lead { display: inline-flex; align-items: center; gap: 10px; margin-right: 6px; min-width: 0; }
/* The Snow map popup's Text when no address can be built: the popup's Text pill drawn from tokens, dimmed and inert, with
   its reason in the tooltip. The live pill keeps the popup's existing inline look, moved verbatim. */
.fcs-map-off { display: inline-block; background: var(--fs-tl-blue); color: var(--mud-palette-primary-text); padding: 4px 14px;
               border-radius: 6px; font-weight: 600; opacity: .45; cursor: not-allowed; }

/* ---- FasMailCompose (mail 10/2, R. Nugent, signed off 10/2): the compose window's parts, keyed on the component's classes,
   because its fields are Mud roots a scoped sheet cannot reach. Tokens only. ---- */
.fmc-meta { font-size: 12px; color: var(--fs-text-muted); }
.fmc-label { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--fs-text-muted); margin-bottom: 4px; }
.fmc .fmc-sig-box.fmc-sig-box { padding: 8px 10px; font-size: 12.5px; line-height: 1.5; color: var(--fs-text-secondary); }
.fmc-att { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.fmc .fmc-attach.fmc-attach { text-transform: none; }
.fmc-att .mud-file-upload-files { display: none; }   /* the window lists the files itself, as chips */
.fmc-note { font-size: 12px; color: var(--fs-text-muted); }
.fmc .fmc-pick.fmc-pick { margin-top: -6px; padding: 4px 0; max-width: 360px; }
.fmc-pick-item { display: flex; gap: 10px; align-items: baseline; padding: 4px 12px; font-size: 12.5px; cursor: pointer; }
.fmc-pick-item:hover { background: var(--fs-rail-hover); }
.fmc-pick-item span { color: var(--fs-text-muted); font-size: 12px; }
/* ---- FasMailInbox (mail 10/2): the inbox window's parts, the same way. A message's header and each thumbnail are plain
   buttons so a keyboard opens them; .fmi-head and .fmi-thumb-btn take the browser's button look off. ---- */
.fmi-bar { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; }
.fmi-bar .fmi-search { flex: 1 1 320px; }
.fmi-busy { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 12.5px; color: var(--fs-text-muted); }
.fmi-empty, .fmi-notice { margin-top: 12px; font-size: 12.5px; color: var(--fs-text-muted); }
.fmi-notice { text-align: center; }
.fmi-alert.fmi-alert { margin-top: 12px; }
.fmi-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.fmi-msg.fmi-msg { padding: 8px 12px; }
.fmi-msg.fmi-open.fmi-open { border-color: var(--mud-palette-primary); }
.fmi-head { display: block; width: 100%; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.fmi-head:focus-visible, .fmi-thumb-btn:focus-visible { outline: 2px solid var(--mud-palette-primary); outline-offset: 2px; border-radius: 4px; }
.fmi-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 12.5px; }
.fmi-from { font-weight: 600; color: var(--mud-palette-text-primary); }
.fmi-when { font-size: 11.5px; font-weight: 600; color: var(--fs-text-secondary); white-space: nowrap; }
.fmi-subj { display: block; font-size: 13px; font-weight: 700; color: var(--mud-palette-text-primary); }
.fmi-prev { display: block; font-size: 12px; color: var(--fs-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fmi-body { margin-top: 8px; padding: 8px 10px; max-height: 220px; overflow: auto; white-space: pre-wrap; font-size: 12.5px; color: var(--fs-text-secondary);
            background: var(--fs-rail-head-bg); border-radius: var(--fs-radius-md); }
.fmi-thumbs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.fmi-thumb-btn { padding: 0; border: 0; background: none; line-height: 0; cursor: pointer; }
.fmi-thumb { width: 54px; height: 54px; object-fit: cover; border-radius: 6px; border: 1px solid var(--fs-tl-line); }
.fmi-acts { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin-top: 6px; }
.fmi-acts .fmi-reply.fmi-reply { text-transform: none; }
/* emailwo 10/9 (R. Nugent, signed off 10/9): Create work order beside Reply, in its dress, and the tag a client's work order
   email carries (its number, read from the subject), on the chip tokens. The row wraps on a narrow screen. */
.fmi-acts .fmi-wo.fmi-wo { text-transform: none; }
/* adddocs 10/15 (R. Nugent, signed off 10/15): Add to documents beside Create work order, in its dress; the Documents section's
   Add documents button; and the Add documents window's Mud parts (a Mud root takes no scoped styles). */
.fmi-acts .fmi-docs.fmi-docs { text-transform: none; }
.stx-docs-add-btn.stx-docs-add-btn { text-transform: none; margin-left: auto; flex-shrink: 0; }
.sad-desc.sad-desc.sad-desc.sad-desc { margin-top: 14px; }   /* over Mud's dense outlined field (three classes, loaded after) */
.sad-inbox-icon.sad-inbox-icon { font-size: 18px; }
/* massinbox 10/16 (R. Nugent): Reply off in Mass Assign's inbox, said under the search bar on the off tokens FasCommStrip's Email
   line reads; FasEmailFrom's two lines, moved here unchanged from the Add documents window's .sad-from and .sad-left; and the
   mail icon on Mass Assign's From your inbox door. */
.fmi-off { margin-top: 8px; font-size: 12px; line-height: 1.5; color: var(--fs-warn-text); }
.fef-from { margin: 0 0 10px; padding: 6px 10px; font-size: 12.5px; color: var(--mud-palette-text-primary);
            background: var(--mud-palette-surface); border: 1px dashed var(--fs-chip-line); border-radius: var(--fs-radius-md); }
.fef-left { margin: 0 0 10px; font-size: 12px; color: var(--fs-text-muted); }
.smd-inbox-icon.smd-inbox-icon { font-size: 15px; }
.fmi-wo-tag { display: inline-block; padding: 0 8px; border-radius: 9px; font-size: 11px; font-weight: 700; line-height: 18px;
              background: var(--fs-chip-bg); color: var(--fs-chip-fg); border: 1px solid var(--fs-chip-line); }
.fmi-att { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; color: var(--fs-chip-fg); }
.fmi-more { text-align: center; margin-top: 12px; }
.fmi-bar .fmi-btn.fmi-btn, .fmi-more .fmi-btn.fmi-btn, .fmi-alert .fmi-btn.fmi-btn { text-transform: none; font-weight: 600; }
/* panelw 10/13 (R. Nugent, signed off 10/13): while the Snow Tracker drawer's edge is being dragged, wwwroot/js/fas-drawer.js
   puts this class on <html>, so the resize cursor holds wherever the pointer goes and nothing on the page gets selected. */
html.fas-drawer-dragging, html.fas-drawer-dragging * { cursor: col-resize !important; user-select: none !important; }

/* ── Integrations (intpage 10/16, ADR-0050, mockup signed off 10/16): FasLogoMark and the Integrations page. Every root is
   a Mud component, so these rules are global and keyed on the house classes, with the class repeated where a Mud rule would
   otherwise win (site.css loads before MudBlazor.min.css); Mud's own generated classes are never named. Tokens only: the
   integration accents are --fs-int-* in the :root block above. */

/* FasBrandMark (fbm, fsiq 10/31): the client portal brand mark, F&S IQ, a picture from wwwroot/images/brand (Arial Bold,
   outlined, trimmed tight to the letters). These heights give the same letter size as 19px sidebar text and a 40px
   page heading; the height spans cap top to the Q tail. */
.fbm.fbm { display: block; width: auto; max-width: 100%; flex: none; }
.fbm.fbm-nav { height: 15px; }
.fbm.fbm-hero { height: 32px; margin: 0 auto; }
/* The short Land green rule under the hero mark on the client home (Pages/Index.razor), a MudDivider. */
.fasiq-rule.fasiq-rule { width: 56px; height: 3px; border: 0; opacity: 1; background: var(--fs-disc-land); margin: 10px auto 12px; flex: none; }

/* FasLogoMark (flm): a client's or an integration's logo, or the name's initials when there is no picture. */
.flm.flm { background: var(--mud-palette-surface); color: var(--mud-palette-primary); border: 1px solid var(--fs-tl-line); font-weight: 700; overflow: hidden; flex: none; }
.flm.flm-initials { background: var(--mud-palette-primary); color: var(--mud-palette-primary-text); border-color: transparent; }
/* The class is repeated so these outrank Mud's .mud-avatar.mud-avatar-* sizes, which load after site.css (10/17). */
.flm.flm.flm-small  { width: 24px; height: 24px; font-size: 10px; border-radius: 6px; }
.flm.flm.flm-medium { width: 36px; height: 36px; font-size: 13px; border-radius: 8px; }
.flm.flm.flm-large  { width: 52px; height: 52px; font-size: 17px; border-radius: 12px; }
/* A picture keeps its own shape (10/16: a wide client logo such as CVS was cropped in the square): the mark grows
   sideways up to twice its height and the picture is fitted inside, never cut. Initials stay square. The picture's
   limit is in pixels (box width less padding), because a percentage of a box sized by its own picture means no limit;
   that, and Mud's later loading sizes winning a tie, cropped the CVS logo on staging 10/17. */
.flm.flm.flm-picture { width: auto; padding: 3px 5px; }
.flm.flm.flm-small.flm-picture  { min-width: 24px; max-width: 48px; }
.flm.flm.flm-medium.flm-picture { min-width: 36px; max-width: 72px; }
.flm.flm.flm-large.flm-picture  { min-width: 52px; max-width: 104px; }
.flm.flm .flm-img.flm-img { width: auto; height: 100%; object-fit: contain; flex: 0 0 auto; }
.flm.flm-small  .flm-img.flm-img { max-width: 38px; }
.flm.flm-medium .flm-img.flm-img { max-width: 62px; }
.flm.flm-large  .flm-img.flm-img { max-width: 94px; }
.flm.flm-tone-servicechannel { background: var(--fs-int-servicechannel-soft); color: var(--fs-int-servicechannel); border-color: transparent; }
.flm.flm-tone-sitefotos      { background: var(--fs-int-sitefotos-soft);      color: var(--fs-int-sitefotos);      border-color: transparent; }

/* Shared inks for the page's small text. */
.fint-muted { color: var(--fs-text-muted); }
.fint-own   { color: var(--fs-chip-fg); font-weight: 700; }
.fint-mono  { font-family: var(--fs-font-mono); }
.fint-empty { color: var(--fs-text-muted); font-style: italic; }
.fint-num   { font-variant-numeric: tabular-nums; }

/* The page and its compact command band (Julian 10/16: keep the band small). */
.fint-page { padding: 0 16px 32px; }
.fint-band.fint-band { margin: 0 -16px; padding: 10px 16px; background: var(--mud-palette-surface); border-bottom: 1px solid var(--fs-tl-line); }
.fint-band-title.fint-band-title { line-height: 1.2; }
.fint-band-sub { color: var(--fs-text-muted); }
.fint-crumb.fint-crumb { cursor: pointer; }
.fint-stat-n.fint-stat-n { color: var(--mud-palette-primary); line-height: 1.1; font-variant-numeric: tabular-nums; }
.fint-stat-t { color: var(--fs-text-muted); }
.fint-search.fint-search { max-width: 280px; }

/* Integration tiles: the integration's accent on a top rule, a ring when selected, a lift on hover. */
.fint-tile.fint-tile { position: relative; overflow: hidden; height: 100%; padding: 16px; border-radius: var(--fs-radius-lg); cursor: pointer;
                       transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease; }
.fint-tile::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 4px; background: var(--fint-accent, var(--fs-tl-line)); }
.fint-tile.fint-tone-servicechannel { --fint-accent: var(--fs-int-servicechannel); }
.fint-tile.fint-tone-sitefotos      { --fint-accent: var(--fs-int-sitefotos); }
.fint-tile.fint-tile:hover { box-shadow: var(--fs-shadow-lift); transform: translateY(-2px); }
.fint-tile.fint-tile-on { border-color: var(--fint-accent); box-shadow: 0 0 0 2px var(--fint-accent); }
.fint-tile:focus-visible { outline: 2px solid var(--mud-palette-primary); outline-offset: 2px; }
.fint-tile.fint-tile-next { cursor: default; border-style: dashed; background: transparent; display: flex; align-items: center; justify-content: center; min-height: 200px; text-align: center; }
.fint-tile.fint-tile-next:hover { box-shadow: none; transform: none; }
.fint-env { padding: 2px 10px; border-radius: 999px; border: 1px solid var(--fs-tl-line); }
.fint-dot.fint-dot { width: 10px; height: 10px; color: var(--fs-tl-line); }
.fint-dot.fint-dot-on { color: var(--fs-status-completed-fg); border-radius: 50%; animation: fint-pulse 2.4s ease-in-out infinite; }
@keyframes fint-pulse { 0%, 100% { filter: drop-shadow(0 0 0 currentColor); } 50% { filter: drop-shadow(0 0 4px currentColor); } }

/* The roster, the matrix and the workspace. */
.fint-roster.fint-roster, .fint-ws.fint-ws { border-radius: var(--fs-radius-lg); overflow: hidden; }
.fint-ws.fint-ws { padding: 16px; }
.fint-roster-head { padding: 12px 16px; border-bottom: 1px solid var(--fs-tl-line); }
.fint-row-click { cursor: pointer; }
.fint-meter { min-width: 160px; gap: 4px; }
.fint-legend { padding: 10px 16px; border-top: 1px solid var(--fs-tl-line); }
.fint-cell.fint-cell { text-transform: none; padding: 4px 6px; justify-content: flex-start; text-align: left; }
/* The client and its integration side by side, joined by a link badge with a short dashed line out each side, in the
   shared line and primary tokens. The badge is a Mud element (MudElement span); the lines are its pseudo elements. */
.fint-link { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
             margin: 0 22px; border-radius: 50%; background: var(--mud-palette-surface); color: var(--mud-palette-primary);
             border: 1px solid var(--fs-tl-line); box-shadow: var(--fs-shadow-bar); }
.fint-link::before, .fint-link::after { content: ""; position: absolute; top: 50%; width: 18px; border-top: 2px dashed var(--fs-tl-line); }
.fint-link::before { right: 100%; margin-right: 2px; }
.fint-link::after  { left: 100%;  margin-left: 2px; }
/* The match badge under a store key (Stores tab): a small Mud text button in sentence case, flush with the key above it.
   Mud colours it (Success, Warning, Error); the class only trims Mud's button metrics. */
.fint-keylink.fint-keylink { text-transform: none; letter-spacing: 0; font-size: 12px; font-weight: 600; min-width: 0;
                             padding: 0 4px; margin-left: -4px; line-height: 1.6; }
/* The store opened from its match badge (match tab): a card over the list, and its row washed in the list. */
.fint-focus.fint-focus { padding: 12px 16px; border-radius: 12px; border-color: var(--fs-tl-line); }
.fint-focus .fint-focus-grid { margin-top: 4px; }
.fint-grid .fint-focus-row > td { background: var(--mud-palette-action-default-hover); }
.fint-default { color: var(--fs-text-secondary); }

@media (prefers-reduced-motion: reduce) {
    .fint-dot.fint-dot-on { animation: none; }
    .fint-tile.fint-tile, .fint-tile.fint-tile:hover { transition: none; transform: none; }
}

/* ── fitview 10/26 (R. Nugent; Gate 1 signed off 10/26): the Snow pages fill the window and fit every screen. ──────────────────────
   The Snow Tracker grid, the Snow Tracker Map and the client's Storm Status. The pages' own parts are in
   Pages/SnowTracker20.razor.css and Shared/SnowMapsCanvas.razor.css; what is here is the shell (MainLayout's elements) and the
   shared components' Mud roots, which a scoped sheet cannot reach. fs-dense marks a Snow page (the grid's body and the map's
   column), and every rule here sits under it or a :has() on it, so the rest of FasCentral draws exactly as before. Mud's sheet
   loads after this one, so a rule that meets one of Mud's repeats a class to win (house gotcha). Tokens only. */

/* 1. Fill the window. Above a phone the page's main column is a flex column and its article grows to fill it, so the grid's
   rows or the map can take whatever height is left (the pages carry it down from there). The shell already stands the full
   height of the window (MainLayout.razor.css); the padding keeps the pager or the summary off the window's bottom edge. */
@media (min-width: 720.02px) and (min-height: 500.02px), (min-width: 720.02px) and (orientation: portrait) {
    .fc-main:has(.fs-dense) { display: flex; flex-direction: column; }
    .fc-main:has(.fs-dense) > article { flex: 1 0 auto; display: flex; flex-direction: column; padding-bottom: 12px; }
}

/* 2. The summary cards (SnowKpiRow, a MudGrid root keyed on skr) by the room the row has, not by the screen. The row is its own
   container, so the menu and the side panel being open or folded no longer matter: six across where they fit at a readable
   width, then three, then two; the client's four go four or two. A title keeps to one line and ends in an ellipsis rather
   than wrapping; two across on a phone it may take two lines. MudItem's own columns stay underneath as the fallback. The widths are the card at the theme's size. */
.mud-grid.skr { container-type: inline-size; }
.mud-grid.skr .fkc-label.fkc-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@container (min-width: 1150px) { .mud-grid.skr > .mud-grid-item { flex: 0 0 16.6667%; max-width: 16.6667%; } }
@container (min-width: 540px) and (max-width: 1149.98px) { .mud-grid.skr > .mud-grid-item { flex: 0 0 33.3333%; max-width: 33.3333%; } }
@container (max-width: 539.98px) { .mud-grid.skr > .mud-grid-item { flex: 0 0 50%; max-width: 50%; } }
@container (min-width: 720px) { .mud-grid.skr:not(:has(> .mud-grid-item:nth-child(5))) > .mud-grid-item { flex: 0 0 25%; max-width: 25%; } }
@container (max-width: 719.98px) { .mud-grid.skr:not(:has(> .mud-grid-item:nth-child(5))) > .mud-grid-item { flex: 0 0 50%; max-width: 50%; } }
@container (max-width: 539.98px) { .mud-grid.skr .fkc-label.fkc-label { white-space: normal; font-size: 10.5px; letter-spacing: .03em; line-height: 1.35; } }

/* 2b. A tablet (a window 720 to 1199px wide, or a touch screen above a phone): a tablet layout rather than a squeezed desktop. The
   title and the summary cards compact so the grid starts higher; the grid's name columns are in SnowTracker20.razor.css. */
@media (min-width: 720.02px) and (max-width: 1199.98px), (min-width: 720.02px) and (pointer: coarse) {
    .fs-dense .mud-typography-h4.mud-typography-h4 { font-size: 1.75rem; }
    .fs-dense .fkc-hit.fkc-hit { padding: 9px 12px 9px 15px; }
    .fs-dense .fkc-card .mud-typography-h5.mud-typography-h5 { font-size: 1.3rem; line-height: 1.3; }
}

/* 3. A phone (767px and under, or a short touch screen turned sideways), the spec's section 6. The page's own green bar goes (the FasCentral
   bar above it stays: it is the way to the menu), the side padding tightens, and the title, the cards and the filter bar
   compact: the filters two to a row, search and the buttons each on a row of their own. The article's side padding needs
   !important to meet MainLayout's own, which carries one (MainLayout.razor.css says why). */
@media (max-width: 767.98px), (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
    .fc-main:has(.fs-dense) .fpb.fpb { display: none; }
    .fc-main:has(.fs-dense) > article.content { padding-left: 10px !important; padding-right: 10px !important; }
    .fs-dense .mud-typography-h4.mud-typography-h4 { font-size: 1.6rem; }
    .fs-dense .fkc-hit.fkc-hit { padding: 9px 10px 9px 13px; }
    .fs-dense .fkc-card .mud-typography-h5.mud-typography-h5 { font-size: 1.25rem; }
    #st-filterbar .mud-paper > .d-flex { display: grid !important; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
    #st-filterbar .fvc { grid-column: 1 / -1; border-right: 0; }
    #st-filterbar .vsp-week { grid-column: 1 / -1; }   /* stbar 11/02: the Service Tracker's bar takes this phone layout too (its Week) */
    #st-filterbar .flex-grow-1 { grid-column: 1 / -1; }
    #st-filterbar .st-search.st-search { flex-basis: 100%; max-width: none; }
}

/* 4. prodtype 10/27 (R. Nugent; Gate 1 signed off 10/27): the 80% look is retired, and the dialogs' with it (fitdlg 10/26). On a
   mouse screen the Snow pages drew themselves at 80% (the root size, and each shared part's pixel measure at four fifths), and the
   team keeps fascentral.io at 80% browser zoom, so the two stacked to 64% and the type read too small. The pages and their dialogs
   draw at the theme's own size now, PROD's, as every other page does, and the browser's zoom is the one size control. Parts 1 to
   3 (the fill, the cards by room, tablets, phones) and the fit rules in the pages' and dialogs' own sheets are unchanged. */

/* sitelock 10/27 (R. Nugent; Gate 1 signed off 10/27 on Claude outputs/Snow-Tracker-Site-Lock-Gate1-2026-10-27.png): who is in a
   site. The grid's lock eye (in a MudTooltip), the filter strip's legend, Site in use (its lines are built in code) and the read-only
   window's lines, so one global block where a scoped sheet cannot reach. Colours read tokens; the eye is the KPI cards' amber. */
:root { --fs-lock-eye: var(--fs-kpi-warn); }
.fslock-slot { display: inline-flex; align-items: center; justify-content: center; width: 22px; vertical-align: middle; }
.fslock-eye { display: inline-flex; align-items: center; color: var(--fs-lock-eye); }
svg.fslock-eye { width: 20px; height: 20px; flex: none; }
.fslock-tip-t { font-weight: 700; }
.fslock-tip-d { opacity: .85; }
.fslock-q { display: flex; align-items: center; gap: 10px; }
.fslock-pop-line { margin-top: 6px; font-size: 12.5px; line-height: 1.5; color: var(--fs-text-secondary); }
.fslock-pop-hint { margin-top: 10px; padding: 10px 12px; border: 1px solid var(--mud-palette-lines-default); border-radius: var(--fs-radius-md);
                   background: var(--fs-kpi-surface); font-size: 12px; line-height: 1.5; color: var(--fs-text-muted); }
.fslock-wait { margin-top: 4px; font-size: 12px; color: var(--fs-warn-text); }
.fslock-gotit { margin-bottom: var(--fs-gap-md); padding: 10px 14px; border: 1px solid var(--fs-kpi-success-fg); border-radius: var(--fs-radius-md);
                background: var(--fs-kpi-success-bg); color: var(--fs-kpi-good); font-size: 13px; font-weight: 600; }
.ffch-legend { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; font-size: 12px; font-weight: 600; color: var(--fs-text-secondary); }
.ffch-legend + .ffch-clear.ffch-clear { margin-left: 10px; }

/* erdgrid 10/27 (Gate 1 signed off 10/27, E. Haag): the house grid look, and ER Dispatch Manager's grid.
   fas-grid is the Snow Tracker 2.0 header and cell look (SnowTracker20.razor.css, .stx-grid, gridpar 10/7), written once
   here so a second page can take it. Snow Tracker 2.0 keeps its own copy until it moves onto this class in its own change.
   Global, not scoped: these reach MudTable's own cells, which a scoped sheet cannot (house gotcha). Tokens only. */
.fas-grid .mud-table-root .mud-table-row .mud-table-cell {
    padding: 6px 7px;
}

.fas-grid .mud-table-root .mud-table-head .mud-table-cell {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.fas-grid .mud-table-root .mud-table-body td.mud-table-cell {
    font-size: 12.5px;
}

    .fas-grid .mud-table-root .mud-table-body td.mud-table-cell .mud-typography-body2 {
        font-size: inherit;
    }

.fas-grid .mud-table-sort-label .mud-table-sort-label-icon:not(.mud-direction-asc):not(.mud-direction-desc) {
    display: none;
}

.fas-grid td.mud-table-cell .fsp {
    font-size: inherit;
    font-weight: inherit;
}

/* ER Dispatch Manager (erdgrid 10/27, detail row 10/28). The page's inline style block, moved here as tokens; same colours
   as before. The frozen header needs the table's own scroll box to have a height: 240px is the bar, the filter bar, the
   pager and the page padding. Zebra comes from RowClass (erd-row-alt), not nth-child, so an open detail row does not
   shift the stripes. Zebra, hover and the active row repeat Mud's table selector chain so they outrank its hover rule. */
.erd-toolbar {
    padding: 14px 18px 0;
}

    .erd-toolbar .erd-search {
        flex: 0 0 240px;
    }

    .erd-toolbar .erd-pending {
        min-width: 170px;
    }

.erd-alert.erd-alert {
    margin: 12px 18px 0;
}

.erd-grid {
    padding: 14px 18px 18px;
}

    .erd-grid .mud-table-container {
        max-height: calc(100vh - 240px);
        overflow: auto;
    }

    .erd-grid table.mud-table-root {
        min-width: 1650px;
    }

    .erd-grid .mud-table-root .mud-table-head .mud-table-cell {
        white-space: nowrap;
    }

    .erd-grid .mud-table-root .mud-table-row .mud-table-cell.erd-chev-cell {
        width: 34px;
        padding: 0 2px;
    }

    .erd-grid .mud-table-container .mud-table-root .mud-table-body tr.mud-table-row {
        cursor: pointer;
    }

        .erd-grid .mud-table-container .mud-table-root .mud-table-body tr.mud-table-row.erd-row-alt {
            background: var(--fs-erd-zebra);
        }

        .erd-grid .mud-table-container .mud-table-root .mud-table-body tr.mud-table-row:hover {
            background: var(--mud-palette-table-hover);
        }

        .erd-grid .mud-table-container .mud-table-root .mud-table-body tr.mud-table-row.erd-row-active > td {
            background: var(--fs-erd-active-row);
            font-weight: 600;
        }

            .erd-grid .mud-table-container .mud-table-root .mud-table-body tr.mud-table-row.erd-row-active > td:first-child {
                box-shadow: inset 4px 0 0 var(--fs-erd-accent);
            }

    .erd-grid .mud-table-container .mud-table-root .mud-table-body td.erd-detail-cell {
        cursor: default;
        padding: 0;
        background: var(--mud-palette-surface);
        border-bottom: 1px solid var(--mud-palette-lines-default);
    }

.erd-act-row {
    display: flex;
    gap: 6px;
    white-space: nowrap;
}

    /* erdaward 11/02 (Eric): the grid's Award button in a dark green instead of Mud's default success (#00C853). */
    .erd-act-row .erd-award-btn:not(.mud-button-disabled) {
        color: var(--fs-erd-award);
        border-color: var(--fs-erd-award);
    }

        .erd-act-row .erd-award-btn:not(.mud-button-disabled):hover {
            background: var(--fs-erd-award-soft);
        }

.erd-bar-btn.erd-bar-btn:not(.mud-button-disabled) {
    border-color: var(--fs-erd-accent);
    color: var(--fs-erd-accent);
    background: var(--mud-palette-surface);
}

    .erd-bar-btn.erd-bar-btn:not(.mud-button-disabled):hover {
        background: var(--fs-erd-accent-soft);
    }

.erd-bar-btn.erd-bar-btn.mud-button-disabled {
    background: var(--fs-status-none-bg);
}

.erd-create-btn.erd-create-btn {
    background: var(--fs-erd-accent);
    color: var(--mud-palette-primary-text);
    font-weight: 700;
}

    .erd-create-btn.erd-create-btn:hover {
        background: var(--fs-erd-accent-hover);
    }

    /* erdfocus 11/04 (Eric): when a dialog closes with the keyboard, focus returns to the top-bar button that opened it.
   Mud's own :focus-visible turned "+ Create ER Dispatch" green; keep the orange and show a ring instead. */
    .erd-create-btn.erd-create-btn:focus-visible {
        background: var(--fs-erd-accent);
        outline: 2px solid var(--fs-erd-accent);
        outline-offset: 2px;
    }

.erd-bar-btn.erd-bar-btn:focus-visible {
    outline: 2px solid var(--fs-erd-accent);
    outline-offset: 2px;
}

/* FasColumnFilter (erdgrid 10/27): the header filter icon and its box. The box is a MudPopover, which renders in
   MudPopoverProvider outside the page, so these rules are global (house gotcha). Tokens only. */
.fcf {
    display: inline-flex;
    vertical-align: middle;
}

    .fcf .fcf-btn {
        padding: 2px;
        margin-left: 2px;
        color: var(--fs-text-muted);
    }

        .fcf .fcf-btn .mud-icon-root {
            font-size: 16px;
            width: 16px;
            height: 16px;
        }

        .fcf .fcf-btn.fcf-on {
            color: var(--mud-palette-primary);
        }

.fcf-pop .fcf-body {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px;
}

    .fcf-pop .fcf-body .mud-input-control {
        width: 160px;
        margin: 0;
    }

/* notechips 10/29 (R. Nugent; Gate 1 signed off 10/29 on Claude outputs/Snow-Tracker-Comment-Type-Chips-Gate1-2026-10-29.png): the comment
   types, the Risk Tracker spec's registry (Comment Type Chips and Bubbles, section 4) on this app's tokens. One class per type sets the ink
   and the tint, and the chip dots (FasCommentChips) and the badges (FasCommentBadge) read them, so a chip and its badges always agree. A
   class the registry does not know falls back to the Status pair. Both components root on Mud parts, so their rules live here (section 11). */
.fct-user    { --fct-ink: var(--fs-note-user);    --fct-tint: var(--fs-note-user-bg); }
.fct-client  { --fct-ink: var(--fs-note-client);  --fct-tint: var(--fs-note-client-bg); }
.fct-weather { --fct-ink: var(--fs-note-weather); --fct-tint: var(--fs-note-weather-bg); }
.fct-wo      { --fct-ink: var(--fs-note-wo);      --fct-tint: var(--fs-note-wo-bg); }
.fct-status  { --fct-ink: var(--fs-note-status);  --fct-tint: var(--fs-note-status-bg); }
.fct-vendor  { --fct-ink: var(--fs-note-vendor);  --fct-tint: var(--fs-note-vendor-bg); }
/* mobilechips 10/29 (Gate 1 signed off 10/29): the two types it adds. */
.fct-mobile  { --fct-ink: var(--fs-note-mobile);  --fct-tint: var(--fs-note-mobile-bg); }
.fct-system  { --fct-ink: var(--fs-note-system);  --fct-tint: var(--fs-note-system-bg); }
.fcb { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 10.5px; font-weight: 600; line-height: 1.2; white-space: nowrap;
       color: var(--fct-ink, var(--fs-note-status)); background: var(--fct-tint, var(--fs-note-status-bg)); }
.fcc { display: flex; flex-wrap: wrap; gap: 2px; }
.fcc-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; flex: none;
           background: var(--fct-ink, var(--fs-note-status)); }
.fcc-count { margin-left: 5px; font-weight: 600; opacity: .75; }

/* mudicons 11/02 (R. Nugent: "all FontAwesome anywhere replaced with mudblazor all in one shot - no exceptions"; Gate 1 signed off
   11/02). Icons are MudBlazor (MudIcon with Icons.Material.*); the standard's rule 14 and build check FAS0014 keep it that way.
   fs-ico is a MudIcon set in running text, in a button or in a chip: its box follows the text around it, as the old icons did, so
   a rule that sizes an icon by font size still does. The box is 1.2em because a Material glyph sits inside a margin of its 24 grid
   and draws a median 1/1.2 the size of the old glyph in the same box (measured on all 79 icons on 11/02); it sits on the text the
   way they did. svg.fs-ico outranks Mud's own size class (.mud-icon-size-medium) whatever the order of the stylesheets, and a
   context rule that sizes, spaces or colours its icons names two classes or more, so it outranks this. */
svg.fs-ico { font-size: inherit; width: 1.2em; height: 1.2em; margin: 0; vertical-align: -0.225em; }
/* An icon that is the button itself (a chip's remove x): the span carries the click, the role, the focus and the label. */
.fs-ico-btn { display: inline-flex; align-items: center; cursor: pointer; }
/* fs-spin: MudProgressCircular, the house wait spinner, where a spinning icon sat in a line of text. */
.fs-spin.fs-spin.fs-spin { width: 1.2em; height: 1.2em; vertical-align: -0.225em; }

/* photozip 11/02 (R. Nugent, Gate 1 signed off 11/02): FasPhotoZipLink, the staff Download (.zip) on a set of check-in photos.
   Its root is a Mud component (MudElement as an anchor), so its rules live here, keyed on its class, on tokens. A host's own link
   rule wins where it has one (the Service Tracker's check-ins window colours it like its View all link); elsewhere it reads in
   the theme's primary. The icon is the house fs-ico; Compact sizes it for a header row and sits at the row's end. */
.fpz { display: inline-flex; align-items: baseline; gap: 2px; color: var(--mud-palette-primary); font-weight: 600;
       text-decoration: none; white-space: nowrap; cursor: pointer; }
.fpz svg.fs-ico { align-self: center; }   /* the text sets the line, so the link sits on the count line's baseline */
.fpz:hover { text-decoration: underline; }
.fpz:focus-visible { outline: 2px solid var(--mud-palette-primary); outline-offset: 2px; border-radius: 3px; }
.fpz-block { display: flex; width: fit-content; margin-top: 6px; font-size: 12px; }
.fpz-compact { margin-left: auto; padding: 2px; border-radius: 4px; }
.fpz-compact:hover { text-decoration: none; opacity: .8; }
.fpz-compact svg.fs-ico { width: 18px; height: 18px; }

/* ── FasViewChips (stbar 11/02, R. Nugent; Gate 1 signed off 11/02): the VIEW group at the start of the Snow Tracker 2.0 and Service
   Tracker tool bars (My stores and NVA on Snow, NVA on the Service Tracker). The values are Snow's VIEW row's (four 9/30, toolbar
   9/30), moved here unchanged from SnowTracker20.razor.css, because the root is a Mud component, which a scoped sheet cannot reach.
   The chips are MudChip and keep Mud's own look; only the group, its label and the counts are ours. The group opens the bar, set
   off from the filters by a rule. Tokens only. */
.fvc { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 2px 0 0; padding-right: 10px;
       border-right: 1px solid var(--mud-palette-lines-default); }
.fvc-label { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; color: var(--fs-text-muted); margin-right: 4px; }
.fvc-n { font-weight: 700; margin-left: 4px; opacity: .85; }

/* ── ServiceTrackerKpiRow (stbar 11/02, R. Nugent; Gate 1 signed off 11/02): the Service Tracker's cards (FasKpiCard v2) by the room
   the row has, not by the screen, as SnowKpiRow's are (fitview 10/26): five across where they fit at a readable width, then three,
   then two; the client's three go three, or two on a phone. A title keeps to one line and ends in an ellipsis rather than wrapping;
   on a phone it may take two lines. The row is a MudGrid root, which a scoped sheet cannot reach, so the rules are here, keyed on
   stkr; MudItem's own columns stay underneath as the fallback. */
.mud-grid.stkr { container-type: inline-size; }
.mud-grid.stkr .fkc-label.fkc-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@container (min-width: 1000px) { .mud-grid.stkr > .mud-grid-item { flex: 0 0 20%; max-width: 20%; } }
@container (min-width: 540px) and (max-width: 999.98px) { .mud-grid.stkr > .mud-grid-item { flex: 0 0 33.3333%; max-width: 33.3333%; } }
@container (max-width: 539.98px) { .mud-grid.stkr > .mud-grid-item { flex: 0 0 50%; max-width: 50%; } }
@container (min-width: 540px) { .mud-grid.stkr:not(:has(> .mud-grid-item:nth-child(4))) > .mud-grid-item { flex: 0 0 33.3333%; max-width: 33.3333%; } }
/* fsreplied 11/3: the client's four (F&S Replied beside its three) go four across where five would, else two by two. */
@container (min-width: 1000px) { .mud-grid.stkr:has(> .mud-grid-item:nth-child(4)):not(:has(> .mud-grid-item:nth-child(5))) > .mud-grid-item { flex: 0 0 25%; max-width: 25%; } }
@container (min-width: 540px) and (max-width: 999.98px) { .mud-grid.stkr:has(> .mud-grid-item:nth-child(4)):not(:has(> .mud-grid-item:nth-child(5))) > .mud-grid-item { flex: 0 0 50%; max-width: 50%; } }
@container (max-width: 539.98px) { .mud-grid.stkr .fkc-label.fkc-label { white-space: normal; font-size: 10.5px; letter-spacing: .03em; line-height: 1.35; } }
