/*
 * Climate data theme, on top of Bootstrap 5.3.
 *
 * "Open landscape" identity: a sidebar going from the sky down to green hills, a soft sage canvas, forest green as
 * the action color, sky blue and sun yellow as discreet highlights (the data keeps its own colors). Plus Jakarta Sans
 * for text, Bricolage Grotesque for the titles. Desktop only: the sidebar folds into a rail of icons, not into a
 * phone menu.
 * Colors are tokens redefined for each theme (data-bs-theme on <html>, set by the "theme" Stimulus controller): the
 * dark theme is the same landscape at night. Every Bootstrap component below reads from these tokens.
 */

/* ==========================================================================
   Design tokens
   ========================================================================== */
:root,
[data-bs-theme="light"] {
    --app-bg: #f3f6f0;
    --app-surface: #ffffff;
    --app-surface-muted: #edf2ea;
    --app-surface-sunken: #f6f8f4;
    --app-border: #dfe6da;
    --app-border-strong: #c7d2c1;
    --app-text: #17261f;
    --app-text-muted: #5a6a61;
    --app-text-subtle: #8a988f;

    --app-primary: #1f7a55;
    --app-primary-rgb: 31, 122, 85;
    --app-primary-hover: #186445;
    --app-primary-active: #135238;
    --app-primary-subtle: #e1f0e6;
    --app-primary-border: #b3d9c3;
    --app-on-primary: #ffffff;

    --app-sky: #2f8fce;
    --app-sky-subtle: #e2f0f9;
    --app-sun: #f2b33d;
    --app-sun-subtle: #fdf2d9;
    --app-danger: #c8412f;
    --app-danger-subtle: #fbe9e5;

    --app-backdrop:
        radial-gradient(60rem 30rem at 100% 0%, rgba(47, 143, 206, 0.07), transparent 70%),
        radial-gradient(50rem 30rem at 0% 100%, rgba(31, 122, 85, 0.06), transparent 70%),
        var(--app-bg);

    --app-side-bg: linear-gradient(180deg, #ddeef8 0%, #e9f3ef 45%, #eef4ea 100%);
    --app-side-text: #2c4237;
    --app-side-muted: #6b7f74;
    --app-side-hover: rgba(255, 255, 255, 0.6);
    --app-side-active-bg: #ffffff;
    --app-side-border: rgba(31, 122, 85, 0.12);
    --app-hill-back: #d3e8d6;
    --app-hill-mid: #b4d9bd;
    --app-hill-front: #8cc7a0;
    --app-sun-glow: #ffd166;

    --app-shadow-xs: 0 1px 2px rgba(23, 38, 31, 0.05);
    --app-shadow-sm: 0 0 0 1px rgba(23, 38, 31, 0.04), 0 1px 3px rgba(23, 38, 31, 0.06);
    --app-shadow-md: 0 0 0 1px rgba(23, 38, 31, 0.04), 0 8px 20px -6px rgba(23, 38, 31, 0.12);
    --app-shadow-lg: 0 0 0 1px rgba(23, 38, 31, 0.04), 0 18px 44px -10px rgba(23, 38, 31, 0.22);

    --app-chart-text: #5a6a61;
    --app-chart-grid: rgba(23, 38, 31, 0.08);
    --app-chart-tooltip-bg: #17261f;
    --app-chart-tooltip-title: #ffffff;
    --app-chart-tooltip-body: #dfe8e2;

    --bs-body-color: var(--app-text);
    --bs-body-color-rgb: 23, 38, 31;
    --bs-body-bg: var(--app-bg);
    --bs-body-bg-rgb: 243, 246, 240;
    --bs-emphasis-color: var(--app-text);
    --bs-secondary-color: var(--app-text-muted);
    --bs-secondary-color-rgb: 90, 106, 97;
    --bs-secondary-bg: #e4ebe0;
    --bs-secondary-bg-rgb: 228, 235, 224;
    --bs-tertiary-bg: var(--app-surface-muted);
    --bs-tertiary-bg-rgb: 237, 242, 234;
    --bs-heading-color: var(--app-text);
    --bs-border-color: var(--app-border);
    --bs-border-color-translucent: rgba(23, 38, 31, 0.09);
    --bs-light-rgb: 237, 242, 234;

    --bs-primary: var(--app-primary);
    --bs-primary-rgb: var(--app-primary-rgb);
    --bs-primary-text-emphasis: var(--app-primary-active);
    --bs-primary-bg-subtle: var(--app-primary-subtle);
    --bs-primary-border-subtle: var(--app-primary-border);
    --bs-link-color: var(--app-primary);
    --bs-link-color-rgb: var(--app-primary-rgb);
    --bs-link-hover-color: var(--app-primary-hover);
    --bs-link-hover-color-rgb: 24, 100, 69;
    --bs-focus-ring-color: rgba(var(--app-primary-rgb), 0.25);
}

[data-bs-theme="dark"] {
    --app-bg: #0e1814;
    --app-surface: #15221c;
    --app-surface-muted: #1c2b24;
    --app-surface-sunken: #12201a;
    --app-border: #24362e;
    --app-border-strong: #34493f;
    --app-text: #e5eee8;
    --app-text-muted: #9db0a5;
    --app-text-subtle: #6f8378;

    --app-primary: #5cc995;
    --app-primary-rgb: 92, 201, 149;
    --app-primary-hover: #7dd8ab;
    --app-primary-active: #9be3bf;
    --app-primary-subtle: #173a2a;
    --app-primary-border: #2b5c45;
    --app-on-primary: #062016;

    --app-sky: #6bb8e8;
    --app-sky-subtle: #142c3c;
    --app-sun: #f6c55d;
    --app-sun-subtle: #3a3018;
    --app-danger: #ff8f7d;
    --app-danger-subtle: #3d2421;

    --app-backdrop:
        radial-gradient(60rem 30rem at 100% 0%, rgba(107, 184, 232, 0.06), transparent 70%),
        radial-gradient(50rem 30rem at 0% 100%, rgba(92, 201, 149, 0.05), transparent 70%),
        var(--app-bg);

    --app-side-bg: linear-gradient(180deg, #0c1a28 0%, #0f1f1d 50%, #10201a 100%);
    --app-side-text: #d3e2d9;
    --app-side-muted: #7f9488;
    --app-side-hover: rgba(255, 255, 255, 0.05);
    --app-side-active-bg: rgba(92, 201, 149, 0.14);
    --app-side-border: rgba(255, 255, 255, 0.06);
    --app-hill-back: #142b22;
    --app-hill-mid: #18372a;
    --app-hill-front: #1e4734;
    --app-sun-glow: #e9eef5;

    --app-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
    --app-shadow-sm: 0 0 0 1px rgba(255, 255, 255, 0.03), 0 1px 3px rgba(0, 0, 0, 0.3);
    --app-shadow-md: 0 0 0 1px rgba(255, 255, 255, 0.04), 0 10px 24px -8px rgba(0, 0, 0, 0.5);
    --app-shadow-lg: 0 0 0 1px rgba(255, 255, 255, 0.05), 0 20px 48px -10px rgba(0, 0, 0, 0.6);

    --app-chart-text: #9db0a5;
    --app-chart-grid: rgba(229, 238, 232, 0.08);
    --app-chart-tooltip-bg: #e5eee8;
    --app-chart-tooltip-title: #0e1814;
    --app-chart-tooltip-body: #24362e;

    --bs-body-color: var(--app-text);
    --bs-body-color-rgb: 229, 238, 232;
    --bs-body-bg: var(--app-bg);
    --bs-body-bg-rgb: 14, 24, 20;
    --bs-emphasis-color: #ffffff;
    --bs-secondary-color: var(--app-text-muted);
    --bs-secondary-color-rgb: 157, 176, 165;
    --bs-secondary-bg: #24362e;
    --bs-secondary-bg-rgb: 36, 54, 46;
    --bs-tertiary-bg: var(--app-surface-muted);
    --bs-tertiary-bg-rgb: 28, 43, 36;
    --bs-heading-color: var(--app-text);
    --bs-border-color: var(--app-border);
    --bs-border-color-translucent: rgba(255, 255, 255, 0.08);
    --bs-light-rgb: 28, 43, 36;

    --bs-primary: var(--app-primary);
    --bs-primary-rgb: var(--app-primary-rgb);
    --bs-primary-text-emphasis: var(--app-primary-active);
    --bs-primary-bg-subtle: var(--app-primary-subtle);
    --bs-primary-border-subtle: var(--app-primary-border);
    --bs-link-color: var(--app-primary);
    --bs-link-color-rgb: var(--app-primary-rgb);
    --bs-link-hover-color: var(--app-primary-hover);
    --bs-link-hover-color-rgb: 125, 216, 171;
    --bs-focus-ring-color: rgba(var(--app-primary-rgb), 0.3);
}

:root {
    --app-font: "Plus Jakarta Sans Variable", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --app-font-display: "Bricolage Grotesque Variable", var(--app-font);

    --app-sidebar-width: 17.25rem;
    --app-rail-width: 4.75rem;

    --app-radius-sm: 0.6rem;
    --app-radius: 0.85rem;
    --app-radius-lg: 1.15rem;
    --app-focus-ring: 0 0 0 3px rgba(var(--app-primary-rgb), 0.22);

    --bs-body-font-family: var(--app-font);
    --bs-body-font-size: 0.9375rem;
    --bs-border-radius: var(--app-radius-sm);
    --bs-border-radius-sm: 0.45rem;
    --bs-border-radius-lg: var(--app-radius);
    --bs-border-radius-xl: var(--app-radius-lg);
    --bs-border-radius-xxl: 1.4rem;
    --bs-box-shadow-sm: var(--app-shadow-sm);
    --bs-box-shadow: var(--app-shadow-md);
    --bs-box-shadow-lg: var(--app-shadow-lg);
}

/* ==========================================================================
   Base
   ========================================================================== */
body {
    min-width: 64rem;
    min-height: 100vh;
    background: var(--app-backdrop);
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-weight: 650;
    letter-spacing: -0.01em;
}

h1, .h1, h2, .h2 {
    font-family: var(--app-font-display);
    letter-spacing: -0.02em;
}

/* Every data page opens with a breadcrumb and an `h1.h3` title: giving
   that pair a consistent, larger treatment here is what makes each page read
   as "you are here" at a glance, without touching each template. */
.app-main h1.h3 {
    font-family: var(--app-font-display);
    font-size: 1.85rem;
    font-weight: 700;
    letter-spacing: -0.025em;
}

.app-main h1.h3 .text-muted {
    font-family: var(--app-font);
    font-size: 0.7em;
    font-weight: 500 !important;
}

a {
    text-underline-offset: 0.2em;
}

::selection {
    background: rgba(var(--app-primary-rgb), 0.2);
}

:focus-visible {
    outline: 2px solid var(--app-primary);
    outline-offset: 2px;
}

.min-w-0 {
    min-width: 0;
}

.app-skip-link {
    position: absolute;
    top: -3rem;
    left: 1rem;
    z-index: 2000;
    padding: 0.5rem 1rem;
    border-radius: var(--app-radius-sm);
    background: var(--app-primary);
    color: var(--app-on-primary);
    font-weight: 600;
    text-decoration: none;
    transition: top 0.15s ease;
}

.app-skip-link:focus {
    top: 0.75rem;
    color: var(--app-on-primary);
}

/* ==========================================================================
   Bootstrap components, re-skinned
   ========================================================================== */

/* Breadcrumb */
.breadcrumb {
    --bs-breadcrumb-divider: "›";
    --bs-breadcrumb-margin-bottom: 0.4rem;
    --bs-breadcrumb-item-padding-x: 0.5rem;
    --bs-breadcrumb-divider-color: var(--app-text-subtle);
    --bs-breadcrumb-item-active-color: var(--app-text-muted);
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--app-text-muted);
}

.breadcrumb a {
    color: var(--app-text-muted);
    text-decoration: none;
}

.breadcrumb a:hover {
    color: var(--app-primary);
    text-decoration: underline;
}

/* Buttons */
.btn {
    --bs-btn-font-weight: 600;
    --bs-btn-border-radius: var(--app-radius-sm);
    --bs-btn-focus-box-shadow: var(--app-focus-ring);
    transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.btn-sm {
    --bs-btn-border-radius: 0.5rem;
}

.btn-primary,
.btn-success {
    --bs-btn-color: var(--app-on-primary);
    --bs-btn-bg: var(--app-primary);
    --bs-btn-border-color: var(--app-primary);
    --bs-btn-hover-color: var(--app-on-primary);
    --bs-btn-hover-bg: var(--app-primary-hover);
    --bs-btn-hover-border-color: var(--app-primary-hover);
    --bs-btn-active-color: var(--app-on-primary);
    --bs-btn-active-bg: var(--app-primary-active);
    --bs-btn-active-border-color: var(--app-primary-active);
    --bs-btn-disabled-color: var(--app-on-primary);
    --bs-btn-disabled-bg: var(--app-primary);
    --bs-btn-disabled-border-color: var(--app-primary);
    box-shadow: var(--app-shadow-xs);
}

.btn-primary:hover,
.btn-success:hover {
    box-shadow: 0 6px 16px -6px rgba(var(--app-primary-rgb), 0.55);
}

.btn-outline-primary {
    --bs-btn-color: var(--app-primary);
    --bs-btn-bg: var(--app-surface);
    --bs-btn-border-color: var(--app-border-strong);
    --bs-btn-hover-color: var(--app-primary-active);
    --bs-btn-hover-bg: var(--app-primary-subtle);
    --bs-btn-hover-border-color: var(--app-primary-border);
    --bs-btn-active-color: var(--app-on-primary);
    --bs-btn-active-bg: var(--app-primary);
    --bs-btn-active-border-color: var(--app-primary);
    --bs-btn-disabled-color: var(--app-text-subtle);
    --bs-btn-disabled-bg: var(--app-surface);
    --bs-btn-disabled-border-color: var(--app-border);
}

.btn-outline-secondary {
    --bs-btn-color: var(--app-text);
    --bs-btn-bg: var(--app-surface);
    --bs-btn-border-color: var(--app-border-strong);
    --bs-btn-hover-color: var(--app-text);
    --bs-btn-hover-bg: var(--app-surface-muted);
    --bs-btn-hover-border-color: var(--app-border-strong);
    --bs-btn-active-color: var(--app-text);
    --bs-btn-active-bg: var(--app-border);
    --bs-btn-active-border-color: var(--app-border-strong);
    --bs-btn-disabled-color: var(--app-text-subtle);
    --bs-btn-disabled-bg: var(--app-surface);
    --bs-btn-disabled-border-color: var(--app-border);
}

.btn-outline-danger {
    --bs-btn-color: var(--app-danger);
    --bs-btn-bg: var(--app-surface);
    --bs-btn-border-color: var(--app-border-strong);
    --bs-btn-hover-color: var(--app-danger);
    --bs-btn-hover-bg: var(--app-danger-subtle);
    --bs-btn-hover-border-color: var(--app-danger);
}

.btn-link {
    --bs-btn-color: var(--app-primary);
    --bs-btn-hover-color: var(--app-primary-hover);
    --bs-btn-active-color: var(--app-primary-active);
    --bs-btn-font-weight: 600;
    text-decoration: none;
}

.btn-link:hover {
    text-decoration: underline;
}

/* Cards: white (or night green) surfaces with a hairline border, so that the
   `card border-0 shadow-sm rounded-4` blocks of every page stay visible on the
   canvas in both themes. */
.card {
    --bs-card-border-color: var(--app-border);
    --bs-card-border-radius: var(--app-radius-lg);
    --bs-card-inner-border-radius: calc(var(--app-radius-lg) - 1px);
    --bs-card-cap-bg: transparent;
    --bs-card-bg: var(--app-surface);
    --bs-card-color: var(--app-text);
}

.card.border-0 {
    box-shadow: 0 0 0 1px var(--app-border), var(--app-shadow-xs) !important;
}

.card.border-0.shadow-sm {
    box-shadow: 0 0 0 1px var(--app-border), 0 4px 14px -8px rgba(23, 38, 31, 0.14) !important;
}

.card-header {
    font-weight: 600;
    border-bottom-color: var(--app-border);
}

.rounded-4 {
    border-radius: var(--app-radius-lg) !important;
}

/* Forms */
.form-label {
    color: var(--app-text);
}

.form-label.small,
.form-text {
    color: var(--app-text-muted);
}

.form-control,
.form-select {
    color: var(--app-text);
    border-color: var(--app-border-strong);
    border-radius: var(--app-radius-sm);
    background-color: var(--app-surface);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-control-sm,
.form-select-sm {
    border-radius: 0.5rem;
    min-height: 2.125rem;
}

.form-control:hover,
.form-select:hover {
    border-color: var(--app-primary-border);
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: var(--app-primary);
    box-shadow: var(--app-focus-ring);
}

.form-control:disabled,
.form-select:disabled {
    background-color: var(--app-surface-muted);
}

.form-control::placeholder {
    color: var(--app-text-subtle);
}

[data-bs-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator {
    filter: invert(0.85);
}

.form-check-input {
    border-color: var(--app-border-strong);
    background-color: var(--app-surface);
}

.form-check-input:checked {
    background-color: var(--app-primary);
    border-color: var(--app-primary);
}

[data-bs-theme="dark"] .form-check-input:checked[type="checkbox"] {
    --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23062016' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}

[data-bs-theme="dark"] .form-check-input:checked[type="radio"] {
    --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23062016'/%3e%3c/svg%3e");
}

.form-switch .form-check-input:focus:not(:checked) {
    --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%231f7a55'/%3e%3c/svg%3e");
}

.form-range::-webkit-slider-thumb {
    background-color: var(--app-primary);
}

.form-range::-moz-range-thumb {
    background-color: var(--app-primary);
}

.form-range::-webkit-slider-thumb:active,
.form-range::-moz-range-thumb:active {
    background-color: var(--app-primary-border);
}

.form-range::-webkit-slider-runnable-track,
.form-range::-moz-range-track {
    background-color: var(--app-border);
}

.form-range:focus::-webkit-slider-thumb {
    box-shadow: 0 0 0 1px var(--app-surface), var(--app-focus-ring);
}

.form-range:focus::-moz-range-thumb {
    box-shadow: 0 0 0 1px var(--app-surface), var(--app-focus-ring);
}

/* Year / option chips (btn-check + rounded-pill buttons): make the "on"
   state unmistakable, since they're the main way to pick what to display. */
.btn-check + .btn-outline-primary.rounded-pill {
    --bs-btn-color: var(--app-text);
    font-variant-numeric: tabular-nums;
}

.btn-check:checked + .btn-outline-primary {
    box-shadow: 0 4px 12px -6px rgba(var(--app-primary-rgb), 0.6);
}

hr {
    border-color: var(--app-border);
    opacity: 1;
}

/* Tabs: rendered as a segmented control rather than folder tabs. It reads
   as "pick a view" to any user. */
.nav-tabs {
    --bs-nav-tabs-border-width: 0;
    --bs-nav-link-color: var(--app-text-muted);
    --bs-nav-link-hover-color: var(--app-text);
    --bs-nav-link-font-weight: 600;
    display: flex;
    flex-wrap: wrap;
    width: fit-content;
    max-width: 100%;
    gap: 0.25rem;
    padding: 0.3rem;
    background: var(--app-surface-muted);
    border: 1px solid var(--app-border);
    border-radius: calc(var(--app-radius) + 0.1rem);
}

.nav-tabs .nav-link {
    padding: 0.45rem 0.95rem;
    border: 0;
    border-radius: var(--app-radius-sm);
    font-size: 0.875rem;
    white-space: nowrap;
    transition: color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
}

.nav-tabs .nav-link:hover {
    background: color-mix(in srgb, var(--app-surface) 60%, transparent);
}

.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
    color: var(--app-primary-active);
    background: var(--app-surface);
    box-shadow: var(--app-shadow-sm);
}

.nav-pills {
    --bs-nav-pills-link-active-bg: var(--app-primary);
    --bs-nav-pills-link-active-color: var(--app-on-primary);
    --bs-nav-pills-border-radius: var(--app-radius-sm);
    --bs-nav-link-color: var(--app-text-muted);
}

/* Tables */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--app-text);
    --bs-table-border-color: var(--app-border);
    --bs-table-hover-bg: rgba(var(--app-primary-rgb), 0.06);
    --bs-table-hover-color: var(--app-text);
    --bs-table-striped-bg: rgba(var(--bs-body-color-rgb), 0.025);
    --bs-table-striped-color: var(--app-text);
    --bs-table-active-color: var(--app-text);
    font-variant-numeric: tabular-nums;
}

.table > thead th {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--app-text-muted);
    white-space: nowrap;
}

.table-light {
    --bs-table-bg: var(--app-surface-sunken);
    --bs-table-color: var(--app-text-muted);
    --bs-table-border-color: var(--app-border);
    --bs-table-striped-bg: var(--app-surface-sunken);
    --bs-table-striped-color: var(--app-text-muted);
    --bs-table-active-bg: var(--app-surface-muted);
    --bs-table-active-color: var(--app-text);
    --bs-table-hover-bg: var(--app-surface-muted);
    --bs-table-hover-color: var(--app-text);
    color: var(--app-text-muted);
    border-color: var(--app-border);
}

.table-responsive {
    border-radius: var(--app-radius-sm);
}

.table-responsive.border {
    background: var(--app-surface);
}

/* Badges */
.badge {
    --bs-badge-font-weight: 600;
    --bs-badge-border-radius: 0.45rem;
    letter-spacing: 0.01em;
}

.text-bg-light {
    color: var(--app-text) !important;
    background-color: var(--app-surface-muted) !important;
}

.text-bg-primary {
    color: var(--app-on-primary) !important;
    background-color: var(--app-primary) !important;
}

.text-bg-success {
    color: var(--app-on-primary) !important;
    background-color: var(--app-primary) !important;
}

/* Dropdowns, list groups, modals, alerts, popovers, tooltips */
.dropdown-menu {
    --bs-dropdown-bg: var(--app-surface);
    --bs-dropdown-color: var(--app-text);
    --bs-dropdown-border-color: var(--app-border);
    --bs-dropdown-border-radius: var(--app-radius);
    --bs-dropdown-box-shadow: var(--app-shadow-lg);
    --bs-dropdown-link-color: var(--app-text);
    --bs-dropdown-link-hover-color: var(--app-text);
    --bs-dropdown-link-hover-bg: var(--app-surface-muted);
    --bs-dropdown-link-active-color: var(--app-primary-active);
    --bs-dropdown-link-active-bg: var(--app-primary-subtle);
    --bs-dropdown-divider-bg: var(--app-border);
    --bs-dropdown-padding-x: 0.4rem;
    --bs-dropdown-item-border-radius: 0.55rem;
    --bs-dropdown-font-size: 0.875rem;
    box-shadow: var(--bs-dropdown-box-shadow);
}

.list-group {
    --bs-list-group-bg: var(--app-surface);
    --bs-list-group-color: var(--app-text);
    --bs-list-group-border-color: var(--app-border);
    --bs-list-group-active-bg: var(--app-primary);
    --bs-list-group-active-color: var(--app-on-primary);
    --bs-list-group-active-border-color: var(--app-primary);
    --bs-list-group-action-hover-bg: var(--app-surface-muted);
    --bs-list-group-action-hover-color: var(--app-text);
}

.modal {
    --bs-modal-bg: var(--app-surface);
    --bs-modal-color: var(--app-text);
    --bs-modal-border-width: 0;
    --bs-modal-border-radius: var(--app-radius-lg);
    --bs-modal-box-shadow: var(--app-shadow-lg);
    --bs-modal-header-border-color: var(--app-border);
    --bs-modal-footer-border-color: var(--app-border);
}

.modal-content {
    box-shadow: var(--bs-modal-box-shadow);
}

.modal-title {
    font-family: var(--app-font-display);
    font-weight: 650;
}

.modal-backdrop {
    --bs-backdrop-bg: #06100c;
    --bs-backdrop-opacity: 0.5;
}

.alert {
    --bs-alert-border-radius: var(--app-radius);
    font-size: 0.9rem;
}

.popover {
    --bs-popover-bg: var(--app-surface);
    --bs-popover-body-color: var(--app-text);
    --bs-popover-header-bg: var(--app-surface-muted);
    --bs-popover-border-color: var(--app-border);
    --bs-popover-border-radius: var(--app-radius);
    --bs-popover-box-shadow: var(--app-shadow-lg);
    font-family: var(--app-font);
}

.tooltip {
    --bs-tooltip-bg: var(--app-chart-tooltip-bg);
    --bs-tooltip-color: var(--app-chart-tooltip-title);
    --bs-tooltip-border-radius: 0.5rem;
    font-family: var(--app-font);
}

.progress {
    --bs-progress-bar-bg: var(--app-primary);
    --bs-progress-bg: var(--app-surface-muted);
}

.pagination {
    --bs-pagination-color: var(--app-text);
    --bs-pagination-bg: var(--app-surface);
    --bs-pagination-border-color: var(--app-border);
    --bs-pagination-hover-bg: var(--app-surface-muted);
    --bs-pagination-active-color: var(--app-on-primary);
    --bs-pagination-active-bg: var(--app-primary);
    --bs-pagination-active-border-color: var(--app-primary);
    --bs-pagination-focus-box-shadow: var(--app-focus-ring);
}

/* Leaflet: the controls and popups follow the theme; the tiles stay the
   providers' own, slightly dimmed at night so that the map does not glare. */
.leaflet-container {
    font-family: var(--app-font);
    background: var(--app-surface-muted);
}

.leaflet-bar,
.leaflet-control-layers {
    border: 1px solid var(--app-border) !important;
    border-radius: var(--app-radius-sm) !important;
    box-shadow: var(--app-shadow-md) !important;
}

.leaflet-popup-content-wrapper {
    border-radius: var(--app-radius);
    box-shadow: var(--app-shadow-lg);
}

[data-bs-theme="dark"] .leaflet-tile-pane {
    filter: brightness(0.82) saturate(0.9);
}

[data-bs-theme="dark"] .leaflet-bar a,
[data-bs-theme="dark"] .leaflet-control-layers,
[data-bs-theme="dark"] .leaflet-popup-content-wrapper,
[data-bs-theme="dark"] .leaflet-popup-tip {
    background: var(--app-surface);
    color: var(--app-text);
}

[data-bs-theme="dark"] .leaflet-bar a {
    border-bottom-color: var(--app-border);
}

[data-bs-theme="dark"] .leaflet-bar a:hover {
    background: var(--app-surface-muted);
}

[data-bs-theme="dark"] .leaflet-control-attribution {
    background: rgba(14, 24, 20, 0.75);
    color: var(--app-text-muted);
}

[data-bs-theme="dark"] .leaflet-control-attribution a {
    color: var(--app-primary);
}

/* ==========================================================================
   Shell: the sidebar on the left, the page on the right
   ========================================================================== */
.app-shell {
    display: flex;
    min-height: 100vh;
}

.app-shell-main {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
}

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

/* The pages open with `container-fluid px-4 py-4`: a little more air next to
   the sidebar. */
.app-main > .container-fluid.px-4 {
    padding: 1.75rem 2.25rem 2rem !important;
}

/* ==========================================================================
   Sidebar: from the sky down to the hills
   ========================================================================== */
.app-sidebar {
    position: sticky;
    top: 0;
    z-index: 1030;
    display: flex;
    flex: 0 0 var(--app-sidebar-width);
    flex-direction: column;
    width: var(--app-sidebar-width);
    height: 100vh;
    background: var(--app-side-bg);
    border-right: 1px solid var(--app-side-border);
    color: var(--app-side-text);
}

.app-side-head {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 1.15rem 0.9rem 0.9rem 1.1rem;
}

.app-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.65rem;
    min-width: 0;
    color: var(--app-side-text);
    text-decoration: none;
}

