:root {
    /* Radius scale — one card standard everywhere; pills stay full-round. */
    --pi-radius-card: 16px;
    --pi-radius-control: 8px;
    --pi-radius-pill: 999px;

    /* Caption/metadata type scale — two steps below body, not a dozen one-offs. */
    --pi-font-caption: 0.75rem;
    --pi-font-micro: 0.6875rem;

    /* z-index scale. MudBlazor's own portaled overlays (menus/dialogs/snackbars) occupy
       roughly 1200–1400; app-level fixed elements stay below that band except the boot
       splash, which must sit above literally everything until it is dismissed. */
    --pi-z-app-banner: 1000;
    --pi-z-assistant-fab: 1050;
    --pi-z-splash: 9999;
}

/* ── Antigravity treatment ────────────────────────────────────────────────
   The palette lives in PlatinumIntegrationTheme.cs; this is the shape half of
   the same idea, and a deliberate mirror of PlatinumWeigh's block of the same
   name. Two things carry it: pills instead of soft rectangles on anything you
   click, and hairlines instead of drop shadows everywhere.

   Kept OUT of the dark theme on purpose. Dark mode already reads as its own
   product and separates surfaces by lightness rather than by border; forcing a
   1px hairline onto a dark card just makes it look sketched. The `pi-dark`
   marker class is set by js/boot.js — MudBlazor signals the theme through CSS
   variables alone, so a stylesheet has nothing else to branch on. */
.mud-button-root:not(.mud-icon-button):not(.mud-button-fab) {
    border-radius: var(--pi-radius-pill);
    padding-inline: 20px;
}
.mud-chip { border-radius: var(--pi-radius-pill); }

/* Elevation is the app's own decision (cards, tables, the site-health strip),
   so MudBlazor's ambient shadows are turned off rather than fought
   component-by-component. A surface separates itself with a hairline. */
:root:not(.pi-dark) .mud-paper:not(.mud-drawer):not(.mud-appbar):not(.mud-popover) {
    box-shadow: none;
}
:root:not(.pi-dark) .mud-appbar {
    box-shadow: none;
    border-bottom: 1px solid var(--mud-palette-divider);
}
:root:not(.pi-dark) .mud-drawer {
    border-right: 1px solid var(--mud-palette-divider);
}
:root:not(.pi-dark) .mud-input-outlined .mud-input-outlined-border {
    border-color: var(--mud-palette-lines-default);
}

/* Data tables read as content cards, matching PlatinumWeigh: one flat bordered
   surface, a tinted header band so column names register at a glance on a long
   list, and tabular figures so a column of tonnages lines up instead of reading
   ragged — the single most common way a data screen looks unfinished. */
.mud-table {
    border: 1px solid var(--mud-palette-divider);
    border-radius: var(--pi-radius-card);
    overflow: hidden;
}
.mud-card .mud-table,
.mud-expand-panel .mud-table {
    border: none;
    border-radius: 0;
}
.mud-table .mud-table-head .mud-table-cell {
    background: var(--mud-palette-background-grey);
    font-weight: 600;
    white-space: nowrap;
}
.mud-table .mud-table-cell { font-variant-numeric: tabular-nums; }

html, body {
    font-family: Inter, 'Segoe UI', system-ui, Roboto, Helvetica, Arial, sans-serif;
}

a, .btn-link {
    color: #006bb7;
}

.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;
}

h1:focus {
    outline: none;
}
h1:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.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."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* Platinum Brink UI Custom Styles */
.pi-quick-tile {
  cursor: pointer;
  transition: transform .2s, box-shadow .2s;
  border-radius: var(--pi-radius-card);
}
.pi-quick-tile:hover  { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,0,0,.08); }
.pi-quick-tile:active { transform: translateY(0);    box-shadow: 0 4px 10px rgba(0,0,0,.05); }
.pi-quick-tile:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}
.pi-quick-tile--gradient {
    color: #fff !important;
}
.pi-quick-tile--gradient .mud-typography {
    color: inherit !important;
}
.pi-quick-tile--gradient .mud-typography.mud-typography-body2 {
    color: rgba(255,255,255,0.75) !important;
}

/* Shared KPI summary card — used by Home.razor's dashboard tiles and Analytics.razor's KPI row so
   both pages present the same "metric card" pattern instead of two different ones.
   Border at rest, shadow only appears on hover — never both at once ("ghost card"). */
