/**
 * WatchMyBirds Design System v2 - retro-industrial field console.
 */

:root {
    /* --- Design Tokens --- */

    /* Core Palette - V078: Stone x Cool White */
    --color-bg: #f3f3f2;
    --color-surface: #fdfbf7;
    --color-surface-2: #eef0ee;
    --color-surface-3: #e4e7e5;

    --color-primary: #53676b;
    --color-primary-dark: #39484b;
    --color-primary-light: #d8dede;

    --color-accent: #979fa0;
    --color-accent-dark: #737b7c;
    --color-accent-light: #d9dddd;

    --color-secondary: #7f8888;
    --color-secondary-light: #ecefef;

    --color-text: #202426;
    --color-text-muted: #666f70;
    --color-text-subtle: #8a9293;

    --color-border: #d6dada;
    --color-border-light: #e7ebeb;

    --color-success: #5f7a66;
    --color-warning: #b99663;
    --color-danger: #9c6b63;
    --color-info: #617c85;

    /* Human Impact (Noise Analysis) */
    --color-impact: #9e8570;
    --color-impact-light: #efe5d8;
    --color-impact-dark: #6f5b4b;
    --color-impact-ratio: #74889a;

    /* Species colours — Wong (2011) colour-blind-friendly palette.
       Eight deterministic slots are assigned alphabetically by
       scientific name. The same scientific name always gets the same
       slot on bbox borders, cell accents, badge tints, and reference
       image borders. */
    --species-colour-0: #0072B2; /* blue */
    --species-colour-1: #E69F00; /* orange */
    --species-colour-2: #009E73; /* green */
    --species-colour-3: #CC79A7; /* pink */
    --species-colour-4: #56B4E9; /* sky */
    --species-colour-5: #D55E00; /* vermilion */
    --species-colour-6: #F0E442; /* yellow — non-text only */
    --species-colour-7: #4B3F2E; /* dark umber — readable on light and dark; replaces the earlier #000000 that rendered as unreadable all-black bbox borders/labels when a species landed on slot 7 alphabetically */

    /* Spacing Scale (8pt grid) */
    --space-2xs: 4px;
    --space-xs: 8px;
    --space-sm: 12px;
    --space-md: 16px;
    --space-lg: 24px;
    --space-xl: 32px;
    --space-2xl: 48px;
    --space-3xl: 64px;

    /* Radius Scale */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-xl: 20px;
    --radius-full: 9999px;

    /* Shadows */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -2px rgba(0, 0, 0, 0.02);
    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.08);

    /* Typography (UI Best Practice Scale) */
    --font-size-xs: 0.875rem;
    --font-size-sm: 1rem;
    --font-size-md: 1.125rem;
    --font-size-lg: 1.25rem;
    --font-size-xl: 1.5rem;
    --font-size-2xl: 1.875rem;
    --font-size-3xl: 2.25rem;

    /* Transitions */
    --transition-fast: 150ms ease;
    --transition-normal: 250ms ease;

    /* Z-Index */
    --z-appbar: 1000;
    --z-modal: 1100;
    --z-tooltip: 1200;

    /* Layout — top app bar height. Mobile overrides below this token at
       the 760px breakpoint when the nav stacks. Every sticky element
       that sits below the app bar reads from this token. */
    --appbar-height: 64px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   DARK-MODE PALETTE
   Redefines every load-bearing token inside the OS-level dark scope.
   Every Review surface rule that uses `var(--color-*)` or
   `var(--species-colour-N)` picks the dark variant up automatically,
   including highlight accents, species colour bindings, receipt accents,
   and zoom-toggle states. Token-only; no surface rules are touched apart
   from a handful of hardcoded light backgrounds that must be overridden
   explicitly (see the "Review-surface dark-mode overrides" block
   further down this file).

   Scope mechanism: the dark palette applies in two cases:
     1. `@media (prefers-color-scheme: dark)` AND the root does NOT
        carry `data-theme="light"` — OS preference is the default.
     2. `:root[data-theme="dark"]` — the user explicitly chose dark in
        Settings (base.html hydrates this attribute from localStorage
        before first paint, so there is no flash of the wrong palette).
   Users who pick "Light" in Settings set `data-theme="light"` on the
   root, which wins over the media query. "System" mode leaves the
   attribute absent so the OS preference passes through unchanged.

   Wong palette dark variants: same hues as the light palette, but
   slightly lifted toward the "bright" Wong variants so they remain
   readable on a dark surface without breaking the colour-blind-friendly
   relationships between slots. The two slots that meaningfully change:
     - slot 6 (yellow) is now text-safe on dark; the "non-text only"
       constraint from the light scope no longer applies.
     - slot 7 (black) becomes near-white — a dark background needs a
       light fallback, same semantic role.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        /* Core surfaces — dark stone, cool graphite tint. */
        --color-bg: #15181a;
        --color-surface: #1e2326;
        --color-surface-2: #262c2f;
        --color-surface-3: #2f3539;

        /* Primary family — lifted from #53676b toward a readable warm
           slate so review highlights, the stage-connecting cue, the
           grid border, and the species change-receipt accent all stay
           visible on dark backgrounds. */
        --color-primary: #92a7ab;
        --color-primary-dark: #c9d3d5;
        --color-primary-light: #394649;

        --color-accent: #b4bcbd;
        --color-accent-dark: #cfd5d6;
        --color-accent-light: #394042;

        --color-secondary: #9aa3a3;
        --color-secondary-light: #343a3a;

        /* Text — high-contrast cool white on dark stone. */
        --color-text: #e8ebec;
        --color-text-muted: #a0a7a8;
        --color-text-subtle: #7b8284;

        --color-border: #3a4145;
        --color-border-light: #2c3235;

        /* Semantic states — same hues, lifted lightness. */
        --color-success: #8fb396;
        --color-warning: #e1b87c;
        --color-danger: #d89089;
        --color-info: #8fb0b9;

        /* Human Impact (Noise Analysis) — warm wood tint stays, but
           the pair of light/dark swap roles inside the dark scope. */
        --color-impact: #c6ae95;
        --color-impact-light: #4a3d30;
        --color-impact-dark: #e8d8c3;
        --color-impact-ratio: #a0b5c6;

        /* Wong palette dark variants. Same hues, lifted for
           dark-background readability. Slot indices stay stable. */
        --species-colour-0: #4aa3d9; /* blue — lifted from #0072B2 */
        --species-colour-1: #f3b340; /* orange — lifted from #E69F00 */
        --species-colour-2: #3fbe93; /* green — lifted from #009E73 */
        --species-colour-3: #e09bc2; /* pink — lifted from #CC79A7 */
        --species-colour-4: #7bc4ee; /* sky — lifted from #56B4E9 */
        --species-colour-5: #e8793a; /* vermilion — lifted from #D55E00 */
        --species-colour-6: #f5ea63; /* yellow — text-safe on dark */
        --species-colour-7: #b89a78; /* warm umber — readable on both dark UI chrome and light image backgrounds; replaces the earlier near-white that disappeared against bright bird images. Kept in the warm palette family so it is visually distinct from the cool slots 0/4. Must stay in sync with the SPECIES_COLOURS_FALLBACK[7] value in assets/js/gallery_utils.js. */

        /* Shadows — stronger on dark so cards stay visibly lifted. */
        --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
        --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.25);
        --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.42), 0 4px 6px -2px rgba(0, 0, 0, 0.22);
        --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.5);
    }
}

/* Explicit dark override (user chose "Dark" in Settings regardless of
   OS preference). Token values are intentionally identical to the
   `@media` block above — CSS has no mixin, so the duplication is the
   simplest correct path. Keep these two blocks in sync when tokens
   change. */
:root[data-theme="dark"] {
    --color-bg: #15181a;
    --color-surface: #1e2326;
    --color-surface-2: #262c2f;
    --color-surface-3: #2f3539;

    --color-primary: #92a7ab;
    --color-primary-dark: #c9d3d5;
    --color-primary-light: #394649;

    --color-accent: #b4bcbd;
    --color-accent-dark: #cfd5d6;
    --color-accent-light: #394042;

    --color-secondary: #9aa3a3;
    --color-secondary-light: #343a3a;

    --color-text: #e8ebec;
    --color-text-muted: #a0a7a8;
    --color-text-subtle: #7b8284;

    --color-border: #3a4145;
    --color-border-light: #2c3235;

    --color-success: #8fb396;
    --color-warning: #e1b87c;
    --color-danger: #d89089;
    --color-info: #8fb0b9;

    --color-impact: #c6ae95;
    --color-impact-light: #4a3d30;
    --color-impact-dark: #e8d8c3;
    --color-impact-ratio: #a0b5c6;

    --species-colour-0: #4aa3d9;
    --species-colour-1: #f3b340;
    --species-colour-2: #3fbe93;
    --species-colour-3: #e09bc2;
    --species-colour-4: #7bc4ee;
    --species-colour-5: #e8793a;
    --species-colour-6: #f5ea63;
    --species-colour-7: #b89a78;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.25);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.42), 0 4px 6px -2px rgba(0, 0, 0, 0.22);
    --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.5);
}

/* --- Global Base Styles --- */

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    background-color: var(--color-bg);
    color: var(--color-text);
    font-family: "IBM Plex Sans", "Avenir Next", "Segoe UI", sans-serif;
    font-size: var(--font-size-md);
    line-height: 1.5;
    margin: 0;
    -webkit-font-smoothing: antialiased;
    background-image: none;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    color: var(--color-text);
    font-weight: 700;
    margin-top: 0;
    margin-bottom: var(--space-md);
    letter-spacing: -0.025em;
    font-family: "Avenir Next Condensed", "Arial Narrow", "IBM Plex Sans", sans-serif;
    text-transform: uppercase;
}

a {
    color: var(--color-primary);
    text-decoration: none;
    transition: color var(--transition-fast);
}

a:hover {
    color: var(--color-primary-dark);
}

img {
    max-width: 100%;
    height: auto;
}

pre,
code {
    font-family: 'SF Mono', 'Fira Code', 'JetBrains Mono', monospace;
}

/* --- Selection Color --- */
::selection {
    background-color: var(--color-primary-light);
    color: var(--color-primary-dark);
}

/* --- Layout Utility Classes --- */

.page {
    padding-top: var(--space-md);
    /* App Bar offset is handled by .status-bar margin-top; only a small gap is needed here. */
    padding-bottom: var(--space-2xl);
    min-height: 100vh;
}

@media (max-width: 480px) {
    .app-footer {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: center;
        gap: var(--space-xs);
    }

    .app-footer > .ms-1,
    .app-footer > .ms-2 {
        margin-left: 0 !important;
    }
}

.section {
    margin-top: var(--space-2xl);
    margin-bottom: var(--space-2xl);
}

.section__title {
    font-size: var(--font-size-xl);
    border-left: 4px solid var(--color-primary);
    padding-left: var(--space-md);
    margin-bottom: var(--space-lg);
}

.page__header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-xl);
}

.page__title {
    font-size: var(--font-size-3xl);
    margin-bottom: 0;
}

.page__actions {
    display: flex;
    gap: var(--space-sm);
}

/* --- Component: App Bar --- */

.app-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--appbar-height);
    background: #f4ecd9;
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    padding: 0 var(--space-xl);
    z-index: var(--z-appbar);
}

/* Dark scope override — the hardcoded cream above is fine on light
   skins but stranded light text (--color-text becomes near-white) on
   a cream background in dark mode. Keep it token-driven only inside
   the dark scope so the existing light look is unchanged. */
:root[data-theme="dark"] .app-bar {
    background: var(--color-surface);
}

.app-bar__brand {
    display: flex;
    align-items: center;
    font-weight: 700;
    font-size: var(--font-size-lg);
    color: var(--color-text);
    margin-right: var(--space-xl);
}

.app-bar__toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0;
    cursor: pointer;
    color: var(--color-text);
    box-shadow: var(--shadow-sm);
}

.app-bar__toggle:hover,
.app-bar__toggle:focus-visible {
    background: var(--color-surface-2);
    border-color: var(--color-primary);
}

.app-bar__nav {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    flex: 1;
    overflow: visible;
}

/* Spacer for primary/secondary separation */
.app-bar__spacer {
    flex: 1;
    min-width: var(--space-lg);
}

/* Base link style */
.app-bar__link {
    padding: var(--space-sm) var(--space-md);
    color: var(--color-text-muted);
    font-weight: 500;
    font-size: var(--font-size-sm);
    transition: all var(--transition-fast);
    border-bottom: 2px solid transparent;
    white-space: nowrap;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}

.app-bar__link:hover {
    color: var(--color-text);
}

/* PRIMARY navigation links */
.app-bar__link--primary {
    color: var(--color-text);
    font-weight: 600;
}

/* SECONDARY navigation links (muted) */
.app-bar__link--secondary {
    font-size: var(--font-size-xs);
    opacity: 0.7;
}

.app-bar__link--secondary:hover {
    opacity: 1;
}

/* ACTIVE state = underline, NOT button */
.app-bar__link.active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

.app-bar__link--secondary.active {
    opacity: 1;
}

/* Badge styles */
.app-bar__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 600;
    padding: 2px 6px;
    border-radius: var(--radius-full);
    background: var(--color-surface-2);
    color: var(--color-text-muted);
    margin-left: var(--space-2xs);
}

.app-bar__badge--subtle {
    background: transparent;
    color: var(--color-text-muted);
    opacity: 0.6;
}

/* --- Component: App Bar Dropdown --- */

.app-bar__dropdown {
    position: relative;
    display: flex;
    align-items: center;
}

.app-bar__dropdown-trigger {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    border-bottom: 2px solid transparent;
}

.app-bar__dropdown-chevron {
    transition: transform var(--transition-fast);
    opacity: 0.5;
}

.app-bar__dropdown.open .app-bar__dropdown-chevron {
    transform: rotate(180deg);
}

/* Active state: underline the trigger when a child page is active */
.app-bar__dropdown.active .app-bar__dropdown-trigger {
    opacity: 1;
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

.app-bar__dropdown-menu {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 180px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-xs) 0;
    z-index: calc(var(--z-appbar) + 10);
    animation: dropdownFadeIn 0.15s ease;
}

.app-bar__dropdown.open .app-bar__dropdown-menu {
    display: block;
}

@keyframes dropdownFadeIn {
    from {
        opacity: 0;
        transform: translateY(-6px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.app-bar__dropdown-item {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: var(--space-sm) var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--color-text);
    transition: background var(--transition-fast);
    border-radius: var(--radius-sm);
    white-space: nowrap;
    text-decoration: none;
}

.app-bar__dropdown-item:hover {
    background: var(--color-surface-2);
    color: var(--color-text);
}

.app-bar__dropdown-item.active {
    color: var(--color-primary);
    font-weight: 600;
}

/* ═══════════════════════════════════════════════════════════════════════════
   STATUS BAR - Minimal, muted (whispers, doesn't shout)
   ═══════════════════════════════════════════════════════════════════════════ */

/* The mascot hero canvas backs the whole status bar from inside this
   wrapper (position context); children render above it via z-index. */
.app-mascot-bar {
    position: relative;
    overflow: hidden;
    background: var(--color-bg);   /* page background — bar melts into the page */
    --led-ticker-bg: transparent;
    --led-ticker-on: var(--color-text);  /* dark ink glyphs on light paper */
    --mascot-hero-scrim: none;           /* no scrim on a light background */
}
/* blend modes are set per-canvas in mascot_hero.html (backdrop=multiply,
   fx=difference); no blanket rule here so the fx layer isn't overridden */
.app-mascot-bar::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background: var(--mascot-hero-scrim);
}
.app-mascot-bar .led-ticker { background: transparent; }

.status-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-lg);
    padding: var(--space-xs) var(--space-xl);
    background-color: transparent;
    border-bottom: 1px solid var(--color-border-light);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    margin-top: var(--appbar-height);
    position: relative;
    z-index: 2;
}

.status-bar__item {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
}

.status-bar__label {
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 0.75rem;
    color: var(--color-text-muted);
}

.status-bar__value {
    font-weight: 500;
    color: var(--color-text-muted);
}

/* Warning states - ONLY visible when critical */
.status-bar__value--warning {
    color: var(--color-warning);
    font-weight: 600;
}

.status-bar__value--danger {
    color: var(--color-danger);
    font-weight: 700;
}

/* Status dot for detection indicator */
.status-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    background-color: var(--color-text-subtle);
}

.status-dot--online {
    background-color: var(--color-success);
    box-shadow: 0 0 8px var(--color-success);
}

.status-dot--busy {
    background-color: var(--color-warning);
}

/* --- Component: Cards --- */

.card {
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    margin-bottom: var(--space-lg);
}

.card__header {
    padding: var(--space-lg);
    border-bottom: 1px solid var(--color-border-light);
    background-color: var(--color-surface);
}

.card__title {
    font-size: var(--font-size-lg);
    margin-bottom: 0;
}

.card__body {
    padding: var(--space-lg);
}

.card__footer {
    padding: var(--space-md) var(--space-lg);
    background-color: var(--color-surface-2);
    border-top: 1px solid var(--color-border-light);
}

/* --- Component: Buttons --- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-sm) var(--space-lg);
    border-radius: var(--radius-lg);
    font-weight: 600;
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
    border: 1px solid transparent;
    gap: var(--space-xs);
    white-space: nowrap;
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn--primary {
    background-color: var(--color-primary);
    color: white;
}

.btn--primary:hover:not(:disabled) {
    background-color: var(--color-primary-dark);
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn--secondary {
    background-color: var(--color-surface);
    border-color: var(--color-border);
    color: var(--color-text);
}

.btn--secondary:hover:not(:disabled) {
    background-color: var(--color-surface-2);
    border-color: var(--color-border-light);
}

.btn--accent {
    background-color: var(--color-accent);
    color: var(--color-text);
}

.btn--accent:hover:not(:disabled) {
    background-color: var(--color-accent-dark);
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn--danger {
    background-color: var(--color-surface);
    border-color: var(--color-danger);
    color: var(--color-danger);
}

.btn--danger:hover:not(:disabled) {
    background-color: var(--color-danger);
    color: white;
}

.btn--success {
    background-color: #2e7d32;
    border-color: #2e7d32;
    color: white;
}

.btn--success:hover:not(:disabled) {
    background-color: #1b5e20;
    border-color: #1b5e20;
    color: white;
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn--outline-primary {
    background-color: transparent;
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.btn--outline-primary:hover:not(:disabled) {
    background-color: var(--color-primary);
    color: white;
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn--outline-warning {
    background-color: transparent;
    border-color: var(--color-warning);
    color: var(--color-warning);
}

.btn--outline-warning:hover:not(:disabled) {
    background-color: var(--color-warning);
    color: white;
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn--outline-danger {
    background-color: transparent;
    border-color: var(--color-danger);
    color: var(--color-danger);
}

.btn--outline-danger:hover:not(:disabled) {
    background-color: var(--color-danger);
    color: white;
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn--info {
    background-color: var(--color-secondary);
    color: white;
}

.btn--info:hover:not(:disabled) {
    background-color: var(--color-secondary-dark, #0277bd);
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn--lg {
    padding: var(--space-md) var(--space-xl);
    font-size: var(--font-size-md);
}

.btn--sm {
    padding: var(--space-xs) var(--space-md);
    font-size: var(--font-size-xs);
}

.btn--block {
    width: 100%;
    display: flex;
}

/* --- Component: Badges --- */

.badge {
    display: inline-flex;
    align-items: center;
    padding: 0.125rem 0.5rem;
    border-radius: var(--radius-full);
    font-size: var(--font-size-xs);
    font-weight: 700;
    background-color: var(--color-surface-2);
    color: var(--color-text-muted);
}

.badge--accent {
    background-color: var(--color-accent);
    color: white;
}

.badge--warning {
    background-color: #fff3e0;
    color: #ef6c00;
}

/* --- Component: Utils --- */

.hidden {
    display: none !important;
}

.animate-spin {
    animation: spin 1s linear infinite;
}

@keyframes spin {
    from {
        transform: rotate(0deg);
    }

    to {
        transform: rotate(360deg);
    }
}

.animate-pulse {
    animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes pulse {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: .5;
    }
}

/* Grid System */
.grid {
    display: grid;
    gap: var(--space-lg);
}

.grid--2 {
    grid-template-columns: repeat(2, 1fr);
}

.grid--3 {
    grid-template-columns: repeat(3, 1fr);
}

.grid--4 {
    grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 768px) {
    .grid--2,
    .grid--3,
    .grid--4 {
        grid-template-columns: 1fr;
    }
}

/* The authenticated navigation carries substantially more links than the
   public shell. Switch both variants to the same compact menu before the
   fixed bar can overrun laptop-sized viewports. */
@media (max-width: 1100px) {
    .app-bar__brand {
        margin-right: var(--space-md);
    }

    /* Show hamburger menu on mobile */
    .app-bar__toggle {
        display: inline-flex;
        margin-left: auto;
    }

    .app-bar__nav {
        display: none;
    }

    /* Mobile menu open state */
    .app-bar__nav.open {
        display: flex;
        flex-direction: column;
        position: absolute;
        top: var(--appbar-height);
        left: 0;
        right: 0;
        background: var(--color-surface);
        padding: var(--space-md);
        border-bottom: 1px solid var(--color-border);
        box-shadow: var(--shadow-lg);
        z-index: 1000;
        gap: var(--space-2xs);
    }

    .app-bar__nav.open .app-bar__link {
        padding: var(--space-sm) var(--space-md);
        border-radius: var(--radius-md);
    }

    /* Mobile dropdown: inline stacked (no absolute flyout) */
    .app-bar__dropdown {
        flex-direction: column;
        align-items: stretch;
    }

    .app-bar__dropdown-menu {
        position: static;
        border: none;
        box-shadow: none;
        background: transparent;
        padding: 0;
        min-width: unset;
        animation: none;
    }

    .app-bar__dropdown.open .app-bar__dropdown-menu {
        display: flex;
        flex-direction: column;
    }

    .app-bar__dropdown-item {
        padding: var(--space-xs) var(--space-md) var(--space-xs) var(--space-xl);
        border-radius: var(--radius-md);
        font-size: var(--font-size-xs);
        opacity: 0.8;
    }

    .app-bar__dropdown-item:hover {
        opacity: 1;
    }
}

@media (max-width: 768px) {
    /* Status bar mobile: compact icon-only view */
    .status-bar {
        gap: var(--space-md);
        padding: var(--space-2xs) var(--space-md);
        justify-content: center;
    }

    .status-bar__label {
        display: none;
    }

    .status-bar__meter {
        display: none;
    }

    .status-bar__item--desktop {
        display: none;
    }
}

/* --- Dropzone component for Inbox --- */
.dropzone {
    border: 2px dashed var(--color-border);
    border-radius: var(--radius-xl);
    padding: var(--space-3xl);
    text-align: center;
    background: var(--color-surface-2);
    cursor: pointer;
    transition: all var(--transition-normal);
}

.dropzone:hover,
.dropzone.active {
    border-color: var(--color-primary);
    background: var(--color-primary-light);
}

.dropzone__icon {
    font-size: 3rem;
    margin-bottom: var(--space-md);
    opacity: 0.5;
}

.dropzone__text {
    font-weight: 600;
    font-size: var(--font-size-lg);
}

.dropzone__hint {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    margin-top: var(--space-xs);
}

/* --- Stat Card --- */
.stat-card {
    background: var(--color-surface);
    padding: var(--space-lg);
    border-radius: var(--radius-xl);
    border: 1px solid var(--color-border);
    text-align: center;
}

.stat-card__value {
    font-size: var(--font-size-2xl);
    font-weight: 800;
    color: var(--color-primary-dark);
}

.stat-card__label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-weight: 600;
    text-transform: uppercase;
}

/* --- Stats Row (Dashboard Engagement) --- */
.stats-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-md);
    margin-bottom: var(--space-xl);
}

.stat-item {
    background: var(--color-surface);
    padding: var(--space-md) var(--space-lg);
    border-radius: var(--radius-lg);
    border-left: 4px solid var(--color-primary);
    box-shadow: var(--shadow-sm);
    transition: all var(--transition-fast);
}

.stat-item:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.stat-item--accent {
    border-left-color: var(--color-accent);
}

.stat-item--secondary {
    border-left-color: var(--color-secondary);
}

.stat-item--warning {
    border-left-color: var(--color-warning);
}

.stat-item--neon {
    border: 2px solid #ff2bd6;
    border-left: 2px solid #ff2bd6;
    box-shadow: 0 0 10px rgba(255, 43, 214, 0.5);
}

.stat-item__value {
    font-size: var(--font-size-2xl);
    font-weight: 800;
    color: var(--color-text);
    line-height: 1.1;
}

.stat-item__label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-top: var(--space-2xs);
}

@media (max-width: 992px) {
    .stats-row {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .stats-row {
        grid-template-columns: 1fr;
    }
}

/* --- Empty State Message --- */
.empty-state__message {
    font-size: var(--font-size-md);
    color: var(--color-text-muted);
    font-style: italic;
}

/* --- Alerts --- */
.alert {
    padding: var(--space-md) var(--space-lg);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-lg);
    border: 1px solid transparent;
}

.alert--info {
    background: var(--color-secondary-light);
    border-color: var(--color-secondary);
    color: #01579b;
}

.alert--warning {
    background: #fffde7;
    border-color: #fbc02d;
    color: #f57f17;
}

.alert--success {
    background: var(--color-primary-light);
    border-color: var(--color-primary);
    color: #33691e;
}

.alert--danger {
    background: #ffebee;
    border-color: #ef5350;
    color: #b71c1c;
}

/* ═══════════════════════════════════════════════════════════════════════════
   MODE SWITCH - Modern 3-Way Toggle (Normal / Paid / Advanced)
   ═══════════════════════════════════════════════════════════════════════════ */

.mode-switch {
    display: inline-flex;
    align-items: center;
    background: var(--color-surface-2);
    border-radius: var(--radius-full);
    padding: 4px;
    gap: 2px;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.06);
    position: relative;
}

.mode-switch__option {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-lg);
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
    font-weight: 500;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: all var(--transition-normal);
    border: none;
    background: transparent;
    position: relative;
    z-index: 1;
    white-space: nowrap;
}

.mode-switch__option:hover:not(.mode-switch__option--active) {
    color: var(--color-text);
    background: rgba(255, 255, 255, 0.5);
}

.mode-switch__option--active {
    background: var(--color-surface);
    color: var(--color-primary-dark);
    box-shadow: var(--shadow-md);
    font-weight: 600;
}