.app-brand:hover,
.app-brand:focus {
    color: var(--app-side-text);
}

.app-brand-mark {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 2.3rem;
    height: 2.3rem;
    border-radius: 0.8rem;
    background: linear-gradient(140deg, #3f9fd8 0%, #1f7a55 100%);
    box-shadow: 0 6px 14px -6px rgba(31, 122, 85, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.25);
    color: #fff;
}

.app-brand-sun {
    fill: #ffd166;
}

.app-brand-text {
    font-family: var(--app-font-display);
    font-size: 1.2rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    white-space: nowrap;
}

.app-brand-text span {
    margin-left: 0.2rem;
    font-weight: 450;
    color: var(--app-primary);
}

.app-side-toggle {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 0;
    border-radius: 0.55rem;
    background: transparent;
    color: var(--app-side-muted);
    transition: background-color 0.15s ease, color 0.15s ease;
}

.app-side-toggle:hover {
    background: var(--app-side-hover);
    color: var(--app-side-text);
}

.app-side-scroll {
    position: relative;
    z-index: 2;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 1.5rem), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 1.5rem), transparent);
    flex: 1 1 auto;
    min-height: 0;
    padding: 0.25rem 0.75rem 1rem;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--app-side-border) transparent;
}

.app-side-section + .app-side-section {
    margin-top: 1.1rem;
}