.pi-kpi-card {
    padding: 1.5rem;
    border-radius: var(--pi-radius-card) !important;
    border: 1px solid var(--mud-palette-divider);
    background: var(--mud-palette-surface);
    position: relative;
    overflow: hidden;
    transition: transform 0.18s, box-shadow 0.18s, border-color 0.18s;
}
.pi-kpi-card:hover {
    transform: translateY(-2px);
    border-color: transparent;
    box-shadow: 0 12px 28px rgba(0,0,0,0.12) !important;
}
/* Gradient hero cards (Ecosystem Health on Home) — coloured background with white text. */
.pi-kpi-card--gradient {
    border: none;
    color: #fff !important;
}
.pi-kpi-card--gradient .mud-typography {
    color: inherit !important;
}
.pi-kpi-card--gradient .mud-typography.mud-typography-subtitle2 {
    color: rgba(255,255,255,0.7) !important;
}
.pi-kpi-card--gradient .mud-typography.mud-typography-body2 {
    color: rgba(255,255,255,0.8) !important;
}
.pi-kpi-icon {
    width: 44px; height: 44px; border-radius: var(--pi-radius-control);
    display: flex; align-items: center; justify-content: center;
}
.pi-kpi-sub {
    display: flex; align-items: center; gap: 4px;
    font-size: var(--pi-font-caption); font-weight: 600;
    margin-top: 0.4rem;
}

/* Press/tap feedback — a small physical-feeling scale-down on press, state-only (not decorative),
   matching DESIGN.md's product-register motion rules (150-250ms, transform/opacity only). */
.mud-button-root:active {
    transform: scale(0.97);
}
.mud-button-root {
    transition: transform 0.1s ease-out;
}
#splash-screen {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: var(--pi-z-splash, 9999);
    display: flex;
    align-items: center;
    justify-content: center;
}
#splashCanvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
.splash-overlay {
    position: relative;
    z-index: 10;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.splash-logo-wrap {
    position: relative;
    width: 120px;
    height: 120px;
    margin-bottom: 2rem;
}
.splash-logo {
    width: 100%;
    height: 100%;
    position: relative;
    z-index: 2;
}
.splash-glow {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 140%;
    height: 140%;
    transform: translate(-50%, -50%);
    background: radial-gradient(circle, rgba(0,51,102,0.15) 0%, rgba(0,51,102,0) 70%);
    z-index: 1;
}
.splash-tagline {
    font-family: Inter, 'Segoe UI', system-ui, sans-serif;
    color: #64748b;
    font-size: 0.9rem;
    font-weight: 500;
    letter-spacing: 0.5px;
}

/* ── Edition trend chart (EditionTrend.razor) ────────────────────────────────────
   A 0–100 viewBox stretched edge-to-edge with preserveAspectRatio="none", so the
   chart fills any column width. That stretch is non-uniform, which is exactly why
   every stroke carries vector-effect:non-scaling-stroke — without it the line
   thins horizontally and thickens vertically as the container changes shape.
   Colour comes from the theme, so it tracks light and dark without a second
   palette. */
.pi-trend { position: relative; width: 100%; height: 190px; }
.pi-trend-svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; overflow: visible; }
.pi-trend-grid {
    stroke: var(--mud-palette-divider);
    stroke-width: 1;
    stroke-dasharray: 3 4;
    opacity: 0.6;
}
.pi-trend-line { stroke: var(--mud-palette-primary); stroke-width: 2; stroke-linejoin: round; }
.pi-trend-area { fill: var(--mud-palette-primary); opacity: 0.10; }
/* The peak, labelled in HTML rather than SVG text so it never scales unevenly. */
.pi-trend-peak {
    position: absolute; top: 4px; left: 0;
    font-size: var(--pi-font-caption); font-weight: 600;
    color: var(--mud-palette-text-secondary);
    background: var(--mud-palette-surface);
    padding: 1px 6px; border-radius: var(--pi-radius-control);
    font-variant-numeric: tabular-nums;
}
.pi-trend-axis {
    display: flex; justify-content: space-between;
    margin-top: 6px;
    font-size: var(--pi-font-caption);
    color: var(--mud-palette-text-secondary);
}

/* ── Grouped bar chart (EditionTrend.razor) ──────────────────────────────────────
   Replaced the line/area SVG on 2026-08-21 at the client's request: bars, landfilled
   beside diverted, figures on hover. HTML rather than SVG because each bar needs a
   tooltip anchored to it, which is a positioned child here and a fight inside a
   stretched viewBox.

   Landfilled uses the theme's primary ink and diverted the success green — the same
   pairing the KPI cards already use for those two figures, so the chart and the cards
   above it never disagree about which colour means what. */