/* Variant: Premium (Gold accent for Paid) */
.mode-switch__option--paid.mode-switch__option--active {
    color: #b8860b;
    background: linear-gradient(135deg, #fff 0%, #fffef0 100%);
    box-shadow: var(--shadow-md), 0 0 0 1px rgba(218, 165, 32, 0.2);
}

/* Variant: Pro (Teal accent for Advanced) */
.mode-switch__option--advanced.mode-switch__option--active {
    color: var(--color-accent-dark);
    background: linear-gradient(135deg, #fff 0%, #f0fffd 100%);
    box-shadow: var(--shadow-md), 0 0 0 1px rgba(0, 137, 123, 0.2);
}

.mode-switch__icon {
    font-size: 1rem;
    line-height: 1;
}

/* Hidden radio inputs for form compatibility */
.mode-switch__input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    pointer-events: none;
}

/* Focus state for accessibility */
.mode-switch__input:focus+.mode-switch__option {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* Compact variant for tight spaces */
.mode-switch--compact .mode-switch__option {
    padding: var(--space-2xs) var(--space-md);
    font-size: var(--font-size-xs);
}

/* Large variant for prominent placement */
.mode-switch--lg .mode-switch__option {
    padding: var(--space-sm) var(--space-xl);
    font-size: var(--font-size-md);
}

/* Dark mode variant */
.mode-switch--dark {
    background: rgba(0, 0, 0, 0.1);
}

.mode-switch--dark .mode-switch__option {
    color: rgba(255, 255, 255, 0.7);
}

.mode-switch--dark .mode-switch__option:hover:not(.mode-switch__option--active) {
    color: white;
    background: rgba(255, 255, 255, 0.1);
}

.mode-switch--dark .mode-switch__option--active {
    background: white;
    color: var(--color-text);
}

/* Mobile responsive */
@media (max-width: 480px) {
    .mode-switch {
        width: 100%;
        justify-content: stretch;
    }

    .mode-switch__option {
        flex: 1;
        justify-content: center;
        padding: var(--space-sm) var(--space-xs);
    }

    .mode-switch__label {
        display: none;
    }

    .mode-switch--show-labels-mobile .mode-switch__label {
        display: inline;
        font-size: var(--font-size-xs);
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PAGE CONTROL BAR - Unified page-level navigation/action bar
   Based on Gallery Day View design standard
   ═══════════════════════════════════════════════════════════════════════════ */

.page-control-bar {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: 12px var(--space-md);
    height: 60px;
    margin-bottom: var(--space-md);
}

.page-control-bar__left {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.page-control-bar__title {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-text);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 6px 12px;
    white-space: nowrap;
}

.page-control-bar__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px 8px;
    border-radius: var(--radius-full);
    background: var(--color-primary-light);
    color: var(--color-primary-dark);
    font-size: var(--font-size-xs);
    font-weight: 600;
    min-width: 24px;
}

.page-control-bar__center {
    flex: 1 1 auto;
    display: flex;
    justify-content: center;
    min-width: 0;
}

.page-control-bar__meta {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    white-space: nowrap;
}

.page-control-bar__right {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

/* Select All checkbox styling */
.page-control-bar__select-all {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding: 4px 10px;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: all var(--transition-fast);
    font-size: var(--font-size-sm);
}

.page-control-bar__select-all:hover {
    background: var(--color-surface-3);
    border-color: var(--color-primary);
}

.page-control-bar__checkbox {
    width: 16px;
    height: 16px;
    accent-color: var(--color-primary);
    cursor: pointer;
}

.page-control-bar__checkbox:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.page-control-bar__select-label {
    font-weight: 500;
    color: var(--color-text);
}

/* Focus states for accessibility */
.page-control-bar__checkbox:focus-visible,
.page-control-bar .btn:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* Button styles within control bar */
.page-control-bar .btn {
    height: 32px;
    padding: 0 var(--space-md);
    font-size: var(--font-size-xs);
}

.page-control-bar .btn--icon-only {
    width: 32px;
    padding: 0;
}

/* Selected counter visibility */
#selected-counter {
    transition: opacity var(--transition-fast);
}

#selected-counter:empty,
#selected-counter[data-count="0"] {
    opacity: 0.5;
}

/* Responsive: Two-row layout before dense controls begin to collide. */
@media (max-width: 1100px) {
    .page-control-bar {
        height: auto;
        flex-wrap: wrap;
        padding: var(--space-sm) var(--space-md);
        gap: var(--space-sm);
    }

    .page-control-bar__left {
        order: 1;
    }

    .page-control-bar__right {
        order: 2;
        margin-left: auto;
        max-width: 100%;
        flex-wrap: wrap;
    }

    .page-control-bar__center {
        order: 3;
        flex-basis: 100%;
        justify-content: flex-start;
    }

    .page-control-bar__meta {
        order: 4;
        margin-left: auto;
    }

    /* Icon-only buttons on mobile */
    .page-control-bar .btn--mobile-icon .btn__label {
        display: none;
    }
}

/* Very narrow screens */
@media (max-width: 480px) {
    .page-control-bar__select-label {
        display: none;
    }

    .page-control-bar__meta {
        font-size: 10px;
    }
}

@media (max-width: 720px) {
    .page-control-bar__right {
        flex: 1 1 100%;
        width: 100%;
        min-width: 0;
        margin-left: 0;
        justify-content: flex-start;
    }

    .page-control-bar__meta {
        margin-left: 0;
    }

}

/* Filter bar inside page-control-bar */
.page-control-bar .filter-bar-container {
    display: flex;
    align-items: center;
    margin: 0;
}

.page-control-bar .filter-pill {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: 6px 10px;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    flex-wrap: nowrap;
}

.page-control-bar .filter-group {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    flex-shrink: 0;
}

.page-control-bar .sort-select-minimal {
    flex-shrink: 0;
}

/* --- Filter Control Elements (Slider, Buttons, Dropdown) --- */

.filter-btn-mini {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    padding: 0;
    transition: all var(--transition-fast);
}

.filter-btn-mini:hover {
    background: var(--color-surface-3);
    color: var(--color-primary);
    border-color: var(--color-primary);
}

.filter-btn-mini.active {
    background: var(--color-warning);
    border-color: var(--color-warning);
    color: white;
}

.slider-minimal {
    -webkit-appearance: none;
    appearance: none;
    width: 100px;
    height: 6px;
    background: var(--color-surface-3);
    border-radius: var(--radius-full);
    outline: none;
    margin: 0 4px;
}

.slider-minimal::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--color-primary);
    cursor: pointer;
    border: 2px solid var(--color-surface);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    transition: transform var(--transition-fast);
}

.slider-minimal::-webkit-slider-thumb:hover {
    transform: scale(1.2);
}

.score-badge-pill {
    font-size: var(--font-size-xs);
    font-weight: 600;
    color: var(--color-primary-dark);
    min-width: 36px;
    text-align: center;
}

.sort-select-minimal {
    appearance: none;
    background-color: transparent;
    border: none;
    font-size: var(--font-size-xs);
    font-weight: 500;
    color: var(--color-text);
    padding: 4px 20px 4px 8px;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23636e72' d='M6 8.5L2 4.5h8z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 4px center;
    border-radius: var(--radius-sm);
    transition: background-color var(--transition-fast);
}

.sort-select-minimal:hover {
    background-color: var(--color-surface-3);
}

.sort-select-minimal:focus {
    outline: none;
    background-color: var(--color-surface-3);
}

/* Filter controls are declared after the generic phone layout, so keep the
   narrow-screen overrides next to them to preserve the cascade. */
@media (max-width: 720px) {
    .page-control-bar .filter-bar-container,
    .page-control-bar .filter-pill {
        width: 100%;
        min-width: 0;
    }

    .page-control-bar .filter-pill {
        flex-wrap: wrap;
        border-radius: var(--radius-lg);
    }

    .page-control-bar .filter-group {
        flex: 1 1 100%;
        min-width: 0;
    }

    .page-control-bar .slider-minimal {
        flex: 1 1 60px;
        width: auto;
        min-width: 60px;
    }

    .page-control-bar .sort-select-minimal {
        flex: 1 1 9rem;
        min-width: 0;
        max-width: 100%;
    }

    .filter-btn-mini {
        position: relative;
        flex: 0 0 36px;
        width: 36px;
        min-width: 36px;
        height: 36px;
    }

    .filter-btn-mini::before {
        position: absolute;
        inset: -4px;
        content: "";
    }
}

.review-action-bar {
    position: sticky;
    top: 0;
    z-index: 100;
}

/* ═══════════════════════════════════════════════════════════════════════════
   TRASH GRID - Trash Items
   Migrated from templates/trash.html
   ═══════════════════════════════════════════════════════════════════════════ */

.trash-range-input {
    width: 11rem;
    max-width: 100%;
}

.page-control-bar--trash-summary {
    margin-bottom: var(--space-md);
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-sm);
}

.trash-workbench {
    display: grid;
    grid-template-columns: minmax(300px, 340px) minmax(0, 1fr);
    gap: var(--space-lg);
    align-items: start;
}

.trash-workbench__ops {
    position: sticky;
    top: calc(var(--space-lg) + var(--appbar-height));
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.trash-workbench__content {
    min-width: 0;
}

.page-control-bar--trash-panel {
    height: auto;
    min-height: 0;
    margin-bottom: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    padding: 16px;
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-sm);
}

.page-control-bar--trash-panel .page-control-bar__left,
.page-control-bar--trash-panel .page-control-bar__meta,
.page-control-bar--trash-panel .page-control-bar__right {
    width: 100%;
}

.page-control-bar--trash-panel .page-control-bar__left {
    flex-wrap: wrap;
    align-items: flex-start;
}

.page-control-bar--trash-panel .page-control-bar__meta {
    white-space: normal;
    line-height: 1.4;
}

.page-control-bar--trash-panel .page-control-bar__right {
    justify-content: flex-start;
    flex-wrap: wrap;
}

.page-control-bar--trash-panel .page-control-bar__title {
    background: var(--color-surface-2);
    border-color: var(--color-border);
}

.page-control-bar--trash-panel .page-control-bar__select-all {
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.trash-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--space-lg);
    justify-content: center;
}

.trash-item {
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-xl);
    overflow: hidden;
    position: relative;
    cursor: pointer;
    transition: all var(--transition-fast);
    box-shadow: var(--shadow-sm);
}

.trash-item:hover {
    border-color: var(--color-border);
    transform: translateY(-2px);
}

.trash-item.selected {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 22%, transparent), var(--shadow-sm);
}

.trash-item__image {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
    opacity: 0.72;
}

.trash-item.selected .trash-item__image {
    opacity: 1;
}

.trash-item__checkbox {
    position: absolute;
    top: var(--space-sm);
    right: var(--space-sm);
    width: 22px;
    height: 22px;
    accent-color: var(--color-primary);
    cursor: pointer;
}

.trash-item__type-badge {
    position: absolute;
    top: var(--space-sm);
    left: var(--space-sm);
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: 0.05em;
    padding: 4px 8px;
    border-radius: var(--radius-full);
    background: var(--color-danger);
    color: white;
    z-index: 1;
}

.trash-item__type-badge--image {
    background: var(--color-warning, #d4a017);
    color: var(--color-text);
}

.trash-item__info {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 14px;
    text-align: left;
}

.trash-item__name {
    width: 100%;
    font-size: var(--font-size-base);
    font-weight: 800;
    color: var(--color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.trash-item__time {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-weight: 700;
}

@media (max-width: 960px) {
    .trash-workbench {
        grid-template-columns: 1fr;
    }

    .trash-workbench__ops {
        position: static;
    }
}

@media (max-width: 720px) {
    .trash-range-input {
        width: 100%;
    }

    .page-control-bar--trash-panel .page-control-bar__right {
        flex-direction: column;
        align-items: stretch;
    }

    .trash-grid {
        grid-template-columns: 1fr;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   GALLERY GRID - Subgallery Items
   Migrated from templates/subgallery.html
   ═══════════════════════════════════════════════════════════════════════════ */

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-md);
    justify-content: center;
}

.gallery-item {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: all var(--transition-fast);
    cursor: pointer;
}

.gallery-item:hover {
    border-color: var(--color-primary);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.gallery-item__image {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    display: block;
}

.gallery-item__info {
    padding: var(--space-sm);
    text-align: center;
}

.gallery-item__name {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-text);
    margin-bottom: 2px;
}

.gallery-item__latin {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-style: italic;
    margin-bottom: var(--space-xs);
}

.gallery-item__score {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-accent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   PAGINATION - Shared Style
   Migrated from templates/subgallery.html and templates/trash.html
   ═══════════════════════════════════════════════════════════════════════════ */

.pagination-wrapper {
    display: flex;
    justify-content: center;
    margin: var(--space-xl) 0;
}

.pagination {
    display: flex;
    gap: var(--space-xs);
    list-style: none;
    padding: 0;
    margin: 0;
}

.pagination li a,
.pagination li span {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 var(--space-sm);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
    text-decoration: none;
    font-size: var(--font-size-sm);
    transition: all var(--transition-fast);
}

.pagination li a:hover {
    background: var(--color-surface-2);
    border-color: var(--color-border-light);
    color: var(--color-text);
}

.pagination li.active span {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: white;
}

.pagination li.disabled span {
    opacity: 0.5;
    cursor: not-allowed;
}

.review-pagination {
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
    padding-inline: var(--space-md);
}

.review-pagination .pagination {
    flex-wrap: wrap;
    justify-content: center;
}

.review-pagination .pagination li a,
.review-pagination .pagination li span {
    font-variant-numeric: tabular-nums;
    transition-property: background-color, border-color, color;
}

.review-pagination a:focus-visible,
.review-pagination input:focus-visible,
.review-pagination button:focus-visible {
    outline: 3px solid var(--color-primary);
    outline-offset: 2px;
}

.review-pagination .review-pagination__ellipsis span {
    background: transparent;
    border-color: transparent;
    min-width: 0;
}

.review-pagination__jump {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-sm);
    max-width: 100%;
}

.review-pagination__jump .form-control {
    width: 6rem;
}

.review-pagination__jump .form-control,
.review-pagination__jump .btn {
    min-height: 36px;
}

@media (max-width: 760px), (hover: none), (pointer: coarse) {
    .review-pagination .pagination li a,
    .review-pagination .pagination li span {
        min-width: 44px;
        height: 44px;
    }

    .review-pagination__jump .form-control,
    .review-pagination__jump .btn {
        min-height: 44px;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EMPTY STATE - Shared Style
   ═══════════════════════════════════════════════════════════════════════════ */

.empty-state {
    text-align: center;
    padding: var(--space-3xl);
    color: var(--color-text-muted);
}

.empty-state__icon {
    font-size: 4rem;
    opacity: 0.4;
    margin-bottom: var(--space-lg);
}

/* ═══════════════════════════════════════════════════════════════════════════
   SPECIES GRID - Species Summary Items
   Migrated from templates/species.html
   ═══════════════════════════════════════════════════════════════════════════ */

.species-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-md);
    justify-content: center;
}

.species-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: all var(--transition-fast);
    cursor: pointer;
}

.species-card:hover {
    border-color: var(--color-primary);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.species-card__image {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    display: block;
}

.species-card__info {
    padding: var(--space-sm);
    text-align: center;
}

.species-card__name {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-text);
    margin-bottom: 2px;
}

.species-card__latin {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-style: italic;
    margin-bottom: var(--space-xs);
}

.species-card__score {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-accent);
}

/* Count badge overlay - positioned top-right on thumbnail */
.species-card__count {
    position: absolute;
    top: 8px;
    right: 8px;
    background: var(--color-primary);
    color: white;
    font-size: var(--font-size-xs);
    font-weight: 700;
    padding: 4px 8px;
    border-radius: var(--radius-full);
    min-width: 28px;
    text-align: center;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.filter-info {
    text-align: center;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-lg);
}

/* ═══════════════════════════════════════════════════════════════════════════
   DATE GRID - Gallery Date Cards
   Migrated from templates/gallery.html
   ═══════════════════════════════════════════════════════════════════════════ */

.date-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-md);
    justify-content: center;
}

.date-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: all var(--transition-fast);
    text-decoration: none;
}

.date-card:hover {
    border-color: var(--color-primary);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.date-card__image {
    position: relative;
    aspect-ratio: 1;
    overflow: hidden;
}

.date-card__image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.date-card__count {
    position: absolute;
    top: var(--space-sm);
    right: var(--space-sm);
    background: var(--color-surface);
    color: var(--color-accent);
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    font-weight: 600;
}

.date-card__label {
    padding: var(--space-sm);
    text-align: center;
    font-size: var(--font-size-sm);
    color: var(--color-text);
    font-weight: 500;
}

/* ═══════════════════════════════════════════════════════════════════════════
   STREAM PAGE - Live Video Stream
   Migrated from templates/stream.html
   ═══════════════════════════════════════════════════════════════════════════ */

/* Stream Container - Full-width, centered, prominent.
   The stream page uses a tighter vertical rhythm than the rest of
   the app — 6px instead of --space-lg (24px). Four places hold
   this number: the negative margin-top here (cancels .page's
   24px padding-top down to 6px without touching the global rule),
   margin-bottom here, .section--stream-width margin-top, and the
   inline margin-top on the Best-of-Species board in stream.html.
   If this changes, move all four. */
.stream-wrapper {
    margin-top: calc(6px - var(--space-lg));
    margin-bottom: 6px;
}

.stream-container {
    position: relative;
    /* Desktop ceiling so a 4:3 source (75% height/width) can't dominate
       the viewport. --content-max-width is the shared reading frame when
       a skin defines it; the literal fallback keeps the stream bounded
       even where that var is unset. */
    max-width: var(--content-max-width, 880px);
    margin: 0 auto;
    border-radius: var(--radius-xl);
    overflow: hidden;
    border: 1px solid var(--color-border);
    background: #000;
}

/* Section variant that aligns its content with the Live stream's
   reading frame. Used by the Today's Visitors / Best of Species
   block under the stream so the boards line up vertically with
   the video container above. */
.section--stream-width {
    max-width: var(--content-max-width);
    margin-left: auto;
    margin-right: auto;
    /* Tighter-than-system 6px gap below the video. The global
       .section { margin-top: --space-2xl } would otherwise win
       collapse and balloon this to 48px. See .stream-wrapper for
       the matching rule. */
    margin-top: 6px;
}

.stream-actions {
    max-width: var(--content-max-width);
    /* No vertical margin: this row often renders empty (public view) or
       hidden (admin view, pause banner d-none). Letting it contribute a
       margin-top here would defeat the stream-page's single-rhythm rule
       — see .stream-wrapper { margin-bottom: --space-lg }. */
    margin: 0 auto;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: var(--space-sm);
}

.stream-embed {
    position: relative;
    /* aspect-ratio keeps the frame matched to the source (16:9 until
       stream.html's probe pins --stream-aspect to the real ratio);
       max-height caps how tall a non-16:9 source (4:3 → 75% of width)
       may grow, and the browser shrinks width to honour it, centring
       the frame. width:auto + margin:auto give the side-centring. */
    width: auto;
    max-width: 100%;
    aspect-ratio: var(--stream-aspect, 1.7778);
    max-height: 70vh;
    margin-inline: auto;
}

.stream-embed__frame,
.stream-embed__fallback {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    z-index: 1;
}

.stream-embed__loading-static {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    background: #090909;
    opacity: 1;
    transition: opacity 240ms ease;
    z-index: 2;
}

.stream-embed__loading-static.is-hidden {
    opacity: 0;
    pointer-events: none;
}

.stream-embed__loading-status {
    position: absolute;
    left: var(--space-md);
    bottom: var(--space-md);
    z-index: 3;
    color: #f4ecd9;
    font-size: calc(var(--font-size-sm) * 2);
    font-weight: 600;
    letter-spacing: 0.02em;
    text-shadow: 0 1px 2px #000, 1px 1px 3px #000;
    transition: opacity 240ms ease;
}

.stream-embed__loading-status.is-hidden {
    opacity: 0;
    pointer-events: none;
}

.stream-embed__fallback {
    display: none;
    object-fit: contain;
}

.stream-video {
    width: 100%;
    display: block;
    background: #000;
}

.stream-report-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid rgba(196, 165, 104, 0.26);
    border-radius: 999px;
    background: rgba(33, 27, 20, 0.74);
    color: rgba(255, 248, 235, 0.92);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16);
    backdrop-filter: blur(12px);
    transition:
        transform 0.16s ease,
        background 0.16s ease,
        border-color 0.16s ease,
        color 0.16s ease,
        opacity 0.16s ease;
}

.stream-report-action:hover,
.stream-report-action:focus-visible {
    transform: translateY(-1px);
    background: rgba(47, 38, 28, 0.88);
    border-color: rgba(227, 193, 126, 0.52);
    color: #fffaf0;
}

.stream-report-action:focus-visible {
    outline: 2px solid rgba(227, 193, 126, 0.44);
    outline-offset: 2px;
}

.stream-report-action[disabled] {
    opacity: 0.72;
    cursor: wait;
}

.stream-report-action__icon {
    width: 13px;
    height: 13px;
}

.settings-inline-action {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    flex-wrap: wrap;
    margin-top: 0.85rem;
}

.settings-inline-action__status {
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

.settings-inline-action__status[data-state="error"] {
    color: var(--color-danger);
}

.settings-inline-action__status[data-state="success"] {
    color: var(--color-success);
}

@media (max-width: 767px) {
    .stream-actions {
        padding-right: 0.15rem;
    }

    .stream-report-action {
        position: relative;
        width: 36px;
        height: 36px;
    }

    .stream-report-action::before {
        position: absolute;
        inset: -4px;
        content: "";
    }

    .stream-report-action__icon {
        width: 12px;
        height: 12px;
    }
}

@keyframes pulse {
    0% {
        opacity: 1;
        transform: scale(1);
    }

    50% {
        opacity: 0.5;
        transform: scale(0.8);
    }

    100% {
        opacity: 1;
        transform: scale(1);
    }
}

.stats-row--stream {
    max-width: var(--content-max-width);
    margin-left: auto;
    margin-right: auto;
}

/* ═══════════════════════════════════════════════════════════════════════
   LED TICKER — canvas-based dot-matrix Späti-Laufband under the stream.
   Sits between the live video and the four-tile stats row. Renders a
   live SSE feed of detections plus a heartbeat segment (clock + stats)
   when no recent detections are in the queue.
   ═══════════════════════════════════════════════════════════════════════ */

.led-ticker {
    max-width: var(--content-max-width);
    margin: var(--space-sm) auto;
    padding: 0;
    background: var(--color-bg);
    border: 1px solid var(--color-border-light);
    border-radius: 0;
    box-shadow: none;
    overflow: hidden;
    line-height: 0; /* canvas line-box would add stray pixels */
}

.led-ticker__canvas {
    display: block;
    width: 100%;
    /* image-rendering: pixelated keeps the LED grid crisp when the
       canvas is up-scaled to the on-screen width. */
    image-rendering: pixelated;
    image-rendering: -moz-crisp-edges;
    image-rendering: crisp-edges;
}

@media (prefers-reduced-motion: reduce) {
    /* Honor a11y: hide the ticker entirely under reduced-motion since
       the value is in the scroll. Static-snapshot fallback would just
       show whatever 1280px window happens to be visible — worse UX. */
    .led-ticker { display: none; }
}

/* Timestamp Overlay */
.stream-timestamp {
    position: absolute;
    top: var(--space-md);
    right: var(--space-md);
    padding: var(--space-xs) var(--space-sm);
    background: rgba(0, 0, 0, 0.7);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-family: 'SF Mono', 'Fira Code', monospace;
    backdrop-filter: none;
}

/* PTZ Overlay */
.ptz-overlay {
    position: absolute;
    bottom: var(--space-md);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    background: rgba(0, 0, 0, 0.7);
    border-radius: var(--radius-lg);
    backdrop-filter: none;
    opacity: 0;
    transition: opacity var(--transition-normal);
}

.stream-container:hover .ptz-overlay {
    opacity: 1;
}

.ptz-btn {
    width: 32px;
    height: 32px;
    border: none;
    border-radius: var(--radius-full);
    background: rgba(255, 255, 255, 0.15);
    color: white;
    font-size: 14px;
    cursor: pointer;
    transition: all var(--transition-fast);
    display: flex;
    align-items: center;
    justify-content: center;
}

.ptz-btn:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: scale(1.1);
}

.ptz-btn:active {
    transform: scale(0.95);
}

.ptz-btn:disabled {
    opacity: 0.3;
    cursor: not-allowed;
}

/* D-Pad */
.ptz-dpad {
    display: grid;
    grid-template-columns: repeat(3, 24px);
    grid-template-rows: repeat(3, 24px);
    gap: 2px;
}

.ptz-dpad .ptz-btn {
    width: 24px;
    height: 24px;
    font-size: 10px;
}

.ptz-dpad .center-btn {
    background: rgba(255, 255, 255, 0.05);
}

/* Zoom */
.ptz-zoom {
    display: flex;
    align-items: center;
    gap: 4px;
}

.ptz-zoom input[type="range"] {
    width: 50px;
    height: 4px;
    cursor: pointer;
    accent-color: var(--color-accent);
}

.stream-ptz-status {
    margin-right: auto;
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: var(--space-xs) var(--space-sm);
    background: rgba(0, 0, 0, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: var(--radius-sm);
    color: white;
    font-size: var(--font-size-xs);
    font-family: inherit;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.stream-ptz-status:hover,
.stream-ptz-status:focus-visible {
    background: rgba(0, 0, 0, 0.88);
    border-color: rgba(255, 255, 255, 0.32);
    outline: none;
}

.stream-ptz-status[hidden] {
    display: none;
}

.stream-ptz-status__label {
    color: rgba(255, 255, 255, 0.68);
}

.stream-ptz-status__value {
    font-family: 'SF Mono', 'Fira Code', monospace;
    text-transform: capitalize;
}

/* Landing Status Row */
.landing-health {
    max-width: var(--content-narrow-max-width);
    margin: 0 auto var(--space-xl);
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-md);
}

.landing-health__item {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-sm) var(--space-md);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-sm);
}

.landing-health__item--wide {
    grid-column: 1 / -1;
}

.landing-health__meta {
    display: grid;
    gap: 4px;
    min-width: 0;
}

.landing-health__label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.landing-health__value {
    font-size: var(--font-size-sm);
    color: var(--color-text);
    font-weight: 500;
    text-align: left;
    line-height: 1.35;
    overflow-wrap: anywhere;
}

.landing-health__badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 86px;
    border-radius: var(--radius-full);
    padding: 4px 10px;
    font-size: var(--font-size-xs);
    font-weight: 700;
    border: 1px solid transparent;
    flex-shrink: 0;
}

.landing-health__badge--ok {
    background: rgba(47, 111, 62, 0.14);
    color: #1f6f2e;
    border-color: rgba(47, 111, 62, 0.22);
}

.landing-health__badge--warn {
    background: rgba(246, 173, 85, 0.18);
    color: #9c6100;
    border-color: rgba(246, 173, 85, 0.3);
}

.landing-health__badge--bad {
    background: rgba(229, 62, 62, 0.12);
    color: #b83232;
    border-color: rgba(229, 62, 62, 0.28);
}

.landing-health__badge--neutral {
    background: rgba(120, 134, 156, 0.12);
    color: #5f6f86;
    border-color: rgba(120, 134, 156, 0.22);
}