.app-side-title {
    padding: 0 0.6rem 0.35rem;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--app-side-muted);
    white-space: nowrap;
}

.app-side-link {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    width: 100%;
    padding: 0.38rem 0.5rem 0.38rem 0.4rem;
    border: 0;
    border-radius: 0.7rem;
    background: transparent;
    color: var(--app-side-text);
    font-size: 0.875rem;
    font-weight: 550;
    text-align: left;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.app-side-link + .app-side-link,
.app-side-group + .app-side-group {
    margin-top: 0.1rem;
}

.app-side-link:hover {
    background: var(--app-side-hover);
    color: var(--app-side-text);
}

.app-side-icon {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 0.6rem;
    font-size: 1.02rem;
    color: var(--app-side-muted);
    transition: background-color 0.15s ease, color 0.15s ease;
}

.app-side-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-side-link.active {
    background: var(--app-side-active-bg);
    color: var(--app-primary-active);
    font-weight: 650;
    box-shadow: var(--app-shadow-sm);
}

.app-side-link.active .app-side-icon {
    background: var(--app-primary);
    color: var(--app-on-primary);
}

[data-bs-theme="dark"] .app-side-link.active {
    box-shadow: none;
}

/* A theme of the sidebar: its data types fold under it. */
.app-side-group-toggle.active {
    box-shadow: none;
    background: transparent;
}

.app-side-group-toggle.active .app-side-icon {
    background: var(--app-primary-subtle);
    color: var(--app-primary);
}

.app-side-chevron {
    margin-left: auto;
    font-size: 0.7rem;
    color: var(--app-side-muted);
    transition: transform 0.2s ease;
}

.app-side-group-toggle.collapsed .app-side-chevron {
    transform: rotate(-90deg);
}

.app-side-sublist ul {
    position: relative;
    margin: 0.1rem 0 0.35rem 1.4rem;
    padding: 0 0 0 0.65rem;
    list-style: none;
    border-left: 1px dashed var(--app-side-border);
}

.app-side-flyout-title {
    display: none;
}

.app-side-sublink {
    display: block;
    padding: 0.3rem 0.6rem;
    border-radius: 0.5rem;
    color: var(--app-side-muted);
    font-size: 0.82rem;
    font-weight: 500;
    line-height: 1.3;
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.app-side-sublink:hover {
    background: var(--app-side-hover);
    color: var(--app-side-text);
}

.app-side-sublink.active {
    position: relative;
    background: var(--app-side-active-bg);
    color: var(--app-primary-active);
    font-weight: 650;
}

.app-side-sublink.active::before {
    content: "";
    position: absolute;
    top: 50%;
    left: -0.95rem;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--app-primary);
    box-shadow: 0 0 0 3px var(--app-primary-subtle);
    transform: translateY(-50%);
}

/* The account, above the hills. */
.app-side-foot {
    position: relative;
    z-index: 3;
    padding: 0.6rem 0.75rem 0.9rem;
}

.app-user-button {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    width: 100%;
    padding: 0.45rem 0.55rem 0.45rem 0.45rem;
    border: 1px solid var(--app-side-border);
    border-radius: 0.95rem;
    background: color-mix(in srgb, var(--app-surface) 82%, transparent);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    box-shadow: var(--app-shadow-sm);
    color: var(--app-text);
    text-align: left;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.app-user-button:hover,
.app-user-button[aria-expanded="true"] {
    border-color: var(--app-primary-border);
    box-shadow: var(--app-shadow-md);
}

.app-user-name {
    display: flex;
    flex-direction: column;
    min-width: 0;
    font-size: 0.85rem;
    font-weight: 650;
    line-height: 1.25;
}

.app-user-name small {
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--app-text-muted);
    white-space: nowrap;
}

.app-user-more {
    margin-left: auto;
    color: var(--app-text-subtle);
}

.app-user-menu {
    width: 18.5rem;
    padding: 0.4rem;
}

.app-user-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.5rem 0.65rem;
    font-weight: 550;
}