.pi-bars {
    display: flex; align-items: flex-end; justify-content: center; gap: 6px;
    width: 100%; height: 200px;
}
/* Column per bucket: optional value on top, the bars, optional label underneath — the same
   stacking order and bottom alignment the Fleet page's monthly columns use. */
/* Capped so a 5-bucket window clusters in the middle instead of stringing five hairlines across
   the full page width; a 30-bucket window is under the cap anyway and fills as normal. */
.pi-bars-slot {
    position: relative;
    flex: 1 1 0; min-width: 0; max-width: 110px; height: 100%;
    display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
}
.pi-bars-group {
    flex: 1 1 auto;
    display: flex; align-items: flex-end; justify-content: center; gap: 3px;
    width: 100%; min-height: 0;
}
.pi-bar {
    flex: 1 1 0; min-width: 0; max-width: 34px;
    border-radius: 6px 6px 2px 2px;
    transition: filter .15s ease;
}
/* One bar per bucket gets the full Fleet-column width; a pair splits it. */
.pi-bar--total { max-width: 48px; }
.pi-bar--landfilled, .pi-bar--total {
    background: linear-gradient(180deg, var(--mud-palette-primary), color-mix(in srgb, var(--mud-palette-primary) 45%, transparent));
}
.pi-bar--diverted {
    background: linear-gradient(180deg, var(--mud-palette-success), color-mix(in srgb, var(--mud-palette-success) 45%, transparent));
}
.pi-bars-slot:hover .pi-bar { filter: brightness(1.12); }

/* Stacked-by-site bar. column-reverse so the first (largest) segment sits at the BOTTOM, which keeps
   the biggest contributor on the baseline where the eye compares bars against each other. */
.pi-bar--stack {
    display: flex; flex-direction: column-reverse;
    max-width: 48px; overflow: hidden;
}
.pi-bar-seg { width: 100%; flex: 0 0 auto; }
/* Only the visually topmost segment carries the rounded cap. */
.pi-bar--stack .pi-bar-seg:last-child { border-radius: 6px 6px 0 0; }
.pi-bars-label {
    flex: 0 0 auto;
    margin-top: 6px; font-size: var(--pi-font-micro);
    color: var(--mud-palette-text-secondary); font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}

/* Tooltip. Hidden rather than absent so there is no layout shift on hover. */
.pi-bars-tip {
    position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
    display: flex; flex-direction: column; gap: 2px;
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-divider);
    border-radius: 10px;
    box-shadow: 0 6px 18px rgba(0,0,0,.14);
    padding: 8px 12px;
    font-size: var(--pi-font-caption);
    color: var(--mud-palette-text-primary);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity .12s ease;
    z-index: 5;
}
.pi-bars-slot:hover .pi-bars-tip { opacity: 1; visibility: visible; }
/* The first and last few slots would otherwise push their tooltip off the chart edge. */
.pi-bars-slot:first-child .pi-bars-tip,
.pi-bars-slot:nth-child(2) .pi-bars-tip { left: 0; transform: none; }
.pi-bars-slot:last-child .pi-bars-tip,
.pi-bars-slot:nth-last-child(2) .pi-bars-tip { left: auto; right: 0; transform: none; }
.pi-bars-tip-total { border-top: 1px solid var(--mud-palette-divider); margin-top: 2px; padding-top: 3px; }
/* Phone widths: drop the hover card entirely.
   It is hidden, not absent, so it stays in the layout — and a ~214px card centred on a middle column
   reaches past a 390px viewport and makes the whole PAGE scroll sideways (caught by visual-audit.js on
   /fleet, 402px vs 390px). Nothing is lost: a hover card is a pointer affordance and touch devices can
   never open it. The bars, their labels and the legend all still read. */
@media (max-width: 600px) {
    .pi-bars-tip { display: none; }
}

/* ── Site tab strip (Landfill page) ──────────────────────────────────────────────
   Underline tabs rather than pills, deliberately: the period selector directly below is
   already a pill chipset, and two pill rows stacked read as one confusing control. An
   underline says "you are looking at a different slice", which is what a tab means. */