/* Quiet-day Hero */
.quiet-hero {
    max-width: var(--content-narrow-max-width);
    margin: 0 auto;
    padding: var(--space-xl);
    border-radius: var(--radius-xl);
    border: 1px solid var(--color-border);
    background:
        radial-gradient(circle at top right, rgba(88, 156, 132, 0.16), transparent 35%),
        radial-gradient(circle at 12% 16%, rgba(91, 141, 239, 0.15), transparent 28%),
        var(--color-surface);
}

.quiet-hero__copy {
    margin-bottom: var(--space-md);
}

.quiet-hero__preview {
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--color-border);
}

.quiet-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
}

.quiet-hero__btn {
    text-decoration: none;
    font-size: var(--font-size-sm);
    font-weight: 700;
    border-radius: var(--radius-md);
    padding: 10px 14px;
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

.quiet-hero__btn:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow-sm);
}

.quiet-hero__btn--primary {
    background: var(--color-primary);
    color: #fff;
}

.quiet-hero__btn--secondary {
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    color: var(--color-text);
}

/* Quiet-day Recent Preview.
   No max-width here — the only consumer (Live page Today's Visitors)
   inherits its width from the surrounding section, and .quiet-hero
   .quiet-preview below overrides padding/border for the hero variant.
   A historical 1000px default was always cancelled at the call site. */
.quiet-preview {
    margin: 0 auto;
    padding: var(--space-lg);
    border-radius: var(--radius-xl);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
}

.quiet-hero .quiet-preview {
    max-width: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.quiet-preview__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    margin-bottom: var(--space-md);
}

.quiet-preview__title {
    margin: 0;
    font-size: var(--font-size-lg);
}

.quiet-preview__title-link {
    color: inherit;
    text-decoration: none;
}

.quiet-preview__title-link:hover,
.quiet-preview__title-link:focus-visible {
    color: var(--color-primary-dark);
}

.quiet-preview__all {
    font-size: var(--font-size-sm);
    font-weight: 600;
    text-decoration: none;
    color: var(--color-primary-dark);
}

.quiet-preview__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-sm);
}

.quiet-preview__item {
    text-decoration: none;
    color: inherit;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--color-surface-1);
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

.quiet-preview__item:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-sm);
}

.quiet-preview__link {
    display: block;
    color: inherit;
    text-decoration: none;
}

.quiet-preview__thumb {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    display: block;
}

.quiet-preview__meta {
    padding: var(--space-sm);
    display: grid;
    gap: 2px;
}

.quiet-preview__name {
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: var(--color-text);
}

.quiet-preview__time {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

.quiet-preview__empty {
    margin: 0;
    color: var(--color-text-muted);
}

.best-species-board {
    display: grid;
    gap: var(--space-md);
}

.best-species-board__featured {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-sm);
}

.best-species-board__grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-sm);
}

.best-species-card {
    position: relative;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: linear-gradient(180deg, var(--color-surface) 0%, var(--color-surface-1) 100%);
    transition: transform var(--transition-fast), box-shadow var(--transition-fast),
        border-color var(--transition-fast);
}

.best-species-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
    border-color: var(--color-primary);
}

.best-species-card__link {
    display: flex;
    flex-direction: column;
    height: 100%;
    color: inherit;
    text-decoration: none;
}

.best-species-card__photos {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px;
    background: var(--color-surface-2);
}

.best-species-card__photos--single {
    grid-template-columns: minmax(0, 1fr);
}

.best-species-card__photos .best-species-card__image {
    aspect-ratio: 1 / 1;
}

.best-species-card__photos--single .best-species-card__image {
    aspect-ratio: 2 / 1;
    object-fit: contain;
}

.best-species-board__more > summary {
    width: fit-content;
    margin: 0 auto;
    padding: var(--space-xs) var(--space-md);
    cursor: pointer;
    color: var(--color-text);
}

.best-species-board__more[open] > summary {
    margin-bottom: var(--space-sm);
}

.best-species-card__media {
    position: relative;
}

.best-species-card__media-link {
    display: block;
    width: 100%;
    border: 0;
    padding: 0;
    background: transparent;
    cursor: pointer;
    color: inherit;
    text-decoration: none;
}

.best-species-card__image {
    width: 100%;
    display: block;
    object-fit: cover;
    object-position: center top;
    background: var(--color-surface-2);
}

.best-species-card__image--featured {
    aspect-ratio: 1 / 1;
}

.best-species-card__image--grid {
    aspect-ratio: 1 / 1;
}

.best-species-card__placeholder {
    width: 100%;
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-surface-2);
    font-size: 2rem;
}

.best-species-card__placeholder--featured {
    aspect-ratio: 1 / 1;
}

.best-species-card__story-strip {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px;
    padding: 2px 2px 0;
    background: var(--color-surface-1);
}

.best-species-card__story-strip--link {
    color: inherit;
    text-decoration: none;
}

.best-species-card__story-frame {
    display: block;
    overflow: hidden;
    border-radius: calc(var(--radius-md) - 2px);
    background: var(--color-surface-2);
}

.best-species-card__story-image,
.best-species-card__story-empty {
    width: 100%;
    aspect-ratio: 1 / 1;
    display: block;
}

.best-species-card__story-image {
    object-fit: cover;
    object-position: center top;
}

.best-species-card__story-empty {
    display: flex;
    align-items: center;
    justify-content: center;
}

.best-species-card__body {
    display: grid;
    gap: 6px;
    padding: var(--space-md);
}

.best-species-card__body--compact {
    padding: var(--space-sm);
}

.best-species-card__name {
    font-size: var(--font-size-md);
    font-weight: 700;
    color: var(--color-text);
}

.best-species-card--featured .best-species-card__name {
    font-size: var(--font-size-lg);
}

.best-species-card__latin {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    font-style: italic;
}

.best-species-card__facts {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 2px;
}

.best-species-card__fact {
    display: inline-flex;
    align-items: center;
    min-height: 30px;
    padding: 6px 10px;
    border-radius: var(--radius-full);
    border: 1px solid var(--color-border);
    background: var(--color-surface-2);
    color: var(--color-text-muted);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.best-species-card--featured .best-species-card__fact {
    font-size: 0.9rem;
    min-height: 34px;
    padding: 7px 12px;
}

@media (max-width: 992px) {
    .landing-health {
        grid-template-columns: 1fr;
    }

    .best-species-board__featured,
    .best-species-board__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 640px) {
    .best-species-board__featured,
    .best-species-board__grid {
        grid-template-columns: 1fr;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   RESTORE PAGE - Import Backup
   Migrated from templates/restore.html
   ═══════════════════════════════════════════════════════════════════════════ */

.upload-zone {
    border: 2px dashed var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    text-align: center;
    cursor: pointer;
    transition: all var(--transition-fast);
    background: var(--color-surface-2);
}

.upload-zone:hover,
.upload-zone.drag-over {
    border-color: var(--color-primary);
    background: rgba(47, 111, 62, 0.1);
}

.upload-zone__text {
    font-size: var(--font-size-lg);
    font-weight: 500;
    margin-top: var(--space-md);
}

.upload-zone__hint {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    margin-top: var(--space-sm);
}

.progress-bar {
    height: 8px;
    background: var(--color-surface-2);
    border-radius: 4px;
    overflow: hidden;
}

.progress-bar__fill {
    height: 100%;
    background: var(--color-primary);
    transition: width 0.3s ease;
}

.restore-option {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-sm);
    padding: var(--space-md);
    background: var(--color-surface-2);
    border: 2px solid var(--color-border);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.restore-option:hover {
    border-color: var(--color-border-light);
}

.restore-option.selected {
    border-color: var(--color-primary);
    background: rgba(47, 111, 62, 0.1);
}

.restore-option input[type="checkbox"] {
    width: 20px;
    height: 20px;
    accent-color: var(--color-primary);
    cursor: pointer;
}

.restore-option__content {
    flex: 1;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.restore-option__title {
    font-weight: 600;
    color: var(--color-text);
}

.restore-option__size {
    font-family: 'SF Mono', monospace;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.restore-option__desc {
    width: 100%;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    padding-left: 28px;
}

.db-strategy-box {
    margin-left: 28px;
    padding: var(--space-md);
    background: var(--color-surface-1);
    border-radius: var(--radius-md);
}

.db-strategy-title {
    font-weight: 500;
    margin-bottom: var(--space-sm);
}

.db-strategy-options {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.db-strategy-option {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
}

.db-strategy-option.selected {
    border-color: var(--color-primary);
    background: rgba(47, 111, 62, 0.05);
}

.db-strategy-option__title {
    font-weight: 500;
}

.db-strategy-option__desc {
    width: 100%;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    padding-left: 24px;
}

.settings-preview-box {
    margin-left: 28px;
    padding: var(--space-md);
    background: var(--color-surface-1);
    border-radius: var(--radius-md);
    margin-top: var(--space-md);
}

.settings-preview-title {
    font-weight: 500;
    margin-bottom: var(--space-sm);
}

.settings-preview-content {
    font-family: 'SF Mono', monospace;
    font-size: var(--font-size-sm);
    max-height: 200px;
    overflow-y: auto;
}

.settings-preview-content .key {
    color: var(--color-primary);
}

.settings-preview-content .masked {
    color: var(--color-danger);
}

.progress-stage {
    font-size: var(--font-size-lg);
    font-weight: 600;
}

.progress-message {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.conflicts-title {
    font-weight: 500;
    color: var(--color-warning);
    margin-bottom: var(--space-sm);
}

.conflicts-list {
    font-size: var(--font-size-sm);
    font-family: 'SF Mono', monospace;
    max-height: 150px;
    overflow-y: auto;
    padding-left: var(--space-md);
}

.stat-row {
    display: flex;
    justify-content: space-between;
    padding: var(--space-sm) 0;
    border-bottom: 1px solid var(--color-border);
}

.stat-row:last-child {
    border-bottom: none;
}

.stat-row__label {
    color: var(--color-text-muted);
}

.stat-row__value {
    font-weight: 500;
    color: var(--color-text);
}

/* ═══════════════════════════════════════════════════════════════════════════
   BACKUP PAGE - Create Backup
   Migrated from templates/backup.html
   ═══════════════════════════════════════════════════════════════════════════ */

.backup-option {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-sm);
    padding: var(--space-md);
    background: var(--color-surface-2);
    border: 2px solid var(--color-border);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-md);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.backup-option:hover {
    border-color: var(--color-border-light);
}

.backup-option.selected {
    border-color: var(--color-primary);
    background: rgba(47, 111, 62, 0.1);
}

.backup-option input[type="checkbox"] {
    width: 20px;
    height: 20px;
    accent-color: var(--color-primary);
    cursor: pointer;
}

.backup-option__content {
    flex: 1;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.backup-option__title {
    font-weight: 600;
    color: var(--color-text);
}

.backup-option__size {
    font-family: 'SF Mono', monospace;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.backup-option__desc {
    width: 100%;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    padding-left: 28px;
}

.recovery-discovery {
    display: grid;
    gap: var(--space-xs, 0.35rem);
    margin: var(--space-md, 0.75rem) 0;
    padding: var(--space-md, 0.9rem);
    border: 1px solid var(--color-primary, #53676b);
    border-left-width: 4px;
    border-radius: var(--radius-md, 0.5rem);
    background: var(--color-surface-2, #f4f6f5);
}

.recovery-discovery[hidden] {
    display: none;
}

.wm-modal__fields.recovery-preview {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-md, 0.75rem);
}

.recovery-preview__item {
    min-width: 0;
    padding: var(--space-sm, 0.6rem);
    border-radius: var(--radius-md, 0.5rem);
    background: var(--color-surface-2, #f4f6f5);
}

.recovery-preview__item strong,
.recovery-preview__item span {
    display: block;
}

.recovery-preview__wide {
    grid-column: 1 / -1;
}

.recovery-confirmations {
    display: grid;
    gap: var(--space-sm, 0.6rem);
    margin-right: auto;
    text-align: left;
}

.recovery-confirmations label {
    display: flex;
    align-items: flex-start;
    gap: var(--space-sm, 0.6rem);
}

.wm-modal__action--form:has(.recovery-confirmations) {
    flex-direction: column;
    align-items: stretch;
}

.wm-modal__action--form:has(.recovery-confirmations) .wm-modal__actions {
    justify-content: flex-end;
}

#usbRecoveryModal .wm-modal__content,
#usbRecoveryModal .wm-modal__form {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

#usbRecoveryModal .wm-modal__form,
#usbRecoveryModal .wm-modal__body {
    flex: 1 1 auto;
}

#usbRecoveryModal .wm-modal__body {
    min-height: 0;
    overflow-y: auto;
}

#usbRecoveryModal .wm-modal__action {
    flex: 0 0 auto;
}

@media (max-width: 640px) {
    .wm-modal__fields.recovery-preview {
        grid-template-columns: 1fr;
    }

    .recovery-preview__wide {
        grid-column: auto;
    }

}

.total-size-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--space-md) var(--space-lg);
    background: var(--color-primary);
    color: white;
    border-radius: var(--radius-lg);
    font-weight: 500;
}

.total-size-value {
    font-size: var(--font-size-xl);
    font-weight: 700;
    font-family: 'SF Mono', monospace;
}

/* ═══════════════════════════════════════════════════════════════════════════
   EDIT PAGE - Edit Detections
   Migrated from templates/edit.html
   ═══════════════════════════════════════════════════════════════════════════ */

.gallery-grid-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 1.5rem;
    padding-bottom: 100px;
}

.edit-tile {
    position: relative;
    border: 1px solid #dee2e6;
    padding: 10px;
    border-radius: 8px;
    transition: transform 0.2s;
    cursor: pointer;
}

.edit-tile:hover {
    transform: translateY(-5px);
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}

.edit-checkbox-wrapper {
    position: absolute;
    top: 15px;
    left: 15px;
    z-index: 10;
    background: rgba(255, 255, 255, 0.8);
    padding: 5px;
    border-radius: 4px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    cursor: default;
}

.edit-checkbox {
    width: 1.2rem;
    height: 1.2rem;
    cursor: pointer;
}

.sticky-action-footer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1000;
}

.wm-batch-footer {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    padding: 10px 20px;
    background: rgba(26, 29, 35, 0.95);
    border-top: 1px solid rgba(167, 139, 250, 0.3);
    backdrop-filter: none;
    justify-content: center;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.wm-batch-footer.visible,
.wm-batch-footer--static {
    display: flex;
}

.wm-batch-footer__counter {
    color: rgba(255, 255, 255, 0.7);
    font-size: var(--font-size-sm);
}

.wm-batch-footer .btn {
    font-size: var(--font-size-sm);
    padding: 6px 16px;
    white-space: nowrap;
}

/* Button contrast overrides for the dark batch-footer scope. The base
   .btn-- variants were designed for light page backgrounds; on the
   dark footer they either vanish (btn--danger reads as light-on-dark)
   or drop below readable contrast when disabled (opacity 0.5 on
   already-muted tones). Force bright backgrounds + white text inside
   the footer so every action stays visible even with 0 selection. */
.wm-batch-footer .btn--danger {
    background-color: var(--color-danger);
    border-color: var(--color-danger);
    color: #fff;
}

.wm-batch-footer .btn--danger:hover:not(:disabled) {
    background-color: var(--color-danger);
    filter: brightness(1.1);
    color: #fff;
}

.wm-batch-footer .btn--outline-danger {
    background-color: transparent;
    border-color: rgba(239, 83, 80, 0.85);
    color: rgba(255, 183, 178, 1);
}

.wm-batch-footer .btn--outline-danger:hover:not(:disabled) {
    background-color: rgba(239, 83, 80, 0.18);
    color: #fff;
}

.wm-batch-footer .btn--primary {
    background-color: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.wm-batch-footer .btn--outline-primary {
    background-color: transparent;
    border-color: rgba(167, 139, 250, 0.7);
    color: rgba(221, 214, 254, 1);
}

.wm-batch-footer .btn--outline-primary:hover:not(:disabled) {
    background-color: rgba(167, 139, 250, 0.18);
    color: #fff;
}

.wm-batch-footer .btn--secondary {
    background-color: transparent;
    border-color: rgba(255, 255, 255, 0.3);
    color: rgba(255, 255, 255, 0.92);
}

.wm-batch-footer .btn--secondary:hover:not(:disabled) {
    background-color: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.55);
    color: #fff;
}

/* Disabled state: keep the button visible (outline + label readable)
   instead of letting opacity 0.5 wash it out against the dark bg. */
.wm-batch-footer .btn:disabled {
    opacity: 1;
    filter: saturate(0.55) brightness(0.85);
    cursor: not-allowed;
    color: rgba(255, 255, 255, 0.62);
    border-color: rgba(255, 255, 255, 0.18);
}

.wm-batch-footer .btn--danger:disabled,
.wm-batch-footer .btn--primary:disabled {
    background-color: rgba(255, 255, 255, 0.08);
}

.thumbnail-wrapper img {
    width: 100%;
    height: auto;
    object-fit: cover;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LOGS PAGE - System Logs Viewer
   Migrated from templates/logs.html
   ═══════════════════════════════════════════════════════════════════════════ */

.log-viewer {
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
    font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
    font-size: 12px;
    line-height: 1.6;
    overflow-y: auto;
    overflow-x: auto;
    max-height: 70vh;
    min-width: 0;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow-wrap: anywhere;
    color: var(--color-text-muted);
}

.log-viewer div {
    padding: 2px 0;
    border-bottom: 1px solid var(--color-surface-2);
}

.log-viewer div:last-child {
    border-bottom: none;
}

.log-info {
    color: #58a6ff;
}

.log-warning {
    color: #d29922;
}

.log-error {
    color: #f85149;
    font-weight: 600;
}

.log-timestamp {
    color: var(--color-text-subtle);
}

.log-name {
    color: #7ee787;
}

/* Scrollbar */
.log-viewer::-webkit-scrollbar {
    width: 8px;
}

.log-viewer::-webkit-scrollbar-track {
    background: var(--color-surface);
    border-radius: var(--radius-sm);
}

.log-viewer::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: var(--radius-sm);
}

.log-viewer::-webkit-scrollbar-thumb:hover {
    background: var(--color-border-light);
}

.filter-btn {
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    font-weight: 500;
    border: 1px solid var(--color-border);
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.filter-btn.active {
    background: var(--color-surface-2);
    color: var(--color-text);
    border-color: var(--color-border-light);
}

.filter-btn[data-level="INFO"]:hover,
.filter-btn[data-level="INFO"].active {
    color: #58a6ff;
    border-color: #58a6ff;
}

.filter-btn[data-level="WARNING"]:hover,
.filter-btn[data-level="WARNING"].active {
    color: #d29922;
    border-color: #d29922;
}

.filter-btn[data-level="ERROR"]:hover,
.filter-btn[data-level="ERROR"].active {
    color: #f85149;
    border-color: #f85149;
}

.logs-page-actions {
    display: flex;
    gap: var(--space-sm);
    align-items: center;
}

.logs-auto-refresh {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.logs-summary-grid {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.logs-summary-note {
    margin-top: var(--space-xs);
}

.logs-metric-value {
    font-size: 1.2rem;
    line-height: 1.25;
    word-break: break-word;
}

.logs-tabbar {
    display: flex;
    gap: var(--space-xs);
    align-items: center;
    flex-wrap: wrap;
    min-width: 0;
}

.logs-tab {
    white-space: nowrap;
}

.logs-card-body {
    padding: 0;
}

.logs-pane {
    display: none;
}

.logs-pane.active {
    display: block;
}

.logs-pane-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-sm);
    padding: 12px 14px;
    border-bottom: 1px solid var(--color-border);
    background: var(--color-surface);
    flex-wrap: wrap;
    min-width: 0;
}

.logs-pane-header > :first-child {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.logs-level-filters {
    display: flex;
    gap: var(--space-xs);
    flex-wrap: wrap;
    flex-shrink: 0;
}

.logs-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-sm);
    flex-wrap: wrap;
}

.logs-footer-controls {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-xs);
}

@media (max-width: 720px) {
    .logs-pane-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .logs-page-actions {
        width: 100%;
        justify-content: flex-start;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ANALYTICS PAGE - Pure CSS/Jinja2 Implementation
   Migrated from templates/analytics_pure.html
   ═══════════════════════════════════════════════════════════════════════════ */

.analytics-dashboard {
    max-width: 1200px;
    margin: 0 auto;
}

.dashboard-header {
    text-align: center;
    margin-bottom: var(--space-xl);
    padding: var(--space-lg);
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-dark) 100%);
    border-radius: var(--radius-xl);
    color: white;
    box-shadow: 0 4px 20px rgba(76, 175, 80, 0.3);
}

.dashboard-header__title {
    margin: 0;
    font-size: var(--font-size-3xl);
    font-weight: 700;
    letter-spacing: -0.5px;
    color: white;
}

.dashboard-header__subtitle {
    margin: var(--space-xs) 0 0;
    opacity: 0.9;
    font-size: var(--font-size-md);
    font-weight: 400;
}

/* Summary Cards Grid */
.summary-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-md);
    margin-bottom: var(--space-xl);
}

@media (max-width: 992px) {
    .summary-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .summary-grid {
        grid-template-columns: 1fr;
    }
}

.summary-card {
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    box-shadow: var(--shadow-sm);
    border-left: 4px solid var(--color-primary);
    transition: all var(--transition-fast);
}

.summary-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.summary-card--accent {
    border-left-color: var(--color-accent);
}

.summary-card--secondary {
    border-left-color: var(--color-secondary);
}

.summary-card--warning {
    border-left-color: var(--color-warning);
}

.summary-card--event {
    border-left-color: var(--color-info);
}

.summary-card__value {
    font-size: var(--font-size-2xl);
    font-weight: 800;
    color: var(--color-text);
    line-height: 1.1;
}

.summary-card__label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-top: var(--space-2xs);
}

/* Chart Cards */
.chart-card {
    background: var(--color-surface);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-sm);
    padding: var(--space-lg);
    margin-bottom: var(--space-xl);
    transition: all var(--transition-fast);
}

.chart-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.chart-card__title {
    margin: 0 0 var(--space-md) 0;
    font-size: var(--font-size-md);
    font-weight: 600;
    color: var(--color-text);
    padding-bottom: var(--space-sm);
    border-bottom: 2px solid var(--color-border-light);
}

.chart-card__badge {
    float: right;
    background: rgba(76, 175, 80, 0.1);
    color: var(--color-primary-dark);
    font-size: var(--font-size-xs);
    font-weight: 600;
    padding: var(--space-2xs) var(--space-sm);
    border-radius: var(--radius-full);
}

.chart-card__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    margin-bottom: var(--space-md);
}

.chart-card__toolbar .chart-card__title {
    margin-bottom: 0;
    padding-bottom: 0;
    border-bottom: none;
}

.chart-card__meta {
    margin: calc(var(--space-xs) * -1) 0 var(--space-sm);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

@media (max-width: 768px) {
    .chart-card__toolbar {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* Pure CSS Time-of-Day Histogram */
.histogram {
    display: flex;
    align-items: flex-end;
    height: 200px;
    gap: 2px;
    padding: var(--space-md) 0;
}

.histogram__bar {
    flex: 1;
    background: linear-gradient(to top, var(--color-primary), var(--color-primary-light));
    border-radius: 2px 2px 0 0;
    min-height: 4px;
    transition: all var(--transition-fast);
    position: relative;
}

.histogram__bar:hover {
    background: linear-gradient(to top, var(--color-primary-dark), var(--color-primary));
}

.histogram__bar:hover::after {
    content: attr(data-count);
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    background: var(--color-text);
    color: white;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 10px;
    white-space: nowrap;
}

.histogram__labels {
    display: flex;
    justify-content: space-between;
    padding-top: var(--space-xs);
    border-top: 1px solid var(--color-border);
}

.histogram__label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

/* Species Activity Table */
.species-table {
    width: 100%;
    border-collapse: collapse;
}

.species-table__header {
    display: flex;
    padding: var(--space-sm) var(--space-md);
    font-weight: 600;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    border-bottom: 2px solid var(--color-primary);
    margin-bottom: var(--space-xs);
    background: var(--color-bg);
}

.species-table__row {
    display: flex;
    align-items: center;
    padding: var(--space-xs) var(--space-md);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    margin-bottom: 2px;
    transition: background var(--transition-fast);
}

.species-table__row:hover {
    background: var(--color-surface-2);
}

.species-table__axis-row {
    display: flex;
    align-items: center;
    padding: 0 var(--space-md) var(--space-xs);
    margin-bottom: var(--space-xs);
}

.species-table__col-name {
    width: 180px;
    flex-shrink: 0;
    font-weight: 500;
    color: var(--color-text);
    font-style: italic;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.species-table__col-graph {
    flex: 1;
    height: 30px;
    margin: 0 var(--space-md);
}

.species-table__axis-labels {
    display: grid;
    grid-template-columns: repeat(24, minmax(0, 1fr));
    gap: 0;
    font-size: 9px;
    line-height: 1;
    color: var(--color-text-muted);
    font-family: 'SF Mono', 'Fira Code', monospace;
}

.species-table__axis-label {
    text-align: center;
    opacity: 0.6;
}

.species-table__axis-label--major {
    opacity: 1;
    color: var(--color-text);
    font-weight: 600;
}

.species-table__col-peak {
    width: 60px;
    flex-shrink: 0;
    text-align: right;
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.species-table__col-count {
    width: 50px;
    flex-shrink: 0;
    text-align: right;
    font-weight: 600;
    color: var(--color-primary-dark);
}

/* Sparkline SVG */
.sparkline {
    width: 100%;
    height: 30px;
    display: block;
}

.sparkline__guide {
    stroke: rgba(15, 23, 42, 0.08);
    stroke-width: 0.75;
    vector-effect: non-scaling-stroke;
}

.sparkline__guide--major {
    stroke: rgba(15, 23, 42, 0.16);
}

/* Loading State */
.loading-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: var(--space-3xl);
    background: var(--color-surface);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-sm);
}

.spinner {
    width: 40px;
    height: 40px;
    border: 3px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin-bottom: var(--space-md);
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

/* ── Section Utilities ─────────────────────────────────────────── */

/* Section Divider */
.section-divider {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin: var(--space-2xl) 0 var(--space-xl) 0;
    padding: var(--space-md) 0;
}

.section-divider::before,
.section-divider::after {
    content: "";
    flex: 1;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--color-border), transparent);
}

.section-divider__icon {
    font-size: 1.5rem;
}

.section-divider__text {
    font-size: var(--font-size-lg);
    font-weight: 700;
    color: var(--color-text);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    white-space: nowrap;
}

/* Summary Grid Variants */
.summary-grid--2col {
    grid-template-columns: repeat(2, 1fr);
}

.summary-grid--3col {
    grid-template-columns: repeat(3, 1fr);
}

.summary-card--noise {
    border-left-color: #9ca3af;
}

/* Histogram Legend */
.histogram-legend {
    display: flex;
    gap: var(--space-lg);
    margin-bottom: var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.histogram-legend__item {
    display: flex;
    align-items: center;
    gap: 6px;
}

.histogram-legend__swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 3px;
}

.histogram-legend__swatch--noise {
    background: linear-gradient(to top, #9ca3af, #d1d5db);
}

/* Overlay Histogram Container */
.histogram-overlay {
    position: relative;
    height: 200px;
}

.histogram--layer {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: flex-end;
    gap: 2px;
    padding: var(--space-md) 0;
}

/* Noise bars (gray, behind) */
.histogram__bar--noise {
    background: linear-gradient(to top, #9ca3af, #d1d5db);
    opacity: 0.45;
    border-radius: 2px 2px 0 0;
    min-height: 2px;
    flex: 1;
    transition: all var(--transition-fast);
}

.histogram__bar--noise:hover {
    opacity: 0.7;
    background: linear-gradient(to top, #6b7280, #9ca3af);
}

/* Score Badges */
.species-table__col-score {
    width: 90px;
    flex-shrink: 0;
    display: flex;
    gap: 4px;
    justify-content: flex-end;
}

.score-badge {
    display: inline-block;
    padding: 1px 6px;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    font-family: 'SF Mono', 'Fira Code', monospace;
    background: rgba(47, 111, 62, 0.1);
    color: var(--color-primary-dark);
}

.score-badge--max {
    background: rgba(47, 111, 62, 0.2);
    font-weight: 600;
}

/* Date Range Column */
.species-table__col-dates {
    width: 140px;
    flex-shrink: 0;
    text-align: right;
}

.date-range-text {
    font-size: var(--font-size-xs);
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: var(--color-text-muted);
    white-space: nowrap;
}

@media (max-width: 768px) {
    .chart-card__toolbar {
        flex-direction: column;
        align-items: flex-start;
    }

    .summary-grid--2col {
        grid-template-columns: 1fr;
    }

    .summary-grid--3col {
        grid-template-columns: 1fr;
    }

    .species-table__col-dates {
        display: none;
    }

    .species-table__col-score {
        width: 70px;
    }

    .species-table__col-name {
        width: 132px;
    }

    .species-table__col-graph {
        margin: 0 var(--space-sm);
    }

    .species-table__axis-labels {
        font-size: 8px;
    }
}

/* Event Intelligence */
.section-divider--events::before,
.section-divider--events::after {
    background: linear-gradient(90deg, transparent, var(--color-info), transparent);
}

.section-divider--events .section-divider__text {
    color: var(--color-info);
}

.event-profile-list {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-xs);
    max-width: 560px;
}

.event-profile-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    border-radius: var(--radius-full);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border-light);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
}

.event-profile-pill strong {
    color: var(--color-text);
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: 0.95em;
}

.event-intelligence-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-xl);
}