.app-user-menu .dropdown-item .bi {
    color: var(--app-text-muted);
}

.app-user-menu .dropdown-item.active .bi {
    color: inherit;
}

.app-user-menu-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.55rem 0.6rem 0.85rem;
    border-bottom: 1px solid var(--app-border);
}

.app-user-menu-section {
    padding: 0.75rem 0.6rem;
    margin-bottom: 0.35rem;
    border-bottom: 1px solid var(--app-border);
}

.app-user-menu-label {
    margin-bottom: 0.45rem;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--app-text-muted);
}

.app-user-menu-logout:hover,
.app-user-menu-logout:hover .bi {
    background: var(--app-danger-subtle);
    color: var(--app-danger);
}

.app-theme-switch {
    display: flex;
    gap: 0.25rem;
    padding: 0.25rem;
    border-radius: 0.75rem;
    background: var(--app-surface-muted);
}

.app-theme-switch .btn {
    flex: 1;
    gap: 0.35rem;
    padding: 0.35rem 0.5rem;
    border: 0;
    border-radius: 0.55rem;
    font-size: 0.8rem;
    color: var(--app-text-muted);
    white-space: nowrap;
}

.app-theme-switch .btn .bi {
    margin-right: 0.3rem;
}

.app-theme-switch .btn:hover {
    color: var(--app-text);
}