.pi-tabs {
    display: flex; align-items: flex-end; gap: 4px;
    border-bottom: 1px solid var(--mud-palette-divider);
    margin-bottom: 20px; overflow-x: auto;
}
.pi-tab {
    appearance: none; background: none; border: 0; cursor: pointer;
    padding: 8px 14px 10px;
    font: inherit; font-size: 0.875rem; font-weight: 600;
    color: var(--mud-palette-text-secondary);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;                 /* sit the underline ON the strip's rule */
    white-space: nowrap;
    display: inline-flex; align-items: center; gap: 7px;
    transition: color .12s ease, border-color .12s ease;
}
.pi-tab:hover { color: var(--mud-palette-text-primary); }
.pi-tab--active {
    color: var(--mud-palette-text-primary);
    border-bottom-color: var(--mud-palette-primary);
}
/* The tab's dot is the same colour that site's segments use in the stacked chart, so the strip
   doubles as the chart's key. */
.pi-tab-dot { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 auto; }

/* Legend + tooltip swatches. */
.pi-bar-key {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: var(--pi-font-caption);
    color: var(--mud-palette-text-secondary);
}
.pi-bar-swatch { width: 10px; height: 10px; border-radius: 3px; display: inline-block; flex: 0 0 auto; margin-right: 5px; }
.pi-bar-key .pi-bar-swatch { margin-right: 0; }
.pi-bar-swatch--landfilled { background: var(--mud-palette-primary); }
.pi-bar-swatch--diverted   { background: var(--mud-palette-success); }

/* ── Waste-mix doughnut (LandfillWasteMix.razor) ─────────────────────────────────
   A conic-gradient div, hollowed with a radial MASK rather than an inner disc: the
   panel sits directly on the page, so an inner circle painted in --mud-palette-surface
   would read as a pale plug against --mud-palette-background. A mask makes the hole
   genuinely transparent, so it is right on both, and in dark mode.

   No SVG, for the same reason the bar chart is HTML: the centred total is a normally-
   positioned child here rather than a fight inside a stretched viewBox. */