.event-intelligence-block {
    min-width: 0;
}

.event-intelligence-block__title {
    margin: 0 0 var(--space-sm);
    color: var(--color-text);
    font-size: var(--font-size-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.event-intelligence-table {
    display: grid;
    gap: 2px;
}

.event-intelligence-table__row {
    display: grid;
    grid-template-columns: minmax(120px, 1fr) 72px 72px 88px;
    align-items: center;
    gap: var(--space-xs);
    min-height: 34px;
    padding: 6px var(--space-sm);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: var(--font-size-sm);
}

.event-intelligence-table__row--header {
    background: var(--color-bg);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 2px solid var(--color-info);
}

.event-intelligence-table__row span:not(:first-child) {
    text-align: right;
    font-family: 'SF Mono', 'Fira Code', monospace;
}

.event-intelligence-table__species {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-style: italic;
}

@media (max-width: 900px) {
    .event-intelligence-grid {
        grid-template-columns: 1fr;
    }

    .event-profile-list {
        justify-content: flex-start;
    }
}

@media (max-width: 560px) {
    .event-intelligence-table__row {
        grid-template-columns: minmax(84px, 1fr) 52px 52px 68px;
        padding-inline: var(--space-xs);
        font-size: var(--font-size-xs);
    }
}

/* ── Weather Analytics Section ───────────────────────────────────── */

:root {
    --color-weather-temp: #ef6c35;
    --color-weather-temp-light: #fdba74;
    --color-weather-rain: #3b82f6;
    --color-weather-rain-light: #93c5fd;
    --color-weather-wind: #0d9488;
    --color-weather-wind-light: #5eead4;
    --color-weather-bg: rgba(239, 108, 53, 0.04);
}

/* Section Divider - Weather variant */
.section-divider--weather::before,
.section-divider--weather::after {
    background: linear-gradient(90deg, transparent, var(--color-weather-temp), transparent);
}

.section-divider--weather .section-divider__text {
    color: var(--color-weather-temp);
}

/* Weather Summary Cards */
.summary-grid--4col {
    grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 992px) {
    .summary-grid--4col {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .summary-grid--4col {
        grid-template-columns: 1fr;
    }
}

.summary-card--weather {
    border-left-color: var(--color-weather-temp);
}

.summary-card--weather-temp {
    border-left-color: var(--color-weather-temp-light);
}

.summary-card--weather-rain {
    border-left-color: var(--color-weather-rain);
}

.summary-card--weather-wind {
    border-left-color: var(--color-weather-wind);
}

.weather-emoji-lg {
    font-size: 1.6em;
    vertical-align: -3px;
    margin-right: 4px;
}

/* Weather Chart Card */
.chart-card--weather {
    border-top: 3px solid var(--color-weather-temp);
    background: linear-gradient(180deg, var(--color-weather-bg), var(--color-surface));
}

.chart-card__badge--weather {
    background: rgba(239, 108, 53, 0.1);
    color: var(--color-weather-temp);
}

/* Weather Legend Swatches */
.histogram-legend__swatch--temp {
    background: var(--color-weather-temp);
}

.histogram-legend__swatch--wind-line {
    background: var(--color-weather-wind);
    background: repeating-linear-gradient(90deg,
            var(--color-weather-wind) 0 4px,
            transparent 4px 7px);
}

.histogram-legend__swatch--precip {
    background: var(--color-weather-rain);
    opacity: 0.5;
}

/* Temperature/Wind Timeline */
.weather-timeline {
    position: relative;
    height: 140px;
    margin-bottom: var(--space-xs);
}

.weather-timeline__y-labels {
    position: absolute;
    top: 0;
    right: 0;
    height: 120px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 10px 0;
    font-size: var(--font-size-xs);
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: var(--color-text-muted);
    pointer-events: none;
}

/* Condition Distribution */
.condition-dist {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.condition-dist__row {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-xs) 0;
}

.condition-dist__label {
    width: 160px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 6px;
}

.condition-dist__emoji {
    font-size: 1.2em;
}

.condition-dist__text {
    font-size: var(--font-size-sm);
    color: var(--color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.condition-dist__bar-wrap {
    flex: 1;
    height: 24px;
    background: var(--color-surface-2);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.condition-dist__bar {
    height: 100%;
    background: linear-gradient(90deg, var(--color-weather-temp), var(--color-weather-temp-light));
    border-radius: var(--radius-sm);
    display: flex;
    align-items: center;
    padding-left: 8px;
    min-width: 36px;
    transition: width 0.5s ease;
}

.condition-dist__bar--activity {
    background: linear-gradient(90deg, var(--color-primary), var(--color-primary-light));
}

.condition-dist__pct {
    font-size: var(--font-size-xs);
    font-weight: 600;
    color: white;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
    white-space: nowrap;
}

.condition-dist__count {
    width: 80px;
    flex-shrink: 0;
    text-align: right;
    font-size: var(--font-size-sm);
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: var(--color-text-muted);
}

/* Weekly Weather Summary */
.weekly-weather {
    overflow: hidden;
}

.weekly-weather__header {
    display: flex;
    padding: var(--space-xs) var(--space-sm);
    font-weight: 600;
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    color: var(--color-text-muted);
    border-bottom: 2px solid var(--color-weather-temp);
    margin-bottom: var(--space-xs);
}

.weekly-weather__row {
    display: flex;
    align-items: center;
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-sm);
    transition: background var(--transition-fast);
    margin-bottom: 2px;
}

.weekly-weather__row:hover {
    background: var(--color-surface-2);
}

.weekly-weather__col-day {
    width: 64px;
    flex-shrink: 0;
}

.weekly-weather__date {
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: var(--font-size-sm);
    color: var(--color-text);
}

.weekly-weather__col-temp {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
}

.weekly-weather__temp-lo,
.weekly-weather__temp-hi {
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    width: 38px;
    flex-shrink: 0;
    text-align: right;
    white-space: nowrap;
}

.weekly-weather__temp-hi {
    text-align: left;
    color: var(--color-weather-temp);
    font-weight: 600;
}

.weekly-weather__temp-range {
    flex: 1;
    min-width: 60px;
    height: 6px;
    background: var(--color-surface-2);
    border-radius: 3px;
    position: relative;
    overflow: hidden;
}

.weekly-weather__temp-bar {
    position: absolute;
    top: 0;
    height: 100%;
    /* gradient set inline via hue_lo/hue_hi for cold→warm coloring */
    border-radius: 3px;
    min-width: 8px;
    transition: background 0.3s ease;
}

.weekly-weather__col-bar {
    width: 160px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: var(--space-xs);
}

.weekly-weather__precip-bar-wrap {
    flex: 1;
    height: 8px;
    background: var(--color-surface-2);
    border-radius: 4px;
    overflow: hidden;
}

.weekly-weather__precip-bar {
    height: 100%;
    background: linear-gradient(90deg, var(--color-weather-rain-light), var(--color-weather-rain));
    border-radius: 4px;
    min-width: 4px;
}

.weekly-weather__precip-val {
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: var(--font-size-xs);
    color: var(--color-weather-rain);
    font-weight: 500;
    white-space: nowrap;
}

.weekly-weather__precip-none {
    font-size: var(--font-size-sm);
    color: var(--color-text-subtle);
}

.weekly-weather__col-wind {
    width: 90px;
    flex-shrink: 0;
    text-align: right;
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    white-space: nowrap;
}

@media (max-width: 768px) {
    .condition-dist__label {
        width: 120px;
    }

    .condition-dist__count {
        width: 50px;
        font-size: var(--font-size-xs);
    }

    .weekly-weather__col-bar {
        width: 100px;
    }

    .weekly-weather__col-wind {
        display: none;
    }
}

/* ── Species Impact Simulation Section ──────────────────────────────── */

:root {
    --color-sim: #0891b2;
    --color-sim-dark: #0e7490;
    --color-sim-light: #22d3ee;
    --color-sim-bg: rgba(8, 145, 178, 0.04);
    --color-delta-positive: #16a34a;
    --color-delta-negative: #dc2626;
}

/* Section Divider - Simulation variant */
.section-divider--simulation::before,
.section-divider--simulation::after {
    background: linear-gradient(90deg, transparent, var(--color-sim), transparent);
}

.section-divider--simulation .section-divider__text {
    color: var(--color-sim-dark);
}

/* Simulation Chart Card */
.chart-card--simulation {
    border-top: 3px solid var(--color-sim);
    background: linear-gradient(180deg, var(--color-sim-bg), var(--color-surface));
}

.chart-card__badge--simulation {
    background: rgba(8, 145, 178, 0.1);
    color: var(--color-sim-dark);
}

.sim-description {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    margin: 0 0 var(--space-lg) 0;
    line-height: 1.6;
}

/* Species Selector */
.sim-selector {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-xl);
}

.sim-selector__label {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-text);
    white-space: nowrap;
}

.sim-select {
    flex: 1;
    max-width: 400px;
    padding: var(--space-sm) var(--space-md);
    background: var(--color-surface-2);
    border: 2px solid var(--color-border);
    border-radius: var(--radius-lg);
    color: var(--color-text);
    font-size: var(--font-size-sm);
    font-family: inherit;
    cursor: pointer;
    transition: all var(--transition-fast);
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%239ca3af' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 36px;
}

.sim-select:hover {
    border-color: var(--color-sim);
}

.sim-select:focus {
    outline: none;
    border-color: var(--color-sim);
    box-shadow: 0 0 0 3px rgba(8, 145, 178, 0.15);
}

.sim-loading {
    font-size: 1.2em;
    animation: pulse 1s ease-in-out infinite;
}

@keyframes pulse {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0.4;
    }
}

/* Delta Metric Cards Grid */
.sim-delta-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-md);
    margin-bottom: var(--space-xl);
}

@media (max-width: 992px) {
    .sim-delta-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .sim-delta-grid {
        grid-template-columns: 1fr;
    }
}

.sim-delta-card {
    background: var(--color-surface-2);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
    border-left: 4px solid var(--color-border);
    transition: all 0.4s ease;
}

.sim-delta-card--negative {
    border-left-color: var(--color-delta-negative);
    background: rgba(220, 38, 38, 0.04);
}

.sim-delta-card--positive {
    border-left-color: var(--color-delta-positive);
    background: rgba(22, 163, 74, 0.04);
}

.sim-delta-card__label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: var(--space-xs);
}

.sim-delta-card__values {
    display: flex;
    align-items: baseline;
    gap: var(--space-xs);
    margin-bottom: var(--space-2xs);
}

.sim-delta-card__real {
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: var(--font-size-lg);
    font-weight: 700;
    color: var(--color-text);
}

.sim-delta-card__arrow {
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.sim-delta-card__sim {
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: var(--font-size-lg);
    font-weight: 700;
    color: var(--color-sim);
}

.sim-delta-card__delta {
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-text-muted);
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    display: inline-block;
}

.sim-delta-card__delta--negative {
    color: var(--color-delta-negative);
    background: rgba(220, 38, 38, 0.08);
}

.sim-delta-card__delta--positive {
    color: var(--color-delta-positive);
    background: rgba(22, 163, 74, 0.08);
}

/* Time Series Chart */
.sim-chart-container {
    margin-top: var(--space-lg);
}

.sim-chart__subtitle {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-text);
    margin: 0 0 var(--space-sm) 0;
}

.sim-chart-legend {
    display: flex;
    gap: var(--space-lg);
    margin-bottom: var(--space-md);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.sim-chart-legend__item {
    display: flex;
    align-items: center;
    gap: 6px;
}

.sim-chart-legend__swatch {
    display: inline-block;
    width: 24px;
    height: 3px;
    border-radius: 2px;
}

.sim-chart-legend__swatch--real {
    background: var(--color-primary);
}

.sim-chart-legend__swatch--sim {
    background: var(--color-sim);
    background: repeating-linear-gradient(90deg,
            var(--color-sim) 0 6px,
            transparent 6px 10px);
    height: 3px;
}

.sim-timeline {
    position: relative;
    height: 180px;
    margin-bottom: var(--space-xs);
}

.sim-timeline__svg {
    width: 100%;
    height: 160px;
    display: block;
}

.sim-timeline__y-labels {
    position: absolute;
    top: 0;
    right: 0;
    height: 160px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 15px 0 5px 0;
    font-size: var(--font-size-xs);
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: var(--color-text-muted);
    pointer-events: none;
}

.sim-empty-hint {
    text-align: center;
    padding: var(--space-lg);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    opacity: 0.7;
}

@media (max-width: 768px) {
    .sim-selector {
        flex-direction: column;
        align-items: stretch;
    }

    .sim-select {
        max-width: 100%;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   FILTER BAR - Score Slider and Sort Controls
   Migrated from templates/partials/filter_bar.html
   ═══════════════════════════════════════════════════════════════════════════ */

#filter-set-default {
    color: var(--color-text-muted);
    font-size: 0.9rem;
    transition: color var(--transition-fast), transform var(--transition-fast);
}

#filter-set-default:hover {
    color: var(--color-warning);
}

#filter-set-default.active {
    color: var(--color-warning);
}

/* ═══════════════════════════════════════════════════════════════════════════
   NAVBAR - Modern Dark Glassmorphism Style
   Migrated from templates/partials/navbar.html
   ═══════════════════════════════════════════════════════════════════════════ */