.app-theme-switch .btn.active {
    background: var(--app-surface);
    color: var(--app-primary-active);
    box-shadow: var(--app-shadow-sm);
}

.app-avatar {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    overflow: hidden;
    border-radius: 50%;
    background: linear-gradient(140deg, #3f9fd8 0%, #1f7a55 100%);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    user-select: none;
}

.app-avatar img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.app-avatar-lg {
    width: 2.75rem;
    height: 2.75rem;
    font-size: 0.95rem;
}

.app-avatar-guest {
    background: var(--app-primary-subtle);
    color: var(--app-primary);
    font-size: 1.05rem;
}

/* Rolling hills closing the sidebar, with the sun (the moon at night)
   rising behind them. */
.app-side-hills {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1;
    width: 100%;
    height: 7.5rem;
    pointer-events: none;
}

.app-sidebar::after {
    content: "";
    position: absolute;
    right: 2.4rem;
    bottom: 4rem;
    z-index: 0;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    background: var(--app-sun-glow);
    box-shadow: 0 0 0 0.6rem color-mix(in srgb, var(--app-sun-glow) 25%, transparent), 0 0 2.5rem color-mix(in srgb, var(--app-sun-glow) 60%, transparent);
    opacity: 0.85;
    pointer-events: none;
}

[data-bs-theme="dark"] .app-sidebar::after {
    width: 2rem;
    height: 2rem;
    box-shadow: inset -0.55rem -0.2rem 0 0 #c9d3df, 0 0 2rem rgba(233, 238, 245, 0.25);
    background: transparent;
    opacity: 0.8;
}

.app-hill-back { fill: var(--app-hill-back); }
.app-hill-mid { fill: var(--app-hill-mid); }
.app-hill-front { fill: var(--app-hill-front); }

/* Folded sidebar: a rail of icons; a theme's data types open as a flyout on
   hover, the labels as small bubbles. */
.app-sidebar.is-collapsed {
    flex-basis: var(--app-rail-width);
    width: var(--app-rail-width);
}

.app-sidebar.is-collapsed .app-side-head {
    flex-direction: column;
    padding: 1rem 0 0.75rem;
}

.app-sidebar.is-collapsed .app-brand-text,
.app-sidebar.is-collapsed .app-side-title,
.app-sidebar.is-collapsed .app-side-chevron,
.app-sidebar.is-collapsed .app-user-name,
.app-sidebar.is-collapsed .app-user-more,
.app-sidebar.is-collapsed::after {
    display: none;
}

.app-sidebar.is-collapsed .app-side-scroll {
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
    padding-inline: 0.85rem;
}

.app-sidebar.is-collapsed .app-side-section + .app-side-section {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--app-side-border);
}

.app-sidebar.is-collapsed .app-side-link {
    position: relative;
    justify-content: center;
    padding: 0.3rem;
}

.app-sidebar.is-collapsed .app-side-link .app-side-label {
    position: absolute;
    top: 50%;
    left: calc(100% + 0.75rem);
    z-index: 1060;
    display: none;
    padding: 0.35rem 0.65rem;
    border-radius: 0.5rem;
    background: var(--app-chart-tooltip-bg);
    color: var(--app-chart-tooltip-title);
    font-size: 0.8rem;
    font-weight: 600;
    box-shadow: var(--app-shadow-md);
    transform: translateY(-50%);
    pointer-events: none;
}

.app-sidebar.is-collapsed .app-side-link:not(.app-side-group-toggle):hover .app-side-label,
.app-sidebar.is-collapsed .app-side-link:not(.app-side-group-toggle):focus-visible .app-side-label {
    display: block;
}

.app-sidebar.is-collapsed .app-side-group {
    position: relative;
}

.app-sidebar.is-collapsed .app-side-sublist,
.app-sidebar.is-collapsed .app-side-sublist.show {
    position: absolute;
    top: -0.5rem;
    left: 100%;
    z-index: 1060;
    display: none;
    height: auto !important;
    padding-left: 0.75rem;
}

.app-sidebar.is-collapsed .app-side-group:hover .app-side-sublist,
.app-sidebar.is-collapsed .app-side-group:focus-within .app-side-sublist {
    display: block !important;
}

.app-sidebar.is-collapsed .app-side-sublist ul {
    width: 16rem;
    margin: 0;
    padding: 0 0.4rem 0.4rem;
    border: 1px solid var(--app-border);
    border-top: 0;
    border-radius: 0 0 var(--app-radius) var(--app-radius);
    background: var(--app-surface);
    box-shadow: var(--app-shadow-lg);
}

.app-sidebar.is-collapsed .app-side-flyout-title {
    display: block;
    width: 16rem;
    padding: 0.65rem 0.8rem 0.45rem;
    border: 1px solid var(--app-border);
    border-bottom: 0;
    border-radius: var(--app-radius) var(--app-radius) 0 0;
    background: var(--app-surface);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--app-text-muted);
}

.app-sidebar.is-collapsed .app-side-sublink {
    color: var(--app-text);
}

.app-sidebar.is-collapsed .app-side-sublink:hover {
    background: var(--app-surface-muted);
}

.app-sidebar.is-collapsed .app-side-sublink.active {
    background: var(--app-primary-subtle);
}

.app-sidebar.is-collapsed .app-side-sublink.active::before {
    display: none;
}

.app-sidebar.is-collapsed .app-side-foot {
    padding-inline: 0.85rem;
}

.app-sidebar.is-collapsed .app-user-button {
    justify-content: center;
    padding: 0.3rem;
}

/* ==========================================================================
   Footer
   ========================================================================== */
.app-footer {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.75rem;
    margin: 2rem 2.25rem 0;
    padding-block: 1.25rem 1.5rem;
    border-top: 1px dashed var(--app-border-strong);
    font-size: 0.8125rem;
    color: var(--app-text-muted);
}

.app-footer-leaf {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 50%;
    background: var(--app-primary-subtle);
    color: var(--app-primary);
}

.app-footer-note {
    max-width: 48rem;
    margin: 0;
}

/* ==========================================================================
   Home page
   ========================================================================== */
.home-page {
    padding: 1.75rem 2.25rem 0;
}

/* The hero: a landscape banner, the sky behind the title and the hills
   along its bottom edge. */
.home-hero {
    position: relative;
    overflow: hidden;
    padding: 2.5rem 2.5rem 7.5rem;
    border: 1px solid var(--app-border);
    border-radius: 1.6rem;
    background:
        radial-gradient(14rem 14rem at 88% 22%, color-mix(in srgb, var(--app-sun) 45%, transparent), transparent 70%),
        linear-gradient(180deg, color-mix(in srgb, var(--app-sky) 16%, var(--app-surface)) 0%, var(--app-surface) 80%);
    box-shadow: var(--app-shadow-sm);
}

[data-bs-theme="dark"] .home-hero {
    background:
        radial-gradient(10rem 10rem at 88% 22%, rgba(233, 238, 245, 0.12), transparent 70%),
        linear-gradient(180deg, #0f2233 0%, var(--app-surface) 85%);
}

.home-hero-content {
    position: relative;
    z-index: 1;
}

.home-hero-landscape {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 0;
    width: 100%;
    height: 9rem;
    pointer-events: none;
}

.home-hero-landscape .app-hill-back { opacity: 0.7; }

.home-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 1rem;
    padding: 0.3rem 0.8rem;
    border: 1px solid var(--app-primary-border);
    border-radius: 999px;
    background: color-mix(in srgb, var(--app-surface) 70%, transparent);
    color: var(--app-primary-active);
    font-size: 0.8rem;
    font-weight: 650;
}

.home-eyebrow-dot {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: var(--app-primary);
    box-shadow: 0 0 0 3px var(--app-primary-subtle);
}

.home-title {
    max-width: 52rem;
    margin-bottom: 0.85rem;
    font-family: var(--app-font-display);
    font-size: clamp(2rem, 1.2rem + 2vw, 2.9rem);
    font-weight: 700;
    letter-spacing: -0.035em;
    line-height: 1.08;
    text-wrap: balance;
}