.pi-donut-wrap {
    position: relative;
    width: 100%; max-width: 190px; aspect-ratio: 1;
    margin: 0 auto 14px;
}
.pi-donut {
    width: 100%; height: 100%; border-radius: 50%;
    /* 56% hole: a band thick enough that a 3% arc is still a visible wedge rather than a hairline,
       while leaving room for a five-digit tonnage in the middle. */
    -webkit-mask: radial-gradient(circle, transparent 55.5%, #000 56%);
    mask: radial-gradient(circle, transparent 55.5%, #000 56%);
}
.pi-donut-center {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    pointer-events: none; text-align: center;
}
.pi-donut-total {
    font-size: 1.35rem; font-weight: 600; line-height: 1.1;
    color: var(--mud-palette-text-primary);
    font-variant-numeric: tabular-nums;
}
.pi-donut-unit {
    font-size: var(--pi-font-micro);
    color: var(--mud-palette-text-secondary);
    letter-spacing: .04em; text-transform: uppercase;
}
.pi-donut-legend { display: flex; flex-direction: column; gap: 6px; }
.pi-donut-legend-row {
    display: flex; align-items: center; gap: 8px;
    font-size: var(--pi-font-caption);
    color: var(--mud-palette-text-primary);
}
/* Name takes the slack and truncates; the percentage is the column the eye scans down, so it is
   right-aligned on a fixed width and never shifts between rows. */
.pi-donut-legend-name {
    flex: 1 1 auto; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pi-donut-legend-pct {
    flex: 0 0 auto; font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* ── Data completeness panel (DataCompleteness.razor) ────────────────────────────
   A findings list, not a table: each row carries a sentence about what the gap breaks
   and what to do, and neither wraps sensibly in a column. */
.pi-dq-list { display: flex; flex-direction: column; }
.pi-dq-row {
    display: flex; gap: 12px;
    padding: 12px 0;
    border-top: 1px solid var(--mud-palette-divider);
}
.pi-dq-row:first-child { border-top: 0; padding-top: 0; }
/* A passing check is a reassurance, not a finding — it recedes. */
.pi-dq-row--ok { opacity: .62; }
.pi-dq-dot {
    flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%;
    margin-top: 6px;
}
.pi-dq-body { min-width: 0; flex: 1 1 auto; }
.pi-dq-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; }
.pi-dq-title { font-weight: 600; font-size: 0.9rem; color: var(--mud-palette-text-primary); }
.pi-dq-badge {
    font-size: var(--pi-font-micro); font-weight: 700;
    padding: 1px 8px; border-radius: var(--pi-radius-pill);
    text-transform: uppercase; letter-spacing: .03em; white-space: nowrap;
}
.pi-dq-scale {
    font-size: var(--pi-font-caption); font-weight: 700;
    color: var(--mud-palette-text-secondary);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Which deployment, set apart so it reads as a location rather than part of the count. */
.pi-dq-where {
    font-size: var(--pi-font-caption); color: var(--mud-palette-text-secondary);
    border-left: 1px solid var(--mud-palette-divider); padding-left: 8px;
}
.pi-dq-line {
    font-size: var(--pi-font-caption); color: var(--mud-palette-text-secondary);
    margin-top: 3px; line-height: 1.5;
}
.pi-dq-eg { font-style: italic; }

/* ── Period-over-period change chip (DeltaChip.razor) ────────────────────────────
   Colour carries meaning (up=good/green, down=bad/red), but never colour alone — the
   ▲/▼/— glyph + sign keep it legible for colour-vision-deficient users and in mono. */
.pi-delta {
    display: inline-flex; align-items: center;
    font-size: var(--pi-font-caption); font-weight: 700;
    padding: 2px 8px; border-radius: var(--pi-radius-pill);
    white-space: nowrap; line-height: 1.4;
}
.pi-delta-up   { color: #0e7c4a; background: color-mix(in srgb, #10B981 16%, transparent); }
.pi-delta-down { color: #b42318; background: color-mix(in srgb, #EF4444 16%, transparent); }
.pi-delta-flat { color: var(--mud-palette-text-secondary); background: var(--mud-palette-divider); }

/* ── Seasonality / busiest-times mini bar columns ───────────────────────────────── */
.pi-season-bars {
    display: flex; align-items: flex-end; gap: 4px;
    height: 130px; width: 100%;
}
.pi-season-col {
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
    height: 100%;
}
.pi-season-fill {
    width: 100%; max-width: 34px;
    border-radius: 6px 6px 2px 2px;
    background: linear-gradient(180deg, var(--mud-palette-primary), color-mix(in srgb, var(--mud-palette-primary) 55%, transparent));
    transition: filter .15s ease;
    min-height: 2px;
}
.pi-season-col:hover .pi-season-fill { filter: brightness(1.12); }
.pi-season-fill.pi-season-peak {
    background: linear-gradient(180deg, var(--mud-palette-tertiary), color-mix(in srgb, var(--mud-palette-tertiary) 55%, transparent));
}
.pi-season-label {
    margin-top: 6px; font-size: var(--pi-font-micro);
    color: var(--mud-palette-text-secondary); font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}

/* ── Busiest-time-of-day banner — a stated fact instead of a squashed 24-bar chart ── */
.pi-hour-banner {
    display: inline-flex; align-items: center; gap: 10px;
    padding: 10px 16px; border-radius: var(--pi-radius-pill);
    background: color-mix(in srgb, var(--mud-palette-primary) 12%, transparent);
    font-size: 0.85rem; font-weight: 600;
}
.pi-hour-banner .mud-icon-root { color: var(--mud-palette-primary); }
.pi-hour-banner-sub {
    font-weight: 500; color: var(--mud-palette-text-secondary);
    font-size: var(--pi-font-caption);
}

/* ── Fleet page: monthly fuel-spend columns ─────────────────────────────────────── */
.pi-fleet-bars {
    display: flex; align-items: flex-end; gap: 6px;
    width: 100%;
    /* Grows to fill its card (which is a flex column) so the columns reach the bottom instead of leaving
       dead space under a fixed-height chart; the floor keeps it a chart on a narrow screen. */
    flex: 1 1 auto; min-height: 190px;
}
.pi-fleet-col {
    /* Anchors the hover card below. */
    position: relative;
    flex: 1 1 0; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
    height: 100%;
}
/* Reuses the Landfill chart's hover card verbatim (.pi-bars-tip), so the two charts behave identically. */
.pi-fleet-col:hover .pi-bars-tip { opacity: 1; visibility: visible; }
.pi-fleet-col:first-child .pi-bars-tip { left: 0; transform: none; }
.pi-fleet-col:last-child .pi-bars-tip { left: auto; right: 0; transform: none; }
.pi-fleet-val {
    font-size: var(--pi-font-micro); font-weight: 700;
    color: var(--mud-palette-text-secondary); margin-bottom: 4px; white-space: nowrap;
}
.pi-fleet-fill {
    width: 100%; max-width: 40px; min-height: 2px;
    border-radius: 6px 6px 2px 2px;
    background: linear-gradient(180deg, var(--mud-palette-primary), color-mix(in srgb, var(--mud-palette-primary) 45%, transparent));
    transition: filter .15s ease;
}
.pi-fleet-col:hover .pi-fleet-fill { filter: brightness(1.12); }

/* Stacked by deployment on the All tab. column-reverse so the first (largest) segment sits at the BOTTOM,
   which keeps the biggest contributor on the baseline where the eye compares columns against each other —
   same rule as the Landfill chart's stack.
   ⚠ Must come AFTER .pi-fleet-fill: same specificity, so `background:none` only wins on source order. */
.pi-fleet-fill--stack {
    display: flex; flex-direction: column-reverse;
    overflow: hidden;
    background: none;                 /* the segments paint it; the gradient would show through any gap */
}
.pi-fleet-seg { width: 100%; flex: 0 0 auto; }
/* The parent's overflow:hidden already rounds the cap; this keeps it right if that ever changes. */
.pi-fleet-fill--stack .pi-fleet-seg:last-child { border-radius: 6px 6px 0 0; }
.pi-fleet-label {
    margin-top: 6px; font-size: var(--pi-font-micro);
    color: var(--mud-palette-text-secondary); font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}

/* The Fleet page's horizontal trip-type bars (.pi-hbar-*) and its vehicle-status stacked bar
   (.pi-stacked, .pi-legend-*) were removed on 2026-08-22 along with their CSS — both were replaced by
   doughnuts (Donut.razor), which answer "what is this fleet made of" at a glance and match the rest of
   the product. Nothing else referenced them. */

/* ── Mobile responsiveness ────────────────────────────────────────────────────────
   Systematic rules that prevent overflow, text clipping, and layout breakage at
   every breakpoint. These are the "impeccable" standard — no horizontal scroll,
   no overlapping elements, no text running off the edge on any device. */

/* Page titles scale down on phones so they never wrap awkwardly. */
.pi-page-title {
    word-break: break-word;
    overflow-wrap: break-word;
}
@media (max-width: 599px) {
    .pi-page-title.mud-typography-h4 {
        font-size: 1.5rem !important;
    }
    /* KPI large values shrink to fit without overflow. */
    .pi-kpi-card .mud-typography-h4 {
        font-size: 1.25rem !important;
    }
    .pi-kpi-card .mud-typography-h3 {
        font-size: 1.5rem !important;
    }
    /* The ecosystem health cards on Home.razor. */
    .pi-kpi-card {
        padding: 1rem !important;
    }
    /* Tabs need horizontal scroll when labels are too wide. */
    .mud-tabs-tabbar {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }
    .mud-tabs-tabbar .mud-tab {
        min-width: auto !important;
        padding: 6px 12px !important;
        font-size: 0.8rem !important;
    }
    /* Hide icons in tabs on very small screens to save space. */
    .mud-tabs-tabbar .mud-tab .mud-tab-icon-text .mud-icon-root {
        display: none;
    }
    /* Data grid / table: wrap in a scrollable container to prevent page-level horizontal scroll. */
    .mud-table {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }
    .mud-data-grid {
        overflow-x: auto !important;
    }
    /* Quick-access tiles get a bit less padding. */
    .pi-quick-tile {
        padding: 1.25rem !important;
    }
    .pi-quick-tile .mud-typography-h6 {
        font-size: 1rem !important;
    }
    /* Fleet tab strip: enable horizontal scrolling. */
    .pi-tabs {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .pi-tabs::-webkit-scrollbar {
        display: none;
    }
    /* Report viewer shell: reduce the fixed height so the data fits on screen. */
    .mud-container {
        padding-left: 12px !important;
        padding-right: 12px !important;
    }
}

/* Tablet adjustments (600px–959px). */
@media (min-width: 600px) and (max-width: 959px) {
    .pi-page-title.mud-typography-h4 {
        font-size: 1.75rem !important;
    }
}

/* Global overflow guard: the main content area should never cause page-level horizontal scroll. */
.mud-main-content {
    overflow-x: hidden;
}
/* The container inside main content clips any runaway children. */
.mud-main-content > .mud-container {
    overflow-x: hidden;
    max-width: 100%;
}