.modern-navbar {
    background: linear-gradient(135deg, #0d9488 0%, #0284c7 50%, #2563eb 100%);
    box-shadow: 0 4px 20px rgba(13, 148, 136, 0.3);
    padding: 0.75rem 1.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.modern-navbar .navbar-brand {
    color: #ffffff;
    font-size: 1.25rem;
    font-weight: 500;
    transition: all 0.3s ease;
}

.modern-navbar .navbar-brand:hover {
    transform: scale(1.02);
}

.modern-navbar .nav-link {
    color: rgba(255, 255, 255, 0.85) !important;
    padding: 0.6rem 1rem !important;
    border-radius: 8px;
    transition: all 0.2s ease;
    font-size: 1rem;
    font-weight: 450;
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.modern-navbar .nav-link:hover {
    color: #ffffff !important;
    background: rgba(255, 255, 255, 0.1);
    transform: translateY(-1px);
}

.modern-navbar .nav-link.active {
    color: #ffffff !important;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}

.modern-navbar .nav-icon {
    font-size: 0.85rem;
}

.modern-navbar .badge {
    font-size: 0.65rem;
    padding: 0.2rem 0.4rem;
}

/* Mobile improvements */
@media (max-width: 991px) {
    .modern-navbar {
        padding: 0.75rem 1rem;
    }

    .modern-navbar .nav-link {
        padding: 0.75rem 1rem !important;
        margin: 0.15rem 0;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   TASKBAR - Sticky Bottom Navigation and Status
   Migrated from templates/partials/taskbar.html
   ═══════════════════════════════════════════════════════════════════════════ */

.modern-taskbar {
    z-index: 1050;
    background: linear-gradient(135deg, #0d9488 0%, #0284c7 50%, #2563eb 100%);
    box-shadow: 0 -4px 20px rgba(13, 148, 136, 0.3);
}

/* Prevent content overlap with fixed taskbar */
body {
    padding-bottom: 50px;
}

.bg-white-25 {
    background-color: rgba(255, 255, 255, 0.25) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   MODAL ACTION BAR - Compact Footer for Modals
   Migrated from templates/components/modal_action_bar.html
   ═══════════════════════════════════════════════════════════════════════════ */

.modal-action-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 14px;
    background: linear-gradient(180deg, rgba(244, 236, 217, 0.98), rgba(230, 218, 191, 0.98));
    border-top: 1px solid rgba(95, 71, 37, 0.18);
    gap: 10px;
    flex-wrap: wrap;
}

/* Header-action variant. Drops the footer chrome
   (no gradient, no top-border, tighter padding) so the action group sits
   cleanly to the right of the title inside .wm-modal__header. */
.modal-action-bar--in-header {
    padding: 0;
    background: none;
    border-top: none;
    gap: 6px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.modal-action-bar__group {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.modal-action-bar--in-header .modal-action-bar__group {
    gap: 4px;
}

.modal-action-bar__nav {
    gap: 0 !important;
}

.modal-action-bar .btn,
.modal-action-bar a.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 38px;
    padding: 0 14px;
    border: 1px solid rgba(95, 71, 37, 0.24);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(255, 252, 247, 0.98), rgba(239, 229, 206, 0.98));
    color: #3d2f1d;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.7),
        0 4px 10px rgba(61, 45, 24, 0.08);
    transition: background 0.14s ease, border-color 0.14s ease, transform 0.14s ease, box-shadow 0.14s ease;
}

.modal-action-bar .btn:hover,
.modal-action-bar a.btn:hover {
    background: linear-gradient(180deg, rgba(255, 254, 250, 1), rgba(244, 234, 211, 1));
    border-color: rgba(95, 71, 37, 0.34);
    transform: translateY(-1px);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.8),
        0 8px 16px rgba(61, 45, 24, 0.12);
}

.modal-action-bar .btn--primary {
    background: linear-gradient(180deg, rgba(118, 134, 72, 0.96), rgba(93, 108, 56, 0.98));
    border-color: rgba(76, 90, 44, 0.44);
    color: #f8f3e8;
    box-shadow:
        inset 0 1px 0 rgba(214, 224, 186, 0.32),
        0 6px 14px rgba(61, 45, 24, 0.14);
}

.modal-action-bar .btn--primary:hover {
    background: linear-gradient(180deg, rgba(129, 146, 79, 0.98), rgba(101, 116, 60, 1));
}

.modal-action-bar .btn:focus-visible,
.modal-action-bar a.btn:focus-visible {
    outline: 2px solid rgba(122, 109, 66, 0.72);
    outline-offset: 2px;
}

/* The header exposes only navigation, one disclosure control, and Close.
   Utility labels move into the menu so the title and image keep priority. */
.modal-action-bar--in-header .modal-action-bar__icon {
    width: 38px;
    min-width: 38px;
    min-height: 38px;
    padding: 0;
    border-radius: 11px;
    font-size: 1rem;
    letter-spacing: 0;
    box-shadow: none;
}

.modal-action-bar__nav .btn:first-child {
    border-radius: 11px 0 0 11px;
}

.modal-action-bar__nav .btn:last-child {
    margin-left: -1px;
    border-radius: 0 11px 11px 0;
}

.modal-action-bar__more {
    font-size: 0.78rem !important;
    font-weight: 800;
}

.modal-action-bar__close {
    font-size: 1.35rem !important;
    font-weight: 500 !important;
}

.modal-action-bar__close:hover {
    border-color: rgba(159, 75, 45, 0.34) !important;
    color: var(--color-danger, #9f4b2d) !important;
}

.modal-action-bar__menu {
    position: relative;
}

.modal-action-bar .modal-action-bar__dropdown {
    top: calc(100% + 8px);
    right: 0;
    bottom: auto;
    min-width: 224px;
    margin-bottom: 0;
    overflow: hidden;
    text-align: left;
}

.modal-action-bar__dropdown a.wm-toolbox__item {
    text-decoration: none;
}

.modal-action-bar__menu-label {
    display: block;
    padding: 7px 12px 4px;
    color: var(--color-text-muted);
    font-size: 0.65rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    line-height: 1;
    text-transform: uppercase;
}

.modal-action-bar__menu-label--separated {
    margin-top: 4px;
    padding-top: 10px;
    border-top: 1px solid var(--color-border-light);
}

.modal-action-bar__item--disabled {
    cursor: default;
    opacity: 0.58;
}

/* Favorite button: ensure minimum touch target */
.fav-btn {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
    background: none;
    border: none;
    cursor: pointer;
    border-radius: var(--radius-full);
    transition: transform 0.15s ease;
}

.fav-btn:active {
    transform: scale(0.85);
}

/* Mobile: action bar wraps into 2 rows */
@media (max-width: 480px) {
    .modal-action-bar {
        justify-content: center;
        gap: var(--space-xs);
        padding: var(--space-xs) var(--space-sm);
    }

    .modal-action-bar__group {
        gap: 4px;
    }

    .modal-action-bar .btn {
        font-size: var(--font-size-xs);
        padding: 6px 8px;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   UI_STANDARD.md - WM-MODAL
   Standard Modal Structure
   ═══════════════════════════════════════════════════════════════════════════ */

.wm-modal__dialog {
    /* Modal scales with viewport up to a generous ceiling so the image is
       bigger than the source tile on any display from 13" laptop to 5K. */
    max-width: min(1600px, calc(100vw - 4rem));
}

.wm-modal__content {
    border-radius: var(--radius-xl);
    overflow: hidden;
    max-height: calc(100vh - 2rem);
}

.wm-modal__header {
    position: relative;
    z-index: 30;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-md);
    border-bottom: 1px solid var(--color-border-light);
}

.wm-modal__title {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
}

.wm-modal__title-text {
    font-size: var(--font-size-lg);
    font-weight: 600;
    color: var(--color-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wm-modal__title-sub {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wm-modal__title-conf {
    font-variant-numeric: tabular-nums;
}

.wm-modal__close {
    flex-shrink: 0;
}

/* Header-action slot. Holds compact navigation (Previous / Next / More /
   Close) inside .wm-modal__header. Title gets flex: 1 above
   so a long species name truncates with ellipsis instead of pushing
   the buttons off-screen. */
.wm-modal__header-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

.wm-modal__body {
    padding: var(--space-md);
    background: var(--color-surface-2);
    text-align: center;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.wm-modal__image {
    margin-bottom: var(--space-md);
}

/* In the detail modal the image should consume the
   available viewport height. The global .wm-image-viewer__img cap of 65vh
   stays the default for non-modal surfaces (Stream, Gallery tiles); the
   modal raises it. The reserved header/padding budget lives in
   --wm-modal-chrome so maximize mode can tune it without touching
   the image rule. */
.wm-modal__body {
    --wm-modal-chrome: 13rem;
}

/* Height budget for the detail modal.

   The image used to be capped against the raw viewport
   (100vh - --wm-modal-chrome) while the bird-editor rail below it was laid
   out as an ordinary static block. Nothing reserved space for that rail, so
   image + toolbar + status could exceed .wm-modal__content's
   max-height (100vh - 2rem) and the toolbar was clipped by its
   overflow: hidden. The shortfall was constant (~57px at any window
   height >= 716px CSS), because the image cap grows with the viewport just
   as fast as the window does - which is why enlarging the window never
   helped and only zooming the browser out did.

   The body is now a flex column that derives the image budget instead of
   guessing it: the editor rail claims its intrinsic height first
   (flex: 0 0 auto) and the image region takes what is left
   (flex: 1 1 auto; min-height: 0). min-height: 0 is required - the
   flex default of min-height: auto refuses to shrink a flex item below its
   intrinsic content height, which is what pushed the rail out of the
   clipped box.

   Deliberately NOT reintroducing the two patterns that previously broke
   bbox overlays (see the note on .wm-modal__image .wm-image-viewer__img):
   .wm-image-viewer itself stays a plain block that shrink-wraps its <img>,
   and no object-fit is applied. Only the body - one level above the overlay
   container - becomes a flex column, so the overlay/layer geometry contract
   is untouched. */
.wm-modal__content:has(.wm-bird-editor) {
    display: flex;
    flex-direction: column;
}

.wm-modal__content:has(.wm-bird-editor) > .wm-modal__header {
    flex: 0 0 auto;
}

.wm-modal__body:has(.wm-bird-editor) {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    flex: 1 1 auto;
    min-height: 0;
}

.wm-modal__body:has(.wm-bird-editor) > .wm-modal__image {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

/* The editor rail is the primary control surface: it is never the thing
   that gets clipped. */
.wm-modal__body:has(.wm-bird-editor) > .wm-bird-editor {
    flex: 0 0 auto;
}

/* Inside the flex column the image is bounded by the space the rail left
   over, not by a viewport guess. Both bounds are kept: whichever is
   smaller wins. */
.wm-modal__body:has(.wm-bird-editor) .wm-image-viewer {
    min-height: 0;
    max-height: 100%;
}

.wm-modal__body:has(.wm-bird-editor) .wm-image-viewer__img {
    max-height: 100%;
}

/* Modal-image sizing correction.
   A prior version added `display: flex; justify-content: center`
   to .wm-modal__image .wm-image-viewer AND `object-fit: contain` to
   the inner <img>. That combination broke bbox overlays appwide:
     - flex+center could shrink the <img> while the canvas overlay
       (position:absolute; top:0; left:0) stayed bound to the flex
       container, drifting away from the actual image rect.
     - object-fit:contain could letterbox the image inside the <img>
       element, again leaving the canvas drawing on the strip and
       not on the rendered image.
   Reverted both. The image now sizes naturally via `max-height`
   alone — the <img> element shrinks/grows to match its rendered
   bitmap, so the absolutely-positioned canvas always overlaps the
   image exactly. The viewport cap is kept
   via max-height. */
.wm-modal__image .wm-image-viewer__img {
    max-height: calc(100vh - var(--wm-modal-chrome));
}

.wm-modal__image .wm-toolbox {
    bottom: 14px;
    right: 14px;
}

.wm-modal__image .wm-toolbox__btn {
    min-width: 40px;
    height: 40px;
    font-size: 0.95rem;
}

.wm-modal__info {
    text-align: left;
}

/* Retired — header action group replaces this footer row.
   Class kept for one release in case any external override consumes it. */
.wm-modal__action {
    border-top: 1px solid var(--color-border-light);
}

/* Slim sibling-strip below the image on multi-bird frames only.
   Per-card action buttons (Change Species, Trash) are gone;
   the header action group now acts on the active detection (set via
   canvas-click or sibling-card-click → wmb:active-detection-change). */
.wm-modal__sibling-strip {
    margin-top: var(--space-sm);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--color-border-light);
}

.wm-modal__sibling-strip .sibling-cards {
    flex-wrap: nowrap !important;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 4px;
}

.wm-modal__sibling-strip .sibling-card {
    flex: 0 0 auto;
}

/* Active companion gets a clear visual mark; the canvas + sibling-strip
   both react to wmb:active-detection-change in gallery_utils.js. */
.wm-modal__sibling-strip .sibling-card[data-is-current="true"] {
    border-color: var(--color-accent, #c97c2a);
    box-shadow: 0 0 0 2px rgba(201, 124, 42, 0.18);
}

/* Shared full-frame safety gate. This native dialog is mounted once by
   base.html and populated by tile_actions.js for every no-bird decision. */
.wm-no-bird-confirm {
    box-sizing: border-box;
    width: 95vw;
    max-width: none;
    max-height: 94vh;
    padding: 0;
    overflow: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
}

.wm-no-bird-confirm::backdrop {
    background: rgb(0 0 0 / 72%);
}

.wm-no-bird-confirm__content {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
    padding: var(--space-md);
}

.wm-no-bird-confirm__content h2,
.wm-no-bird-confirm__summary,
.wm-no-bird-confirm__hint {
    margin: 0;
}

.wm-no-bird-confirm__content h2 {
    font-size: var(--font-size-lg);
    font-weight: 600;
}

.wm-no-bird-confirm__summary {
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.wm-no-bird-confirm__preview {
    display: block;
    width: 100%;
    height: auto;
    max-height: calc(94vh - 190px);
    border-radius: var(--radius-sm);
    background: #000;
    object-fit: contain;
}

.wm-no-bird-confirm__hint {
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.wm-no-bird-confirm__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-sm);
    margin-top: var(--space-xs);
}

/* Maximized variant. Toggled via the ⛶ button in
   the header action group (toggleModalMaximize in gallery_utils.js).
   Dialog fills the viewport, header chrome shrinks to icons + title-only,
   subtitle and sibling-strip hide so the image gets the entire stage. */
.wm-modal.wm-modal--maximized .wm-modal__dialog {
    max-width: 100vw;
    width: 100vw;
    margin: 0;
    height: 100vh;
    max-height: 100vh;
}

.wm-modal.wm-modal--maximized .wm-modal__content {
    max-height: 100vh;
    height: 100vh;
    border-radius: 0;
}

.wm-modal.wm-modal--maximized .wm-modal__body {
    --wm-modal-chrome: 4rem;
    padding: var(--space-xs);
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.wm-modal.wm-modal--maximized .wm-modal__image .wm-image-viewer__img {
    max-height: calc(100vh - var(--wm-modal-chrome));
    max-width: 100%;
}

.wm-modal.wm-modal--maximized .wm-modal__title-sub {
    display: none;
}

.wm-modal.wm-modal--maximized .wm-modal__sibling-strip {
    display: none;
}

.wm-modal.wm-modal--maximized .wm-modal__header {
    padding: var(--space-xs) var(--space-sm);
    border-bottom: none;
    background: rgba(0, 0, 0, 0.04);
}

.wm-modal.wm-modal--maximized .wm-modal__maximize-btn {
    background: var(--color-accent, #c97c2a);
    color: #fff;
    border-color: var(--color-accent, #c97c2a);
}

/* The compact header stays on one line down to phone widths; utility actions
   are already collapsed into More. Below 480px the dialog goes edge-to-edge. */
@media (max-width: 900px) {
    .wm-modal__header {
        flex-wrap: nowrap;
    }

    .wm-modal__header-actions {
        flex-basis: auto;
    }

    .modal-action-bar--in-header {
        justify-content: flex-end;
    }
}

@media (max-width: 480px) {
    .wm-modal__dialog {
        margin: 0.5rem;
        max-width: calc(100vw - 1rem);
    }

    .wm-modal__body {
        padding: var(--space-sm);
        max-height: 70vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    .wm-modal__header {
        padding: var(--space-xs) var(--space-sm);
    }
}

@media (max-height: 700px) {
    .wm-modal__body {
        --wm-modal-chrome: 15rem;
        padding-block: var(--space-sm);
    }

    .wm-modal__image .wm-image-viewer__img {
        max-height: max(180px, calc(100dvh - var(--wm-modal-chrome)));
    }

    .wm-bird-editor__toolbar {
        min-height: 48px;
        padding-block: 6px;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   UI_STANDARD.md - WM-TILE
   Standard Thumbnail / Tile Structure
   ═══════════════════════════════════════════════════════════════════════════ */

.wm-tile {
    position: relative;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: all var(--transition-fast);
}

.wm-tile:hover {
    border-color: var(--color-primary);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.wm-tile--interactive {
    cursor: pointer;
}

.wm-tile__button {
    display: block;
    width: 100%;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
}

.wm-tile__button--fill {
    height: 100%;
}

.wm-tile__media {
    position: relative;
    width: 100%;
}

.wm-tile__image {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    display: block;
}

.wm-tile__badge {
    position: absolute;
    top: 8px;
    right: 8px;
    background: var(--color-primary);
    color: white;
    font-size: var(--font-size-xs);
    font-weight: 700;
    padding: 4px 8px;
    border-radius: var(--radius-full);
    min-width: 28px;
    text-align: center;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.wm-tile__body {
    padding: var(--space-sm);
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.wm-tile__body--link {
    text-decoration: none;
    color: inherit;
}

.wm-tile__name {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-text);
}

.wm-tile__latin {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-style: italic;
}

.wm-tile__score {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-accent);
}

/* Score badge on tile media */
.wm-tile__score-badge {
    position: absolute;
    bottom: 6px;
    right: 6px;
    font-size: 0.85rem;
    line-height: 1;
    width: 22px;
    height: 22px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 5;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

/* Interactive Favorite Badge on Tiles (⭐) */
.wm-tile__fav-badge {
    position: absolute;
    bottom: 6px;
    right: 6px;
    font-size: 1.1rem;
    line-height: 1;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 10;
    cursor: pointer;
    background: rgba(0, 0, 0, 0.5);
    color: rgba(255, 255, 255, 0.8);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
    pointer-events: auto;
    transition: all var(--transition-fast);
    /* Hidden by default unless active/hovered */
    opacity: 0;
    transform: scale(0.9);
}

.wm-tile__media:hover .wm-tile__fav-badge,
.wm-tile__fav-badge.wm-tile__fav-badge--active {
    opacity: 1;
    transform: scale(1);
}

.wm-tile__fav-badge:hover {
    background: rgba(0, 0, 0, 0.8);
    transform: scale(1.1) !important;
}

.wm-tile__fav-badge--active {
    background: rgba(251, 191, 36, 0.95);
    /* Amber/Gold */
    color: #fff;
    box-shadow: 0 2px 8px rgba(251, 191, 36, 0.5);
}

.wm-tile__fav-badge--active:hover {
    background: rgba(245, 158, 11, 1);
}

/* ═══════════════════════════════════════════════════════════════════════════
   SPECIES COLOUR BINDINGS (Gallery / Stream / Trash)
   Mirrors the `.review-event-panel__cell[data-species-colour]` and
   `.review-batch-cell[data-species-colour]` patterns so every tile on
   these surfaces that carries a `data-species-colour` attribute picks
   up the Wong palette token automatically.

   The `--cell-species-colour` custom property is set both by the
   template's inline `style` attribute (via the server-side
   `assign_species_colours` slot) and by the CSS `[data-species-colour="N"]`
   selector below. The inline style wins (higher specificity), so the
   CSS selectors serve as a readable mapping and as a fallback when
   the inline attribute is present but the inline style is missing.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Shared host rule: the same variable feeds badge tint, border accent,
   and the canvas bbox stroke on all three surfaces. */
.wm-tile[data-species-colour],
.quiet-preview__item[data-species-colour],
.trash-item[data-species-colour] {
    --cell-species-colour: var(--species-colour-0);
    border-top: 2px solid var(--cell-species-colour, var(--color-border));
}

/* Slot-by-slot overrides (0..7). */
.wm-tile[data-species-colour="0"],
.quiet-preview__item[data-species-colour="0"],
.trash-item[data-species-colour="0"] { --cell-species-colour: var(--species-colour-0); }

.wm-tile[data-species-colour="1"],
.quiet-preview__item[data-species-colour="1"],
.trash-item[data-species-colour="1"] { --cell-species-colour: var(--species-colour-1); }

.wm-tile[data-species-colour="2"],
.quiet-preview__item[data-species-colour="2"],
.trash-item[data-species-colour="2"] { --cell-species-colour: var(--species-colour-2); }

.wm-tile[data-species-colour="3"],
.quiet-preview__item[data-species-colour="3"],
.trash-item[data-species-colour="3"] { --cell-species-colour: var(--species-colour-3); }

.wm-tile[data-species-colour="4"],
.quiet-preview__item[data-species-colour="4"],
.trash-item[data-species-colour="4"] { --cell-species-colour: var(--species-colour-4); }

.wm-tile[data-species-colour="5"],
.quiet-preview__item[data-species-colour="5"],
.trash-item[data-species-colour="5"] { --cell-species-colour: var(--species-colour-5); }

.wm-tile[data-species-colour="6"],
.quiet-preview__item[data-species-colour="6"],
.trash-item[data-species-colour="6"] { --cell-species-colour: var(--species-colour-6); }

.wm-tile[data-species-colour="7"],
.quiet-preview__item[data-species-colour="7"],
.trash-item[data-species-colour="7"] { --cell-species-colour: var(--species-colour-7); }

/* Species-badge tint on the tile body: a 15%-opacity background of the
   species colour token so the species name reads as the same hue as the
   bbox border, exactly matching the Review cell behaviour. */
.wm-tile[data-species-colour] .wm-tile__name,
.quiet-preview__item[data-species-colour] .quiet-preview__name {
    color: var(--cell-species-colour, inherit);
}

.trash-item[data-species-colour] .trash-item__name {
    color: var(--cell-species-colour, inherit);
}

/* Left-corner media badges (cover jump / source link) */
.cover-jump-badge,
.source-link-badge {
    position: absolute;
    bottom: 6px;
    left: 6px;
    font-size: 0.9rem;
    line-height: 1;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.5);
    color: white;
    text-decoration: none;
    opacity: 0;
    transform: scale(0.9);
    transition: opacity 0.15s ease, transform 0.15s ease, background 0.15s ease;
    z-index: 10;
    pointer-events: auto;
}

.date-card__image:hover .cover-jump-badge,
.wm-tile__media:hover .cover-jump-badge,
.wm-tile__media:hover .source-link-badge {
    opacity: 1;
    transform: scale(1);
}

.cover-jump-badge:hover,
.source-link-badge:hover {
    transform: scale(1.15) !important;
    background: rgba(13, 148, 136, 0.85);
    box-shadow: 0 2px 8px rgba(13, 148, 136, 0.4);
}

/* Touch screens have no dependable hover reveal. Keep these compact media
   affordances visible instead of leaving an invisible live hit target. */
@media (hover: none) {
    .cover-jump-badge,
    .source-link-badge {
        opacity: 1;
        transform: none;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   UI_STANDARD.md - WM-IMAGE-VIEWER
   Standard Image Viewer Structure
   ═══════════════════════════════════════════════════════════════════════════ */

.wm-image-viewer {
    position: relative;
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    border-radius: var(--radius-md);
}

.wm-image-viewer--loading {
    width: min(100%, 720px);
    min-height: min(65vh, 420px);
    background:
        linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0)),
        var(--color-surface-3);
}

.wm-image-viewer--loading::after {
    content: "";
    position: absolute;
    width: 36px;
    height: 36px;
    left: calc(50% - 18px);
    top: calc(50% - 18px);
    border: 3px solid rgba(148, 163, 184, 0.35);
    border-top-color: var(--color-accent);
    border-radius: 50%;
    animation: spin 0.9s linear infinite;
}

.wm-image-viewer--loading .wm-image-viewer__img {
    opacity: 0;
}

.wm-image-viewer__img {
    max-height: 65vh;
    max-width: 100%;
    display: block;
    cursor: pointer;
    transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    transform-origin: center center;
}

.wm-image-viewer--zoomed .wm-image-viewer__img {
    /* transform is set dynamically via JS */
    will-change: transform;
}

/* Explicit image-view choices. The detail variant floats over the image at
   bottom centre; the gallery variant uses the same interaction language in
   the page toolbar. Neither belongs to the detection-action toolbox. */
.wm-view-mode-toggle {
    --wm-view-mode-bg: rgba(47, 39, 27, 0.84);
    --wm-view-mode-border: rgba(255, 255, 255, 0.2);
    --wm-view-mode-text: rgba(255, 255, 255, 0.82);
    --wm-view-mode-active-bg: rgba(250, 247, 240, 0.96);
    --wm-view-mode-active-text: #3d3020;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--wm-view-mode-border);
    border-radius: 13px;
    background: var(--wm-view-mode-bg);
    box-shadow: 0 6px 18px rgba(24, 18, 10, 0.26);
}

.wm-view-mode-toggle--viewer {
    position: absolute;
    z-index: 16;
    left: 50%;
    bottom: 12px;
    transform: translateX(-50%);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.wm-view-mode-toggle__option {
    appearance: none;
    min-width: 62px;
    min-height: 34px;
    padding: 0 12px;
    border: 0;
    border-radius: 9px;
    background: transparent;
    color: var(--wm-view-mode-text);
    font: inherit;
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1;
    cursor: pointer;
    transition: background-color 140ms ease, color 140ms ease, box-shadow 140ms ease;
}

.wm-view-mode-toggle__option:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.12);
}

.wm-view-mode-toggle__option.is-active {
    color: var(--wm-view-mode-active-text);
    background: var(--wm-view-mode-active-bg);
    box-shadow: 0 1px 4px rgba(31, 24, 14, 0.18);
}

.wm-view-mode-toggle__option:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.wm-view-mode-toggle--gallery {
    --wm-view-mode-bg: rgba(246, 242, 233, 0.96);
    --wm-view-mode-border: rgba(95, 71, 37, 0.2);
    --wm-view-mode-text: #66543a;
    --wm-view-mode-active-bg: #66583d;
    --wm-view-mode-active-text: #fffdf8;
    box-shadow: 0 2px 7px rgba(61, 45, 24, 0.08);
}

.wm-view-mode-toggle--gallery .wm-view-mode-toggle__option:hover {
    color: #3d3020;
    background: rgba(95, 71, 37, 0.09);
}

.wm-view-mode-toggle--gallery .wm-view-mode-toggle__option.is-active {
    color: var(--wm-view-mode-active-text);
    background: var(--wm-view-mode-active-bg);
}

@media (max-width: 480px) {
    .wm-view-mode-toggle--viewer {
        bottom: 8px;
    }

    .wm-view-mode-toggle__option {
        min-width: 56px;
        min-height: 32px;
        padding-inline: 10px;
    }
}

/* Favorite Toggle Button (❤️) */
.fav-btn {
    cursor: pointer;
    font-size: 1.6rem;
    opacity: 0.35;
    transition: opacity 0.2s, transform 0.2s, background 0.2s;
    background: rgba(0, 0, 0, 0.08);
    border: 1.5px solid rgba(0, 0, 0, 0.12);
    padding: 6px 10px;
    border-radius: var(--radius-full);
    line-height: 1;
}

.fav-btn:hover {
    opacity: 1;
    transform: scale(1.15);
    background: rgba(220, 38, 38, 0.1);
    border-color: rgba(220, 38, 38, 0.3);
}

.fav-btn--active {
    opacity: 1;
    background: rgba(220, 38, 38, 0.12);
    border-color: rgba(220, 38, 38, 0.4);
    filter: drop-shadow(0 0 4px rgba(220, 38, 38, 0.5));
}

.wm-image-viewer__overlay {
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
    display: none;
}

/* Shared detail-modal bird editor. The image remains the dominant surface;
   every mutable object action lives in the single rail immediately below it. */
.wm-modal__image:has(+ .wm-bird-editor) {
    margin-bottom: 0;
}

.wm-training-export-notice {
    padding: var(--space-sm) var(--space-md);
    margin-bottom: var(--space-sm);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-secondary);
    border-radius: var(--radius-md);
    background: var(--color-secondary-light);
    color: var(--color-text);
    font-size: var(--font-size-sm);
    line-height: 1.5;
}

.wm-training-export-notice strong {
    display: block;
}

.wm-training-export-notice p {
    margin: 0;
}

.wm-bird-editor {
    width: min(100%, 1120px);
    margin: 0 auto;
    color: var(--color-text);
}

.wm-bird-editor__toolbar {
    display: grid;
    grid-template-columns: auto minmax(11rem, 1fr) auto;
    align-items: center;
    gap: var(--space-sm);
    min-height: 58px;
    padding: 8px 10px;
    border: 1px solid var(--color-border-light);
    border-top: 0;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    background: color-mix(in srgb, var(--color-surface) 94%, #cda15d 6%);
    box-shadow: 0 8px 24px rgba(44, 34, 20, 0.08);
}

.wm-view-mode-toggle--editor {
    --wm-view-mode-bg: color-mix(in srgb, var(--color-surface-2) 92%, #7b6541 8%);
    --wm-view-mode-border: var(--color-border);
    --wm-view-mode-text: var(--color-text-muted);
    --wm-view-mode-active-bg: #66583d;
    --wm-view-mode-active-text: #fffdf8;
    box-shadow: none;
}

.wm-bird-editor__species {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    min-width: 0;
    min-height: 40px;
    padding: 0 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
    font-size: var(--font-size-sm);
    font-weight: 650;
    text-align: left;
}

.wm-bird-editor__bird-select-label {
    display: block;
    min-width: 0;
}

.wm-bird-editor__species {
    width: 100%;
}

.wm-bird-editor__species:hover,
.wm-bird-editor__species:focus-visible {
    border-color: var(--color-accent);
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 18%, transparent);
}

.wm-bird-editor__species[aria-disabled="true"] {
    opacity: 0.58;
}

.wm-bird-editor__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
}

.wm-bird-editor__actions .btn {
    min-height: 40px;
    white-space: nowrap;
}

.wm-bird-editor__menu {
    position: relative;
}

.wm-bird-editor__menu > .wm-toolbox__more {
    min-width: 42px;
    min-height: 40px;
    font-size: 1.05rem;
}

.wm-bird-editor__menu .wm-toolbox__dropdown {
    right: 0;
    bottom: calc(100% + 6px);
}

.wm-bird-editor__draw-hint {
    min-width: 11rem;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    text-align: left;
}

.wm-bird-editor__status {
    min-height: 26px;
    padding: 5px 12px 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    text-align: left;
}

.wm-bird-editor__layer {
    position: absolute;
    z-index: 15;
    overflow: visible;
    pointer-events: none;
    transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    transform-origin: center center;
}

.wm-bird-editor__layer.is-adding {
    cursor: crosshair;
    pointer-events: auto;
    touch-action: none;
}

.wm-bird-editor__box {
    position: absolute;
    box-sizing: border-box;
    border: var(--wm-bird-editor-soft-stroke, 0.75px) solid rgba(245, 228, 184, 0.94);
    border-radius: var(--wm-bird-editor-radius, 3px);
    background: rgba(37, 30, 21, 0.03);
    box-shadow: 0 0 0 var(--wm-bird-editor-soft-stroke, 0.75px) rgba(30, 23, 14, 0.55);
    pointer-events: auto;
    transition: border-color 120ms ease, box-shadow 120ms ease, background 120ms ease;
}

.wm-bird-editor__box.is-in-review {
    border-style: dashed;
}

.wm-bird-editor__box.is-selected {
    z-index: 2;
    border-width: var(--wm-bird-editor-stroke, 1px);
    border-color: #f3bf5d;
    background: rgba(243, 191, 93, 0.07);
    box-shadow:
        0 0 0 var(--wm-bird-editor-soft-stroke, 0.75px) rgba(30, 23, 14, 0.64),
        0 0 var(--wm-bird-editor-glow, 14px) rgba(243, 191, 93, 0.2);
}

.wm-bird-editor__box.is-dismissed {
    border-style: dashed;
    border-color: #ced2d5;
    background: rgba(48, 53, 58, 0.10);
}

.wm-bird-editor__box.is-dismissed .wm-bird-editor__box-label,
.wm-bird-editor__box.is-dismissed.is-selected .wm-bird-editor__box-label {
    background: #e4e7ea;
    color: #30353a;
}

.wm-bird-editor__box.is-dismissed.is-selected {
    border-color: #fff;
    box-shadow: 0 0 0 2px #535b64;
}

.wm-bird-editor__box-body {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
    touch-action: none;
}

.wm-bird-editor__layer.is-editing .wm-bird-editor__box.is-selected .wm-bird-editor__box-body {
    cursor: move;
}

.wm-bird-editor__box-body:focus-visible {
    outline: var(--wm-bird-editor-focus, 2px) solid #fff;
    outline-offset: var(--wm-bird-editor-focus, 2px);
}

.wm-bird-editor__box-label {
    position: absolute;
    left: -3px;
    bottom: calc(100% + 3px);
    width: max-content;
    max-width: 220px;
    min-height: 28px;
    display: inline-grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: stretch;
    padding: 0;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.32);
    border-radius: 7px;
    background: rgba(43, 35, 24, 0.9);
    color: #fffaf0;
    font: inherit;
    backdrop-filter: blur(8px);
    transform-origin: 0 0;
}

.wm-bird-editor__box-label-name,
.wm-bird-editor__box-label-picker {
    min-height: 28px;
    padding: 4px 8px;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
}

button.wm-bird-editor__box-label-name,
.wm-bird-editor__box-label-picker {
    transition: background-color 120ms ease, box-shadow 120ms ease;
}

.wm-bird-editor__box-label-name {
    overflow: hidden;
    text-overflow: ellipsis;
}

.wm-bird-editor__box-label-picker {
    min-width: 30px;
    border-left: 1px solid rgba(255, 255, 255, 0.28);
    cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
    button.wm-bird-editor__box-label-name:hover,
    .wm-bird-editor__box-label-picker:hover {
        background: rgba(44, 33, 19, 0.18);
        box-shadow: inset 0 0 0 2px rgba(44, 33, 19, 0.3);
    }
}

.wm-bird-editor__box.is-label-inside .wm-bird-editor__box-label {
    top: 3px;
    bottom: auto;
}

.wm-bird-editor__box.is-label-right .wm-bird-editor__box-label {
    right: -3px;
    left: auto;
}

.wm-bird-editor__box.is-selected .wm-bird-editor__box-label {
    background: #e8ad43;
    color: #2c2113;
}

.wm-bird-editor__handle {
    position: absolute;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 5px solid transparent;
    border-radius: 50%;
    background: #f3bf5d;
    background-clip: content-box;
    transform: scale(var(--wm-bird-editor-handle-scale, 1));
    transform-origin: center;
    touch-action: none;
}

.wm-bird-editor__handle--n { top: -9px; left: calc(50% - 9px); cursor: ns-resize; }
.wm-bird-editor__handle--e { right: -9px; top: calc(50% - 9px); cursor: ew-resize; }
.wm-bird-editor__handle--s { bottom: -9px; left: calc(50% - 9px); cursor: ns-resize; }
.wm-bird-editor__handle--w { left: -9px; top: calc(50% - 9px); cursor: ew-resize; }
.wm-bird-editor__handle--nw { top: -9px; left: -9px; cursor: nwse-resize; }
.wm-bird-editor__handle--ne { top: -9px; right: -9px; cursor: nesw-resize; }
.wm-bird-editor__handle--se { right: -9px; bottom: -9px; cursor: nwse-resize; }
.wm-bird-editor__handle--sw { left: -9px; bottom: -9px; cursor: nesw-resize; }

.wm-modal.wm-modal--maximized .wm-modal__body {
    --wm-modal-chrome: 8.5rem;
}

@media (max-width: 760px) {
    .wm-bird-editor__toolbar {
        grid-template-columns: auto minmax(0, 1fr);
        gap: 6px;
    }

    .wm-bird-editor__actions {
        grid-column: 1 / -1;
        justify-content: stretch;
    }

    .wm-bird-editor__actions .btn:not([hidden]) {
        flex: 1 1 auto;
    }

    .wm-bird-editor__menu {
        flex: 0 0 auto;
    }

    .wm-bird-editor__status {
        padding-inline: 4px;
    }
}

@media (max-width: 460px) {
    .wm-bird-editor__toolbar {
        grid-template-columns: 1fr;
    }

    .wm-view-mode-toggle--editor,
    .wm-bird-editor__species,
    .wm-bird-editor__actions {
        width: 100%;
    }

    .wm-view-mode-toggle--editor .wm-view-mode-toggle__option {
        flex: 1 1 50%;
    }

    .wm-bird-editor__actions {
        grid-column: 1;
        flex-wrap: wrap;
    }

    .wm-bird-editor__box-label {
        max-width: 130px;
    }
}

.wm-bbox-label-layer {
    position: absolute;
    z-index: 14;
    overflow: visible;
    pointer-events: none;
}

.wm-bbox-label {
    position: absolute;
    display: inline-flex;
    max-width: min(260px, 72vw);
    min-height: 32px;
    overflow: hidden;
    transform-origin: 0 0;
    border: 2px solid var(--bbox-label-colour, #f5c84c);
    border-radius: 8px;
    background: var(--bbox-label-colour, #f5c84c);
    color: #101412;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.38);
    font-size: 0.78rem;
    font-weight: 750;
    line-height: 1;
    pointer-events: auto;
    white-space: nowrap;
}

.wm-bbox-label.is-reviewed {
    box-shadow:
        0 0 0 2px rgba(255, 255, 255, 0.92),
        0 0 0 4px rgba(32, 116, 75, 0.92),
        0 3px 10px rgba(0, 0, 0, 0.42);
}

.wm-bbox-label.is-corrected {
    box-shadow:
        0 0 0 2px rgba(255, 255, 255, 0.92),
        0 0 0 4px rgba(55, 105, 150, 0.92),
        0 3px 10px rgba(0, 0, 0, 0.42);
}

.wm-bbox-label__confirm,
.wm-bbox-label__status,
.wm-bbox-label__picker {
    min-height: 30px;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
}

.wm-bbox-label__confirm,
.wm-bbox-label__picker {
    transition: background-color 120ms ease, box-shadow 120ms ease;
}

.wm-bbox-label__confirm,
.wm-bbox-label__status {
    display: inline-flex;
    min-width: 0;
    align-items: center;
    padding: 0 10px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wm-bbox-label__confirm {
    cursor: pointer;
}

.wm-bbox-label__confirm:disabled {
    cursor: wait;
    opacity: 0.7;
}

.wm-bbox-label__picker {
    flex: 0 0 34px;
    width: 34px;
    padding: 0;
    border-left: 1px solid rgba(16, 20, 18, 0.38);
    cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
    .wm-bbox-label__confirm:hover,
    .wm-bbox-label__picker:hover {
        background: rgba(16, 20, 18, 0.2);
        box-shadow: inset 0 0 0 2px rgba(16, 20, 18, 0.34);
    }
}

.wm-bbox-label__confirm:focus-visible,
.wm-bbox-label__picker:focus-visible {
    position: relative;
    z-index: 1;
    outline: 3px solid #fff;
    outline-offset: -3px;
}

/* Direct correction sits on the canonical image viewer. The visible border
   stays slim while each side gets a wider invisible hit target for a mouse. */
.wm-bbox-editor {
    position: absolute;
    inset: 0;
    z-index: 12;
    overflow: hidden;
    pointer-events: none;
}

.wm-bbox-editor__box {
    position: absolute;
    box-sizing: border-box;
    border: 1px solid #f5c84c;
    border-radius: 2px;
    background: rgba(245, 200, 76, 0.06);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55), 0 0 16px rgba(245, 200, 76, 0.16);
    cursor: move;
    outline: none;
    pointer-events: auto;
    touch-action: none;
}

.wm-bbox-editor__box:focus-visible {
    box-shadow: 0 0 0 2px #101412, 0 0 0 5px #f5c84c;
}

.wm-bbox-editor__box.is-dragging {
    background: rgba(245, 200, 76, 0.12);
}

.wm-bbox-editor__edge,
.wm-bbox-editor__corner {
    position: absolute;
    display: block;
    pointer-events: auto;
    touch-action: none;
}

.wm-bbox-editor__edge--n,
.wm-bbox-editor__edge--s {
    right: 12px;
    left: 12px;
    height: 16px;
    cursor: ns-resize;
}

.wm-bbox-editor__edge--n { top: -8px; }
.wm-bbox-editor__edge--s { bottom: -8px; }

.wm-bbox-editor__edge--e,
.wm-bbox-editor__edge--w {
    top: 12px;
    bottom: 12px;
    width: 16px;
    cursor: ew-resize;
}

.wm-bbox-editor__edge--e { right: -8px; }
.wm-bbox-editor__edge--w { left: -8px; }

.wm-bbox-editor__corner {
    width: 18px;
    height: 18px;
    border: 5px solid transparent;
    border-radius: 50%;
    background: #f5c84c;
    background-clip: content-box;
}

.wm-bbox-editor__corner--nw,
.wm-bbox-editor__corner--se { cursor: nwse-resize; }

.wm-bbox-editor__corner--ne,
.wm-bbox-editor__corner--sw { cursor: nesw-resize; }

.wm-bbox-editor__corner--nw { top: -9px; left: -9px; }
.wm-bbox-editor__corner--ne { top: -9px; right: -9px; }
.wm-bbox-editor__corner--se { right: -9px; bottom: -9px; }
.wm-bbox-editor__corner--sw { bottom: -9px; left: -9px; }

.wm-bbox-editor__controls {
    position: absolute;
    right: 12px;
    bottom: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: calc(100% - 24px);
    padding: 8px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: var(--radius-md);
    background: rgba(16, 20, 18, 0.9);
    box-shadow: var(--shadow-lg);
    color: #fff;
    pointer-events: auto;
}

.wm-bbox-editor__hint {
    padding: 0 4px;
    font-size: 0.78rem;
    white-space: nowrap;
}

.wm-correction-details {
    width: min(34rem, calc(100vw - 2rem));
    max-height: min(80vh, 46rem);
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
}

.wm-correction-details::backdrop {
    background: rgb(0 0 0 / 72%);
}

.wm-correction-details__panel {
    display: grid;
    gap: var(--space-4);
    padding: var(--space-5);
}

.wm-correction-details__panel h2,
.wm-correction-details__scope,
.wm-correction-details__empty,
.wm-correction-details__facts {
    margin: 0;
}

.wm-correction-details__scope,
.wm-correction-details__empty {
    color: var(--color-text-muted);
}

.wm-correction-details__readiness {
    display: grid;
    gap: var(--space-2);
}

.wm-correction-details__readiness-item {
    padding: var(--space-3);
    border-inline-start: 3px solid var(--color-warning);
    background: var(--color-surface-subtle);
}

.wm-correction-details__readiness-item.is-ready {
    border-inline-start-color: var(--color-success);
}

.wm-correction-details__facts {
    display: grid;
    grid-template-columns: minmax(9rem, 1fr) minmax(10rem, 1.4fr);
    gap: var(--space-2) var(--space-4);
}

.wm-correction-details__facts dt {
    color: var(--color-text-muted);
}

.wm-correction-details__facts dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.wm-correction-details__close {
    justify-self: end;
}

.canonical-dataset {
    display: grid;
    gap: var(--space-xl);
}

.canonical-dataset__header {
    display: flex;
    align-items: start;
    justify-content: space-between;
    gap: var(--space-xl);
}

.canonical-dataset__header h1,
.canonical-dataset__header p {
    margin-top: 0;
}

.canonical-dataset__header > div > p:last-child {
    max-width: 42rem;
    margin-bottom: 0;
    color: var(--color-text-muted);
}

.canonical-dataset__eyebrow {
    margin: 0 0 var(--space-sm);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.canonical-dataset__summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: 0;
    margin: 0;
    border-block: 1px solid var(--color-border);
}

.canonical-dataset__summary > div {
    padding: var(--space-lg) var(--space-xl);
    border-inline-end: 1px solid var(--color-border);
}

.canonical-dataset__summary > div:last-child {
    border-inline-end: 0;
}

.canonical-dataset__summary dt {
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.canonical-dataset__summary dd {
    margin: var(--space-xs) 0 0;
    font-size: var(--font-size-lg);
}

.canonical-review {
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-inline-start: 4px solid var(--color-success);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    animation: canonical-review-arrive 420ms ease-out both;
}

.canonical-review__status {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    min-height: 2.5rem;
    padding: var(--space-sm) var(--space-xl);
    border-bottom: 1px solid var(--color-border-light);
    color: var(--color-success);
    font-family: var(--font-family-mono, monospace);
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.canonical-review__led {
    width: 0.62rem;
    height: 0.62rem;
    border-radius: 50%;
    background: var(--color-success);
    box-shadow: 0 0 0.65rem var(--color-success);
    animation: canonical-review-led 1.8s ease-in-out infinite;
}

.canonical-review__readiness {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: 0;
    border-bottom: 1px solid var(--color-border-light);
}

.canonical-review__figure {
    padding: clamp(var(--space-lg), 3vw, var(--space-xl));
    border-inline-end: 1px solid var(--color-border-light);
    text-align: center;
}

.canonical-review__figure:last-child {
    border-inline-end: 0;
}

.canonical-review__figure-count {
    margin: 0;
    color: var(--color-success);
    font-family: var(--font-family-mono, monospace);
    font-size: clamp(1.8rem, 4vw, 2.6rem);
    font-weight: 750;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.canonical-review__figure:last-child .canonical-review__figure-count {
    color: var(--color-primary);
}

.canonical-review__figure-label {
    margin: var(--space-xs) 0 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.canonical-review__content {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: clamp(var(--space-lg), 4vw, var(--space-3xl));
    padding: clamp(var(--space-xl), 4vw, var(--space-3xl));
}

.canonical-review__content p {
    margin: 0;
}

.canonical-review__copy h2 {
    margin-bottom: var(--space-sm);
}

.canonical-review__copy > p:last-child {
    max-width: 39rem;
    margin-bottom: 0;
    color: var(--color-text-muted);
}

.canonical-review__kicker {
    margin-bottom: var(--space-xs);
    color: var(--color-success);
    font-size: var(--font-size-xs);
    font-weight: 700;
}

.canonical-review__action {
    min-height: 3.25rem;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .canonical-review__action.btn--primary {
        color: var(--color-bg);
    }
}

:root[data-theme="dark"] .canonical-review__action.btn--primary {
    color: var(--color-bg);
}

.canonical-review__arrow {
    display: inline-block;
    transition: transform var(--transition-fast);
}

.canonical-review__action:hover .canonical-review__arrow,
.canonical-review__action:focus-visible .canonical-review__arrow {
    transform: translateX(0.25rem);
}

.canonical-review--complete {
    border-inline-start-color: var(--color-primary);
}

.canonical-review--complete .canonical-review__status,
.canonical-review--complete .canonical-review__kicker {
    color: var(--color-primary);
}

.canonical-review--complete .canonical-review__led {
    background: var(--color-primary);
    box-shadow: none;
    animation: none;
}

.canonical-dataset__manifest {
    display: grid;
    gap: var(--space-md);
}

.canonical-dataset__contribute {
    display: grid;
    gap: var(--space-sm);
    justify-items: start;
    border-top: 1px solid var(--color-border);
    padding-top: var(--space-lg);
}

.canonical-dataset__contribute h2 {
    margin: 0;
}

.canonical-dataset__contribute p {
    margin: 0;
    max-width: 62ch;
}

.canonical-dataset__contribute .btn {
    margin-top: var(--space-xs);
}

.canonical-dataset__section-heading {
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: var(--space-xl);
}

.canonical-dataset__section-heading h2,
.canonical-dataset__section-heading p {
    margin-top: 0;
}

.canonical-dataset__section-heading h2,
.canonical-dataset__section-heading > p {
    margin-bottom: 0;
}

.canonical-dataset__section-heading > p {
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.canonical-dataset__details {
    border-top: 1px solid var(--color-border);
}

.canonical-dataset__details summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-lg);
    min-height: 3.25rem;
    cursor: pointer;
    font-weight: 700;
}

.canonical-dataset__details summary span {
    min-width: 2.25rem;
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-full);
    background: var(--color-surface-2);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    text-align: center;
}

@keyframes canonical-review-arrive {
    from {
        opacity: 0;
        transform: translateY(0.5rem);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes canonical-review-led {
    0%, 100% {
        opacity: 0.55;
        transform: scale(0.88);
    }
    50% {
        opacity: 1;
        transform: scale(1);
    }
}

@media (max-width: 760px) {
    .canonical-dataset__header,
    .canonical-dataset__section-heading {
        align-items: stretch;
        flex-direction: column;
    }

    .canonical-dataset__header .btn {
        align-self: start;
    }

    .canonical-review__content {
        grid-template-columns: 1fr;
    }

    .canonical-review__action {
        width: 100%;
    }
}

@media (max-width: 520px) {
    .canonical-dataset__summary {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .canonical-dataset__summary > div:nth-child(2) {
        border-inline-end: 0;
    }

    .canonical-dataset__summary > div:nth-child(-n + 2) {
        border-bottom: 1px solid var(--color-border);
    }

    .canonical-review__readiness {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (prefers-reduced-motion: reduce) {
    .canonical-review,
    .canonical-review__led {
        animation: none;
    }

    .canonical-review__arrow {
        transition: none;
    }
}

.box-walkthrough {
    display: grid;
    gap: var(--space-xl);
}

.box-walkthrough.container {
    max-width: 1600px;
}

.box-walkthrough__header {
    display: flex;
    align-items: start;
    justify-content: space-between;
    gap: var(--space-xl);
}

.box-walkthrough__header h1,
.box-walkthrough__header p {
    margin-top: 0;
}

.box-walkthrough__remaining {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.box-walkthrough__stage {
    display: grid;
    width: min(100%, 1600px);
    margin-inline: auto;
    container-type: inline-size;
}

.box-walkthrough__image {
    display: flex;
    justify-content: center;
    min-width: 0;
}

.box-walkthrough__image .wm-image-viewer__img {
    max-height: min(85vh, 1100px);
}

.box-walkthrough__actions {
    display: flex;
    justify-content: flex-end;
    width: min(100%, 1120px);
    margin-inline: auto;
    margin-top: var(--space-sm);
}

@container (max-width: 1050px) {
    .box-walkthrough .wm-bird-editor__toolbar {
        grid-template-columns: auto minmax(0, 1fr);
    }

    .box-walkthrough .wm-bird-editor__actions {
        grid-column: 1 / -1;
        justify-content: flex-start;
        flex-wrap: wrap;
    }
}

@container (max-width: 560px) {
    .box-walkthrough .wm-bird-editor__toolbar {
        grid-template-columns: minmax(0, 1fr);
    }

    .box-walkthrough .wm-bird-editor__actions {
        grid-column: 1;
    }
}

.box-walkthrough__empty {
    color: var(--color-text-muted);
}

@media (max-width: 760px) {
    .box-walkthrough__header {
        align-items: stretch;
        flex-direction: column;
    }

    .box-walkthrough__header .btn {
        align-self: start;
    }
}

.wm-bbox-editor__button {
    min-height: 36px;
    padding: 7px 11px;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: var(--radius-sm);
    background: transparent;
    color: #fff;
    font: inherit;
    font-size: 0.82rem;
    font-weight: 650;
}

.wm-bbox-editor__button:hover,
.wm-bbox-editor__button:focus-visible {
    border-color: #fff;
    background: rgba(255, 255, 255, 0.12);
}

.wm-bbox-editor__button--save {
    border-color: #f5c84c;
    background: #f5c84c;
    color: #171a18;
}

.wm-bbox-editor__button:disabled {
    cursor: wait;
    opacity: 0.55;
}

.wm-toolbox-host.is-bbox-editing .wm-toolbox {
    display: none !important;
}

@media (max-width: 620px) {
    .wm-bbox-editor__controls {
        right: 8px;
        bottom: 8px;
        left: 8px;
        justify-content: flex-end;
    }

    .wm-bbox-editor__hint {
        margin-right: auto;
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

@media (prefers-reduced-motion: reduce) {
    .wm-bbox-editor__box,
    .wm-bbox-editor__button {
        transition: none;
    }
}

/* Fallback badge: shown when original image failed and thumb was loaded */
.wm-image-viewer__fallback-badge {
    display: none;
    position: absolute;
    top: 10px;
    right: 10px;
    background: rgba(245, 158, 11, 0.85);
    color: #fff;
    font-size: var(--font-size-xs);
    font-weight: 600;
    padding: 4px 10px;
    border-radius: var(--radius-full);
    pointer-events: none;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
    z-index: 5;
    letter-spacing: 0.02em;
}

.wm-image-viewer--fallback .wm-image-viewer__fallback-badge {
    display: inline-block;
}

.review-desk-bar {
    margin-bottom: var(--space-md);
}

@media (max-width: 1200px) {
    .review-desk-bar {
        height: auto;
        flex-wrap: wrap;
    }

    .review-desk-bar .page-control-bar__right {
        flex: 1 1 100%;
        width: 100%;
        min-width: 0;
        margin-left: 0;
        flex-wrap: wrap;
        justify-content: flex-start;
    }
}

.review-insight-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 auto var(--space-md);
    padding: 0 var(--space-sm);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.review-insight-strip span {
    padding: 6px 10px;
    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--color-surface-raised, var(--color-surface)) 90%, #fff 10%);
    border: 1px solid color-mix(in srgb, var(--color-border) 82%, #fff 18%);
}

.bird-count-icon {
    width: 20px;
    height: 20px;
    display: block;
    flex: 0 0 auto;
}

/* Tinted species badge — 15% opacity background, full-saturation text.
   Honours the host cell's --cell-species-colour token via color-mix. */
.species-badge--coloured {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--cell-species-colour, var(--color-text));
    background: color-mix(in srgb, var(--cell-species-colour, var(--color-accent)) 15%, transparent);
    border: 1px solid color-mix(in srgb, var(--cell-species-colour, var(--color-accent)) 35%, transparent);
}

/* Responsive bbox label class used by the canvas overlay and any
   future HTML-rendered labels. The actual font sizing happens in JS
   via measureText, but the container clamps to a sensible minimum so
   tiny boxes can fall back to initials without overflowing. */
.bbox-label--responsive {
    font-size: clamp(11px, 2.4vw, 13px);
    line-height: 1.1;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════════
   UI_STANDARD.md - WM-MODAL--FORM
   Form Modal Variant
   ═══════════════════════════════════════════════════════════════════════════ */

.wm-modal--form .wm-modal__dialog {
    max-width: 600px;
}

/* Tall form modals (Auto PTZ) outgrow the viewport on
   13" laptops, pushing the footer Save button off-screen. Make the
   content a flex column so only the body scrolls; header + footer
   stay anchored. Equivalent to Bootstrap's modal-dialog-scrollable
   but scoped to the form variant so detail-modal sizing is untouched. */
.wm-modal--form .wm-modal__content {
    display: flex;
    flex-direction: column;
}

.wm-modal--form .wm-modal__body {
    background: var(--color-surface);
    overflow-y: auto;
    min-height: 0;
}

.wm-modal__fields {
    display: flex;
    flex-direction: column;
    gap: var(--space-md);
}

.wm-modal__action--form {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-sm);
    padding: var(--space-md);
}

.wm-modal__actions {
    display: flex;
    gap: var(--space-sm);
}

/* ═══════════════════════════════════════════════════════════════════════════
   UI_STANDARD.md - WM-TILE--REVIEW
   Review Tile Variant (Orphans/Review Queue)
   ═══════════════════════════════════════════════════════════════════════════ */

.wm-tile--review {
    position: relative;
    display: flex;
    flex-direction: column;
}

.wm-tile__select {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 10;
}

.wm-tile__checkbox {
    width: 20px;
    height: 20px;
    cursor: pointer;
}

.wm-tile__badge--reason {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 10;
    font-size: var(--font-size-xs);
}

.wm-tile__meta {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

.wm-review-progress {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    font-variant-numeric: tabular-nums;
}

.wm-review-progress.is-complete {
    color: #236b49;
    font-weight: 700;
}

.wm-review-progress__mark {
    width: 1em;
    color: #236b49;
    font-weight: 800;
}

.wm-review-progress__track {
    width: 56px;
    height: 4px;
    overflow: hidden;
    border-radius: 999px;
    background: rgba(95, 71, 37, 0.14);
}

.wm-review-progress__track > span {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: #2f7d57;
}

.date-card > .wm-review-progress {
    padding: 0 var(--space-sm) var(--space-sm);
}

.wm-review-progress--observation {
    justify-content: center;
}

.wm-tile__meta-row {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-xs);
}

.wm-tile__duration {
    color: var(--color-text-muted);
    font-weight: 500;
}

/* ═══════════════════════════════════════════════════════════════════════════
   OBSERVATION CARD — Horizontal cover + info, expands to filmstrip
   ═══════════════════════════════════════════════════════════════════════════ */

/* Filmstrip must span all grid columns */
#subgallery-grid>.obs-filmstrip {
    grid-column: 1 / -1;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CONCURRENT VISIT SHELL
   Visual-only grouping for BirdEvents whose intervals overlap within
   +/-5 min. Same-species observations stay separate tiles; the shell
   only clarifies "these visits happened at the same time".
   ═══════════════════════════════════════════════════════════════════════════ */

/* The shell is a full-row child of the subgallery grid so its own inner
   grid can manage the tiles inside. */
#subgallery-grid>.concurrent-visit {
    grid-column: 1 / -1;
}

.concurrent-visit {
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-sm) var(--space-md) var(--space-md);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.concurrent-visit__header {
    display: flex;
    align-items: baseline;
    gap: var(--space-sm);
    color: var(--color-text-muted, #5a605d);
    font-size: 0.875rem;
    font-weight: 500;
}

.concurrent-visit__time {
    font-variant-numeric: tabular-nums;
    color: var(--color-text, #1a1f1d);
    font-weight: 600;
}

.concurrent-visit__meta::before {
    content: "·";
    margin-right: var(--space-xs);
    opacity: 0.6;
}

/* Nested grid mirrors the parent gallery grid so tiles inside the shell
   line up visually with tiles outside the shell. */
.concurrent-visit__shell {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: var(--space-md);
}

/* Filmstrips inside a shell still span the full row of the inner grid. */
.concurrent-visit__shell>.obs-filmstrip {
    grid-column: 1 / -1;
}

.obs-card {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
    cursor: pointer;
    transition: all var(--transition-fast);
    margin-bottom: 0;
}

.obs-card:hover {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-md);
    transform: translateY(-1px);
}

.obs-card--expanded {
    border-color: var(--color-primary);
    background: var(--color-surface-2);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    margin-bottom: 0;
}

#subgallery-grid>.wm-tile[data-obs-id] {
    transition:
        transform var(--transition-fast),
        box-shadow 1.6s ease,
        border-color 1.6s ease,
        background-color 1.6s ease;
}

#subgallery-grid>.wm-tile--focus-target[data-obs-id] {
    border-color: #1f6f2e;
    background:
        linear-gradient(180deg, rgba(47, 125, 50, 0.2), rgba(47, 125, 50, 0.08)),
        var(--color-surface);
    box-shadow:
        0 0 0 6px rgba(47, 125, 50, 0.3),
        0 0 0 12px rgba(47, 125, 50, 0.12),
        0 22px 42px rgba(31, 111, 46, 0.24);
    transform: translateY(-2px) scale(1.01);
    animation: subgallery-focus-pulse 1.6s ease-in-out 4;
}

#subgallery-grid>.wm-tile--focus-target-fade[data-obs-id] {
    border-color: var(--color-border);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    animation: none;
}

@keyframes subgallery-focus-pulse {
    0%,
    100% {
        box-shadow:
            0 0 0 6px rgba(47, 125, 50, 0.24),
            0 0 0 12px rgba(47, 125, 50, 0.1),
            0 18px 34px rgba(31, 111, 46, 0.18);
    }

    50% {
        box-shadow:
            0 0 0 9px rgba(47, 125, 50, 0.38),
            0 0 0 18px rgba(47, 125, 50, 0.14),
            0 26px 46px rgba(31, 111, 46, 0.28);
    }
}

.obs-card__cover {
    position: relative;
    flex-shrink: 0;
    width: 120px;
    height: 120px;
    border-radius: var(--radius-md);
    overflow: hidden;
}

.obs-card__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.obs-card__cover .wm-tile__badge {
    top: 6px;
    right: 6px;
    font-size: var(--font-size-xs);
    padding: 3px 7px;
}

.obs-card__info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    flex: 1;
}

.obs-card__name {
    font-size: var(--font-size-md);
    font-weight: 600;
    color: var(--color-text);
}

.obs-card__latin {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    font-style: italic;
}

.obs-card__time-line {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    font-family: 'SF Mono', 'Fira Code', monospace;
}

.obs-card__meta {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: var(--font-size-sm);
}

.obs-card__expand-hint {
    color: var(--color-text-subtle);
    font-size: var(--font-size-xs);
    transition: transform 0.2s;
}

.obs-card--expanded .obs-card__expand-hint {
    transform: rotate(180deg);
}

/* ── Filmstrip (expanded grid of all photos) ───────────────────────── */

.obs-filmstrip {
    background: var(--color-surface-2);
    border: 1px solid var(--color-primary);
    border-top: none;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    padding: var(--space-md);
    margin-bottom: var(--space-md);
    animation: filmstrip-open 0.2s ease-out;
}

@keyframes filmstrip-open {
    from {
        opacity: 0;
        max-height: 0;
    }

    to {
        opacity: 1;
        max-height: 2000px;
    }
}

.obs-filmstrip__header {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-sm);
    flex-wrap: wrap;
}

.obs-filmstrip__title {
    font-weight: 600;
    font-size: var(--font-size-md);
    color: var(--color-text);
}

.obs-filmstrip__time {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.obs-filmstrip__close {
    margin-left: auto;
    font-size: var(--font-size-sm);
    padding: 4px 12px;
}

.obs-filmstrip__grid {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(180px, 220px);
    gap: var(--space-sm);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
    padding-bottom: var(--space-xs);
}

.obs-filmstrip__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    min-width: 0;
    scroll-snap-align: start;
    border-radius: var(--radius-md);
    padding: 6px;
    transition:
        box-shadow 1.6s ease,
        background-color 1.6s ease,
        transform var(--transition-fast);
}

.obs-filmstrip__item--focus-target {
    background: rgba(47, 125, 50, 0.16);
    box-shadow:
        0 0 0 4px rgba(47, 125, 50, 0.28),
        0 12px 24px rgba(31, 111, 46, 0.22);
    transform: translateY(-2px);
}

.obs-filmstrip__item--focus-target-fade {
    background: transparent;
    box-shadow: none;
    transform: none;
}

.obs-filmstrip__media {
    position: relative;
    width: 100%;
}

.obs-filmstrip__button {
    display: block;
    width: 100%;
    padding: 0;
    border: 2px solid transparent;
    background: none;
    cursor: pointer;
    border-radius: var(--radius-sm);
    overflow: hidden;
    transition: border-color 0.15s, transform 0.15s;
}

.obs-filmstrip__button:hover {
    border-color: var(--color-primary);
    transform: translateY(-1px);
}

.obs-filmstrip__thumb {
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    display: block;
}

.obs-filmstrip__label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-family: 'SF Mono', 'Fira Code', monospace;
}

.obs-filmstrip__grid::-webkit-scrollbar {
    height: 10px;
}

.obs-filmstrip__grid::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--color-primary) 40%, transparent);
    border-radius: var(--radius-full);
}

/* ── Responsive: stack vertically on small screens ─────────────────── */
@media (max-width: 480px) {
    .obs-card__cover {
        width: 80px;
        height: 80px;
    }

    .obs-filmstrip__grid {
        grid-auto-columns: minmax(150px, 180px);
    }
}

.wm-tile__size {
    font-size: var(--font-size-xs);
    color: var(--color-text-subtle);
}

.wm-tile__actions {
    display: flex;
    justify-content: center;
    gap: var(--space-xs);
    padding: var(--space-xs);
    border-top: 1px solid var(--color-border-light);
}

/* ═══════════════════════════════════════════════════════════════════════════
   UI_STANDARD.md - WM-TILE--BBOX
   BBox Tile Variant (Thumbnail Macro with Clipping)
   ═══════════════════════════════════════════════════════════════════════════ */

.wm-tile--bbox {
    position: relative;
}

.wm-tile--selectable .wm-tile__select {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 10;
}

.wm-tile__media--bbox {
    overflow: hidden;
}

.wm-tile__image--bbox {
    /* Ensures image behavior within bbox media container */
    object-fit: cover;
}

/* ═══════════════════════════════════════════════════════════════════════════
   WM-TOOLBOX — Shared tile hover action dock
   Hover-reveal toolbar at bottom-right of any wm-tile.
   Desktop: shows on hover. Mobile: shows on tap via :focus-within.
   ═══════════════════════════════════════════════════════════════════════════ */

.wm-toolbox {
    position: absolute;
    bottom: 10px;
    right: 10px;
    z-index: 15;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px;
    border: 1px solid rgba(60, 48, 34, 0.28);
    border-radius: 999px;
    background:
        linear-gradient(180deg, rgba(61, 55, 45, 0.92), rgba(34, 30, 24, 0.95));
    box-shadow: 0 10px 24px rgba(39, 28, 14, 0.28);
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 0.15s ease, transform 0.15s ease;
    pointer-events: none;
}

.wm-toolbox--bar {
    position: static;
    inset: auto;
    opacity: 1;
    transform: none;
    pointer-events: auto;
    gap: 8px;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}

.wm-toolbox-host {
    position: relative;
}

/* Show on tile hover or when any button inside is focused (mobile tap) */
.wm-tile:hover .wm-toolbox,
.wm-tile:focus-within .wm-toolbox,
.wm-toolbox-host:hover .wm-toolbox,
.wm-toolbox-host:focus-within .wm-toolbox,
.trash-item:hover .wm-toolbox,
.trash-item:focus-within .wm-toolbox,
.wm-toolbox:focus-within {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

/* Always show if a dropdown is open */
.wm-toolbox:has(.wm-toolbox__dropdown--open) {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.wm-toolbox__btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid rgba(212, 188, 138, 0.25);
    border-radius: 999px;
    background: linear-gradient(180deg, rgba(121, 103, 71, 0.92), rgba(84, 68, 46, 0.92));
    color: rgba(255, 244, 222, 0.95);
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.12s, transform 0.12s;
    line-height: 1;
    backdrop-filter: none;
}

.wm-toolbox--bar .wm-toolbox__btn {
    min-width: 38px;
    height: 38px;
    border: 1px solid rgba(95, 71, 37, 0.24);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(255, 252, 247, 0.98), rgba(239, 229, 206, 0.98));
    color: #3d2f1d;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.7),
        0 4px 10px rgba(61, 45, 24, 0.08);
    backdrop-filter: none;
}

.wm-toolbox--bar .wm-toolbox__btn:hover {
    background: linear-gradient(180deg, rgba(255, 254, 250, 1), rgba(244, 234, 211, 1));
    border-color: rgba(95, 71, 37, 0.34);
    transform: translateY(-1px);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.8),
        0 8px 16px rgba(61, 45, 24, 0.12);
}

.wm-toolbox__btn:hover {
    background: linear-gradient(180deg, rgba(151, 129, 85, 0.96), rgba(103, 84, 55, 0.96));
    transform: scale(1.1);
}

.wm-toolbox__btn:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* Favorite active state */
.wm-toolbox__fav--active {
    color: #ffe187;
    background: linear-gradient(180deg, rgba(173, 114, 36, 0.98), rgba(110, 71, 20, 0.98));
}

.wm-toolbox--bar .wm-toolbox__fav--active {
    color: #f8f3e8;
    background: linear-gradient(180deg, rgba(156, 120, 53, 0.96), rgba(119, 89, 35, 0.98));
    border-color: rgba(119, 89, 35, 0.38);
}

.wm-toolbox__btn--locked,
.wm-toolbox__item--disabled {
    opacity: 0.58;
}

.wm-toolbox__btn--locked::after {
    content: "·";
    margin-left: 1px;
}

/* Pressed state for stateful toolbox buttons.
   Used by the Smart Zoom toggle (`gallery_utils.js:toggleSmartZoom`)
   and any future stateful toolbox button such as
   bbox-overlay toggles. Stateful buttons must carry `aria-pressed`
   and the `--toggled` modifier so the pressed state is visible in the
   CSS and in the accessibility tree at the same time. */
.wm-toolbox__btn--toggled {
    background: linear-gradient(180deg, rgba(74, 97, 63, 0.96), rgba(60, 80, 50, 0.98));
    border-color: rgba(60, 80, 50, 0.42);
    color: #fdfbf7;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);
}

.wm-toolbox__btn--toggled:hover {
    background: linear-gradient(180deg, rgba(82, 108, 68, 0.98), rgba(66, 88, 55, 1));
}

/* Menu wrapper */
.wm-toolbox__menu {
    position: relative;
}

/* Dropdown */
.wm-toolbox__dropdown {
    display: none;
    position: absolute;
    bottom: 100%;
    right: 0;
    margin-bottom: 4px;
    min-width: 188px;
    background: linear-gradient(180deg, rgba(244, 236, 217, 0.98), rgba(230, 216, 188, 0.98));
    border: 1px solid rgba(95, 71, 37, 0.22);
    border-radius: var(--radius-md);
    padding: 6px 0;
    box-shadow: 0 14px 32px rgba(29, 22, 13, 0.34);
    z-index: 20;
}

.wm-toolbox--bar .wm-toolbox__dropdown {
    top: calc(100% + 8px);
    bottom: auto;
    margin-bottom: 0;
    border-radius: 14px;
}

.wm-toolbox__dropdown--open {
    display: flex;
    flex-direction: column;
}

.wm-toolbox__item {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 8px 12px;
    border: none;
    background: transparent;
    color: var(--color-text);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background 0.1s;
    text-align: left;
    white-space: nowrap;
}

.wm-toolbox__item:hover {
    background: rgba(95, 71, 37, 0.08);
}

.wm-toolbox__item:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

.wm-toolbox__item--danger {
    color: var(--color-danger, #ef4444);
}

.wm-toolbox__item--danger:hover {
    background: rgba(159, 75, 45, 0.12);
}

.wm-toolbox__item--disabled:hover {
    background: transparent;
}

/* Reduced motion preference */
@media (prefers-reduced-motion: reduce) {
    .wm-toolbox {
        transition: none;
    }

    .wm-toolbox__btn {
        transition: none;
    }
}

/* ── Sibling Card Actions ───────────────────────────────────────────── */

.sibling-card__action {
    position: absolute;
    top: 4px;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.7rem;
    opacity: 0.4;
    padding: 2px 4px;
    border-radius: 3px;
    transition: opacity 0.15s, background 0.15s;
}

.sibling-card__action:hover {
    opacity: 1;
}

.sibling-card__action--relabel {
    right: 24px;
}

.sibling-card__action--relabel:hover {
    background: rgba(167, 139, 250, 0.15);
}

.sibling-card__action--delete {
    right: 4px;
}

.sibling-card__action--delete:hover {
    background: rgba(220, 53, 69, 0.15);
}

/* ── Scientific / Ecological Metrics ─────────────────────────────────── */

.scientific-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-md);
    margin-bottom: var(--space-xl);
}

.metric-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-md);
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.metric-card__label {
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
}

.metric-card__value {
    font-size: var(--font-size-xl);
    font-weight: 700;
    font-family: 'SF Mono', 'Fira Code', monospace;
    color: var(--color-text);
}

.metric-card__desc {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    margin-top: var(--space-xs);
    line-height: 1.4;
}

/* Rank Abundance Plot */
.rank-plot {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: var(--space-md);
    font-family: 'SF Mono', 'Fira Code', monospace;
    font-size: var(--font-size-xs);
}

.rank-plot__row {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    height: 24px;
}

.rank-plot__label {
    width: 140px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: right;
    color: var(--color-text-muted);
}

.rank-plot__bar-container {
    flex: 1;
    height: 100%;
    display: flex;
    align-items: center;
}

.rank-plot__bar {
    height: 16px;
    background: var(--color-primary);
    border-radius: 2px;
    min-width: 2px;
    opacity: 0.7;
    transition: width 0.3s ease;
}

.rank-plot__bar--top {
    background: var(--color-primary-dark);
    opacity: 1;
}

.rank-plot__value {
    width: 50px;
    text-align: right;
    color: var(--color-text-muted);
}

/* ═══════════════════════════════════════════════════════════════════════════
   IMPACT ANALYTICS - Banner, Cards, Charts
   ═══════════════════════════════════════════════════════════════════════════ */

/* --- Impact Banner (clickable link card on analytics page) --- */
.impact-banner {
    display: flex;
    align-items: stretch;
    gap: var(--space-lg);
    background: linear-gradient(135deg,
            rgba(239, 108, 0, 0.06) 0%,
            rgba(255, 224, 178, 0.12) 100%);
    border: 1px solid rgba(239, 108, 0, 0.2);
    border-radius: var(--radius-xl);
    padding: var(--space-lg);
    margin-bottom: var(--space-xl);
    text-decoration: none;
    color: var(--color-text);
    transition: all var(--transition-normal);
    backdrop-filter: none;
    overflow: hidden;
    cursor: pointer;
}

.impact-banner:hover {
    border-color: var(--color-impact);
    box-shadow: 0 8px 24px rgba(239, 108, 0, 0.12);
    transform: translateY(-2px);
    color: var(--color-text);
}

.impact-banner__thumb {
    flex: 0 0 200px;
    min-height: 80px;
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-surface);
    border: 1px solid var(--color-border-light);
    display: flex;
    align-items: center;
}

.impact-banner__svg {
    width: 100%;
    height: 80px;
}

.impact-banner__content {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-xs);
}

.impact-banner__title {
    font-size: var(--font-size-lg);
    font-weight: 700;
    color: var(--color-impact-dark);
}

.impact-banner__desc {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    line-height: 1.5;
}

.impact-banner__cta {
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-impact);
    transition: transform var(--transition-fast);
}

.impact-banner:hover .impact-banner__cta {
    transform: translateX(4px);
}

@media (max-width: 640px) {
    .impact-banner {
        flex-direction: column;
    }

    .impact-banner__thumb {
        flex: none;
        height: 60px;
    }
}

/* --- Impact Header (Human Impact page) --- */
.impact-header {
    position: relative;
}

.impact-header__back {
    display: inline-block;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    margin-bottom: var(--space-xs);
    transition: color var(--transition-fast);
}

.impact-header__back:hover {
    color: var(--color-impact);
}

/* --- Impact Summary Cards --- */
.summary-card--impact {
    border-left: 4px solid var(--color-impact);
}

.summary-card--impact .summary-card__value {
    color: var(--color-impact-dark);
}

.summary-card--impact-accent {
    border-left: 4px solid var(--color-impact);
    background: linear-gradient(135deg,
            rgba(239, 108, 0, 0.04) 0%,
            var(--color-surface) 100%);
}

.summary-card--impact-accent .summary-card__value {
    color: var(--color-impact);
}

.summary-card--impact-peak {
    border-left: 4px solid var(--color-warning);
}

.summary-card--impact-peak .summary-card__value {
    color: var(--color-warning);
}

.summary-card--noise {
    border-left: 4px solid var(--color-text-muted);
}

/* --- Impact Chart Cards --- */
.chart-card--impact {
    border-top: 3px solid var(--color-impact);
}

.chart-card--impact-ratio {
    border-top: 3px solid var(--color-impact-ratio);
}

.chart-card--impact-info {
    border-top: 3px solid var(--color-info);
}

.chart-card__badge--impact {
    background: var(--color-impact-light);
    color: var(--color-impact-dark);
}

/* --- Impact Histogram Bars --- */
.histogram__bar--impact {
    background: linear-gradient(180deg, var(--color-impact) 0%, var(--color-impact-dark) 100%);
}

.histogram__bar--impact:hover {
    background: var(--color-impact);
    opacity: 0.9;
}

/* --- Impact Category Breakdown Bars --- */
.condition-dist__bar--impact {
    background: linear-gradient(90deg, var(--color-impact) 0%, var(--color-impact-dark) 100%);
}

/* --- Ratio Chart Extras --- */
.histogram-legend__swatch--ratio {
    background: var(--color-impact-ratio);
}

.ratio-baseline {
    display: inline-block;
    width: 24px;
    height: 2px;
    background: var(--color-warning);
    vertical-align: middle;
    margin: 0 var(--space-2xs);
    border-top: 1px dashed var(--color-warning);
}

/* --- Impact Info Grid (About section) --- */
.impact-info-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-lg);
}

.impact-info-card {
    background: var(--color-surface-2);
    border-radius: var(--radius-lg);
    padding: var(--space-lg);
    text-align: center;
    transition: transform var(--transition-fast);
}

.impact-info-card:hover {
    transform: translateY(-2px);
}

.impact-info-card__icon {
    font-size: 2rem;
    margin-bottom: var(--space-sm);
}

.impact-info-card__title {
    font-weight: 700;
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-xs);
    color: var(--color-text);
}

.impact-info-card__text {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    line-height: 1.6;
}

@media (max-width: 768px) {
    .impact-info-grid {
        grid-template-columns: 1fr;
    }
}

/* --- Impact Back Link --- */
.impact-back-link {
    display: inline-block;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    padding: var(--space-sm) var(--space-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    transition: all var(--transition-fast);
}

.impact-back-link:hover {
    color: var(--color-impact);
    border-color: var(--color-impact);
    background: rgba(239, 108, 0, 0.04);
}

@media (max-width: 640px) {

    .gallery-grid,
    .species-grid,
    .date-grid,
    .trash-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-sm);
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   FADE-IN ANIMATION - Cards appear with subtle upward slide
   Usage: add class "fade-in-item" to elements, JS observer adds "is-visible"
   ═══════════════════════════════════════════════════════════════════════════ */

@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(16px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.fade-in-item {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.2s ease-out, transform 0.2s ease-out;
}

.fade-in-item.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* Prefers reduced motion: skip animation */
@media (prefers-reduced-motion: reduce) {
    .fade-in-item {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   TOAST NOTIFICATIONS - Slide-in feedback from bottom-right
   Usage: window.wmToast('Message', 'success'|'error'|'info')
   ═══════════════════════════════════════════════════════════════════════════ */

.wm-toast-container {
    position: fixed;
    /* Moved from bottom-right to top-right: the dev
       palette-tester widget sits at bottom-right with z-index 99999
       and was overlapping toasts, making them unreadable. Top-right
       is also the convention in Slack/GitHub/Google, keeps the area
       visible above page content, and doesn't collide with the
       fixed toolbar at the top of the page because the toolbar uses
       a lower z-index. */
    top: 80px;
    right: 24px;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
    max-width: min(380px, calc(100vw - 32px));
}

.wm-toast {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06);
    font-size: var(--font-size-sm);
    font-weight: 500;
    color: var(--color-text);
    transform: translateX(120%);
    opacity: 0;
    animation: toastSlideIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    position: relative;
    overflow: hidden;
}

.wm-toast--dismiss {
    animation: toastSlideOut 0.25s ease-in forwards;
}

@keyframes toastSlideIn {
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes toastSlideOut {
    to {
        transform: translateX(120%);
        opacity: 0;
    }
}

.wm-toast__icon {
    font-size: 1.1rem;
    flex-shrink: 0;
}

.wm-toast__text {
    flex: 1;
    line-height: 1.4;
}

.wm-toast__close {
    flex-shrink: 0;
    cursor: pointer;
    color: var(--color-text-muted);
    font-size: 0.9rem;
    padding: 2px 4px;
    border-radius: var(--radius-sm);
    transition: color 0.15s ease, background 0.15s ease;
    border: none;
    background: none;
}

.wm-toast__close:hover {
    color: var(--color-text);
    background: rgba(0, 0, 0, 0.05);
}

/* Progress bar countdown */
.wm-toast__progress {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 3px;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    animation: toastProgress linear forwards;
}

@keyframes toastProgress {
    from {
        width: 100%;
    }

    to {
        width: 0%;
    }
}

/* Variants */
.wm-toast--success {
    border-color: rgba(47, 111, 62, 0.25);
    background: linear-gradient(135deg, #f0faf2, var(--color-surface));
}

.wm-toast--success .wm-toast__progress {
    background: var(--color-primary);
}

.wm-toast--error {
    border-color: rgba(229, 62, 62, 0.25);
    background: linear-gradient(135deg, #fef2f2, var(--color-surface));
}

.wm-toast--error .wm-toast__progress {
    background: var(--color-danger);
}

.wm-toast--info {
    border-color: rgba(2, 136, 209, 0.25);
    background: linear-gradient(135deg, #eff8ff, var(--color-surface));
}

.wm-toast--info .wm-toast__progress {
    background: var(--color-secondary);
}

/* Mobile: full-width at bottom */
@media (max-width: 640px) {
    .wm-toast-container {
        left: 12px;
        right: 12px;
        bottom: 12px;
        max-width: none;
    }
}

/* ── Bootstrap overrides: theme-aware card-headers, badges, forms ── */

.card-header.bg-primary {
    background: var(--color-primary) !important;
    color: var(--color-primary-light) !important;
}

.card-header.bg-info {
    background: var(--color-info) !important;
    color: var(--color-surface) !important;
}

.card-header.bg-secondary {
    background: var(--color-secondary) !important;
    color: var(--color-surface) !important;
}

.card-header.bg-danger {
    background: var(--color-danger) !important;
    color: var(--color-surface) !important;
}

.card-header.bg-light {
    background: var(--color-surface-2) !important;
    color: var(--color-text) !important;
}

.card-header.bg-warning {
    background: var(--color-warning) !important;
    color: var(--color-text) !important;
}

.badge.bg-light,
.badge.text-bg-light {
    background: var(--color-surface-2) !important;
    color: var(--color-text) !important;
}

.badge.bg-secondary {
    background: var(--color-secondary) !important;
    color: var(--color-surface) !important;
}

.badge.bg-primary {
    background: var(--color-primary) !important;
    color: var(--color-primary-light) !important;
}

.badge.bg-success {
    background: var(--color-success) !important;
    color: var(--color-surface) !important;
}

.badge.bg-danger {
    background: var(--color-danger) !important;
    color: var(--color-surface) !important;
}

.badge.bg-warning {
    background: var(--color-warning) !important;
    color: var(--color-text) !important;
}

.badge.bg-info {
    background: var(--color-info) !important;
    color: var(--color-surface) !important;
}

.badge.text-dark {
    color: var(--color-text) !important;
}

.form-control,
.form-select {
    background-color: var(--color-surface);
    color: var(--color-text);
    border-color: var(--color-border);
}

.form-control:focus,
.form-select:focus {
    background-color: var(--color-surface);
    color: var(--color-text);
    border-color: var(--color-primary);
}

.form-text {
    color: var(--color-text-muted);
}

.text-muted {
    color: var(--color-text-muted) !important;
}

.text-dark {
    color: var(--color-text) !important;
}

.alert-info {
    background: var(--color-surface-2);
    color: var(--color-text);
    border-color: var(--color-border);
}

.card {
    background: var(--color-surface);
    border-color: var(--color-border);
}

.card-body {
    color: var(--color-text);
}

.table {
    color: var(--color-text);
}

.btn-light {
    background: var(--color-surface-2);
    color: var(--color-text);
    border-color: var(--color-border);
}

.btn-light:hover {
    background: var(--color-surface-3);
    color: var(--color-text);
}

.alert-light {
    background: var(--color-surface-2);
    color: var(--color-text);
    border-color: var(--color-border) !important;
}

.list-group-item {
    background-color: var(--color-surface);
    color: var(--color-text);
    border-color: var(--color-border);
}

.list-group-item:hover {
    background-color: var(--color-surface-2);
}

.btn-primary {
    background-color: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-surface);
}

.btn-primary:hover {
    background-color: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
    color: var(--color-surface);
}

.btn-outline-primary {
    color: var(--color-primary);
    border-color: var(--color-primary);
}

.btn-outline-primary:hover {
    background-color: var(--color-primary);
    color: var(--color-surface);
}

.btn-outline-secondary {
    color: var(--color-secondary);
    border-color: var(--color-secondary);
}

.btn-outline-secondary:hover {
    background-color: var(--color-secondary);
    color: var(--color-surface);
}

.btn-outline-success {
    color: var(--color-success);
    border-color: var(--color-success);
}

.btn-outline-success:hover {
    background-color: var(--color-success);
    color: var(--color-surface);
}

.btn-outline-danger {
    color: var(--color-danger);
    border-color: var(--color-danger);
}

.btn-outline-danger:hover {
    background-color: var(--color-danger);
    color: var(--color-surface);
}

.btn-outline-warning {
    color: var(--color-warning);
    border-color: var(--color-warning);
}

.btn-outline-warning:hover {
    background-color: var(--color-warning);
    color: var(--color-text);
}

.badge.text-bg-secondary {
    background: var(--color-secondary) !important;
    color: var(--color-surface) !important;
}

.modal-content {
    background-color: var(--color-surface);
    color: var(--color-text);
}

.modal-header {
    border-color: var(--color-border);
}

.form-label {
    color: var(--color-text);
}

.alert-danger {
    background: color-mix(in srgb, var(--color-danger) 12%, var(--color-surface));
    color: var(--color-text);
    border-color: color-mix(in srgb, var(--color-danger) 30%, var(--color-border));
}

.alert-success {
    background: color-mix(in srgb, var(--color-success) 12%, var(--color-surface));
    color: var(--color-text);
    border-color: color-mix(in srgb, var(--color-success) 30%, var(--color-border));
}

.alert-warning {
    background: color-mix(in srgb, var(--color-warning) 12%, var(--color-surface));
    color: var(--color-text);
    border-color: color-mix(in srgb, var(--color-warning) 30%, var(--color-border));
}

.badge.text-bg-success {
    background: var(--color-success) !important;
    color: var(--color-surface) !important;
}

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

.btn-secondary {
    background-color: var(--color-secondary);
    border-color: var(--color-secondary);
    color: var(--color-surface);
}

.btn-secondary:hover {
    background-color: var(--color-accent-dark);
    border-color: var(--color-accent-dark);
    color: var(--color-surface);
}

.spinner-border {
    color: var(--color-text-muted);
}

.text-danger {
    color: var(--color-danger) !important;
}

.text-success {
    color: var(--color-success) !important;
}

.border {
    border-color: var(--color-border) !important;
}

.border-danger {
    border-color: var(--color-danger) !important;
}

code {
    color: var(--color-accent-dark);
    background: var(--color-surface-2);
}

/* ============================================================
   STATION REPORT
   One calm event-led reading surface for /analytics.
   ============================================================ */

.station-report {
    --report-accent: var(--color-primary);
    max-width: 1240px;
    margin: 0 auto;
    padding-bottom: clamp(48px, 8vw, 96px);
    color: var(--color-text);
}
.station-report__eyebrow {
    margin: 0 0 8px;
    color: var(--report-accent);
    font-size: 0.72rem;
    font-weight: 750;
    letter-spacing: 0.13em;
    text-transform: uppercase;
}

.sampling-diagnostics {
    margin: 18px 0 26px;
    padding: 14px 0;
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 0.8rem;
}

.sampling-diagnostics summary {
    color: var(--color-text);
    cursor: pointer;
    font-weight: 700;
}

.sampling-diagnostics > div {
    display: flex;
    gap: 36px;
    margin-top: 16px;
}

.sampling-diagnostics > div p { margin: 0; }
.sampling-diagnostics strong { display: block; color: var(--color-text); font-size: 1.35rem; }
.sampling-diagnostics span { display: block; margin-top: 3px; }
.sampling-diagnostics > p { max-width: 760px; margin: 14px 0 0; line-height: 1.55; }

.report-table-wrap { overflow-x: auto; border-top: 1px solid var(--color-border); }

.storage-exports { overflow-wrap: anywhere; }

.report-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.78rem;
}

.report-table th,
.report-table td {
    padding: 12px 10px;
    border-bottom: 1px solid var(--color-border);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.report-table th:first-child,
.report-table td:first-child { padding-left: 0; text-align: left; }
.report-table thead th { color: var(--color-text-muted); font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; }
.report-table tbody th { font-style: italic; font-weight: 600; }

@media (max-width: 620px) {
    .sampling-diagnostics > div { flex-direction: column; gap: 12px; }
}

@keyframes report-enter {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ============================================================
   ANALYTICS — BIOLOGICAL INSIGHTS
   PCA hero chart + side-by-side diversity/quality tables +
   per-species summary table. Lives at the bottom of /analytics.
   Reuses tokens defined above; no new colours.
   ============================================================ */

/* --- Hero PCA chart -------------------------------------------------- */
.analytics-pca-card { padding-bottom: var(--space-md); }

.analytics-pca {
    margin-top: var(--space-md);
    background: var(--color-surface-2);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-md);
}

.analytics-pca__svg {
    width: 100%;
    height: auto;
    aspect-ratio: 5 / 3;
    display: block;
    overflow: visible;
}

.analytics-pca__axis {
    stroke: var(--color-border);
    stroke-width: 1;
    stroke-dasharray: 4 4;
    opacity: 0.55;
}

.analytics-pca__quadrant {
    fill: var(--color-text-muted);
    font-size: 11px;
    font-family: var(--font-family-mono, ui-monospace, monospace);
    opacity: 0.55;
}

.analytics-pca__point {
    transition: filter 150ms ease-out, transform 150ms ease-out;
    transform-origin: center;
    transform-box: fill-box;
    cursor: default;
}

.analytics-pca__point:hover {
    filter: brightness(1.1) drop-shadow(0 2px 6px rgba(0, 0, 0, 0.18));
}

.analytics-pca__point:hover circle { stroke-width: 2.5; }

.analytics-pca__label {
    fill: var(--color-text);
    font-size: 12px;
    font-weight: 500;
    pointer-events: none;
    paint-order: stroke;
    stroke: var(--color-surface-2);
    stroke-width: 3;
    stroke-linejoin: round;
}

.analytics-pca__legend {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

.analytics-pca__legend-item {
    display: flex;
    align-items: center;
    gap: 6px;
}

.analytics-pca__legend-text { color: var(--color-text-muted); }

.analytics-pca__legend-swatch {
    border-radius: 50%;
    background: var(--color-primary);
    opacity: 0.6;
    display: inline-block;
}

.analytics-pca__legend-swatch--small  { width: 8px;  height: 8px;  }
.analytics-pca__legend-swatch--medium { width: 14px; height: 14px; }
.analytics-pca__legend-swatch--large  { width: 22px; height: 22px; }

.analytics-pca__legend-gradient {
    display: inline-block;
    width: 96px;
    height: 12px;
    border-radius: 6px;
    background: linear-gradient(
        to right,
        hsl(200, 55%, 55%),
        hsl(45, 70%, 60%),
        hsl(20, 65%, 55%),
        hsl(330, 55%, 55%)
    );
}

.analytics-pca__legend-note {
    margin-left: auto;
    font-style: italic;
    opacity: 0.75;
}

/* --- Two-card row for diversity + quality tables --------------------- */
.analytics-bio-tables-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-md);
    margin-top: var(--space-md);
}

@media (max-width: 880px) {
    .analytics-bio-tables-row { grid-template-columns: 1fr; }
}

/* Single-column variant: when only one card occupies the row, the diversity
   table fills the full width instead of leaving an empty column. */
.analytics-bio-tables-row--single {
    grid-template-columns: 1fr;
}

/* --- Tables ---------------------------------------------------------- */
.analytics-bio-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-xs);
    margin-top: 8px;
}

.analytics-bio-table th,
.analytics-bio-table td {
    text-align: left;
    padding: 8px 10px;
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text);
    font-weight: 400;
}

.analytics-bio-table thead th {
    color: var(--color-text-muted);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    background: transparent;
    border-bottom: 1px solid var(--color-border);
    padding-top: 12px;
}

.analytics-bio-table tbody:first-of-type tr:first-child th,
.analytics-bio-table tbody:first-of-type tr:first-child td {
    border-top: none;
}

.analytics-bio-table tbody tr:last-child th,
.analytics-bio-table tbody tr:last-child td {
    border-bottom: none;
}

.analytics-bio-table tbody th {
    color: var(--color-text);
    font-weight: 500;
}

.analytics-bio-table__num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--color-text-muted);
}

.analytics-bio-table__species {
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.analytics-bio-table--zebra tbody tr:nth-child(even) {
    background: var(--color-surface-2);
}

.analytics-bio-table--zebra tbody tr:hover {
    background: var(--color-primary-light);
    transition: background 120ms ease-out;
}

.analytics-bio-table__row--hover {
    background: var(--color-primary-light);
}

/* REVIEW GRID
   ============================================================
   Vertical event-card stack with per-card tile-size stepper.
   Replaces the rail-+-center-stage-+-decision-rail composition
   from `review-stage-panel__*` for the default Review Desk view. */

.review-grid {
    max-width: 1600px;
    margin: 0 auto;
    padding: 16px 16px 96px;
}

.review-grid__stack {
    display: flex;
    flex-direction: column;
    gap: clamp(16px, 2vw, 24px);
}

.review-day-nav {
    max-width: 1600px;
    margin: 0 auto;
    padding: 6px 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.review-day-nav__arrows,
.review-day-nav__form {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.review-day-nav .form-control {
    width: auto;
    min-height: 44px;
}

.review-day-nav [aria-disabled="true"] {
    opacity: 0.45;
    pointer-events: none;
}

@media (max-width: 600px) {
    .review-day-nav__form {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        width: 100%;
    }

    .review-day-nav__form .form-control {
        width: 100%;
        min-width: 0;
    }

    .review-day-nav__form button {
        grid-column: 2;
        justify-self: end;
    }
}

.review-desk-bar {
    height: auto;
    min-height: 44px;
    padding-block: 6px;
    margin-bottom: 4px;
}

.review-day-nav {
    font-size: 0.82rem;
}

.review-day-nav .btn,
.review-day-nav .form-control {
    min-height: 32px;
    padding: 4px 10px;
    font-size: 0.82rem;
}

.review-grid__placeholder {
    text-align: center;
    padding: 32px 16px;
}

/* Inter-event separator.
   A thick, soft, fade-in/fade-out bar that gives the operator a strong
   visual "next event starts here" beat between cards in the stack.
   Rendered between events by review_grid.html, suppressed inside a
   continuity batch (the batch-strip already groups those). The stack's
   own gap supplies the breathing room; this element is the bar itself.
   Token-driven (var(--color-border)) so it tracks light/dark themes. */
.review-grid__event-separator {
    /* override the browser/bootstrap <hr> baseline so this looks
       deliberate, not like a default rule */
    border: 0;
    margin: 0;
    height: 6px;
    width: 100%;
    background: linear-gradient(
        90deg,
        transparent 0%,
        color-mix(in srgb, var(--color-border) 70%, transparent) 12%,
        color-mix(in srgb, var(--color-text-muted, var(--color-border)) 55%, transparent) 50%,
        color-mix(in srgb, var(--color-border) 70%, transparent) 88%,
        transparent 100%
    );
    border-radius: 999px;
    opacity: 0.85;
}

/* .review-grid__batch-footer — retired.
   The sticky bulk-action footer is gone; card-header Smart-Mode
   (Approve / Relabel / No Bird / Trash respect per-card selection)
   replaces it for the per-card workflow. Cross-event bulk action
   is no longer reachable from /admin/review. */

/* Review Grid — Card layout
   ============================================================ */

.review-grid__card {
    position: relative;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-color: color-mix(
        in srgb,
        var(--cell-species-colour, var(--color-border)) 34%,
        var(--color-border)
    );
    border-radius: 12px;
    padding: 12px 16px 20px 22px;
    /* Hard black frame around every event card. Sits OUTSIDE the existing species-tinted
       border so the §6d species-colour anchor stays visible, while the
       operator gets an unmistakable "this is one event" boundary.
       Uses outline (not border) to avoid shifting layout and to keep
       the existing border-color logic untouched. */
    outline: 2px solid #000;
    outline-offset: 0;
    box-shadow:
        0 10px 26px rgba(26, 38, 45, 0.10),
        0 1px 2px rgba(0, 0, 0, 0.06);
    /* Species-coloured vertical rail on the left edge anchors each card
       as a distinct block. The operator's eye
       reads a colour change as a block change without having to parse
       the header text. Cards with no species (eligibility != event_eligible
       before relabel, unknown species) fall back to a neutral border
       colour so the rail is always visible even without a species. */
    --review-card-rail-width: 6px;
}

.review-grid__card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--review-card-rail-width);
    background: var(--cell-species-colour, var(--color-border));
    border-top-left-radius: 12px;
    border-bottom-left-radius: 12px;
}

.review-grid__card--has-species::before {
    /* Slightly stronger anchor when we actually have a species token. */
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05);
}

.review-grid__card::after {
    content: "";
    position: absolute;
    right: 16px;
    bottom: 0;
    left: 22px;
    height: 4px;
    border-bottom-right-radius: 12px;
    background: linear-gradient(
        to right,
        var(--cell-species-colour, var(--color-border)),
        color-mix(in srgb, var(--cell-species-colour, var(--color-border)) 18%, transparent)
    );
    opacity: 0.95;
    pointer-events: none;
}

.review-grid__card-header {
    /* Sticky header per event. The header sticks to the top of the viewport (just below the
       fixed app-bar) while the rest of its card scrolls past. When
       the next card's header reaches the same top offset, it pushes
       the previous one out — iOS section-header pattern. This lets
       the operator act on the current event no matter how far they
       have scrolled inside it. */
    position: sticky;
    top: var(--appbar-height);
    z-index: 20; /* above tile-bbox canvases (z-index 3-4), below
                    bootstrap modal (z-index 1100) and app-bar (1000) */
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 6px 12px;
    flex-wrap: wrap;
    margin: -12px -16px 8px -22px;
    padding: 8px 16px 8px 22px;
    border-bottom: 1px solid color-mix(
        in srgb,
        var(--cell-species-colour, var(--color-border)) 28%,
        var(--color-border)
    );
    /* Solid base + species-tint gradient on top. The base is the
       card-surface colour so sticky-scroll doesn't bleed tiles
       through the header. The species-coloured tint sits over
       the base. */
    background:
        linear-gradient(
            to right,
            color-mix(in srgb, var(--cell-species-colour, var(--color-border)) 14%, transparent),
            color-mix(in srgb, var(--cell-species-colour, var(--color-border)) 4%, transparent) 60%,
            transparent
        ),
        var(--color-surface);
    border-top-right-radius: 12px;
    /* When the header is stuck (scrolled past its in-flow position),
       add a subtle shadow so it visually lifts above the tiles below.
       :stuck pseudo-class is still draft; the box-shadow on a non-
       transparent background reads as "above" without the pseudo. */
    box-shadow: 0 2px 4px -2px rgba(0, 0, 0, 0.08);
}

.review-grid__card-identity {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.review-grid__card-species-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.review-grid__card-proposal {
    color: var(--color-text-muted);
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.review-grid__card-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    font-size: 0.85rem;
    color: var(--color-text-muted);
}

.review-grid__card-window {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 0;
}

.review-grid__card-window-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 2px 6px;
    border: 1px solid color-mix(
        in srgb,
        var(--cell-species-colour, var(--color-border)) 36%,
        var(--color-border)
    );
    border-radius: 7px;
    background: color-mix(
        in srgb,
        var(--cell-species-colour, var(--color-surface-2)) 11%,
        var(--color-surface)
    );
    color: var(--color-text);
    font-variant-numeric: tabular-nums;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.34) inset;
}

.review-grid__card-window-chip--end {
    border-color: color-mix(
        in srgb,
        var(--cell-species-colour, var(--color-primary, #53676b)) 54%,
        var(--color-border)
    );
    background: color-mix(
        in srgb,
        var(--cell-species-colour, var(--color-primary, #53676b)) 17%,
        var(--color-surface)
    );
}

.review-grid__card-window-label {
    font-size: 0.68rem;
    font-weight: 800;
    line-height: 1;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

.review-grid__card-window-value {
    font-size: 0.82rem;
    font-weight: 800;
    line-height: 1.15;
    color: var(--color-text);
}

.review-grid__card-window-divider {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--color-text-muted);
}

.review-grid__card-date,
.review-grid__card-time,
.review-grid__card-count,
.review-grid__card-window-value {
    font-variant-numeric: tabular-nums;
}

.review-grid__card-species {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--color-text);
    line-height: 1.2;
}

.review-grid__card-species[data-species-colour] {
    /* Species accent: a coloured underline anchored to the species
       name, slightly thicker than the legacy 2px so it carries the
       new larger font size. Token-driven per §6d so dark scope
       inherits via --species-colour-N redefinition. */
    border-bottom: 3px solid var(--cell-species-colour, var(--color-text-muted));
    padding-bottom: 2px;
}

.review-grid__card-sep {
    color: var(--color-text-muted);
    opacity: 0.6;
}

.review-grid__card-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 0.8rem;
    font-weight: 600;
}

.review-grid__card-badge--warn {
    background: rgba(255, 178, 0, 0.18);
    color: #a45e00;
}

.review-grid__card-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

@media (max-width: 760px) {
.review-grid__card-actions {
        flex-basis: 100%;
    }
}

@media (min-width: 761px) {
    .review-grid__card-header {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
    }

    .review-grid__card-identity {
        flex-direction: row;
        align-items: center;
        flex-wrap: wrap;
        gap: 4px 10px;
    }

    .review-grid__card-species-row {
        flex-basis: 100%;
    }

    .review-grid__card-actions {
        grid-column: 1 / -1;
    }
}

@media (min-width: 761px) and (hover: hover) and (pointer: fine) {
    .review-grid__card-actions .btn {
        min-height: 30px;
        padding: 4px 9px;
    }

    .review-desk-bar .wm-view-mode-toggle__option {
        min-width: 48px;
        min-height: 28px;
        padding-inline: 8px;
    }
}

@media (max-width: 760px), (hover: none), (pointer: coarse) {
.review-day-nav .btn,
.review-day-nav .form-control,
.review-desk-bar .btn,
.review-desk-bar .wm-view-mode-toggle__option,
.review-grid__card-actions .btn {
        min-height: 44px;
    }

    .review-grid__size-btn {
        min-width: 44px;
    }
}

@media (max-width: 760px) {
    .review-grid__card-actions {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        width: 100%;
    }

    .review-grid__card-actions .btn {
        padding: 4px 6px;
        font-size: 0.75rem;
        white-space: normal;
    }

    .review-grid__card-species {
        font-size: 1rem;
    }
}

/* Keyboard navigation (review_grid_keyboard.js).
   The active event card gets an unmistakable blue focus ring that sits
   inside the existing hard-black event outline so the two never fight.
   The armed action button (cycled with Left/Right, fired with Space)
   gets a pulse ring so the operator always sees what Space will do. */
.review-grid__card--kbd-active {
    box-shadow:
        0 0 0 3px var(--color-accent, #0072B2),
        0 10px 26px rgba(26, 38, 45, 0.10),
        0 1px 2px rgba(0, 0, 0, 0.06);
}

.review-grid__card-action--armed {
    outline: 3px solid var(--color-accent, #0072B2);
    outline-offset: 2px;
    border-radius: 6px;
}

@media (prefers-reduced-motion: no-preference) {
    .review-grid__card-action--armed {
        animation: review-grid-armed-pulse 1.4s ease-in-out infinite;
    }
}

@keyframes review-grid-armed-pulse {
    0%, 100% { outline-color: var(--color-accent, #0072B2); }
    50% { outline-color: color-mix(in srgb, var(--color-accent, #0072B2) 35%, transparent); }
}

/* Global tile-size slider (Apple Photos pattern).
   Single control in the page header; all cards reflow as the slider
   moves. The CSS variable lives on .review-grid root and drives the
   minmax() in every card's tile grid. */
.review-grid {
    /* Default tile size; the slider rewrites this inline. */
    --review-tile-size: 320px;
}

.review-grid__size-control {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-right: 8px;
}

.review-grid__size-slider {
    width: 120px;
    accent-color: var(--color-primary, #53676b);
    cursor: pointer;
}

.review-grid__size-btn {
    min-width: 32px;
    padding: 2px 8px;
    font-weight: 700;
    line-height: 1;
}

@media (max-width: 1200px) {
    .review-grid__size-control {
        flex: 1 1 18rem;
        min-width: 0;
        max-width: 100%;
        margin-right: 0;
    }

    .review-grid__size-slider {
        flex: 1 1 8rem;
        width: auto;
        min-width: 5rem;
    }
}

/* Fixed tile sizes keep events comparable; cap them at the available width. */
.review-grid__card-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--review-tile-size, 320px)), min(var(--review-tile-size, 320px), 100%)));
    justify-content: start;
    gap: 8px;
}

/* Apple-Photos-style tile: just the image, a tiny timestamp, and
   the hover toolbox. No bbox overlay, no species-ref circle, no
   species name — those live in the lightbox modal.

   .review-grid__tile is the click+host element; the inner media
   block holds the <img>. Hover effect: a soft brightness lift, no
   scale (scale fights the grid layout). */
.review-grid__tile {
    position: relative;
    overflow: hidden;
    border-radius: 8px;
    background: var(--color-surface-2);
    isolation: isolate;
    /* Species-coloured frame around every tile so the operator can read the species identity right at the
       image, not only in the card header. The colour is inherited
       from .review-grid__card[style="--cell-species-colour: ..."].
       Cards without a species token (unknown / multi-bird ambig)
       fall back to the regular surface border. */
    border: 2px solid var(--cell-species-colour, transparent);
    box-sizing: border-box;
}

.review-grid__tile--context {
    opacity: 0.65;
    border-style: dashed;
    border-color: var(--color-border);
}

.review-grid__tile-select {
    position: absolute;
    top: 6px;
    left: 6px;
    z-index: 4;
    background: rgba(255, 255, 255, 0.85);
    border-radius: 4px;
    padding: 2px;
    line-height: 0;
    /* Stay visible always on touch devices — hover gates are unreliable. */
    opacity: 1;
}

.review-grid__tile-checkbox {
    margin: 0;
    cursor: pointer;
}

.review-grid__tile-media {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
}

.review-grid__tile-button {
    /* Click-target wrapping the image. No visible chrome — the
       image itself is the affordance, with cursor: zoom-in. */
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: zoom-in;
}

.review-grid__tile-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 180ms ease, filter 180ms ease;
}

.review-grid__tile:hover .review-grid__tile-image {
    /* Apple Photos hover: a subtle brightness lift signals
       interactivity without making the image jump. */
    filter: brightness(1.05);
}

.review-grid__tile-time {
    position: absolute;
    bottom: 6px;
    left: 6px;
    z-index: 3;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    padding: 2px 6px;
    font-size: 0.75rem;
    border-radius: 4px;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}

.review-grid__tile-badge {
    position: absolute;
    top: 6px;
    right: 6px;
    z-index: 3;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    padding: 2px 8px;
    font-size: 0.72rem;
    border-radius: 10px;
    font-weight: 600;
    pointer-events: none;
}

.review-grid__tile-badge--anchor {
    background: rgba(60, 130, 90, 0.85);
}

/* Review Grid — always-visible tile toolbox
   ============================================================
   The default `.wm-toolbox` hides until hover/focus. Hover-only
   reveals are fragile on the Review Grid: touch devices have no
   hover, fast scrolling never triggers it, and the per-tile
   verdict (Trash, Mark No Bird, Change Species) is the highest-
   frequency Review action. Make the toolbox always visible on
   `.review-grid__tile` and slightly more compact so it never
   obscures more than ~20% of the image at any tile size.
*/
.review-grid__tile .wm-toolbox {
    opacity: 1;
    transform: none;
    pointer-events: auto;
    bottom: 6px;
    right: 6px;
    padding: 4px;
    gap: 4px;
    /* Slightly muted background so the always-on chrome doesn't
       shout louder than the bird image. */
    background: linear-gradient(180deg, rgba(61, 55, 45, 0.72), rgba(34, 30, 24, 0.78));
}

.review-grid__tile .wm-toolbox__btn {
    width: 28px;
    height: 28px;
    min-width: 28px;
    font-size: 0.95rem;
}

/* Phone layouts need finger-sized actions. The Review Grid keeps five
   controls in one row, so its visible buttons use 36px plus an equivalent
   44px hit area; ordinary toolboxes can use the full 44px control. */
@media (max-width: 720px), (hover: none) {
    .wm-toolbox__btn,
    .wm-toolbox--bar .wm-toolbox__btn {
        min-width: 44px;
        height: 44px;
    }

    .review-grid__tile .wm-toolbox {
        gap: 8px;
    }

    .review-grid__tile .wm-toolbox__btn {
        position: relative;
        width: 36px;
        min-width: 36px;
        height: 36px;
    }

    .review-grid__tile .wm-toolbox__btn::before {
        position: absolute;
        inset: -4px;
        content: "";
    }
}

/* When tiles are below ~180px the always-on toolbox would cover most
   of the bird image. Fall back to hover-reveal under that threshold.
   Anything ≥180px keeps the toolbox visible.
   The threshold is enforced via container queries so it tracks the
   per-tile rendered size, not the slider value directly. */
@supports (container-type: inline-size) {
    .review-grid__card-tiles {
        container-type: inline-size;
    }
}

.review-grid {
    /* Default: always-visible toolbox at slider sizes ≥ 180px. */
}

.review-grid[style*="--review-tile-size: 120px"] .review-grid__tile .wm-toolbox,
.review-grid[style*="--review-tile-size: 140px"] .review-grid__tile .wm-toolbox,
.review-grid[style*="--review-tile-size: 160px"] .review-grid__tile .wm-toolbox {
    opacity: 0;
    pointer-events: none;
}

.review-grid[style*="--review-tile-size: 120px"] .review-grid__tile:hover .wm-toolbox,
.review-grid[style*="--review-tile-size: 140px"] .review-grid__tile:hover .wm-toolbox,
.review-grid[style*="--review-tile-size: 160px"] .review-grid__tile:hover .wm-toolbox,
.review-grid[style*="--review-tile-size: 120px"] .review-grid__tile:focus-within .wm-toolbox,
.review-grid[style*="--review-tile-size: 140px"] .review-grid__tile:focus-within .wm-toolbox,
.review-grid[style*="--review-tile-size: 160px"] .review-grid__tile:focus-within .wm-toolbox {
    opacity: 1;
    pointer-events: auto;
}

/* Review Grid — selection visual feedback
   ============================================================
   Checked tiles get a token-driven accent ring + tinted overlay
   so the operator can see at a glance which frames are in the
   current bulk-selection. The footer carries the global count;
   each card surfaces its own count when any tile is checked.
*/
.review-grid__tile.is-selected {
    outline: 3px solid var(--color-primary, #53676b);
    outline-offset: -3px;
}

.review-grid__tile.is-selected::after {
    /* Tinted overlay: enough to mark "this is selected" without
       making the bird image hard to read. */
    content: "";
    position: absolute;
    inset: 0;
    background: var(--color-primary, #53676b);
    opacity: 0.12;
    pointer-events: none;
    z-index: 2;
}

.review-grid__card-selected {
    /* Tucked into the meta block; only visible while a selection
       exists on this specific card. */
    display: inline-block;
    margin-left: 4px;
    padding: 2px 8px;
    font-size: 0.78rem;
    font-weight: 600;
    background: var(--color-primary, #53676b);
    color: #fff;
    border-radius: 10px;
    font-variant-numeric: tabular-nums;
}

.review-grid__card.has-selection {
    /* Subtle whole-card cue so the operator can spot which cards
       contribute to the footer count when the page is long. */
    box-shadow: 0 0 0 2px var(--color-primary, #53676b);
}

/* Review Grid — bbox overlay canvas.
   Sits over the tile image; JS sizes it to match img.client*. */
.review-grid__tile-bbox-canvas {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 2;
    display: none;  /* JS toggles via inline style.display */
}

.review-grid__bbox-toggle {
    margin-right: 6px;
}

.review-grid__bbox-toggle.active {
    background: var(--color-primary, #53676b);
    color: #fff;
    border-color: var(--color-primary, #53676b);
}

/* Species and box confirmations remain independent of selection styling. */
.wm-bird-editor__box .wm-bird-editor__box-label.is-species-confirmed {
    background: #187544;
    color: #fff;
    border-color: rgba(255, 255, 255, 0.75);
}
.wm-bird-editor__box[data-box-verdict="confirmed"] {
    border-color: #249c60;
    background: transparent;
}
.wm-bird-editor__box[data-box-verdict="incorrect"] {
    border-color: #bb453b;
}
.wm-bird-editor__box-verdict {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 28px;
    height: 28px;
    display: grid;
    place-items: center;
    border: 1px solid rgba(0, 0, 0, 0.18);
    border-radius: 50%;
    background: #fffdf7;
    color: #655e50;
    font: 700 19px/1 system-ui, sans-serif;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
    transform: scale(var(--wm-bird-editor-handle-scale, 1));
    transform-origin: bottom right;
    pointer-events: auto;
}
.wm-bird-editor__box-verdict[data-verdict="confirmed"] { color: #187544; }
.wm-bird-editor__box-verdict[data-verdict="incorrect"] { color: #b33129; }
.wm-bird-editor__box-verdict[data-verdict="pending"] { color: #846315; }
.wm-bird-editor__layer.is-editing .wm-bird-editor__box.is-selected .wm-bird-editor__box-verdict {
    bottom: 12px;
    right: 12px;
    pointer-events: none;
}
.wm-bird-editor__menu-status {
    padding: 8px 12px 4px;
    font-size: 12px;
    font-weight: 600;
}
.wm-review-progress { flex-wrap: wrap; }

.wm-bird-editor__menu-hint {
    max-width: 220px;
    padding: 0 12px 6px;
    font-size: 11px;
    line-height: 1.4;
    opacity: 0.8;
}
.wm-bird-editor__menu-hint[hidden] { display: none; }

button.wm-bird-editor__box-verdict { padding: 0; cursor: pointer; }
button.wm-bird-editor__box-verdict:hover { background: #e4f3e9; }
button.wm-bird-editor__box-verdict:focus-visible { outline: 3px solid #187544; outline-offset: 2px; }
button.wm-bird-editor__box-verdict:disabled { cursor: default; opacity: 0.65; }

.stream-embed__unavailable {
    position: absolute; inset: 0; z-index: 5;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 8px; padding: 12px; background: var(--color-surface-2); color: var(--color-text);
    text-align: center; font-size: .95rem;
}

.wm-bird-editor__match {
    display: grid;
    gap: 0.4rem;
    padding: 0.75rem;
    font-size: 0.875rem;
}
.wm-bird-editor__match[hidden] { display: none; }
.wm-bird-editor__match select { width: 100%; min-width: 0; }

/* Station history keeps evidence and available media visible independently. */
.station-filters { display: flex; flex-wrap: wrap; align-items: end; gap: var(--space-3, 12px); }
.station-filters label { display: grid; gap: 4px; font-size: .85rem; }
.station-filters input, .station-filters select { color: var(--color-text); background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 6px; min-height: 36px; max-width: 100%; padding: 4px 8px; }
.station-intro { margin: 16px 0; color: var(--color-text-muted); }
.station-unknown { display: block; padding: 16px; margin: 16px 0; border: 1px solid var(--color-border); border-radius: 8px; color: var(--color-text); }
.station-card-status, .station-card-meta { display: block; font-size: .8rem; margin-top: 4px; color: var(--color-text-muted); }
.station-report { max-width: 1440px; margin-inline: auto; }
.station-report section { padding-block: 24px; border-top: 1px solid var(--color-border); }
.station-report__overview { padding-block: 32px; max-width: 900px; }
.station-report__eyebrow { font-size: .8rem; color: var(--color-text-muted); }
.station-report__overview h1 { font-size: clamp(1.8rem, 5vw, 3rem); letter-spacing: -.03em; }
.station-report__table-scroll { max-width: 100%; overflow-x: auto; margin-block: 16px; }
.station-report__table, .station-report__calendar { border-collapse: collapse; width: 100%; font-size: .9rem; }
.station-report__table th, .station-report__table td { text-align: left; padding: 12px; border-bottom: 1px solid var(--color-border); vertical-align: top; }
.station-report__table small { display: block; color: var(--color-text-muted); }
.station-report__table caption { text-align: left; padding: 8px; color: var(--color-text-muted); }
.station-report__calendar th, .station-report__calendar td { padding: 5px; text-align: center; min-width: 25px; border-bottom: 1px solid var(--color-border); }
.station-report__calendar th:first-child { position: sticky; left: 0; min-width: 140px; text-align: left; background: var(--color-surface); z-index: 1; }
.station-report__calendar thead span { writing-mode: vertical-rl; font-size: .65rem; }
.station-report__unknown { color: var(--color-text-muted); }
@media (max-width: 640px) { .station-filters { width: 100%; } .station-report__overview { padding-block: 20px; } }

.station-media-placeholder { display: grid; place-items: center; min-height: 220px; width: 100%; padding: 24px; color: var(--color-text-muted); background: var(--color-surface-2); font-size: .9rem; }
.station-media-status { margin: 0; padding: 8px 16px; color: var(--color-text-muted); background: var(--color-surface-2); }

.canonical-dataset__exports {
    margin-block: var(--space-xl);
}

.canonical-dataset__export {
    padding-block: var(--space-lg);
    border-bottom: 1px solid var(--color-border);
}

.canonical-dataset__export time {
    overflow-wrap: anywhere;
}

.canonical-dataset__export-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-md);
    align-items: center;
}

.canonical-dataset__export-actions form {
    margin: 0;
}