.home-title em {
    font-style: normal;
    background: linear-gradient(100deg, var(--app-sky) 0%, var(--app-primary) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.home-lead {
    max-width: 42rem;
    text-wrap: pretty;
    margin-bottom: 2rem;
    font-size: 1.0625rem;
    color: var(--app-text-muted);
}

.home-actions {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1rem;
    margin: -6rem 1.5rem 0;
}

.home-action {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 1.1rem 1.15rem 1.15rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-lg);
    background: var(--app-surface);
    box-shadow: var(--app-shadow-md);
    color: var(--app-text);
    text-decoration: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.home-action:hover,
.home-action:focus-visible {
    color: var(--app-text);
    border-color: var(--app-primary-border);
    box-shadow: var(--app-shadow-lg);
    transform: translateY(-2px);
}

.home-action-title {
    font-weight: 650;
    line-height: 1.3;
}

.home-action-text {
    font-size: 0.82rem;
    color: var(--app-text-muted);
    line-height: 1.4;
}

.home-action-arrow {
    position: absolute;
    top: 1.1rem;
    right: 1.15rem;
    color: var(--app-text-subtle);
    transition: transform 0.15s ease, color 0.15s ease;
}

.home-action:hover .home-action-arrow {
    color: var(--app-primary);
    transform: translateX(3px);
}

/* A rounded square holding an emoji picto — the one "icon" treatment used
   across the home page, so every section reads the same way. */
.icon-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--app-radius);
    background: var(--app-surface-muted);
    font-size: 1.35rem;
    line-height: 1;
}

.icon-tile-sm {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.65rem;
    font-size: 1.1rem;
}

.icon-tile-primary {
    background: linear-gradient(140deg, var(--app-sky-subtle) 0%, var(--app-primary-subtle) 100%);
}

.home-section {
    padding-top: 2.75rem;
}

.home-section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    margin-bottom: 1.1rem;
}

.home-section-title {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0;
    font-size: 1.4rem;
    font-weight: 700;
}

/* A small leaf before each section title. */
.home-section-title::before {
    content: "";
    width: 0.85rem;
    height: 0.85rem;
    border-radius: 0 70% 0 70%;
    background: linear-gradient(140deg, var(--app-sky) 0%, var(--app-primary) 100%);
}

.home-section-subtitle {
    margin: 0.2rem 0 0;
    font-size: 0.9rem;
    color: var(--app-text-muted);
}

/* "Today in France" status cards: a label, a single big number, and what
   it breaks down into. The number stays neutral; only the level badges
   carry color, so the page stays calm even on a busy alert day. */
.status-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-lg);
    background: var(--app-surface);
    box-shadow: var(--app-shadow-xs);
    color: var(--app-text);
    text-decoration: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.status-card:hover,
.status-card:focus-visible {
    color: var(--app-text);
    border-color: var(--app-primary-border);
    box-shadow: var(--app-shadow-md);
    transform: translateY(-2px);
}

.status-card-body {
    flex: 1 1 auto;
    padding: 1.25rem;
}

.status-card-head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
    font-weight: 650;
}

.status-card-value {
    font-family: var(--app-font-display);
    font-size: 2.6rem;
    font-weight: 700;
    letter-spacing: -0.04em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.status-card-caption {
    margin-top: 0.35rem;
    color: var(--app-text-muted);
    font-size: 0.875rem;
}

.status-card-calm {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--app-primary-active);
    font-weight: 650;
}

.status-card-calm-dot {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    background: var(--app-primary);
    box-shadow: 0 0 0 4px var(--app-primary-subtle);
}

.status-card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1.25rem;
    border-top: 1px solid var(--app-border);
    border-radius: 0 0 var(--app-radius-lg) var(--app-radius-lg);
    background: var(--app-surface-sunken);
    color: var(--app-primary);
    font-size: 0.875rem;
    font-weight: 650;
}

.status-card:hover .status-card-footer span:last-child {
    transform: translateX(3px);
}

.status-card-footer span:last-child {
    transition: transform 0.15s ease;
}

.level-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.55rem 0.2rem 0.4rem;
    border: 1px solid var(--app-border);
    border-radius: 999px;
    background: var(--app-surface);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--app-text);
    white-space: nowrap;
}

.level-badge-swatch {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}

.level-badge strong {
    font-variant-numeric: tabular-nums;
}

/* Dataset cards in "Explorer les données": the whole card is the link. */
.explore-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 1.25rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-lg);
    background: var(--app-surface);
    box-shadow: var(--app-shadow-xs);
    color: var(--app-text);
    text-decoration: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

a.explore-card:hover,
a.explore-card:focus-visible {
    color: var(--app-text);
    border-color: var(--app-primary-border);
    box-shadow: var(--app-shadow-md);
    transform: translateY(-2px);
}

.explore-card-head {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    margin-bottom: 0.75rem;
}

.explore-card-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 650;
    line-height: 1.3;
}

.explore-card-meta {
    margin-top: 0.2rem;
    font-size: 0.8rem;
    color: var(--app-text-muted);
}

.explore-card-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: auto;
    padding-top: 0.75rem;
    color: var(--app-primary);
    font-size: 0.875rem;
    font-weight: 650;
    text-decoration: none;
}

a.explore-card-link:hover {
    color: var(--app-primary-hover);
    text-decoration: underline;
}

.explore-list {
    list-style: none;
    margin: 0 0 0.25rem;
    padding: 0;
}

.explore-list li + li {
    border-top: 1px solid var(--app-border);
}

.explore-list a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0.4rem;
    color: var(--app-text);
    font-size: 0.875rem;
    text-decoration: none;
    border-radius: 0.5rem;
}

.explore-list a:hover {
    color: var(--app-primary-active);
    background: var(--app-primary-subtle);
}

.explore-list-date {
    color: var(--app-text-subtle);
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.metric-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.65rem;
    border: 1px solid var(--app-border);
    border-radius: 999px;
    background: var(--app-surface-muted);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--app-text);
}

.network-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-lg);
    background: var(--app-surface);
    box-shadow: var(--app-shadow-xs);
    overflow: hidden;
}

.network-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1rem 1.25rem;
    /* Hairline separators that work however many columns the grid wraps to. */
    box-shadow: 1px 0 0 var(--app-border), 0 1px 0 var(--app-border);
    color: var(--app-text);
    text-decoration: none;
    transition: background-color 0.15s ease;
}

.network-item:hover,
.network-item:focus-visible {
    color: var(--app-text);
    background-color: var(--app-primary-subtle);
}

.network-item-value {
    font-size: 1.15rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}

.network-item-label {
    font-size: 0.8rem;
    color: var(--app-text-muted);
}

/* ==========================================================================
   Shared components
   ========================================================================== */
.stat-card {
    color: inherit;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

a.stat-card:hover {
    box-shadow: var(--app-shadow-md) !important;
    transform: translateY(-1px);
}

/* Multi-level dropdown support (Bootstrap only ships one level natively). */
.dropdown-submenu {
    position: relative;
}

.dropdown-submenu > .dropdown-menu {
    top: 0;
    left: 100%;
    margin-top: -0.5rem;
}

.dropdown-submenu > a::after {
    content: "";
    display: inline-block;
    margin-left: 0.5em;
    vertical-align: 0.15em;
    border-top: 0.3em solid transparent;
    border-bottom: 0.3em solid transparent;
    border-left: 0.3em solid;
    float: right;
}

@media (min-width: 992px) {
    .dropdown-submenu:hover > .dropdown-menu {
        display: block;
    }
}

/* Chart.js (responsive: true) needs an ancestor with a real height to size
   against; without it, a canvas initialized inside a Bootstrap collapse that
   starts hidden collapses to 0x0 and never recovers its size once revealed. */
.vigilance-chart {
    position: relative;
    height: 280px;
}

/* A chart with a day-by-day x axis over a whole year (e.g. cumulative rainfall). */
.vigilance-chart-tall {
    height: 380px;
}

/* Fixed-size (non-responsive) Chart.js canvas, scaled down via CSS to fit
   narrower cards without needing a JS resize once revealed.
   Both declarations need to beat an inline style Chart.js sets on the canvas
   itself (`style="width:...px; height:...px"`, to manage device-pixel-ratio
   scaling): `max-width` naturally wins over an inline `width` regardless of
   origin (it constrains the computed width from any source), but `height`
   has no such shortcut — `auto` needs `!important` to override the inline
   `height`, or the canvas keeps its full native height while only its width
   shrinks, distorting the aspect ratio (visible as an axis/gridline
   overshooting past the visually-shrunk chart). */
.vigilance-chart-fixed canvas {
    max-width: 100%;
    height: auto !important;
}

/* Same idea as .vigilance-chart-fixed, rendered at a higher native
   resolution (1000x320) so it stays crisp in a wider column. */
.obs-chart-fixed canvas {
    max-width: 100%;
    height: auto !important;
}

/* Météo-France vigilance colors. */
.bg-vigilance-green {
    background-color: #4caf7d;
    color: #fff;
}

.bg-vigilance-yellow {
    background-color: #ffc107;
    color: #1f2328;
}

.bg-vigilance-orange {
    background-color: #fd7e14;
    color: #fff;
}

.bg-vigilance-red {
    background-color: #dc3545;
    color: #fff;
}

/* One column per selected department; grid rows (year blocks, monthly detail,
   chart) auto-size to their tallest cell, so the same year lines up at the
   same height across every department instead of drifting out of sync.
   A department's column is always 1/maxDepartments of the full row width —
   the same width whether 1, 2, or 3 departments are selected — while the
   grid itself only spans as many of those thirds as are actually selected,
   so 1 department fills a third of the row, 2 fill two thirds, 3 fill it. */
.vigilance-dept-grid {
    position: relative;
    display: grid;
    grid-template-columns: repeat(var(--vigilance-dept-count, 1), 1fr);
    gap: 1.5rem 0;
    width: calc(100% * var(--vigilance-dept-count, 1) / var(--vigilance-max-departments, 1));
}

/* A colored swatch + label pair — the map legends (vigilance, wildfire risk,
   water restriction) and the water restriction "situation actuelle" summary
   line all use it to mean the same thing: "this color stands for this
   level". Previously duplicated once per map template; centralized here so a
   non-map template (the water restriction table) can reuse it too. */
.vigilance-map-legend {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.vigilance-map-legend .swatch {
    width: 14px;
    height: 14px;
    border-radius: 3px;
    display: inline-block;
}

/* Grid items default to min-width: auto, which lets a wide child (e.g. a
   many-column table) push its own column wider than its 1fr track instead of
   scrolling within it — min-width: 0 hands that job back to .table-responsive.
   `> .contents > div` covers cells nested one level down under a `.contents`
   wrapper (e.g. the year-tabbed detail tables), which are grid items too
   despite not being a direct DOM child of the grid. */
.vigilance-dept-grid > div,
.vigilance-dept-grid > .contents > div {
    min-width: 0;
}

/* Lets a wrapper group grid children (e.g. under one Stimulus controller)
   without becoming a grid item itself. */
.contents {
    display: contents;
}

/* A table header wired to the sortable-table Stimulus controller. */
th[data-action*='sortable-table#sort'] {
    cursor: pointer;
    user-select: none;
}

th[data-action*='sortable-table#sort']:hover {
    color: var(--bs-primary);
}

/* A single line spanning the full column height, rather than a border on
   every individual row, which reads as a broken/dashed edge because of the
   row gaps. */
.vigilance-dept-divider {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background-color: var(--app-border);
}

/* Same idea as .vigilance-dept-grid/.vigilance-dept-divider, for the weather
   observations screen where columns are stations ("slots") rather than
   departments. */
.obs-slot-grid {
    position: relative;
    display: grid;
    /* minmax(0, …) rather than 1fr, whose min-content floor let a wide table
       (records, monthly detail) stretch its column past the page instead of
       scrolling inside its .table-responsive. */
    grid-template-columns: repeat(var(--obs-slot-count, 1), minmax(0, 1fr));
    gap: 1.5rem 0;
    width: calc(100% * var(--obs-slot-count, 1) / var(--obs-max-slots, 1));
}

.obs-slot-divider {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background-color: var(--app-border);
}

/* Station header above each column: department, name and commune on one
   line, ellipsized instead of wrapping the commune onto its own line. */
.obs-station-label {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    min-width: 0;
}

.obs-station-label .obs-station-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Small info trigger + popover showing the IBM heatwave thresholds tied to a
   given year/department, anchored next to the year label it describes. */
.vigilance-threshold {
    position: relative;
    display: inline-flex;
}

.vigilance-threshold-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    padding: 0;
    border: 1px solid var(--bs-primary);
    border-radius: 50%;
    background: transparent;
    color: var(--bs-primary);
    font-size: 0.65rem;
    font-style: italic;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.vigilance-threshold-trigger:hover,
.vigilance-threshold-trigger:focus-visible {
    background: var(--bs-primary);
    color: var(--app-on-primary);
    outline: none;
}

.vigilance-threshold-panel {
    position: absolute;
    top: calc(100% + 0.5rem);
    left: 0;
    z-index: 1050;
    width: 15rem;
    padding: 0.75rem 0.9rem;
    background: var(--app-surface);
    border: 1px solid var(--app-border);
    border-radius: 0.5rem;
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.15);
}

.vigilance-threshold-panel::before {
    content: "";
    position: absolute;
    bottom: 100%;
    left: 0.5rem;
    border: 0.4rem solid transparent;
    border-bottom-color: var(--app-surface);
    filter: drop-shadow(0 -1px 1px rgba(0, 0, 0, 0.08));
}

.vigilance-threshold-panel-title {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--bs-primary-text-emphasis);
    margin-bottom: 0.5rem;
}

.vigilance-threshold-panel-list {
    display: grid;
    grid-template-columns: auto auto;
    column-gap: 0.75rem;
    row-gap: 0.25rem;
    margin: 0;
    font-size: 0.8rem;
}

.vigilance-threshold-panel-list dt {
    color: var(--app-text-muted);
    font-weight: 400;
}

.vigilance-threshold-panel-list dd {
    margin: 0;
    text-align: right;
    font-weight: 600;
}

.vigilance-section-title {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--app-text-muted);
    margin-bottom: 0.5rem;
}

/* Department picker: a tag-input box where selected departments render as
   removable chips inline with the search field. */
.department-picker-box {
    height: auto;
    min-height: calc(1.5em + 0.75rem + 2px);
    cursor: text;
}

.department-picker-input {
    flex: 1 1 auto;
    min-width: 10rem;
    border: 0;
    padding: 0;
    outline: 0;
    background: transparent;
}

.department-picker-input:disabled {
    background: transparent;
}

.department-picker-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.department-picker-tag {
    font-size: 0.65rem;
    font-weight: 500;
}

/* Compact "chip" for an observed min/max temperature reading, shared by the
   yearly badge, the per-episode cell/button, and their "no data" placeholder,
   so all three read as one consistent design language instead of a plain
   link or a generic Bootstrap badge. */
.temp-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.65rem;
    border: 1px solid var(--app-border);
    border-radius: 999px;
    background: var(--app-surface);
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
}

button.temp-pill {
    cursor: pointer;
    transition: box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
}

button.temp-pill:hover,
button.temp-pill:focus-visible {
    border-color: var(--bs-primary);
    box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.1);
    transform: translateY(-1px);
    outline: none;
}

.temp-pill-empty {
    color: var(--app-text-subtle);
    font-weight: 400;
    background: transparent;
    border-style: dashed;
}

.temp-pill-icon {
    font-size: 0.85rem;
}

/* !important needed here: `.text-bg-light` (used together with `.temp-min`/
   `.temp-max` on the yearly badges) sets its own `color` with `!important`. */
.temp-min {
    color: #0d6efd !important;
}

.temp-max {
    color: #dc3545 !important;
}

.temp-sep {
    color: var(--app-text-subtle);
}

/* Compact "chip" for one pollutant's min–max/avg/median reading in the
   yearly card — same chip language as `.temp-pill`, so a page with 6
   pollutants reads as a wrapped row of small chips instead of 6 full-width
   lines stacked on top of each other. */
.pollutant-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.65rem;
    border: 1px solid var(--app-border);
    border-radius: 999px;
    background: var(--app-surface);
    font-size: 0.8rem;
    line-height: 1;
    white-space: nowrap;
}

.pollutant-pill-label {
    font-weight: 700;
}

/* Small triangles in the daily detail table marking whether a day's value
   sits above or below the period's average/median — shared by every
   observation-style data type (temperature, water level/flow, groundwater
   level/depth, snow, pollutants). The `.stat-trend-median` variant is
   shrunk and faded to read as the secondary of the two markers. */
.stat-trend {
    font-size: 0.65em;
    margin-left: 1px;
}

.stat-trend-median {
    opacity: 0.6;
    font-size: 0.55em;
}

.stat-trend-up {
    color: #dc3545;
}

.stat-trend-down {
    color: #0d6efd;
}

/* "Did it storm" flag, shown next to the max temperature in the thunderstorm
   vigilance screen instead of a min/max temperature range. The lightning
   bolt is an emoji, so `color` has no effect on it — the no/unknown states
   are told apart by fading it out instead (the count next to it fades along
   with it, since both live inside the same .storm-flag-* span). */
.storm-flag-no,
.storm-flag-unknown {
    opacity: 0.35;
    filter: grayscale(1);
}

.storm-flag-unknown sup {
    font-size: 0.7em;
}

.storm-count {
    font-weight: 700;
}

.storm-flag-yes .storm-count {
    color: #fd7e14;
}

/* Shared by both day-by-day detail modals (temperatures and vigilance
   colors): a fixed height regardless of how many days the episode spans, so
   the modal doesn't visually jump in size from one episode to the next —
   only its content scrolls, behind a header that stays put while you do. */
.modal-detail-body {
    height: 22rem;
    overflow-y: auto;
}

.modal-detail-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background-color: var(--app-surface-sunken);
}

/* Day-by-day weather observation table (the date-range view, and the
   monthly detail modal): a capped-height, sticky-header scroll area like
   .modal-detail-body/-table above (reused verbatim for the modal case), plus
   a bit more visual polish than a bare Bootstrap table — a soft header,
   a hover highlight to help track a row across many columns, and slightly
   more breathing room than the very dense vigilance tables. */
.obs-table-scroll {
    max-height: 28rem;
    overflow-y: auto;
}

.obs-table-scroll thead th,
.obs-table-scroll .modal-detail-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
}

.obs-daily-table thead th {
    background-color: var(--app-surface-sunken);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--app-text-muted);
}

.obs-daily-table tbody tr:hover {
    background-color: var(--bs-primary-bg-subtle);
}

/* Fixed 3-column, 2-row grid for the 6 pollutant badges in the pollution
   monthly table: always wraps onto the same number of lines regardless of
   how many pollutants a given month actually reported, so every row keeps
   the same height instead of some wrapping and some staying on one line. */
/* One labelled line per metric ("min 46 · moy 202 · méd 199 · max 299 mm") in
   the water level / groundwater / snow monthly tables — stacked rather than
   crammed side by side, and allowed to wrap in the narrow column (one of up
   to 3 side-by-side station slots) instead of truncating with an ellipsis,
   which used to hide part of the reading entirely. */
.obs-monthly-summary-lines {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    font-size: 0.8rem;
}

.obs-monthly-summary-lines span {
}

.stations-map-search-marker {
    background: transparent;
    border: none;
}

/* Trophy marking a day that holds one of the station's records. */
.record-badge {
    margin-left: 0.2rem;
    font-size: 0.8em;
    cursor: help;
}

.record-table {
    font-size: 0.8125rem;
}

.record-table td,
.record-table th {
    min-width: 5.5rem;
}

/* Weather summary of a year, a month or a date range (see the summaryBadges
   macro): labelled groups of "label: value" lines, side by side when the
   space allows (monthly table, month detail), stacked in a narrow card. */
.obs-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.6rem 1.25rem;
    font-size: 0.8125rem;
}

.obs-summary-title {
    margin-bottom: 0.2rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--app-text-muted);
}

.obs-summary-lines {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.1rem 0.6rem;
    margin: 0;
}

.obs-summary-lines dt {
    font-weight: 500;
    color: var(--app-text-muted);
}

.obs-summary-lines dd {
    margin: 0;
    /* Values are kept short enough for one line (see the macro); a card too
       narrow even for that cuts them rather than wrapping. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Temperature table of the weather summary. */
.obs-summary-table {
    margin-bottom: 0.2rem;
    font-variant-numeric: tabular-nums;
}

.obs-summary-table th,
.obs-summary-table td {
    padding: 0 0.6rem 0.05rem 0;
    white-space: nowrap;
    text-align: right;
}

.obs-summary-table thead th {
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--app-text-muted);
}

.obs-summary-table tbody th {
    font-weight: 500;
    text-align: left;
}

/* A record reached during a year: its tooltip tells the record it replaced. */
.record-held {
    cursor: help;
}

/* Department index: every department as a compact link, code first. */
.department-index {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: 0.5rem;
}

.department-index-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius);
    background: var(--app-surface);
    color: var(--app-text);
    text-decoration: none;
}

.department-index-item:hover {
    border-color: var(--app-primary-border);
    color: var(--app-primary);
}

.department-index-item > span:last-child {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.department-index-code {
    flex-shrink: 0;
    min-width: 2.2rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--app-text-muted);
}

/* Home page weather highlights: one extreme reading per tile. */
.highlight-tile {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    background: var(--app-surface-muted);
    color: var(--app-text);
    text-decoration: none;
}

.highlight-tile:hover {
    border-color: var(--app-primary-border);
}

.highlight-tile-label {
    font-size: 0.75rem;
    color: var(--app-text-muted);
}

.highlight-tile-value {
    font-size: 1.25rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.highlight-tile-place {
    font-size: 0.8125rem;
    color: var(--app-text-muted);
}

/* Sections of a station page (see data/_obs_section.html.twig): one card per kind of figure, each
   with the same header, so the yearly summary, the charts, the normals... read as distinct
   blocks, and every folding section folds the same way. */
.obs-section-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.9rem 1.25rem 0.75rem;
    border-bottom: 1px solid var(--app-border);
}

.obs-section-title {
    font-size: 1rem;
    font-weight: 650;
    margin: 0;
}

.obs-section-description {
    font-size: 0.8125rem;
    color: var(--app-text-muted);
    margin: 0.15rem 0 0;
}

.obs-section-body {
    padding: 1rem 0;
}

.obs-section-toggle {
    flex-shrink: 0;
}

.obs-section-toggle.collapsed .obs-section-toggle-hide,
.obs-section-toggle:not(.collapsed) .obs-section-toggle-show {
    display: none;
}

/* Station name above a section's column, when several stations are compared. */
.obs-slot-caption {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--app-text-muted);
    margin-bottom: 0.5rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A folded section has nothing under its header: no separating line then. */
.obs-section-header:has(+ .collapse:not(.show)) {
    border-bottom-color: transparent;
}

/* A table in a bordered, rounded wrapper (`.table-responsive.border`): room between the rounded
   corners and the first and last columns, and a little more air in each row of a small table. */
.table-responsive.border > .table > :not(caption) > * > :first-child {
    padding-left: 1rem;
}

.table-responsive.border > .table > :not(caption) > * > :last-child {
    padding-right: 1rem;
}

.table-responsive.border > .table-sm > :not(caption) > * > * {
    padding-top: 0.45rem;
    padding-bottom: 0.45rem;
}

/* Department page, year by year: each source is a group of columns under a thin colored bar,
   set apart from the next group by a line with room on both sides, so a figure always reads with
   the source it comes from. */
.department-years > thead th {
    background-color: var(--app-surface);
}

.department-years .group-start {
    border-left: 1px solid var(--app-border);
    padding-left: 1rem;
}

.department-years .group-end {
    padding-right: 1rem;
}

.department-years-groups th:not(:first-child) {
    text-align: left;
    color: var(--app-text);
    text-transform: none;
    font-size: 0.875rem;
    letter-spacing: 0;
    padding-top: 0.7rem;
    border-top: 3px solid var(--department-years-accent, var(--app-border));
}

.department-years-groups a {
    color: inherit;
    text-decoration: none;
}

.department-years-groups a:hover {
    color: var(--app-primary);
    text-decoration: underline;
}

.department-years-vigilance { --department-years-accent: #fd7e14; }
.department-years-flood { --department-years-accent: #0d6efd; }
.department-years-drought { --department-years-accent: #b35c00; }
.department-years-fire { --department-years-accent: #dc3545; }
.department-years-restriction { --department-years-accent: #20c997; }

.department-years-unit {
    display: block;
    font-weight: 400;
    font-size: 0.75rem;
    color: var(--app-text-muted);
}

.department-years-columns th {
    border-bottom: 1px solid var(--app-border-strong);
    font-weight: 500;
}

.department-years > tbody td:first-child {
    font-weight: 600;
}

/* At night, the warm/cold readings and trends take lighter shades of the
   same hues, legible on the dark surfaces. */
[data-bs-theme="dark"] .temp-min { color: #74abff !important; }
[data-bs-theme="dark"] .temp-max { color: #ff7b86 !important; }
[data-bs-theme="dark"] .stat-trend-up { color: #ff7b86; }
[data-bs-theme="dark"] .stat-trend-down { color: #74abff; }

/* At night the primary chips are light green with dark text: their close
   cross stays dark too. */
[data-bs-theme="dark"] .text-bg-primary .btn-close {
    filter: none;
}
