/* EAS Station™ Consolidated Styles */

/* ============================================================================
   EAS STATION - PROFESSIONAL DESIGN SYSTEM
   
   A comprehensive, enterprise-grade design system for emergency alert
   management. Every component follows strict design principles for
   consistency, accessibility, and professional presentation.
   
   Version: 3.0 - Professional Edition
   Author: EAS Station™ Development Team
   ============================================================================ */

/* 1. CSS VARIABLES & DESIGN SYSTEM */

/* iOS 26-Inspired Animation Curves - Fluid & Bouncy */
:root {
    /* Spring-based easing for tactile feel */
    --ease-smooth: cubic-bezier(0.4, 0.0, 0.2, 1);
    --ease-enter: cubic-bezier(0.0, 0.0, 0.2, 1);
    --ease-exit: cubic-bezier(0.4, 0.0, 1, 1);
    --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
    --ease-fluid: cubic-bezier(0.23, 1, 0.32, 1);
    --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
    --ease-elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6);
    --ease-ios: cubic-bezier(0.25, 0.46, 0.45, 0.94);

    /* Glass/Blur effect values */
    --glass-blur: 24px;
    --glass-blur-heavy: 40px;
    --glass-saturation: 180%;
    --glass-opacity: 0.75;

    /* Vibrant accent colors for iOS-style pops of color */
    --vibrant-blue: #007AFF;
    --vibrant-purple: #AF52DE;
    --vibrant-pink: #FF2D92;
    --vibrant-red: #FF3B30;
    --vibrant-orange: #FF9500;
    --vibrant-yellow: #FFCC00;
    --vibrant-green: #34C759;
    --vibrant-teal: #5AC8FA;
    --vibrant-indigo: #5856D6;
    --vibrant-mint: #00C7BE;

    /* Mesh gradient colors */
    --mesh-1: #667eea;
    --mesh-2: #764ba2;
    --mesh-3: #f093fb;
    --mesh-4: #f5576c;
}

/* Cosmo Theme (Default Light Theme) - Professional Palette */
:root,
[data-theme="cosmo"] {
    /* Primary Brand Colors - Refined for professionalism */
    --primary-color: #1e3a8a;
    --primary-soft: #3b82f6;
    --primary-dark: #1e40af;
    --secondary-color: #7c3aed;
    --secondary-soft: #a78bfa;
    --secondary-dark: #5b21b6;
    --accent-color: #3b82f6;

    /* Status Colors - Professional Grade */
    --success-color: #10b981;
    --danger-color: #ef4444;
    --warning-color: #f59e0b;
    --info-color: #3b82f6;
    --critical-color: #dc2626;

    /* Background Colors - Professional Neutrals */
    --light-color: #f8fafc;
    --dark-color: #0f172a;
    --bg-color: #f1f5f9;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #1e3a8a;

    /* Text Colors - Professional Typography */
    --text-color: #0f172a;
    --text-secondary: #475569;
    --text-muted: #94a3b8;

    /* Borders & Shadows - Modern Multi-Layered Depth */
    --border-color: #e2e8f0;
    --shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.08), 0 1px 2px 0 rgba(0, 0, 0, 0.04);
    --shadow-md: 0 4px 8px -2px rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.08);
    --shadow-lg: 0 12px 24px -4px rgba(0, 0, 0, 0.14), 0 6px 12px -2px rgba(0, 0, 0, 0.08);
    --shadow-xl: 0 24px 48px -8px rgba(0, 0, 0, 0.16), 0 12px 24px -4px rgba(0, 0, 0, 0.10);
    --shadow-2xl: 0 32px 64px -12px rgba(0, 0, 0, 0.20), 0 16px 32px -6px rgba(0, 0, 0, 0.12);
    --shadow-color: rgba(0, 0, 0, 0.12);
    --shadow: rgba(0, 0, 0, 0.12);

    /* Border Radius - iOS 26 Style (Larger, Softer) */
    --radius-sm: 0.75rem;    /* 12px */
    --radius-md: 1rem;       /* 16px */
    --radius-lg: 1.25rem;    /* 20px */
    --radius-xl: 1.5rem;     /* 24px */
    --radius-2xl: 2rem;      /* 32px */
    --radius-3xl: 2.5rem;    /* 40px */
    --radius-pill: 9999px;   /* Pill shape */
    --radius-blob: 40% 60% 60% 40% / 60% 30% 70% 40%; /* Organic blob */

    /* Spacing Scale - Perfect Scale (4px base) */
    --spacing-1: 0.25rem;   /* 4px */
    --spacing-2: 0.5rem;    /* 8px */
    --spacing-3: 0.75rem;   /* 12px */
    --spacing-4: 1rem;      /* 16px */
    --spacing-5: 1.25rem;   /* 20px */
    --spacing-6: 1.5rem;    /* 24px */
    --spacing-8: 2rem;      /* 32px */
    --spacing-10: 2.5rem;   /* 40px */
    --spacing-12: 3rem;     /* 48px */
    --spacing-16: 4rem;     /* 64px */
    
    /* Legacy spacing for compatibility */
    --spacing-xs: var(--spacing-2);
    --spacing-sm: var(--spacing-3);
    --spacing-md: var(--spacing-4);
    --spacing-lg: var(--spacing-6);
    --spacing-xl: var(--spacing-8);

    /* Professional Transitions */
    --transition-fast: 150ms var(--ease-smooth);
    --transition-medium: 250ms var(--ease-smooth);
    --transition-slow: 350ms var(--ease-smooth);

    /* Professional Typography System */
    --font-family-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    --font-family-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
    
    /* Type Scale - Perfect Fourth (1.333) */
    --font-size-xs: 0.75rem;      /* 12px */
    --font-size-sm: 0.875rem;     /* 14px */
    --font-size-base: 1rem;       /* 16px */
    --font-size-lg: 1.125rem;     /* 18px */
    --font-size-xl: 1.333rem;     /* 21px */
    --font-size-2xl: 1.777rem;    /* 28px */
    --font-size-3xl: 2.369rem;    /* 38px */
    
    /* Line Heights - Optimized for readability */
    --line-height-tight: 1.25;
    --line-height-base: 1.5;
    --line-height-relaxed: 1.75;
    
    /* Font Weights - Professional Hierarchy */
    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;
    --font-weight-extrabold: 800;

    /* Logo Treatment */
    --logo-backdrop: rgba(255, 255, 255, 0.96);
    --logo-border-color: rgba(32, 72, 133, 0.22);
    --logo-shadow: 0 12px 28px rgba(20, 33, 55, 0.35);
    --logo-padding: 0.25rem 0.65rem;
    --logo-radius: 14px;

    /* Layout Spacing */
    --layout-padding-top: 0.5rem;
    --layout-padding-x: 1.5rem;
    --layout-padding-bottom: 1rem;
    --footer-margin-top: 20px;

    /* Alert Severity Colors */
    --severity-extreme: #e74c3c;
    --severity-severe: #e67e22;
    --severity-moderate: #f39c12;
    --severity-minor: #3498db;
    --severity-unknown: #95a5a6;

    /* Hardware Display Colors */
    --display-oled-bg: #000000;
    --display-oled-text: #ffffff;
    --display-vfd-bg: #001a00;
    --display-vfd-text: #00ff00;
    --display-vfd-dim: #004400;
    --display-muted: #888888;

    /* Terminal/Retro Colors */
    --terminal-bg: #000000;
    --terminal-text: #00ff00;
    --terminal-border: #cccccc;

    /* LED Hardware Colors (for physical LED control) */
    --led-red: #ff0000;
    --led-green: #00ff00;
    --led-blue: #0000ff;
    --led-amber: #ffbf00;
    --led-yellow: #ffff00;
    --led-orange: #ff8000;
    --led-brown: #964b00;
    --led-dim-red: #800000;
    --led-dim-green: #008000;

    /* Boundary Type Colors */
    --boundary-county: #e74c3c;
    --boundary-fire: #e67e22;
    --boundary-ems: #f39c12;
    --boundary-electric: #2ecc71;
    --boundary-school: #3498db;
    --boundary-water: #1abc9c;
    --boundary-gas: #9b59b6;
    --boundary-transit: #34495e;
    --boundary-park: #27ae60;
    --boundary-health: #e91e63;
    --boundary-custom-1: #38bdf8;
    --boundary-custom-2: #fb7185;
    --boundary-custom-3: #845ef7;
    --boundary-custom-4: #22c55e;
    --boundary-custom-5: #f97316;
    --boundary-custom-6: #14b8a6;
    --boundary-custom-7: #facc15;
    --boundary-custom-8: #64748b;

    /* Overlay & Effect Colors */
    --overlay-dark: rgba(0, 0, 0, 0.7);
    --overlay-light: rgba(255, 255, 255, 0.9);
    --glass-bg: rgba(255, 255, 255, 0.1);
    --glass-border: rgba(255, 255, 255, 0.2);

    /* Text on Colored Backgrounds */
    --text-on-dark: #ffffff;
    --text-on-light: #1a1a1a;
    --text-on-color: #ffffff;

    /* Chart & Visualization Colors */
    --chart-primary-start: #667eea;
    --chart-primary-end: #764ba2;
    --chart-success-start: #11998e;
    --chart-success-end: #38ef7d;
    --chart-danger-start: #eb3349;
    --chart-danger-end: #f45c43;
    --chart-warning-start: #f093fb;
    --chart-warning-end: #f5576c;
    --chart-info-start: #4facfe;
    --chart-info-end: #00f2fe;
    --chart-purple-start: #a855f7;
    --chart-purple-end: #6366f1;
    --chart-teal-start: #0891b2;
    --chart-teal-end: #06b6d4;
    --chart-orange-start: #f97316;
    --chart-orange-end: #fb923c;
    --chart-pink-start: #ec4899;
    --chart-pink-end: #f472b6;
    --chart-indigo-start: #6366f1;
    --chart-indigo-end: #818cf8;
    --chart-grid: rgba(0, 0, 0, 0.1);
    --chart-text: rgba(0, 0, 0, 0.7);
}

[data-theme="dark"] {
    --primary-color: #6b96ff;
    --primary-soft: #5580d8;
    --primary-dark: #405a99;
    --secondary-color: #c9a8ff;
    --secondary-soft: #d5b5ff;
    --secondary-dark: #786499;
    --accent-color: #a8c6ff;
    --success-color: #67ffd6;
    --danger-color: #ffafbf;
    --warning-color: #ffe3ad;
    --info-color: #adcfff;
    --critical-color: #ffb0d4;
    --light-color: #455169;
    --dark-color: #161d2b;
    --bg-color: #1b2434;
    --surface-color: #243046;
    --bg-card: #243046;
    --bg-primary: #161d2b;
    --text-color: #ffffff;
    /* Lifted from #8892a6, which measured 4.23:1 on this theme's
       --surface-color (#243046) — just under the AA floor. Note this theme's
       secondary ink is *darker* than its muted ink, which is inverted from
       every other theme but is left as-is: it is a deliberate part of the
       Dark palette and both now clear AA. */
    --text-secondary: #8f99ab;
    --text-muted: #acbad8;
    --border-color: #40516c;
    --shadow-color: rgba(8, 11, 19, 0.55);
    --shadow: rgba(8, 11, 19, 0.55);
    --logo-backdrop: rgba(36, 48, 70, 0.95);
    --logo-border-color: rgba(107, 150, 255, 0.35);
    --logo-shadow: 0 14px 32px rgba(5, 9, 16, 0.55);

    /* Alert Severity Colors - Dark Theme */
    --severity-extreme: #ff6b6b;
    --severity-severe: #ffa94d;
    --severity-moderate: #ffd43b;
    --severity-minor: #74c0fc;
    --severity-unknown: #adb5bd;

    /* Hardware Display Colors - Same for dark theme */
    --display-oled-bg: #000000;
    --display-oled-text: #ffffff;
    --display-vfd-bg: #001a00;
    --display-vfd-text: #00ff00;
    --display-vfd-dim: #004400;
    --display-muted: #888888;

    /* Terminal/Retro Colors - Same for dark theme */
    --terminal-bg: #000000;
    --terminal-text: #00ff00;
    --terminal-border: #666666;

    /* LED Hardware Colors - Same for dark theme */
    --led-red: #ff0000;
    --led-green: #00ff00;
    --led-blue: #0000ff;
    --led-amber: #ffbf00;
    --led-yellow: #ffff00;
    --led-orange: #ff8000;
    --led-brown: #964b00;
    --led-dim-red: #800000;
    --led-dim-green: #008000;

    /* Boundary Type Colors - Dark Theme */
    --boundary-county: #ff6b6b;
    --boundary-fire: #ffa94d;
    --boundary-ems: #ffd43b;
    --boundary-electric: #51cf66;
    --boundary-school: #74c0fc;
    --boundary-water: #3bc9db;
    --boundary-transit: #748ffc;
    --boundary-park: #69db7c;
    --boundary-health: #ff6b9d;
    --boundary-gas: #cc5de8;
    --boundary-custom-1: #74c0fc;
    --boundary-custom-2: #ff8787;
    --boundary-custom-3: #b197fc;
    --boundary-custom-4: #69db7c;
    --boundary-custom-5: #ffa94d;
    --boundary-custom-6: #3bc9db;
    --boundary-custom-7: #ffe066;
    --boundary-custom-8: #868e96;

    /* Overlay & Effect Colors - Dark Theme */
    --overlay-dark: rgba(0, 0, 0, 0.8);
    --overlay-light: rgba(255, 255, 255, 0.1);
    --glass-bg: rgba(36, 48, 70, 0.2);
    --glass-border: rgba(107, 150, 255, 0.3);

    /* Text on Colored Backgrounds - Dark Theme */
    --text-on-dark: #ffffff;
    --text-on-light: #1a1a1a;
    --text-on-color: #ffffff;

    /* Chart & Visualization Colors - Dark Theme */
    --chart-primary-start: #8093ff;
    --chart-primary-end: #9b6bc2;
    --chart-success-start: #3bb9a3;
    --chart-success-end: #63ffa8;
    --chart-danger-start: #ff5c6e;
    --chart-danger-end: #ff8b6d;
    --chart-warning-start: #ffb8ff;
    --chart-warning-end: #ff8b9d;
    --chart-info-start: #6fd7fe;
    --chart-info-end: #5fbbff;
    --chart-purple-start: #c084ff;
    --chart-purple-end: #8b9aff;
    --chart-teal-start: #3db9cf;
    --chart-teal-end: #5cd4ea;
    --chart-orange-start: #ff9b4d;
    --chart-orange-end: #ffb47a;
    --chart-pink-start: #ff6fb8;
    --chart-pink-end: #ff9acf;
    --chart-indigo-start: #8b9aff;
    --chart-indigo-end: #a5b4ff;
    --chart-grid: rgba(255, 255, 255, 0.1);
    --chart-text: rgba(255, 255, 255, 0.7);
}

/* Coffee Theme */
[data-theme="coffee"] {
    --primary-color: #e2b37f;
    --primary-soft: #d5a674;
    --primary-dark: #876b4c;
    --secondary-color: #c7a06e;
    --secondary-soft: #d1aa78;
    --secondary-dark: #776042;
    --accent-color: #edc999;
    --success-color: #9cda7a;
    --danger-color: #ff9da0;
    --warning-color: #ffd886;
    --info-color: #8bd1ff;
    --critical-color: #ff7f7f;
    --light-color: #5b4333;
    --dark-color: #281c12;
    --bg-color: #32261c;
    --surface-color: #403024;
    --bg-card: #403024;
    --bg-primary: #281c12;
    --text-color: #fff9f2;
    --text-secondary: #f4e6d0;
    --text-muted: #d9c2a5;
    --border-color: #6a5240;
    --shadow-color: rgba(10, 7, 4, 0.6);
    --shadow: rgba(10, 7, 4, 0.6);
}

/* Spring Theme */
[data-theme="spring"] {
    --primary-color: #43a047;
    --primary-soft: #66bb6a;
    --primary-dark: #28602a;
    --secondary-color: #8bc34a;
    --secondary-soft: #9ccc65;
    --secondary-dark: #53752c;
    --accent-color: #7cb342;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #f1f8e9;
    --dark-color: #33691e;
    --bg-color: #f9fbe7;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #33691e;
    --text-color: #1b5e20;
    --text-secondary: #2e7d32;
    --text-muted: #558b2f;
    --border-color: #c5e1a5;
    --shadow-color: rgba(67, 160, 71, 0.12);
}

/* Red Theme */
[data-theme="red"] {
    --primary-color: #d32f2f;
    --primary-soft: #ef5350;
    --primary-dark: #c62828;
    --secondary-color: #f44336;
    --secondary-soft: #e57373;
    --secondary-dark: #d32f2f;
    --accent-color: #ff1744;
    --success-color: #4caf50;
    --danger-color: #d32f2f;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #b71c1c;
    --light-color: #ffebee;
    --dark-color: #b71c1c;
    --bg-color: #fafafa;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #d32f2f;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(211, 47, 47, 0.12);
}

/* Green Theme */
[data-theme="green"] {
    --primary-color: #388e3c;
    --primary-soft: #66bb6a;
    --primary-dark: #2e7d32;
    --secondary-color: #4caf50;
    --secondary-soft: #81c784;
    --secondary-dark: #388e3c;
    --accent-color: #00c853;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #e8f5e9;
    --dark-color: #1b5e20;
    --bg-color: #fafafa;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #388e3c;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(56, 142, 60, 0.12);
}

/* Blue Theme */
[data-theme="blue"] {
    --primary-color: #1976d2;
    --primary-soft: #42a5f5;
    --primary-dark: #1565c0;
    --secondary-color: #2196f3;
    --secondary-soft: #64b5f6;
    --secondary-dark: #1976d2;
    --accent-color: #2979ff;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #e3f2fd;
    --dark-color: #0d47a1;
    --bg-color: #fafafa;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #1976d2;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(25, 118, 210, 0.12);
}

/* Purple Theme */
[data-theme="purple"] {
    --primary-color: #7b1fa2;
    --primary-soft: #ab47bc;
    --primary-dark: #6a1b9a;
    --secondary-color: #9c27b0;
    --secondary-soft: #ba68c8;
    --secondary-dark: #7b1fa2;
    --accent-color: #d500f9;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #f3e5f5;
    --dark-color: #4a148c;
    --bg-color: #fafafa;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #7b1fa2;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(123, 31, 162, 0.12);
}

/* Pink Theme */
[data-theme="pink"] {
    --primary-color: #c2185b;
    --primary-soft: #ec407a;
    --primary-dark: #ad1457;
    --secondary-color: #e91e63;
    --secondary-soft: #f06292;
    --secondary-dark: #c2185b;
    --accent-color: #f50057;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #fce4ec;
    --dark-color: #880e4f;
    --bg-color: #fafafa;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #c2185b;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(194, 24, 91, 0.12);
}

/* Orange Theme */
[data-theme="orange"] {
    --primary-color: #f57c00;
    --primary-soft: #ff9800;
    --primary-dark: #e65100;
    --secondary-color: #ff9800;
    --secondary-soft: #ffb74d;
    --secondary-dark: #f57c00;
    --accent-color: #ff6d00;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #fff3e0;
    --dark-color: #e65100;
    --bg-color: #fafafa;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #f57c00;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(245, 124, 0, 0.12);
}

/* Yellow Theme */
[data-theme="yellow"] {
    --primary-color: #f9a825;
    --primary-soft: #fdd835;
    --primary-dark: #f57f17;
    --secondary-color: #ffeb3b;
    --secondary-soft: #fff59d;
    --secondary-dark: #f9a825;
    --accent-color: #ffc400;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #fffde7;
    --dark-color: #f57f17;
    --bg-color: #fafafa;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #f9a825;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(249, 168, 37, 0.12);
}

/* Aurora Theme - Polar lights with teal and violet glows */
[data-theme="aurora"] {
    --primary-color: #00bcd4;
    --primary-soft: #26c6da;
    --primary-dark: #0097a7;
    --secondary-color: #7c4dff;
    --secondary-soft: #b388ff;
    --secondary-dark: #651fff;
    --accent-color: #18ffff;
    --success-color: #00e676;
    --danger-color: #ff5252;
    --warning-color: #ffab40;
    --info-color: #40c4ff;
    --critical-color: #ff1744;
    --light-color: #e0f7fa;
    --dark-color: #006064;
    --bg-color: #1a2332;
    --surface-color: #263238;
    --bg-card: #2c3e50;
    --bg-primary: #00838f;
    --text-color: #e0f7fa;
    --text-secondary: #b2ebf2;
    --text-muted: #80deea;
    --border-color: #37474f;
    --shadow-color: rgba(0, 188, 212, 0.2);
}

/* Nebula Theme - Deep space magenta and cyan */
[data-theme="nebula"] {
    --primary-color: #ab47bc;
    --primary-soft: #ce93d8;
    --primary-dark: #8e24aa;
    --secondary-color: #00acc1;
    --secondary-soft: #4dd0e1;
    --secondary-dark: #00838f;
    --accent-color: #ea80fc;
    --success-color: #00e676;
    --danger-color: #ff5252;
    --warning-color: #ffab40;
    --info-color: #40c4ff;
    --critical-color: #ff1744;
    --light-color: #f3e5f5;
    --dark-color: #4a148c;
    --bg-color: #1a1a2e;
    --surface-color: #16213e;
    --bg-card: #0f3460;
    --bg-primary: #7b1fa2;
    --text-color: #e1bee7;
    --text-secondary: #ce93d8;
    --text-muted: #ba68c8;
    --border-color: #4a148c;
    --shadow-color: rgba(171, 71, 188, 0.2);
}

/* Sunset Theme - Golden hour gradient with warm oranges */
[data-theme="sunset"] {
    --primary-color: #ff6f00;
    --primary-soft: #ff9800;
    --primary-dark: #e65100;
    --secondary-color: #ff5722;
    --secondary-soft: #ff8a65;
    --secondary-dark: #e64a19;
    --accent-color: #ffab00;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #fff3e0;
    --dark-color: #bf360c;
    --bg-color: #fff8f0;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #ff6f00;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(255, 111, 0, 0.12);
}

/* Midnight Theme - Deep slate with neon telemetry accents */
[data-theme="midnight"] {
    --primary-color: #304ffe;
    --primary-soft: #536dfe;
    --primary-dark: #1a237e;
    --secondary-color: #00e5ff;
    --secondary-soft: #18ffff;
    --secondary-dark: #00b8d4;
    --accent-color: #651fff;
    --success-color: #00e676;
    --danger-color: #ff5252;
    --warning-color: #ffab40;
    --info-color: #40c4ff;
    --critical-color: #ff1744;
    --light-color: #e8eaf6;
    --dark-color: #1a237e;
    --bg-color: #0a0e27;
    --surface-color: #1a1d35;
    --bg-card: #242942;
    --bg-primary: #1a237e;
    --text-color: #c5cae9;
    --text-secondary: #9fa8da;
    --text-muted: #7986cb;
    --border-color: #3f51b5;
    --shadow-color: rgba(48, 79, 254, 0.2);
}

/* Tide Theme - Crisp coastal palette with aqua highlights */
[data-theme="tide"] {
    --primary-color: #0097a7;
    --primary-soft: #26c6da;
    --primary-dark: #00838f;
    --secondary-color: #00acc1;
    --secondary-soft: #4dd0e1;
    --secondary-dark: #0097a7;
    --accent-color: #00e5ff;
    --success-color: #4caf50;
    --danger-color: #ef5350;
    --warning-color: #ffa726;
    --info-color: #29b6f6;
    --critical-color: #e53935;
    --light-color: #e0f7fa;
    --dark-color: #006064;
    --bg-color: #f0f9ff;
    --surface-color: #ffffff;
    --bg-card: #ffffff;
    --bg-primary: #0097a7;
    --text-color: #212121;
    --text-secondary: #424242;
    --text-muted: #757575;
    --border-color: #e0e0e0;
    --shadow-color: rgba(0, 151, 167, 0.12);
}

/* Charcoal Theme - Deep gray dark theme */
[data-theme="charcoal"] {
    --primary-color: #78909c;
    --primary-soft: #90a4ae;
    --primary-dark: #546e7a;
    --secondary-color: #607d8b;
    --secondary-soft: #78909c;
    --secondary-dark: #455a64;
    --accent-color: #80cbc4;
    --success-color: #00e676;
    --danger-color: #ff5252;
    --warning-color: #ffab40;
    --info-color: #40c4ff;
    --critical-color: #ff1744;
    --light-color: #eceff1;
    --dark-color: #263238;
    --bg-color: #2c3e50;
    --surface-color: #34495e;
    --bg-card: #3e5363;
    --bg-primary: #455a64;
    --text-color: #eceff1;
    --text-secondary: #cfd8dc;
    --text-muted: #b0bec5;
    --border-color: #455a64;
    --shadow-color: rgba(38, 50, 56, 0.3);
}

/* Obsidian Theme - Pure black AMOLED theme */
[data-theme="obsidian"] {
    --primary-color: #7c4dff;
    --primary-soft: #b388ff;
    --primary-dark: #651fff;
    --secondary-color: #18ffff;
    --secondary-soft: #84ffff;
    --secondary-dark: #00e5ff;
    --accent-color: #ff4081;
    --success-color: #00e676;
    --danger-color: #ff5252;
    --warning-color: #ffab40;
    --info-color: #40c4ff;
    --critical-color: #ff1744;
    --light-color: #ede7f6;
    --dark-color: #4a148c;
    --bg-color: #000000;
    --surface-color: #0d0d0d;
    --bg-card: #1a1a1a;
    --bg-primary: #1a1a1a;
    --text-color: #e1bee7;
    --text-secondary: #ce93d8;
    --text-muted: #ba68c8;
    --border-color: #212121;
    --shadow-color: rgba(124, 77, 255, 0.3);
}

/* Slate Theme - Blue-gray professional dark theme */
[data-theme="slate"] {
    --primary-color: #5c6bc0;
    --primary-soft: #7986cb;
    --primary-dark: #3f51b5;
    --secondary-color: #42a5f5;
    --secondary-soft: #64b5f6;
    --secondary-dark: #2196f3;
    --accent-color: #536dfe;
    --success-color: #00e676;
    --danger-color: #ff5252;
    --warning-color: #ffab40;
    --info-color: #40c4ff;
    --critical-color: #ff1744;
    --light-color: #e8eaf6;
    --dark-color: #1a237e;
    --bg-color: #263238;
    --surface-color: #37474f;
    --bg-card: #455a64;
    --bg-primary: #3f51b5;
    --text-color: #e8eaf6;
    --text-secondary: #c5cae9;
    --text-muted: #9fa8da;
    --border-color: #546e7a;
    --shadow-color: rgba(92, 107, 192, 0.2);
}

/* Lightning Theme - Stormcloud sky with electric-yellow bolts and arc-blue plasma */
[data-theme="lightning"] {
    --primary-color: #ffeb3b;
    --primary-soft: #fff176;
    --primary-dark: #fbc02d;
    --secondary-color: #40c4ff;
    --secondary-soft: #80d8ff;
    --secondary-dark: #00b0ff;
    --accent-color: #ffffff;
    --success-color: #00e676;
    --danger-color: #ff5252;
    --warning-color: #ffab40;
    --info-color: #40c4ff;
    --critical-color: #ff1744;
    --light-color: #fff9c4;
    --dark-color: #0d1b2a;
    --bg-color: #060d1f;
    --surface-color: #14224d;
    --bg-card: #1c2e5e;
    --bg-primary: #1b2a4e;
    --text-color: #ffffff;
    --text-secondary: #eef4ff;
    --text-muted: #d8e0f0;
    --border-color: #5973a8;
    --shadow-color: rgba(0, 0, 0, 0.45);
}

/* ----------------------------------------------------------------------------
   SEMANTIC TEXT INK — readable variants of the status colours
   ----------------------------------------------------------------------------
   The `--success-color` / `--danger-color` / `--warning-color` / `--info-color`
   / `--primary-color` variables are tuned to be *fills*: they sit behind white
   text in `.bg-success`, `.badge`, buttons and chips, so they are deliberately
   vivid. Using that same vivid value as *text on a card* is what broke
   readability across the theme set — e.g. `.text-warning` (#ffa726) on a white
   surface measures 1.94:1, far below the WCAG AA 4.5:1 floor, and `.text-info`
   measures 2.30:1. Those utilities appear ~1700 times across `templates/`.

   So each theme also carries an "ink" variant: same hue, lightness shifted
   until it clears 4.5:1 against that theme's own `--surface-color`. Fills keep
   using `--*-color`; text (`.text-*`, `a`) uses `--*-ink`. Light themes share
   one ink set because they all render on a white surface; the dark themes
   already read well at their vivid values, so their ink maps straight back to
   the fill colour except where measured otherwise.

   Verify with: python3 scripts/diagnostics/check_theme_contrast.py */

/* Light themes (white surface) — Bootstrap's text-emphasis palette, which the
   `.bg-light` overrides further down already standardised on. */
:root {
    --success-ink: #198754;   /* 4.53:1 on #fff */
    --danger-ink: #b02a37;    /* 6.50:1 */
    --warning-ink: #a86400;   /* 4.68:1 — #997404 only reaches 4.33:1 */
    --info-ink: #087990;      /* 5.06:1 */
    --primary-ink: var(--primary-color);
}

/* Dark themes: the vivid status colours already clear AA on a dark surface,
   so ink tracks the fill colour. Without this reset they would inherit the
   light-theme inks above and render dark-on-dark. */
:is([data-theme="dark"],
    [data-theme="coffee"],
    [data-theme="aurora"],
    [data-theme="nebula"],
    [data-theme="midnight"],
    [data-theme="charcoal"],
    [data-theme="obsidian"],
    [data-theme="slate"],
    [data-theme="lightning"]) {
    --success-ink: var(--success-color);
    --danger-ink: var(--danger-color);
    --warning-ink: var(--warning-color);
    --info-ink: var(--info-color);
    --primary-ink: var(--primary-color);
}

/* Per-theme corrections, all measured against that theme's --surface-color.
   Comments record the failing ratio the override replaces. */

/* Light themes whose brand colour is too light to serve as link text. */
[data-theme="green"]  { --primary-ink: #348438; }  /* #388e3c 4.12 -> 4.66 */
[data-theme="orange"] { --primary-ink: #b55c00; }  /* #f57c00 2.70 -> 4.67 */
[data-theme="spring"] { --primary-ink: #37833a; }  /* #43a047 3.30 -> 4.70 */
[data-theme="sunset"] { --primary-ink: #bf5300; }  /* #ff6f00 2.79 -> 4.72 */
[data-theme="tide"]   { --primary-ink: #00818f; }  /* #0097a7 3.51 -> 4.63 */
[data-theme="yellow"] { --primary-ink: #a46705; }  /* #f9a825 1.97 -> 4.65 */

/* Dark themes whose brand/danger colour is too dark for its own surface. */
[data-theme="aurora"]   { --danger-ink: #ff6666; }   /* #ff5252 4.12 -> 4.60 */
[data-theme="charcoal"] { --danger-ink: #ff9c9c;     /* #ff5252 2.91 -> 4.64 */
                          --primary-ink: #abbac2; }  /* #78909c 2.77 -> 4.66 */
[data-theme="midnight"] { --primary-ink: #677efe; }  /* #304ffe 2.89 -> 4.71 */
[data-theme="nebula"]   { --primary-ink: #bc6bc9; }  /* #ab47bc 3.30 -> 4.61 */
[data-theme="obsidian"] { --primary-ink: #875cff; }  /* #7c4dff 4.04 -> 4.63 */
[data-theme="slate"]    { --danger-ink: #ff9696;     /* #ff5252 3.02 -> 4.62 */
                          --primary-ink: #aab2de; }  /* #5c6bc0 1.98 -> 4.65 */

/* Muted ink that fell below AA on its own surface. Cosmo is the default
   theme, so its 2.56:1 muted text affected every out-of-the-box install.
   Deliberately NOT written as `:root, [data-theme="cosmo"]`: `:root` carries
   the same specificity as `[data-theme="dark"]` but sits later in the file,
   so it would win over every dark theme's own muted ink and repaint it. The
   bare-`:root` arm is guarded to the no-attribute case only. */
:root:not([data-theme]),
[data-theme="cosmo"] { --text-muted: #627693; }  /* #94a3b8 2.56 -> 4.63 */
[data-theme="spring"] { --text-muted: #4f822c; } /* #558b2f 4.10 -> 4.60 */
[data-theme="nebula"] { --text-muted: #bc6bc9; } /* #ba68c8 4.47 -> 4.61 */
[data-theme="slate"]  { --text-muted: #aab2de; } /* #9fa8da 4.18 -> 4.65 */

/* Lightning Theme - Electric glow on bolt icons.
   Filter is held steady so only `opacity` animates — interpolating a
   multi-stop drop-shadow stack at 60 fps is what made every page with
   .fa-bolt icons feel heavy on weaker GPUs. */
[data-theme="lightning"] .fa-bolt {
    color: var(--primary-color);
    filter: drop-shadow(0 0 3px rgba(255, 235, 59, 0.7))
            drop-shadow(0 0 8px rgba(64, 196, 255, 0.35));
    animation: lightningFlicker 4.5s ease-in-out infinite;
    will-change: opacity;
}

@keyframes lightningFlicker {
    0%, 40%, 44%, 100% { opacity: 1; }
    42% { opacity: 0.55; }
    43% { opacity: 1; }
}

/* Lightning Theme - Readability overrides
   The primary (#ffeb3b) and info/secondary (#40c4ff) colors are very light,
   so white text on those backgrounds fails contrast. Force dark text there. */
[data-theme="lightning"] .bg-primary,
[data-theme="lightning"] .text-bg-primary,
[data-theme="lightning"] .badge.bg-primary,
[data-theme="lightning"] .card-header.bg-primary,
[data-theme="lightning"] .bg-info,
[data-theme="lightning"] .text-bg-info,
[data-theme="lightning"] .badge.bg-info,
[data-theme="lightning"] .card-header.bg-info,
[data-theme="lightning"] .bg-secondary,
[data-theme="lightning"] .text-bg-secondary,
[data-theme="lightning"] .badge.bg-secondary,
[data-theme="lightning"] .card-header.bg-secondary,
/* Card-header children: the global `.card-header.bg-* *` rule forces every
   descendant (title <h4>, icons, badges) to white, which is invisible on the
   bright yellow→cyan gradient these headers use in this theme.  The base rules
   above only re-ink the header element itself, so the children stay white.
   Re-ink the descendants too (success/danger/warning already do this further
   down). */
[data-theme="lightning"] .card-header.bg-primary *,
[data-theme="lightning"] .card-header.bg-info *,
[data-theme="lightning"] .card-header.bg-secondary * {
    color: #0d1b2a !important;
    text-shadow: none;
}

/* NOTE: a `[data-theme="lightning"] .table thead th { color: #0d1b2a }` rule
   used to live here. It was correct while `.table thead th` painted a bright
   yellow→cyan gradient, but that gradient was removed (it rendered dark text
   on a dark gradient in every other theme). The header now uses the themed
   `--surface-color`/`--text-color` tint, which is already readable in
   lightning — forcing dark ink here made it 1.8:1. Do not reinstate. */

[data-theme="lightning"] .btn-primary {
    color: #0d1b2a;
}

/* ----------------------------------------------------------------------------
   Bootstrap .bg-light surfaces - global readability
   ----------------------------------------------------------------------------
   Two structural problems make `.bg-light` containers unreadable on every
   dark theme (lightning, aurora, nebula, midnight, charcoal, obsidian, slate,
   coffee, dark):

   1. `.card { background: linear-gradient(...) }` is a `background` shorthand
      that paints an OPAQUE surface-color gradient into background-image.
      Bootstrap's `.bg-light { background-color: ... !important }` cannot
      override that, because !important on background-color does not clear an
      image. Result: `<div class="card bg-light">` (or
      `card-body bg-light` / `card-header bg-light` etc.) keeps the dark
      gradient on every theme — visually identical to a non-bg-light card.

   2. With the gradient suppressed, the bg-light surface is near-white, but
      descendant text inherits `--text-color` which resolves to white / cream
      / lavender on dark themes. White-on-white is unreadable.

   Fix: clear the gradient, force the bg-light container to actually paint a
   light surface, and pin dark ink on it (with !important so component-level
   overrides like `.metric-value { color: var(--text-color) }` lose). */
.card.bg-light,
.card.card-body.bg-light,
.card-body.bg-light,
.card-footer.bg-light {
    background-image: none !important;
    background-color: var(--bs-light, #f8f9fa) !important;
}

/* When a `<div class="card bg-light">` wraps an inner `<div class="card-body">`
   (no `bg-light` of its own), the inner card-body's own
   `background-color: var(--surface-color)` paints a dark navy surface on top
   of the now-light card — and the descendant text-color rule below pins dark
   ink on it, producing dark-on-dark again (visible in the audio_monitoring
   "Now Playing" card and any similar `card bg-light > card-body` pattern).
   Make the inner card-body transparent so the parent's light surface shows
   through. Same for card-header / card-footer descendants of a bg-light card. */
.card.bg-light > .card-body,
.card.bg-light > .card-header,
.card.bg-light > .card-footer,
.card.bg-light .card-body,
.card.bg-light .card-header,
.card.bg-light .card-footer {
    background-color: transparent !important;
    background-image: none !important;
}

.bg-light,
.card.bg-light,
.card-header.bg-light,
.card-body.bg-light,
.card-footer.bg-light {
    color: #0d1b2a !important;
    text-shadow: none;
}

/* Force dark ink on plain text descendants of a .bg-light surface, but
   exclude self-coloring components (`.btn`, `.badge`, `.alert`, anything
   with a `.bg-*` background utility) so their own theme-aware text colors
   survive. Without these `:not()` exclusions the !important above would
   bleach dark ink onto bg-primary buttons, colored badges, etc. */
:is(.bg-light, .card.bg-light, .card-header.bg-light, .card-body.bg-light, .card-footer.bg-light) :not(.btn, .badge, .alert, [class*="bg-primary"], [class*="bg-success"], [class*="bg-info"], [class*="bg-warning"], [class*="bg-danger"], [class*="bg-secondary"], [class*="bg-dark"], .btn *, .badge *, .alert *) {
    color: #0d1b2a !important;
    text-shadow: none;
}

/* .text-muted inside a .bg-light region: its own rule sets
   `color: var(--text-muted) !important`, which on dark themes resolves to a
   light gray that is invisible against a near-white bg-light. Pin a darker
   muted ink that still reads as "secondary" against the light surface. */
.bg-light .text-muted,
.card.bg-light .text-muted,
.card-header.bg-light .text-muted,
.card-body.bg-light .text-muted,
.card-footer.bg-light .text-muted {
    color: #495057 !important;
}

/* `<pre>` / `<code>` / `.code-block` inherit a global rule that paints them
   with `background: color-mix(in srgb, var(--text-color) 5%, transparent)`.
   On dark themes inside a `.bg-light` parent, that resolves to a 5% white
   tint over a near-white surface (still light) — but the global text color
   resolves to white, which we then override to #0d1b2a above. The pre block
   itself though has been observed to render as dark-on-dark when its parent
   is a `.card.bg-light` (see the original bug: collapsed JSON details in
   templates/logs.html). Pin an explicit light surface and dark ink so any
   descendant code/pre stays legible. */
.bg-light pre,
.bg-light code,
.bg-light .code-block,
.card.bg-light pre,
.card.bg-light code,
.card-body.bg-light pre,
.card-body.bg-light code,
.card-footer.bg-light pre,
.card-footer.bg-light code,
.card-header.bg-light pre,
.card-header.bg-light code {
    background: rgba(0, 0, 0, 0.06) !important;
    color: #0d1b2a !important;
    border-color: rgba(0, 0, 0, 0.08);
}

/* Bootstrap utility classes inside .bg-light: when an author writes
   `<span class="text-success">` inside a bg-light region, the descendant
   color override above (`color: #0d1b2a`) flattens that intent. Restore
   theme-aware semantic colors (using the dark/text-emphasis variants so they
   read well on a near-white background). */
.bg-light .text-primary,
.card.bg-light .text-primary { color: #0d6efd !important; }
.bg-light .text-success,
.card.bg-light .text-success { color: #198754 !important; }
.bg-light .text-info,
.card.bg-light .text-info { color: #087990 !important; }
.bg-light .text-warning,
.card.bg-light .text-warning { color: #997404 !important; }
.bg-light .text-danger,
.card.bg-light .text-danger { color: #dc3545 !important; }

/* Lightning Theme - small additional tweak: keep the lightning-specific
   muted ink that was tuned for its pale-yellow aesthetic when the theme
   is active; otherwise the global #495057 above applies. */
[data-theme="lightning"] .bg-light .text-muted,
[data-theme="lightning"] .card-header.bg-light .text-muted,
[data-theme="lightning"] .card-body.bg-light .text-muted,
[data-theme="lightning"] .card-footer.bg-light .text-muted {
    color: #3a4d7a !important;
}

/* ----------------------------------------------------------------------------
   Page-local backgrounds that use var(--light-color) directly
   ----------------------------------------------------------------------------
   Several template-local stylesheets (templates/eas/workflow.html,
   templates/index.html, templates/led_control.html) set
   `background: var(--light-color)` on their own components without also
   pinning a text color. On the seven dark themes whose --light-color
   resolves to a near-white tint (pale yellow / lavender / cyan), the
   inherited light body text becomes invisible on those backgrounds
   (e.g. white-on-pale-yellow on the lightning theme). The `.bg-light`
   utility class already has its own dark-text override above; this block
   does the equivalent for the named selectors that use --light-color
   directly.

   We set `color` only on the affected ancestors so unclassed inner text
   inherits the dark color, while inner elements that declare their own
   color (".same-chip button { color: var(--danger-color) }", ".text-success"
   icons, etc.) retain their explicit colors via the cascade. The lone
   exception is `.text-muted`, whose own rule below uses !important and
   would otherwise re-light subtitles inside the chip — a matching
   !important descendant rule below restores readable contrast there. */
:is([data-theme="lightning"],
    [data-theme="aurora"],
    [data-theme="nebula"],
    [data-theme="midnight"],
    [data-theme="charcoal"],
    [data-theme="obsidian"],
    [data-theme="slate"]) :is(
        .workflow-card > .card-header,
        .same-chip,
        #date-filters,
        .alert-summary-panel,
        .feature-group,
        .layout-preset-btn:hover,
        .rss-item-row) {
    color: #0d1b2a;
    text-shadow: none;
}

/* Re-tone .text-muted descendants of the same regions: the global
   `.text-muted { color: var(--text-muted) !important }` rule (in the
   "Bootstrap Color Utilities" section) resolves to a light gray on
   dark themes, which is invisible on a pale --light-color background.
   Pick a darker muted color so the subtitle ("Ohio · FIPS 003 · Entire
   area" inside .same-chip, etc.) reads. */
:is([data-theme="lightning"],
    [data-theme="aurora"],
    [data-theme="nebula"],
    [data-theme="midnight"],
    [data-theme="charcoal"],
    [data-theme="obsidian"],
    [data-theme="slate"]) :is(
        .workflow-card > .card-header,
        .same-chip,
        #date-filters,
        .alert-summary-panel,
        .feature-group,
        .layout-preset-btn:hover,
        .rss-item-row) .text-muted {
    color: #3a4d7a !important;
}

/* `<code>` inside these same near-white-on-dark-theme regions has the
   identical problem, but for a different reason than .text-muted above:
   the global `code { color: var(--text-color) }` rule (Typography
   section) is a declaration directly on the element itself, and any
   explicit rule on an element -- regardless of the ancestor selector's
   specificity -- always wins over inheriting a color from a parent like
   `.same-chip` above. So `.same-chip`'s dark #0d1b2a text never reaches
   its `<code>` children: they keep rendering in --text-color, which on
   these seven themes is a light near-white tint chosen for the (dark)
   page body -- rendering as near-invisible light-on-light text sitting on
   `.same-chip`'s own light background (confirmed live: SAME/FIPS code
   chips on templates/eas/workflow.html measured at a 1.00 contrast ratio,
   i.e. text and background were the literal same colour). `code`'s
   background tint is keyed off the same --text-color too
   (`color-mix(in srgb, var(--text-color) 5%, transparent)`), so it also
   needs to flip to the dark ink for the tint to still read as a subtle
   chip rather than just matching the surrounding light background. */
:is([data-theme="lightning"],
    [data-theme="aurora"],
    [data-theme="nebula"],
    [data-theme="midnight"],
    [data-theme="charcoal"],
    [data-theme="obsidian"],
    [data-theme="slate"]) :is(
        .workflow-card > .card-header,
        .same-chip,
        #date-filters,
        .alert-summary-panel,
        .feature-group,
        .layout-preset-btn:hover,
        .rss-item-row) code {
    color: #0d1b2a;
    background: color-mix(in srgb, #0d1b2a 8%, transparent);
}

/* ----------------------------------------------------------------------------
   Bootstrap .form-text helper text
   ----------------------------------------------------------------------------
   Bootstrap 5's default sets .form-text to a hardcoded muted gray
   (~#6c757d) which has poor contrast on dark themes — the helper text
   under inputs is invisible on `--bg-color: #060d1f` (lightning),
   `#0a0e27` (midnight), `#000000` (obsidian), etc. admin.css already
   ships an equivalent rule, but only admin pages link admin.css; the
   broadcast workflow, dashboard, and LED control pages don't. Promoting
   it to the global stylesheet fixes helper text everywhere by tying it
   to the per-theme --text-muted token (calibrated for readable contrast
   against --bg-color on every theme). */
.form-text {
    color: var(--text-muted);
}

/* Lightning Theme - Navbar opacity
   The default navbar mixes its gradient with 15-20% transparency. Combined
   with the bright yellow body gradient of this theme, page content scrolls
   visibly through the sticky navbar. Opaque gradient + stronger shadow
   keeps the header readable. */
[data-theme="lightning"] .navbar {
    background: linear-gradient(135deg,
        #1a2342 0%,
        #2a1f4a 50%,
        #162848 100%) !important;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-bottom: 1px solid rgba(255, 235, 59, 0.25);
}

[data-theme="lightning"] .navbar.scrolled {
    background: linear-gradient(135deg,
        #141c38 0%,
        #241a42 50%,
        #10203e 100%) !important;
}

/* Lightning Theme - Footer palette
   Default footer fades from --primary-color (yellow) to --secondary-color
   (cyan), producing a large saturated yellow band at the bottom of every
   page. Replace with a deep-storm gradient so the footer reads as part of
   the night sky instead of a giant highlight block. */
[data-theme="lightning"] footer {
    background: linear-gradient(135deg,
        #0a1128 0%,
        #132047 50%,
        #0a1128 100%);
    color: var(--text-color);
}

[data-theme="lightning"] footer a {
    color: rgba(255, 253, 231, 0.85);
}

[data-theme="lightning"] footer a:hover {
    color: var(--primary-color);
}

/* Lightning Theme - Atmospheric storm overlay.
   static/js/core/lightning.js drives the timing and injects fresh SVG bolts
   per strike. The CSS here does the heavy lifting for the *look*: stacked
   drop-shadow bloom, screen blending so bolts add light instead of painting
   lines, and a radial sky flash synced to each strike. */
#lightning-overlay {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 9998;
    overflow: hidden;
}

#lightning-overlay .lightning-flash {
    position: absolute;
    inset: 0;
    --flash-x: 50%;
    --flash-y: 15%;
    background: radial-gradient(ellipse 70% 55% at var(--flash-x) var(--flash-y),
        rgba(255, 255, 255, 0.55) 0%,
        rgba(200, 230, 255, 0.28) 18%,
        rgba(127, 215, 255, 0.12) 38%,
        transparent 65%);
    opacity: 0;
    mix-blend-mode: screen;
    will-change: opacity;
    transition: opacity 420ms cubic-bezier(0.2, 0, 0.3, 1);
}

#lightning-overlay .lightning-flash.lightning-flash-on {
    opacity: 1;
    /* Fast ramp up, the longer transition above handles the fade. */
    transition: opacity 18ms linear;
}

#lightning-overlay .lightning-bolts {
    position: absolute;
    inset: 0;
    mix-blend-mode: screen;
}

#lightning-overlay .lightning-bolt {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    /* Three drop-shadow passes give the bolt a tight white core and a soft
       blue halo without paying for the giant 40 px / 90 px radii the old
       six-pass stack used. Transitioning only `opacity` (not `filter`)
       avoids re-rasterising the blur stack on every frame of the fade. */
    filter:
        drop-shadow(0 0 1.5px #ffffff)
        drop-shadow(0 0 6px #b7e4ff)
        drop-shadow(0 0 20px rgba(64, 180, 255, 0.65));
    will-change: opacity;
    transition: opacity 280ms cubic-bezier(0.2, 0, 0.3, 1);
}

#lightning-overlay .lightning-bolt.lightning-bolt-strike {
    opacity: 1;
    transition: opacity 22ms linear;
}

#lightning-overlay .lightning-bolt.lightning-bolt-dim {
    opacity: 0.18;
    transition: opacity 40ms linear;
}

#lightning-overlay .lightning-bolt.lightning-bolt-fade {
    opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
    [data-theme="lightning"] .fa-bolt {
        animation: none;
    }
    #lightning-overlay {
        display: none;
    }
}

/* Lightning Theme - Page header readability
   .page-header uses a --primary-color → --secondary-color gradient which
   resolves to yellow (#ffeb3b) → cyan (#40c4ff) in this theme.  White text
   on those colours fails every WCAG contrast threshold.  Switch to dark ink
   (matching the theme's --dark-color) so the header text remains legible. */
[data-theme="lightning"] .page-header {
    color: #0d1b2a;
}

[data-theme="lightning"] .page-header h1,
[data-theme="lightning"] .page-header h2,
[data-theme="lightning"] .page-header .page-title {
    color: #0d1b2a;
    text-shadow: 0 1px 3px rgba(255, 255, 255, 0.25);
}

[data-theme="lightning"] .page-header .page-subtitle {
    color: rgba(13, 27, 42, 0.85);
    text-shadow: none;
}

/* Yellow Theme - Page header readability
   Same problem as lightning: the amber (#f9a825) → yellow (#ffeb3b)
   gradient is too bright for white text. Use the same dark ink. */
[data-theme="yellow"] .page-header {
    color: #0d1b2a;
}

[data-theme="yellow"] .page-header h1,
[data-theme="yellow"] .page-header h2,
[data-theme="yellow"] .page-header .page-title {
    color: #0d1b2a;
    text-shadow: 0 1px 3px rgba(255, 255, 255, 0.25);
}

[data-theme="yellow"] .page-header .page-subtitle {
    color: rgba(13, 27, 42, 0.85);
    text-shadow: none;
}

/* Lightning + Yellow - header icon tile and outline-light action buttons
   also need dark ink on the bright gradients. */
[data-theme="lightning"] .page-header .page-header-icon,
[data-theme="yellow"] .page-header .page-header-icon {
    color: #0d1b2a;
    background: rgba(13, 27, 42, 0.08);
    border-color: rgba(13, 27, 42, 0.25);
    text-shadow: none;
}

[data-theme="lightning"] .page-header .page-header-actions .btn-outline-light,
[data-theme="yellow"] .page-header .page-header-actions .btn-outline-light {
    color: #0d1b2a;
    background: rgba(13, 27, 42, 0.08);
    border-color: rgba(13, 27, 42, 0.35);
}

[data-theme="lightning"] .page-header .page-header-actions .btn-outline-light:hover,
[data-theme="yellow"] .page-header .page-header-actions .btn-outline-light:hover {
    color: #0d1b2a;
    background: rgba(13, 27, 42, 0.16);
    border-color: rgba(13, 27, 42, 0.55);
}

/* Coffee Theme - Page header readability
   Third instance of the Lightning/Yellow problem. Coffee's gradient runs
   #e2b37f -> #c7a06e, a pale tan, and the inherited white page-header ink
   measured 1.91:1 on it — the worst reading of any theme, and well under
   even the 3.0 large-text floor. Same dark-ink treatment. */
[data-theme="coffee"] .page-header {
    color: #2a1a0e;
}

[data-theme="coffee"] .page-header h1,
[data-theme="coffee"] .page-header h2,
[data-theme="coffee"] .page-header .page-title {
    color: #2a1a0e;
    text-shadow: 0 1px 3px rgba(255, 255, 255, 0.25);
}

[data-theme="coffee"] .page-header .page-subtitle {
    color: rgba(42, 26, 14, 0.85);
    text-shadow: none;
}

[data-theme="coffee"] .page-header .page-header-icon {
    color: #2a1a0e;
    background: rgba(42, 26, 14, 0.08);
    border-color: rgba(42, 26, 14, 0.25);
}

[data-theme="coffee"] .page-header .page-header-actions .btn-outline-light {
    color: #2a1a0e;
    background: rgba(42, 26, 14, 0.08);
    border-color: rgba(42, 26, 14, 0.35);
}

[data-theme="coffee"] .page-header .page-header-actions .btn-outline-light:hover {
    color: #2a1a0e;
    background: rgba(42, 26, 14, 0.16);
    border-color: rgba(42, 26, 14, 0.55);
}

/* Page header gradients that are too light for white ink, but whose hue would
   look wrong carrying dark ink (unlike Coffee/Yellow/Lightning above). These
   are mid-tone saturated ramps — Aurora's cyan end, Orange, Sunset and Dark's
   lavender end — where white is the right ink and the gradient itself is the
   problem. Deepening both stops keeps the hue and the white text while
   lifting the title clear of the 3.0 large-text floor. */
:is([data-theme="aurora"],
    [data-theme="orange"],
    [data-theme="sunset"],
    [data-theme="dark"]) .page-header {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--primary-color) 74%, #10131c) 0%,
        color-mix(in srgb,
            color-mix(in srgb, var(--primary-color) 90%, var(--secondary-color))
            74%, #10131c) 40%,
        color-mix(in srgb,
            color-mix(in srgb, var(--primary-color) 70%, var(--secondary-color))
            74%, #10131c) 70%,
        color-mix(in srgb, var(--secondary-color) 74%, #10131c) 100%);
}

/* Lightning Theme - Form check / switch readability
   .form-check-input:checked sets background to --primary-color (yellow).
   The standard Bootstrap checkmark and radio SVGs use a white stroke/fill
   which is nearly invisible on yellow.  Override with dark-ink SVGs. */
[data-theme="lightning"] .form-check-input:checked {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%230d1b2a' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
}

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

[data-theme="lightning"] .form-switch .form-check-input:checked {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%230d1b2a'/%3e%3c/svg%3e");
}

/* Lightning Theme - Active list-group item readability
   .list-group-item.active uses --primary-color (yellow) as background with
   white text, producing a near-invisible combination. */
[data-theme="lightning"] .list-group-item.active {
    color: #0d1b2a;
    text-shadow: none;
}

/* Lightning Theme - Dropdown / pagination / nav-pills active state readability
   The shared component rules paint these "active" states with
   background-color: var(--primary-color) and color: white.  In this theme
   --primary-color is bright yellow (#ffeb3b), so white-on-yellow drops to
   ~1.1:1 contrast and the active selection becomes invisible.  Force dark
   ink so the active item is clearly distinguishable. */
[data-theme="lightning"] .dropdown-item.active,
[data-theme="lightning"] .dropdown-item:active,
[data-theme="lightning"] .page-item.active .page-link,
[data-theme="lightning"] .nav-pills .nav-link.active,
[data-theme="lightning"] .nav-pills .show > .nav-link {
    color: #0d1b2a !important;
    text-shadow: none;
}

/* Lightning Theme - Progress bar readability
   .progress-bar fills with --primary-color (yellow); any embedded text label
   would be white-on-yellow.  Force dark text so percentage labels are legible. */
[data-theme="lightning"] .progress-bar {
    color: #0d1b2a;
}

/* Lightning Theme - Success colour readability
   --success-color resolves to #00e676 (bright lime-green) in this theme.
   White text on that background fails WCAG AA (contrast ≈ 2:1).  Apply dark
   text to every component that paints with the success colour. */
[data-theme="lightning"] .badge.bg-success,
[data-theme="lightning"] .text-bg-success,
[data-theme="lightning"] .card-header.bg-success,
[data-theme="lightning"] .card-header.bg-success *,
[data-theme="lightning"] .bg-success {
    color: #0d1b2a !important;
    text-shadow: none;
}

/* Lightning Theme - Danger colour readability
   --danger-color resolves to #ff5252 (bright red) in this theme.
   White text on that background falls to 3.19:1, failing WCAG AA for normal
   text.  Force dark ink so danger badges and card-headers remain legible. */
[data-theme="lightning"] .bg-danger,
[data-theme="lightning"] .text-bg-danger,
[data-theme="lightning"] .badge.bg-danger,
[data-theme="lightning"] .card-header.bg-danger,
[data-theme="lightning"] .card-header.bg-danger * {
    color: #0d1b2a !important;
    text-shadow: none;
}

/* Lightning Theme - Warning colour readability
   --warning-color resolves to #ffab40 (bright orange) in this theme.
   White text on that background is only 1.88:1 — a hard WCAG fail.
   Force dark ink so warning badges and card-headers remain legible. */
[data-theme="lightning"] .bg-warning,
[data-theme="lightning"] .text-bg-warning,
[data-theme="lightning"] .badge.bg-warning,
[data-theme="lightning"] .card-header.bg-warning,
[data-theme="lightning"] .card-header.bg-warning * {
    color: #0d1b2a !important;
    text-shadow: none;
}

/* Lightning Theme - Tone down body ambient gradient.
   The default body uses radial blobs of --primary / --secondary at 10/8%.
   Against this theme's deep-navy background those blobs read as bright
   yellow and saturated cyan ovals that dominate the page and wash out
   foreground content.  Drop them well below the 5% threshold so they
   register as faint atmosphere instead of competing with content. */
[data-theme="lightning"] body {
    background-image:
        radial-gradient(ellipse at 12% 18%,
            rgba(255, 235, 59, 0.04) 0%,
            transparent 45%),
        radial-gradient(ellipse at 88% 82%,
            rgba(64, 196, 255, 0.035) 0%,
            transparent 45%);
}

/* Lightning Theme - Card surface contrast.
   .card paints a near-flat surface tint over --surface-color, with a
   border that mixes --border-color at 50% transparent.  On the deep
   navy bg that border becomes nearly invisible.  Use a fully opaque
   border and a subtle inner highlight so card edges are readable. */
[data-theme="lightning"] .card {
    border-color: var(--border-color);
    box-shadow:
        0 4px 20px rgba(0, 0, 0, 0.45),
        0 8px 32px rgba(0, 0, 0, 0.25),
        0 0 0 1px rgba(255, 255, 255, 0.06) inset;
}

/* Lightning Theme - Form control contrast.
   Inputs paint with --surface-color which is close to --bg-color in this
   theme.  Lift the input surface and use a brighter border so fields
   stand out from the page. */
[data-theme="lightning"] .form-control,
[data-theme="lightning"] .form-select,
[data-theme="lightning"] textarea,
[data-theme="lightning"] input[type="text"],
[data-theme="lightning"] input[type="email"],
[data-theme="lightning"] input[type="password"],
[data-theme="lightning"] input[type="number"],
[data-theme="lightning"] input[type="search"],
[data-theme="lightning"] input[type="tel"],
[data-theme="lightning"] input[type="url"] {
    background-color: #1f2f5e;
    border-color: #6a82b8;
    color: #ffffff;
}

[data-theme="lightning"] .form-control::placeholder,
[data-theme="lightning"] .form-select::placeholder,
[data-theme="lightning"] textarea::placeholder {
    color: #aab8d4;
    opacity: 1;
}

/* Lightning Theme - Atmospheric storm overlay readability.
   The default flash layer peaks at opacity 1 with a bright white core
   and cyan halo, washing out everything behind it.  Cap peak opacity
   so strikes still illuminate the page without making text unreadable. */
[data-theme="lightning"] #lightning-overlay .lightning-flash.lightning-flash-on {
    opacity: 0.55;
}

[data-theme="lightning"] #lightning-overlay .lightning-flash {
    background: radial-gradient(ellipse 70% 55% at var(--flash-x) var(--flash-y),
        rgba(255, 255, 255, 0.35) 0%,
        rgba(200, 230, 255, 0.18) 18%,
        rgba(127, 215, 255, 0.08) 38%,
        transparent 65%);
}


/* 2. BASE & RESET STYLES */

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    font-size: 16px;
    scroll-behavior: smooth;
    overflow-x: hidden;
    max-width: 100%;
}

body {
    font-family: var(--font-family-sans);
    font-size: var(--font-size-base);
    line-height: var(--line-height-base);
    color: var(--text-color);
    background-color: var(--bg-color);
    /* Ambient gradient overlay: two soft radial glows derived from the current
       theme's primary / secondary palette.  Works on both light & dark themes
       because color-mix keeps the tint very low (10 % / 8 %).
       background-attachment: fixed keeps the gradient stationary while the
       page scrolls, creating a subtle depth / parallax effect. */
    background-image:
        radial-gradient(ellipse at 10% 20%,
            color-mix(in srgb, var(--primary-color) 10%, transparent) 0%,
            transparent 55%),
        radial-gradient(ellipse at 90% 80%,
            color-mix(in srgb, var(--secondary-color) 8%, transparent) 0%,
            transparent 55%);
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
    min-height: 100vh;
    /* Flexbox sticky footer pattern - ensures footer sticks to bottom */
    display: flex;
    flex-direction: column;
}

/* ------------------------------------------------------------------
   Mobile overflow defenses
   ------------------------------------------------------------------
   These rules keep every page from scrolling horizontally on narrow
   viewports (≥320px wide).  They cap intrinsic-sized embedded media,
   force code/log blocks to wrap on phones, give stray tables a local
   scroll container, and expose a small text-break utility for long
   unbreakable strings (FIPS codes, hex IDs, URLs, etc.).  Desktop
   styling is preserved – mobile-only rules sit behind a media query.
   ------------------------------------------------------------------ */

/* Cap embedded media so wide images / iframes can never push the page
   past the viewport.  height:auto only applies to bitmaps & video so
   SVG / canvas with explicit drawing sizes are left alone. */
img, video {
    max-width: 100%;
    height: auto;
}
svg, canvas, iframe, embed, object {
    max-width: 100%;
}

/* Utility: opt-in line-breaking for long unbreakable strings (FIPS
   codes, hex hashes, JSON payloads, URLs).  Use sparingly – this is
   meant for value cells / code spans, not flowing prose. */
.text-break-anywhere {
    overflow-wrap: anywhere;
    word-break: break-word;
}

/* Utility: an inline brand logo mark sized to the surrounding text.
   Used for the true-colour SVGs under static/img/logos/ — browser and OS
   marks on the Traffic dashboard, language marks on Repository Statistics.
   Sized in `em` so it tracks whatever font-size the row uses. */
.ti-logo {
    width: 1.15em;
    height: 1.15em;
    vertical-align: -0.2em;
    object-fit: contain;
}

@media (max-width: 767.98px) {
    /* Wrap long lines inside code / log blocks on phones so they stop
       pushing the page sideways.  Desktops keep the original look. */
    pre, code, kbd, samp {
        max-width: 100%;
        overflow-x: auto;
        overflow-wrap: anywhere;
    }
    pre {
        white-space: pre-wrap;
        word-break: break-word;
    }

    /* Safety net for any stray <table> that wasn't wrapped in a
       .table-responsive container.  Turning the table itself into a
       block-level scroll container keeps the surrounding card from
       being forced wider than the viewport.  Selectors are scoped to
       common content areas so we don't disturb tables that are
       already inside .table-responsive (which lives in <main>). */
    .card-body > table,
    .modal-body > table,
    main > table {
        display: block;
        max-width: 100%;
        overflow-x: auto;
    }
}


/* 3. TYPOGRAPHY */

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    color: var(--text-color);
    font-weight: var(--font-weight-bold);
    line-height: 1.3;
    margin-bottom: 0.75rem;
}

h1, .h1 { font-size: 2.5rem; }
h2, .h2 { font-size: 2rem; }
h3, .h3 { font-size: 1.75rem; }
h4, .h4 { font-size: 1.5rem; }
h5, .h5 { font-size: 1.25rem; }
h6, .h6 { font-size: 1rem; }

p {
    line-height: 1.6;
    margin-bottom: 1rem;
}

a {
    /* Ink, not fill: several themes' brand colours are far too light to serve
       as body-copy links (Yellow measured 1.97:1, Slate 1.98:1). */
    color: var(--primary-ink);
    text-decoration: none;
    transition: color var(--transition-fast);
}

a:hover,
a:focus {
    color: var(--secondary-color);
    text-decoration: underline;
}

code,
pre,
.code-block {
    font-family: var(--font-family-mono);
    background: color-mix(in srgb, var(--text-color) 5%, transparent);
    color: var(--text-color);
    padding: 0.2em 0.4em;
    border-radius: var(--radius-sm);
}

.text-muted {
    color: var(--text-muted) !important;
}

.text-secondary {
    color: var(--text-secondary) !important;
}

.lead {
    font-size: var(--font-size-lg);
    color: var(--text-secondary);
}

small,
.small {
    font-size: var(--font-size-sm);
    color: var(--text-muted);
}


/* 4. LAYOUT (Navbar, Containers, Footer) */

/* iOS 26 Navigation Bar - Translucent Blur Effect */
.navbar {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--vibrant-indigo) 85%, transparent) 0%,
        color-mix(in srgb, var(--vibrant-purple) 80%, transparent) 50%,
        color-mix(in srgb, var(--vibrant-blue) 85%, transparent) 100%) !important;
    backdrop-filter: blur(var(--glass-blur-heavy)) saturate(200%);
    -webkit-backdrop-filter: blur(var(--glass-blur-heavy)) saturate(200%);
    box-shadow:
        0 8px 32px rgba(0, 0, 0, 0.15),
        0 1px 0 rgba(255, 255, 255, 0.15) inset;
    border-bottom: 1px solid rgba(255, 255, 255, 0.18);
    padding: 0.4rem 2rem;
    position: sticky;
    top: 0;
    z-index: 1030;
    transition: all 0.4s var(--ease-ios);
}

/* Subtle animation on scroll */
.navbar.scrolled {
    padding: 0.25rem 2rem;
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--vibrant-indigo) 92%, transparent) 0%,
        color-mix(in srgb, var(--vibrant-purple) 88%, transparent) 50%,
        color-mix(in srgb, var(--vibrant-blue) 92%, transparent) 100%) !important;
    box-shadow:
        0 12px 40px rgba(0, 0, 0, 0.2),
        0 1px 0 rgba(255, 255, 255, 0.2) inset;
}

.navbar:hover {
    box-shadow:
        0 12px 40px rgba(0, 0, 0, 0.18),
        0 1px 0 rgba(255, 255, 255, 0.2) inset;
}

.navbar-brand {
    color: white;
    font-weight: var(--font-weight-bold);
    font-size: 1.25rem;
    padding: 0.25rem 1rem;
    margin-right: 1.5rem;
    border-radius: var(--radius-lg);
    transition: all var(--ease-fluid);
    position: relative;
    overflow: hidden;
}

.navbar-brand .logo-wordmark,
.navbar-brand .brand-logo {
    height: 72px;
    width: auto;
}

/* Brand + status indicators row — keep on a single line next to the logo */
.navbar-brand-group {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 0.5rem;
    min-width: 0;
}

.navbar-brand-group .navbar-brand {
    display: inline-flex;
    align-items: center;
    margin-right: 0;
}

/* System health pill — match the visual weight of the WS indicator */
.health-indicator {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    font-size: 0.7rem;
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.04em;
    color: rgba(255, 255, 255, 0.85);
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.15);
    white-space: nowrap;
    cursor: default;
    flex-shrink: 0;
}

.health-indicator .health-label {
    text-transform: uppercase;
    opacity: 0.7;
    font-size: 0.65rem;
}

.health-indicator .health-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--text-muted);
}

.health-indicator .health-dot.health-good {
    background: #2eb08d;
    box-shadow: 0 0 6px rgba(46, 176, 141, 0.6);
}
.health-indicator .health-dot.health-warning {
    background: #f6b968;
    box-shadow: 0 0 6px rgba(246, 185, 104, 0.6);
}
.health-indicator .health-dot.health-danger {
    background: #ef5a5a;
    box-shadow: 0 0 6px rgba(239, 90, 90, 0.6);
}

/* Hide the noisier indicators on narrow screens to keep navbar single-row */
@media (max-width: 991.98px) {
    .health-indicator .health-label,
    .health-indicator .health-text {
        display: none;
    }
    .sl-tower {
        display: none;
    }
}

/* Hide duplicate footer logo */
.footer .footer-brand .footer-logo {
    display: none;
}

/* Make theme toggle buttons less obvious */
.theme-toggle-nav-item {
    opacity: 0.5;
    transition: opacity var(--transition-fast);
}

.theme-toggle-nav-item:hover {
    opacity: 1;
}

.theme-toggle-button {
    background: transparent;
    border: none;
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.9rem;  /* Smaller than default */
    padding: 0.4rem 0.6rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--transition-fast);
}

.theme-toggle-button:hover {
    color: rgba(255, 255, 255, 0.9);
    background: rgba(255, 255, 255, 0.1);
}

.theme-toggle-button:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.2);
}

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

/* WebSocket live/reconnecting indicator */
.ws-indicator {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    font-size: 0.7rem;
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.04em;
    transition: background 0.3s ease, color 0.3s ease;
    white-space: nowrap;
    cursor: default;
}

.ws-indicator__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}

.ws-indicator--live {
    background: rgba(46, 176, 141, 0.18);
    color: #2eb08d;
    border: 1px solid rgba(46, 176, 141, 0.35);
}
.ws-indicator--live .ws-indicator__dot {
    background: #2eb08d;
    box-shadow: 0 0 0 0 rgba(46, 176, 141, 0.6);
    animation: ws-pulse 2s ease-in-out infinite;
}

.ws-indicator--reconnecting {
    background: rgba(246, 185, 104, 0.18);
    color: #c8922a;
    border: 1px solid rgba(246, 185, 104, 0.4);
}
.ws-indicator--reconnecting .ws-indicator__dot {
    background: #f6b968;
    animation: ws-blink 0.8s ease-in-out infinite;
}

.ws-indicator--polling {
    background: rgba(138, 146, 166, 0.15);
    color: var(--text-muted);
    border: 1px solid rgba(138, 146, 166, 0.3);
}
.ws-indicator--polling .ws-indicator__dot {
    background: var(--text-muted);
}

@keyframes ws-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(46, 176, 141, 0.55); }
    50%       { box-shadow: 0 0 0 5px rgba(46, 176, 141, 0); }
}
@keyframes ws-blink {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.3; }
}

/* Animated rainbow accent along the bottom edge of the navbar */
.navbar::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: linear-gradient(90deg,
        var(--vibrant-blue),
        var(--vibrant-purple),
        var(--vibrant-pink),
        var(--vibrant-orange),
        var(--vibrant-blue));
    background-size: 200% 100%;
    animation: gradientShift 8s linear infinite;
    opacity: 0.7;
}

.nav-link {
    color: rgba(255, 255, 255, 0.9);
    font-weight: var(--font-weight-medium);
    padding: 0.4rem 1rem;
    border-radius: var(--radius-pill);
    transition: all 0.3s var(--ease-spring);
    position: relative;
    overflow: hidden;
}

/* Top-level navbar items are an icon plus a label. Bootstrap ships
   `.nav-link { display: block }`, and nothing here overrode it, so the icon
   and label were laid out as inline content: the one plain link (Dashboard —
   every sibling is a .dropdown-toggle) wrapped onto two lines below ~1440px,
   rendering 61px tall against its siblings' 37px and colliding with the
   active-state pill. Scoped to .navbar so .nav-pills / .nav-tabs elsewhere
   keep Bootstrap's own layout. */
.navbar .navbar-nav > .nav-item > .nav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    white-space: nowrap;
}

/* Glow effect behind link */
.nav-link::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg,
        rgba(255, 255, 255, 0.2),
        rgba(255, 255, 255, 0.05));
    border-radius: var(--radius-pill);
    opacity: 0;
    transition: all 0.3s var(--ease-spring);
    transform: scale(0.9);
}

.nav-link:hover::before,
.nav-link:focus::before {
    opacity: 1;
    transform: scale(1);
}

.nav-link:hover,
.nav-link:focus {
    color: white;
    transform: translateY(-2px);
}

/* iOS-style pill active state */
.nav-link.active {
    color: white;
    background: linear-gradient(135deg,
        rgba(255, 255, 255, 0.25) 0%,
        rgba(255, 255, 255, 0.15) 100%);
    box-shadow:
        0 4px 12px rgba(0, 0, 0, 0.15),
        0 0 0 1px rgba(255, 255, 255, 0.2) inset;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.nav-link.active:hover {
    transform: translateY(-2px) scale(1.02);
    box-shadow:
        0 6px 20px rgba(0, 0, 0, 0.2),
        0 0 0 1px rgba(255, 255, 255, 0.25) inset;
}

/* Light theme navbar adjustments - use dark text on light backgrounds */
[data-theme="cosmo"] .navbar,
[data-theme="spring"] .navbar,
[data-theme="red"] .navbar,
[data-theme="green"] .navbar,
[data-theme="blue"] .navbar,
[data-theme="purple"] .navbar,
[data-theme="pink"] .navbar,
[data-theme="orange"] .navbar,
[data-theme="yellow"] .navbar,
[data-theme="sunset"] .navbar,
[data-theme="tide"] .navbar {
    color: var(--text-color);
    /* Frosted glass (#8): keep the themed gradient but leave a little
       translucency so the heavy backdrop-filter blur actually frosts the
       content scrolling beneath it. ~90% keeps nav text fully legible. */
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--primary-color) 90%, transparent),
        color-mix(in srgb, var(--secondary-color) 90%, transparent)) !important;
    /* Light border for definition */
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

/* When scrolled, lean further into the frosted-glass look on light themes */
[data-theme="cosmo"] .navbar.scrolled,
[data-theme="spring"] .navbar.scrolled,
[data-theme="red"] .navbar.scrolled,
[data-theme="green"] .navbar.scrolled,
[data-theme="blue"] .navbar.scrolled,
[data-theme="purple"] .navbar.scrolled,
[data-theme="pink"] .navbar.scrolled,
[data-theme="orange"] .navbar.scrolled,
[data-theme="yellow"] .navbar.scrolled,
[data-theme="sunset"] .navbar.scrolled,
[data-theme="tide"] .navbar.scrolled {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--primary-color) 82%, transparent),
        color-mix(in srgb, var(--secondary-color) 82%, transparent)) !important;
}

[data-theme="cosmo"] .navbar .navbar-brand,
[data-theme="spring"] .navbar .navbar-brand,
[data-theme="red"] .navbar .navbar-brand,
[data-theme="green"] .navbar .navbar-brand,
[data-theme="blue"] .navbar .navbar-brand,
[data-theme="purple"] .navbar .navbar-brand,
[data-theme="pink"] .navbar .navbar-brand,
[data-theme="orange"] .navbar .navbar-brand,
[data-theme="yellow"] .navbar .navbar-brand,
[data-theme="sunset"] .navbar .navbar-brand,
[data-theme="tide"] .navbar .navbar-brand {
    color: var(--text-color);
}

[data-theme="cosmo"] .navbar .nav-link,
[data-theme="spring"] .navbar .nav-link,
[data-theme="red"] .navbar .nav-link,
[data-theme="green"] .navbar .nav-link,
[data-theme="blue"] .navbar .nav-link,
[data-theme="purple"] .navbar .nav-link,
[data-theme="pink"] .navbar .nav-link,
[data-theme="orange"] .navbar .nav-link,
[data-theme="yellow"] .navbar .nav-link,
[data-theme="sunset"] .navbar .nav-link,
[data-theme="tide"] .navbar .nav-link {
    color: rgba(0, 0, 0, 0.75);
}

[data-theme="cosmo"] .navbar .nav-link:hover,
[data-theme="spring"] .navbar .nav-link:hover,
[data-theme="red"] .navbar .nav-link:hover,
[data-theme="green"] .navbar .nav-link:hover,
[data-theme="blue"] .navbar .nav-link:hover,
[data-theme="purple"] .navbar .nav-link:hover,
[data-theme="pink"] .navbar .nav-link:hover,
[data-theme="orange"] .navbar .nav-link:hover,
[data-theme="yellow"] .navbar .nav-link:hover,
[data-theme="sunset"] .navbar .nav-link:hover,
[data-theme="tide"] .navbar .nav-link:hover,
[data-theme="cosmo"] .navbar .nav-link:focus,
[data-theme="spring"] .navbar .nav-link:focus,
[data-theme="red"] .navbar .nav-link:focus,
[data-theme="green"] .navbar .nav-link:focus,
[data-theme="blue"] .navbar .nav-link:focus,
[data-theme="purple"] .navbar .nav-link:focus,
[data-theme="pink"] .navbar .nav-link:focus,
[data-theme="orange"] .navbar .nav-link:focus,
[data-theme="yellow"] .navbar .nav-link:focus,
[data-theme="sunset"] .navbar .nav-link:focus,
[data-theme="tide"] .navbar .nav-link:focus {
    color: rgba(0, 0, 0, 0.95);
    background: rgba(0, 0, 0, 0.08);
}

[data-theme="cosmo"] .navbar .nav-link.active,
[data-theme="spring"] .navbar .nav-link.active,
[data-theme="red"] .navbar .nav-link.active,
[data-theme="green"] .navbar .nav-link.active,
[data-theme="blue"] .navbar .nav-link.active,
[data-theme="purple"] .navbar .nav-link.active,
[data-theme="pink"] .navbar .nav-link.active,
[data-theme="orange"] .navbar .nav-link.active,
[data-theme="yellow"] .navbar .nav-link.active,
[data-theme="sunset"] .navbar .nav-link.active,
[data-theme="tide"] .navbar .nav-link.active {
    color: rgba(0, 0, 0, 0.95);
    background: rgba(0, 0, 0, 0.12);
}

[data-theme="cosmo"] .navbar .theme-toggle-button,
[data-theme="spring"] .navbar .theme-toggle-button,
[data-theme="red"] .navbar .theme-toggle-button,
[data-theme="green"] .navbar .theme-toggle-button,
[data-theme="blue"] .navbar .theme-toggle-button,
[data-theme="purple"] .navbar .theme-toggle-button,
[data-theme="pink"] .navbar .theme-toggle-button,
[data-theme="orange"] .navbar .theme-toggle-button,
[data-theme="yellow"] .navbar .theme-toggle-button,
[data-theme="sunset"] .navbar .theme-toggle-button,
[data-theme="tide"] .navbar .theme-toggle-button {
    color: rgba(0, 0, 0, 0.6);
}

[data-theme="cosmo"] .navbar .theme-toggle-button:hover,
[data-theme="spring"] .navbar .theme-toggle-button:hover,
[data-theme="red"] .navbar .theme-toggle-button:hover,
[data-theme="green"] .navbar .theme-toggle-button:hover,
[data-theme="blue"] .navbar .theme-toggle-button:hover,
[data-theme="purple"] .navbar .theme-toggle-button:hover,
[data-theme="pink"] .navbar .theme-toggle-button:hover,
[data-theme="orange"] .navbar .theme-toggle-button:hover,
[data-theme="yellow"] .navbar .theme-toggle-button:hover,
[data-theme="sunset"] .navbar .theme-toggle-button:hover,
[data-theme="tide"] .navbar .theme-toggle-button:hover {
    color: rgba(0, 0, 0, 0.9);
    background: rgba(0, 0, 0, 0.1);
}

/* Nav Tabs - ensure readability on all themes */
.nav-tabs {
    border-bottom: 2px solid var(--border-color);
}

.nav-tabs .nav-link {
    color: var(--text-color);
    border: 1px solid transparent;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    padding: 0.75rem 1.25rem;
    transition: all var(--transition-fast);
}

.nav-tabs .nav-link:hover,
.nav-tabs .nav-link:focus {
    color: var(--primary-color);
    border-color: var(--border-color);
    /* --primary-color-rgb is undefined, so the rgba() form always tinted blue
       regardless of theme. color-mix tracks the active theme's primary. */
    background-color: color-mix(in srgb, var(--primary-color) 5%, transparent);
}

.nav-tabs .nav-link.active {
    color: var(--primary-color);
    background-color: var(--surface-color);
    border-color: var(--border-color) var(--border-color) var(--surface-color);
    font-weight: var(--font-weight-semibold);
}

/* Container */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: var(--layout-padding-x);
}

.container-fluid {
    width: 100%;
    padding: var(--layout-padding-x);
}

/* Page Shell */
.page-shell {
    /* Grow to fill remaining viewport so the footer is pinned to the bottom */
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
    padding: var(--layout-padding-top) 0 var(--layout-padding-bottom);
    position: relative;
}

/* Ensure page content always renders above the fixed background orbs (z-index: 0).
   Without this, positioned orbs sit on top of normal-flow block elements in the
   stacking order. The index.html page had this rule locally — moved here globally.
   Bootstrap modals (.modal) are excluded: Bootstrap appends the backdrop directly to
   <body> at z-index 1040, so giving the modal element z-index 1 here (higher specificity
   than Bootstrap's own .modal rule) would place the backdrop above the modal dialog,
   making the modal appear visible but completely unclickable. */
.page-shell > *:not(.orb):not(.modal) {
    position: relative;
    z-index: 1;
}

/* Standard Page Header - Modern Elevated Design */
.page-header {
    background: linear-gradient(135deg,
        var(--primary-color) 0%,
        color-mix(in srgb, var(--primary-color) 90%, var(--secondary-color)) 40%,
        color-mix(in srgb, var(--primary-color) 70%, var(--secondary-color)) 70%,
        var(--secondary-color) 100%);
    color: white;
    padding: 2rem 2.5rem;
    margin-bottom: 1.5rem;
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-xl),
                0 0 0 1px rgba(255, 255, 255, 0.1) inset;
    position: relative;
    overflow: hidden;
}

.page-header::before {
    content: "";
    position: absolute;
    top: -30%;
    right: -15%;
    width: 50%;
    height: 150%;
    background: radial-gradient(ellipse at center,
        rgba(255, 255, 255, 0.15),
        rgba(255, 255, 255, 0.05) 50%,
        transparent 75%);
    pointer-events: none;
    animation: headerGlow 8s ease-in-out infinite;
}

@keyframes headerGlow {
    0%, 100% { transform: translate(0, 0) scale(1); opacity: 0.6; }
    50% { transform: translate(-10px, 10px) scale(1.05); opacity: 0.8; }
}

.page-header h1,
.page-header h2,
.page-header .page-title {
    color: #ffffff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3),
                 0 2px 8px rgba(0, 0, 0, 0.15);
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0;
    position: relative;
    z-index: 2;
    letter-spacing: -0.01em;
}

.page-header .page-subtitle {
    color: rgba(255, 255, 255, 0.95);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    font-size: 0.95rem;
    margin-top: 0.5rem;
    margin-bottom: 0;
    font-weight: 500;
    position: relative;
    z-index: 2;
}

.page-header-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
    position: relative;
    z-index: 2;
}

/* Standard header action buttons — compact pills with a hover lift.
   (Promoted from per-page CSS on the dashboard so every page matches.) */
.page-header-actions .btn,
.page-header-gradient .page-header-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.4rem 0.9rem;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.85rem;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
    transition: transform 0.2s ease, box-shadow 0.2s ease,
                background-color 0.2s ease, border-color 0.2s ease;
}

.page-header-actions .btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.22);
}

/* Frosted-glass treatment for the default outline-light header buttons */
.page-header .page-header-actions .btn-outline-light,
.page-header-gradient .page-header-actions .btn-outline-light {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.35);
    color: #ffffff;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

.page-header .page-header-actions .btn-outline-light:hover,
.page-header-gradient .page-header-actions .btn-outline-light:hover {
    background: rgba(255, 255, 255, 0.24);
    border-color: rgba(255, 255, 255, 0.6);
    color: #ffffff;
}

/* Header content wrapper for better z-index control */
.page-header .header-content,
.page-header-gradient .header-content {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-width: 0;
    position: relative;
    z-index: 2;
}

.page-header .header-content .header-text,
.page-header-gradient .header-content .header-text {
    min-width: 0;
}

/* Frosted icon tile rendered by components/page_header.html */
.page-header-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    flex-shrink: 0;
    font-size: 1.3rem;
    color: #ffffff;
    background: rgba(255, 255, 255, 0.14);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: var(--radius-lg);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25),
                0 8px 20px rgba(0, 0, 0, 0.18);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}

@media (max-width: 575.98px) {
    .page-header-icon {
        width: 2.6rem;
        height: 2.6rem;
        font-size: 1.05rem;
        border-radius: var(--radius-md, 1rem);
    }
}

.page-header .header-icon {
    position: relative;
    z-index: 2;
}

/* Page Title Row (for pages without full header) */
.page-title-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.5rem;
    padding-bottom: 1rem;
    border-bottom: 2px solid var(--border-color);
}

.page-title-row h1,
.page-title-row .page-title {
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0;
    color: var(--text-color);
}

.page-title-row .page-subtitle {
    font-size: 0.95rem;
    color: var(--text-secondary);
    margin-top: 0.25rem;
}

.page-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
}

/* Gradient page header variant (more vibrant multi-color gradient) */
.page-header-gradient {
    background: linear-gradient(135deg,
        var(--vibrant-indigo) 0%,
        var(--vibrant-purple) 40%,
        color-mix(in srgb, var(--vibrant-blue) 80%, var(--vibrant-teal)) 100%);
    color: white;
    padding: 2rem 2.5rem;
    margin-bottom: 1.5rem;
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-xl),
                0 0 0 1px rgba(255, 255, 255, 0.1) inset,
                0 0 40px rgba(88, 86, 214, 0.3);
    position: relative;
    overflow: hidden;
}

.page-header-gradient::before {
    content: "";
    position: absolute;
    top: -30%;
    right: -15%;
    width: 50%;
    height: 150%;
    background: radial-gradient(ellipse at center,
        rgba(255, 255, 255, 0.2),
        rgba(255, 255, 255, 0.05) 50%,
        transparent 75%);
    pointer-events: none;
    animation: headerGlow 8s ease-in-out infinite;
}

.page-header-gradient::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg,
        var(--vibrant-pink),
        var(--vibrant-orange),
        var(--vibrant-yellow),
        var(--vibrant-green),
        var(--vibrant-blue),
        var(--vibrant-pink));
    background-size: 300% 100%;
    animation: gradientShift 6s linear infinite;
}

.page-header-gradient h1,
.page-header-gradient h2,
.page-header-gradient .page-title {
    color: #ffffff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35),
                 0 2px 12px rgba(0, 0, 0, 0.2);
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0;
    position: relative;
    z-index: 2;
    letter-spacing: -0.01em;
}

.page-header-gradient .page-subtitle {
    color: rgba(255, 255, 255, 0.95);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    font-size: 0.95rem;
    margin-top: 0.5rem;
    margin-bottom: 0;
    font-weight: 500;
    position: relative;
    z-index: 2;
}

/* Bottom accent line on regular page headers */
.page-header::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 2px;
    background: linear-gradient(90deg,
        transparent,
        rgba(255, 255, 255, 0.4),
        rgba(255, 255, 255, 0.6),
        rgba(255, 255, 255, 0.4),
        transparent);
    opacity: 0.6;
}

/* Footer - Modern Elevated Design */
/* ========================================
   FOOTER - Modern, Sexy Design
   ======================================== */
footer {
    background: linear-gradient(135deg,
        var(--primary-color) 0%,
        color-mix(in srgb, var(--primary-color) 85%, var(--secondary-color)) 50%,
        var(--secondary-color) 100%);
    color: white;
    padding: 4rem 0 2rem;
    /* margin-top: auto pins the footer to the bottom of body (a flex column
       with min-height: 100vh) regardless of whether .page-shell's flex-grow
       is honored — eliminating any phantom whitespace below the footer. */
    margin-top: auto;
    box-shadow:
        0 -8px 32px rgba(0, 0, 0, 0.15),
        0 -2px 8px rgba(0, 0, 0, 0.08);
    position: relative;
    overflow: hidden;
    flex-shrink: 0;
}

/* Animated gradient overlay */
footer::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: 
        radial-gradient(circle at 20% 80%, rgba(255, 255, 255, 0.05) 0%, transparent 50%),
        radial-gradient(circle at 80% 20%, rgba(255, 255, 255, 0.05) 0%, transparent 50%);
    pointer-events: none;
    animation: footerGlow 15s ease-in-out infinite;
}

@keyframes footerGlow {
    0%, 100% { opacity: 0.3; }
    50% { opacity: 0.6; }
}

/* Top accent line */
footer::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg,
        var(--vibrant-blue),
        var(--vibrant-purple),
        var(--vibrant-pink),
        var(--vibrant-orange),
        var(--vibrant-blue));
    background-size: 200% 100%;
    animation: gradientShift 8s linear infinite;
}

@keyframes gradientShift {
    0% { background-position: 0% 50%; }
    100% { background-position: 200% 50%; }
}

footer a {
    color: rgba(255, 255, 255, 0.9);
    text-decoration: none;
    transition: all 0.3s ease;
    position: relative;
}

footer a:hover {
    color: white;
    transform: translateX(2px);
}

/* Main footer content */
.footer-main {
    position: relative;
    z-index: 1;
    margin-bottom: 3rem;
}

/* Brand section */
.footer-brand-section {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.footer-logo-mark {
    width: 64px;
    height: 64px;
    border-radius: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow:
        0 6px 20px rgba(0, 0, 0, 0.25),
        0 0 0 3px rgba(255, 255, 255, 0.15),
        0 0 32px rgba(0, 122, 255, 0.3);
    animation: float 6s ease-in-out infinite;
    overflow: hidden;
}

.footer-logo-mark-img {
    width: 100%;
    height: 100%;
    display: block;
}

@keyframes float {
    0%, 100% { transform: translateY(0px); }
    50% { transform: translateY(-8px); }
}

.footer-brand-text {
    margin-top: 0.5rem;
}

.footer-title {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: 0.25rem;
    background: linear-gradient(135deg, white, rgba(255, 255, 255, 0.8));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.footer-subtitle {
    font-size: 0.9rem;
    opacity: 0.8;
    line-height: 1.4;
}

.footer-copyright {
    font-size: 0.85rem;
    opacity: 0.7;
    margin-top: 1rem;
}

/* Footer Ko-fi support button */
.footer-kofi-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.75rem;
    padding: 0.5rem 1.1rem;
    background-color: #29abe0;
    color: #fff !important;
    font-weight: 700;
    font-size: 0.9rem;
    border-radius: 2rem;
    text-decoration: none;
    box-shadow: 0 2px 6px var(--shadow-color);
    transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

.footer-kofi-btn:hover,
.footer-kofi-btn:focus {
    background-color: #1f93c4;
    color: #fff !important;
    transform: translateY(-1px);
    box-shadow: 0 4px 10px var(--shadow-color);
}

.footer-kofi-btn img {
    height: 1.3em;
    width: auto;
    /* Render the cup as a clean white monochrome mark so it stays visible
       on the Ko-fi blue button background (matches Ko-fi's own button style;
       the source kofi.svg uses the same blue for its strokes/saucer). */
    filter: brightness(0) invert(1);
}

/* Footer columns */
.footer-column {
    text-align: left;
}

.footer-column-title {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 1rem;
    opacity: 0.9;
    position: relative;
    padding-bottom: 0.5rem;
}

.footer-column-title::after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 36px;
    height: 2px;
    background: linear-gradient(90deg, var(--vibrant-teal), var(--vibrant-blue), transparent);
    opacity: 0.75;
    border-radius: 2px;
}

.footer-nav-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.footer-nav-list li {
    transition: transform 0.2s ease;
}

.footer-nav-list li:hover {
    transform: translateX(4px);
}

.footer-nav-list a {
    font-size: 0.9rem;
    display: flex;
    align-items: center;
    opacity: 0.85;
}

.footer-nav-list a i {
    font-size: 0.8rem;
    width: 20px;
    opacity: 0.7;
}

.footer-nav-list a:hover {
    opacity: 1;
}

.footer-nav-list a:hover i {
    opacity: 1;
}

/* Status widgets */
.footer-status-widget {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.footer-clock-widget,
.footer-version-widget,
.footer-health-widget {
    display: flex;
    align-items: center;
    font-size: 0.9rem;
    padding: 0.5rem 0.75rem;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.15);
    transition: all 0.3s ease;
}

.footer-clock-widget:hover,
.footer-version-widget:hover,
.footer-health-widget:hover {
    background: rgba(255, 255, 255, 0.15);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

/* Tech stack section */
.footer-tech-stack {
    position: relative;
    z-index: 1;
    margin-bottom: 2rem;
}

.footer-divider {
    height: 2px;
    background: linear-gradient(90deg,
        transparent 0%,
        var(--vibrant-blue) 20%,
        var(--vibrant-purple) 40%,
        var(--vibrant-pink) 60%,
        var(--vibrant-orange) 80%,
        transparent 100%);
    background-size: 200% 100%;
    animation: gradientShift 8s linear infinite;
    margin: 2rem 0;
    opacity: 0.6;
    border-radius: 2px;
}

.tech-stack-title {
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    text-align: center;
    margin-bottom: 1.5rem;
    opacity: 0.95;
    position: relative;
    display: inline-block;
    width: 100%;
}

.tech-stack-title i {
    color: var(--vibrant-teal);
    filter: drop-shadow(0 0 6px rgba(90, 200, 250, 0.5));
}

/* Glass card container for tech stack badges */
.tech-stack-card {
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: var(--radius-xl, 1.5rem);
    padding: 1.5rem 1.5rem 1.25rem;
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow:
        0 4px 24px rgba(0, 0, 0, 0.15),
        0 0 0 1px rgba(255, 255, 255, 0.08) inset;
    transition: box-shadow 0.3s ease;
}

.tech-stack-card:hover {
    box-shadow:
        0 8px 32px rgba(0, 0, 0, 0.2),
        0 0 0 1px rgba(255, 255, 255, 0.12) inset;
}

.tech-stack-badges {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 0.75rem;
}

.tech-badge {
    transition: transform 0.3s var(--ease-spring), filter 0.3s ease, box-shadow 0.3s ease;
    display: inline-block;
    border-radius: 6px;
}

.tech-badge:hover {
    transform: translateY(-5px) scale(1.08);
    filter: brightness(1.15) saturate(1.2);
}

.tech-badge img {
    height: var(--footer-badge-height, 26px);
    border-radius: 5px;
    box-shadow:
        0 2px 8px rgba(0, 0, 0, 0.25),
        0 0 0 1px rgba(255, 255, 255, 0.08);
    display: block;
}

/* Disclaimer section */
.footer-disclaimer-section {
    position: relative;
    z-index: 1;
}

.footer-disclaimer {
    font-size: 0.85rem;
    text-align: center;
    opacity: 0.85;
    padding: 1.5rem 2rem;
    background: rgba(255, 255, 255, 0.07);
    border-radius: var(--radius-xl, 1.5rem);
    border: 1px solid rgba(255, 255, 255, 0.12);
    backdrop-filter: blur(10px);
    max-width: 900px;
    margin: 0 auto;
    line-height: 1.6;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1) inset;
}

.footer-disclaimer i {
    color: var(--vibrant-yellow);
    font-size: 1rem;
}

.footer-disclaimer strong {
    color: rgba(255, 255, 255, 0.95);
}

/* Responsive adjustments */
@media (max-width: 991.98px) {
    footer {
        padding: 3rem 0 1.5rem;
    }

    .footer-main {
        margin-bottom: 2rem;
    }

    .footer-brand-section {
        text-align: center;
        align-items: center;
    }

    .footer-column {
        text-align: center;
    }

    .footer-column-title::after {
        left: 50%;
        transform: translateX(-50%);
    }

    .footer-nav-list {
        align-items: center;
    }

    .footer-nav-list li:hover {
        transform: translateX(0) scale(1.05);
    }
}

@media (max-width: 575.98px) {
    footer {
        padding: 2rem 0 1rem;
    }

    .footer-logo-mark {
        width: 50px;
        height: 50px;
        font-size: 1.5rem;
    }

    .footer-title {
        font-size: 1.25rem;
    }

    .tech-stack-badges {
        gap: 0.5rem;
    }

    :root {
        --footer-badge-height: 20px;
    }

    .footer-disclaimer {
        font-size: 0.75rem;
        padding: 1rem 1.5rem;
    }
}


/* 5. COMPONENTS (Cards, Buttons, Forms, Tables, etc.) */

/* iOS 26 Floating Island Cards */
.card {
    background: linear-gradient(
        180deg,
        var(--surface-color) 0%,
        color-mix(in srgb, var(--surface-color) 98%, var(--primary-color)) 100%
    );
    border: 1px solid color-mix(in srgb, var(--border-color) 50%, transparent);
    border-radius: var(--radius-2xl);
    box-shadow:
        0 4px 20px rgba(0, 0, 0, 0.08),
        0 8px 32px rgba(0, 0, 0, 0.04),
        0 0 0 1px rgba(255, 255, 255, 0.05) inset;
    margin-bottom: var(--spacing-6);
    transition: all 0.4s var(--ease-spring);
    overflow: hidden;
    position: relative;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    color: var(--text-color);
}

/* Gradient accent line at top */
.card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg,
        var(--vibrant-blue),
        var(--vibrant-purple),
        var(--vibrant-pink),
        var(--vibrant-orange));
    opacity: 0;
    transition: opacity 0.4s var(--ease-spring);
}

/* Animated glow effect */
.card::after {
    content: "";
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: radial-gradient(
        circle at center,
        color-mix(in srgb, var(--vibrant-blue) 5%, transparent) 0%,
        transparent 50%
    );
    opacity: 0;
    transition: opacity 0.6s var(--ease-ios);
    pointer-events: none;
    z-index: 0;
}

.card:hover {
    transform: translateY(-8px) scale(1.01);
    box-shadow:
        0 12px 40px rgba(0, 0, 0, 0.12),
        0 20px 60px color-mix(in srgb, var(--vibrant-blue) 10%, transparent),
        0 0 0 1px rgba(255, 255, 255, 0.1) inset;
    border-color: color-mix(in srgb, var(--vibrant-blue) 30%, transparent);
}

.card:hover::before {
    opacity: 1;
}

.card:hover::after {
    opacity: 1;
}

/* Dropdown menus opened inside a card
   ------------------------------------------------------------------------
   `.card` sets `overflow: hidden` so the ::before accent line, the ::after
   glow and any card media stay inside the rounded corners.  That rule also
   clips every absolutely-positioned descendant that leaves the card box — and
   a Bootstrap dropdown menu is exactly that.  On the Received Alerts filter
   panel the Audio Source / Event Type menus were sliced off at the card's
   bottom edge, leaving barely one option reachable.

   While a menu is open, stop clipping and lift the card above the cards that
   follow it.  The lift is required, not cosmetic: `backdrop-filter` makes each
   `.card` its own stacking context, and equal-`z-index` stacking contexts
   paint in document order, so the next card down the page would paint over an
   un-clipped menu.  Kept well below the navbar/modal/toast layers.

   `:has()` does the work in current browsers; `.has-open-dropdown` is applied
   from Bootstrap's show/hide events in static/js/core/utils.js so the fix also
   holds where `:has()` is unsupported. */
.card:has(.dropdown-menu.show),
.card.has-open-dropdown {
    overflow: visible;
    z-index: 3;
}

/* Both card decorations exist only because the card crops them, so they have
   to sit out the moment it stops cropping. The ::after glow is sized 200% and
   offset -50% — unclipped it bleeds across neighbouring content. The ::before
   accent line is a 3px strip that the card's 24px corner arc trims at each
   end; it cannot round itself to match, because border-radius on a 3px-tall
   box is scaled down to a 3px radius and the ends would poke out past the
   corner as coloured nubs. Both are hover-only flourishes at `opacity: 0`
   otherwise, so holding them at 0 costs nothing visible. */
.card:has(.dropdown-menu.show)::before,
.card:has(.dropdown-menu.show)::after,
.card.has-open-dropdown::before,
.card.has-open-dropdown::after {
    opacity: 0;
}

.card-header {
    background: linear-gradient(135deg,
        var(--vibrant-blue) 0%,
        var(--vibrant-indigo) 50%,
        var(--vibrant-purple) 100%);
    color: white;
    border-bottom: none;
    padding: 1.25rem 1.75rem;
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-base);
    letter-spacing: 0.015em;
    position: relative;
    overflow: hidden;
    z-index: 1;
}

/* Shimmer effect on card header — softened so it doesn't desaturate
   light/dark header variants when sweeping past their right edge. */
.card-header::before {
    content: "";
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(
        90deg,
        transparent,
        rgba(255, 255, 255, 0.06),
        transparent
    );
    animation: cardHeaderShimmer 3s ease-in-out infinite;
}

@keyframes cardHeaderShimmer {
    0%, 100% { left: -100%; }
    50% { left: 100%; }
}

.card-header::after {
    content: "";
    position: absolute;
    top: -50%;
    right: -30%;
    width: 120%;
    height: 200%;
    background: radial-gradient(ellipse at top right,
        rgba(255, 255, 255, 0.08),
        rgba(255, 255, 255, 0.03) 40%,
        transparent 70%);
    pointer-events: none;
}

/* Suppress the white radial halo and shimmer on .bg-light / .bg-dark header
   variants. On bg-light surfaces the halo bleached the right half of the
   header to near-white (visible most acutely on the lightning theme over
   pale-yellow --light-color); on bg-dark surfaces the halo created a stark
   light corner that broke the deep navy gradient. The colored bg-primary /
   bg-info / bg-success / etc. variants keep the subtle shimmer for visual
   interest. */
.card-header.bg-light::before,
.card-header.bg-light::after,
.card-header.bg-dark::before,
.card-header.bg-dark::after {
    display: none;
}

/* Override bg-* classes on card-header to use gradients */
.card-header.bg-primary {
    background: linear-gradient(120deg, var(--primary-color), var(--secondary-color)) !important;
    color: white !important;
}

.card-header.bg-success {
    background: linear-gradient(120deg, var(--success-color), color-mix(in srgb, var(--success-color) 80%, var(--info-color))) !important;
    color: white !important;
}

.card-header.bg-warning {
    background: linear-gradient(120deg, var(--warning-color), color-mix(in srgb, var(--warning-color) 80%, var(--secondary-color))) !important;
    color: #1a1a1a !important;
}

.card-header.bg-danger {
    background: linear-gradient(120deg, var(--danger-color), color-mix(in srgb, var(--danger-color) 80%, var(--secondary-color))) !important;
    color: white !important;
}

.card-header.bg-info {
    background: linear-gradient(120deg, var(--info-color), color-mix(in srgb, var(--info-color) 80%, var(--primary-color))) !important;
    color: white !important;
}

.card-header.bg-secondary {
    background: linear-gradient(120deg, var(--secondary-color), color-mix(in srgb, var(--secondary-color) 80%, var(--primary-color))) !important;
    color: white !important;
}

.card-header.bg-light {
    background: linear-gradient(120deg, var(--light-color), color-mix(in srgb, var(--light-color) 90%, var(--surface-color))) !important;
    color: #1a1a1a !important;
}

.card-header.bg-dark {
    background: linear-gradient(120deg, var(--dark-color), color-mix(in srgb, var(--dark-color) 90%, var(--primary-color))) !important;
    color: white !important;
}

.card-body {
    background-color: var(--surface-color);
    color: var(--text-color);
    padding: 1.25rem;
}

.card-footer {
    background-color: var(--surface-color);
    color: var(--text-color);
    border-top: 1px solid var(--border-color);
    padding: 0.75rem 1.25rem;
}

/* iOS 26 Glassmorphism - Frosted Glass Effect */
.card.glass-effect,
.glass-panel,
.glass {
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--surface-color) 85%, transparent) 0%,
        color-mix(in srgb, var(--surface-color) 70%, transparent) 100%
    );
    backdrop-filter: blur(var(--glass-blur-heavy)) saturate(var(--glass-saturation));
    -webkit-backdrop-filter: blur(var(--glass-blur-heavy)) saturate(var(--glass-saturation));
    border: 1px solid rgba(255, 255, 255, 0.2);
    box-shadow:
        0 8px 32px rgba(0, 0, 0, 0.12),
        0 0 0 1px rgba(255, 255, 255, 0.1) inset,
        0 -1px 0 rgba(255, 255, 255, 0.15) inset;
}

/* Glass variants */
.glass-light {
    background: rgba(255, 255, 255, 0.65);
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
    border: 1px solid rgba(255, 255, 255, 0.3);
}

.glass-dark {
    background: rgba(0, 0, 0, 0.4);
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.glass-vibrant {
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--vibrant-blue) 15%, transparent) 0%,
        color-mix(in srgb, var(--vibrant-purple) 15%, transparent) 50%,
        color-mix(in srgb, var(--vibrant-pink) 15%, transparent) 100%
    );
    backdrop-filter: blur(var(--glass-blur-heavy)) saturate(200%);
    -webkit-backdrop-filter: blur(var(--glass-blur-heavy)) saturate(200%);
    border: 1px solid rgba(255, 255, 255, 0.25);
}

/* iOS 26 Stat Cards - Vibrant Mesh Gradient Style */
.stat-card,
.card-stat-gradient {
    background: linear-gradient(135deg,
        var(--vibrant-blue) 0%,
        var(--vibrant-indigo) 35%,
        var(--vibrant-purple) 65%,
        var(--vibrant-pink) 100%);
    color: white;
    padding: 1.75rem;
    border-radius: var(--radius-2xl);
    text-align: center;
    border: none;
    box-shadow:
        0 8px 32px color-mix(in srgb, var(--vibrant-blue) 25%, transparent),
        0 4px 12px rgba(0, 0, 0, 0.1),
        0 0 0 1px rgba(255, 255, 255, 0.15) inset;
    transition: all 0.4s var(--ease-spring);
    position: relative;
    overflow: hidden;
}

/* Animated gradient shimmer */
.stat-card::before,
.card-stat-gradient::before {
    content: "";
    position: absolute;
    top: 0;
    left: -100%;
    width: 200%;
    height: 100%;
    background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.1) 25%,
        rgba(255, 255, 255, 0.3) 50%,
        rgba(255, 255, 255, 0.1) 75%,
        transparent 100%
    );
    animation: statShimmer 3s ease-in-out infinite;
    pointer-events: none;
}

@keyframes statShimmer {
    0% { left: -100%; }
    100% { left: 100%; }
}

/* Glow orb effect */
.stat-card::after,
.card-stat-gradient::after {
    content: "";
    position: absolute;
    top: -50%;
    right: -30%;
    width: 120%;
    height: 150%;
    background: radial-gradient(circle,
        rgba(255, 255, 255, 0.2) 0%,
        transparent 60%);
    pointer-events: none;
    transition: all 0.6s var(--ease-ios);
}

.stat-card:hover,
.card-stat-gradient:hover {
    transform: translateY(-8px) scale(1.02) rotateX(2deg);
    box-shadow:
        0 20px 50px color-mix(in srgb, var(--vibrant-purple) 35%, transparent),
        0 8px 20px rgba(0, 0, 0, 0.15),
        0 0 0 1px rgba(255, 255, 255, 0.2) inset;
}

.stat-card:hover::after,
.card-stat-gradient:hover::after {
    transform: scale(1.2) translate(-10%, 10%);
}

/* Vibrant gradient variants for stat cards */
.stat-card-success,
.card.bg-success-gradient {
    background: linear-gradient(135deg,
        var(--vibrant-green) 0%,
        var(--vibrant-mint) 50%,
        var(--vibrant-teal) 100%) !important;
    box-shadow:
        0 8px 32px color-mix(in srgb, var(--vibrant-green) 30%, transparent),
        0 4px 12px rgba(0, 0, 0, 0.1),
        0 0 0 1px rgba(255, 255, 255, 0.15) inset;
    color: white;
}

.stat-card-warning,
.card.bg-warning-gradient {
    background: linear-gradient(135deg,
        var(--vibrant-orange) 0%,
        var(--vibrant-yellow) 50%,
        #FFD60A 100%) !important;
    box-shadow:
        0 8px 32px color-mix(in srgb, var(--vibrant-orange) 30%, transparent),
        0 4px 12px rgba(0, 0, 0, 0.1),
        0 0 0 1px rgba(255, 255, 255, 0.15) inset;
    color: #1a1a1a !important;
}

/* Ensure warning gradient text is always dark for readability */
.stat-card-warning *,
.card.bg-warning-gradient *,
.stat-card-warning.text-white,
.card.bg-warning-gradient.text-white,
.stat-card-warning .text-white,
.card.bg-warning-gradient .text-white {
    color: #1a1a1a !important;
}

.stat-card-danger,
.card.bg-danger-gradient {
    background: linear-gradient(135deg,
        var(--vibrant-red) 0%,
        #FF6B6B 50%,
        var(--vibrant-pink) 100%) !important;
    box-shadow:
        0 8px 32px color-mix(in srgb, var(--vibrant-red) 30%, transparent),
        0 4px 12px rgba(0, 0, 0, 0.1),
        0 0 0 1px rgba(255, 255, 255, 0.15) inset;
    color: white;
}

.stat-card-info,
.card.bg-info-gradient {
    background: linear-gradient(135deg,
        var(--vibrant-teal) 0%,
        var(--vibrant-blue) 50%,
        var(--vibrant-indigo) 100%) !important;
    box-shadow:
        0 8px 32px color-mix(in srgb, var(--vibrant-teal) 30%, transparent),
        0 4px 12px rgba(0, 0, 0, 0.1),
        0 0 0 1px rgba(255, 255, 255, 0.15) inset;
    color: white;
}

.stat-card-purple,
.card.bg-purple-gradient {
    background: linear-gradient(135deg,
        var(--vibrant-purple) 0%,
        var(--vibrant-indigo) 50%,
        var(--vibrant-blue) 100%) !important;
    box-shadow:
        0 8px 32px color-mix(in srgb, var(--vibrant-purple) 30%, transparent),
        0 4px 12px rgba(0, 0, 0, 0.1),
        0 0 0 1px rgba(255, 255, 255, 0.15) inset;
    color: white;
}

/* iOS 26 Button System - Vibrant & Tactile */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.875rem 1.75rem;
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-sm);
    text-align: center;
    line-height: 1.4;
    border-radius: var(--radius-xl);
    border: none;
    cursor: pointer;
    transition: all 0.3s var(--ease-spring);
    text-decoration: none;
    white-space: nowrap;
    position: relative;
    overflow: hidden;
    letter-spacing: 0.02em;
    transform-style: preserve-3d;
    backface-visibility: hidden;
}

/* Shimmer effect on hover */
.btn::before {
    content: "";
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(
        90deg,
        transparent,
        rgba(255, 255, 255, 0.3),
        transparent
    );
    transition: left 0.5s var(--ease-ios);
}

.btn:hover::before {
    left: 100%;
}

/* Ripple effect on click */
.btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.4);
    transform: translate(-50%, -50%);
    transition: width 0.4s var(--ease-spring), height 0.4s var(--ease-spring), opacity 0.4s;
    opacity: 0;
}

.btn:active::after {
    width: 200px;
    height: 200px;
    opacity: 0;
    transition: width 0s, height 0s, opacity 0.4s;
}

.btn-primary {
    background: linear-gradient(135deg,
        var(--vibrant-blue) 0%,
        var(--vibrant-indigo) 50%,
        var(--vibrant-purple) 100%);
    color: white;
    box-shadow:
        0 4px 15px color-mix(in srgb, var(--vibrant-blue) 40%, transparent),
        0 2px 4px rgba(0, 0, 0, 0.1),
        0 1px 0 rgba(255, 255, 255, 0.2) inset;
}

.btn-primary:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow:
        0 8px 25px color-mix(in srgb, var(--vibrant-blue) 50%, transparent),
        0 4px 8px rgba(0, 0, 0, 0.15),
        0 1px 0 rgba(255, 255, 255, 0.3) inset;
    filter: brightness(1.05);
}

.btn-primary:active {
    transform: translateY(-1px) scale(0.98);
    box-shadow:
        0 2px 8px color-mix(in srgb, var(--vibrant-blue) 30%, transparent),
        0 1px 2px rgba(0, 0, 0, 0.1);
    filter: brightness(0.95);
}

.btn-secondary {
    background: linear-gradient(135deg,
        var(--vibrant-purple) 0%,
        var(--vibrant-pink) 100%);
    color: white;
    box-shadow: 0 4px 15px color-mix(in srgb, var(--vibrant-purple) 40%, transparent);
}

.btn-secondary:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 8px 25px color-mix(in srgb, var(--vibrant-purple) 50%, transparent);
    filter: brightness(1.05);
}

.btn-success {
    background: linear-gradient(135deg,
        var(--vibrant-green) 0%,
        var(--vibrant-mint) 100%);
    color: white;
    box-shadow: 0 4px 15px color-mix(in srgb, var(--vibrant-green) 40%, transparent);
}

.btn-success:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 8px 25px color-mix(in srgb, var(--vibrant-green) 50%, transparent);
    filter: brightness(1.05);
}

.btn-danger {
    background: linear-gradient(135deg,
        var(--vibrant-red) 0%,
        var(--vibrant-pink) 100%);
    color: white;
    box-shadow: 0 4px 15px color-mix(in srgb, var(--vibrant-red) 40%, transparent);
}

.btn-danger:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 8px 25px color-mix(in srgb, var(--vibrant-red) 50%, transparent);
    filter: brightness(1.05);
}

.btn-warning {
    background: linear-gradient(135deg,
        var(--vibrant-orange) 0%,
        var(--vibrant-yellow) 100%);
    color: #1a1a1a;
    box-shadow: 0 4px 15px color-mix(in srgb, var(--vibrant-orange) 40%, transparent);
}

.btn-warning:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 8px 25px color-mix(in srgb, var(--vibrant-orange) 50%, transparent);
    filter: brightness(1.05);
}

.btn-info {
    background: linear-gradient(135deg,
        var(--vibrant-teal) 0%,
        var(--vibrant-blue) 100%);
    color: white;
    box-shadow: 0 4px 15px color-mix(in srgb, var(--vibrant-teal) 40%, transparent);
}

.btn-info:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 8px 25px color-mix(in srgb, var(--vibrant-teal) 50%, transparent);
    filter: brightness(1.05);
}

.btn-light {
    background: linear-gradient(135deg,
        rgba(255, 255, 255, 0.9) 0%,
        rgba(245, 245, 247, 0.95) 100%);
    color: #1a1a1a;
    border: 1px solid rgba(0, 0, 0, 0.08);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.btn-light:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
    background: linear-gradient(135deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(250, 250, 252, 1) 100%);
    color: #1a1a1a;
}

.btn-dark {
    background: linear-gradient(135deg,
        #1a1a1a 0%,
        #2d2d2d 100%);
    color: white;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
}

.btn-dark:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
    filter: brightness(1.1);
}

/* Pill-shaped button variant */
.btn-pill {
    border-radius: var(--radius-pill) !important;
    padding: 0.875rem 2rem;
}

/* Outline button variants with glass effect */
.btn-outline-primary {
    background: transparent;
    border: 2px solid var(--vibrant-blue);
    color: var(--vibrant-blue);
    box-shadow: none;
}

.btn-outline-primary:hover {
    background: var(--vibrant-blue);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--vibrant-blue) 40%, transparent);
}

.btn-outline-secondary {
    background: transparent;
    border: 2px solid var(--secondary-color);
    color: var(--secondary-color);
    box-shadow: none;
}

.btn-outline-secondary:hover {
    background: var(--secondary-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--secondary-color) 40%, transparent);
}

.btn-outline-success {
    background: transparent;
    border: 2px solid var(--success-color);
    color: var(--success-color);
    box-shadow: none;
}

.btn-outline-success:hover {
    background: var(--success-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--success-color) 40%, transparent);
}

.btn-outline-danger {
    background: transparent;
    border: 2px solid var(--danger-color);
    color: var(--danger-color);
    box-shadow: none;
}

.btn-outline-danger:hover {
    background: var(--danger-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--danger-color) 40%, transparent);
}

.btn-outline-warning {
    background: transparent;
    border: 2px solid var(--warning-color);
    color: var(--warning-color);
    box-shadow: none;
}

.btn-outline-warning:hover {
    background: var(--warning-color);
    color: #1a1a1a;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--warning-color) 40%, transparent);
}

.btn-outline-info {
    background: transparent;
    border: 2px solid var(--info-color);
    color: var(--info-color);
    box-shadow: none;
}

.btn-outline-info:hover {
    background: var(--info-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--info-color) 40%, transparent);
}

.btn-outline-light {
    background: transparent;
    border: 2px solid var(--light-color);
    color: var(--text-color);
    box-shadow: none;
}

.btn-outline-light:hover {
    background: var(--light-color);
    color: #1a1a1a;
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

.btn-outline-dark {
    background: transparent;
    border: 2px solid var(--dark-color);
    color: var(--text-color);
    box-shadow: none;
}

.btn-outline-dark:hover {
    background: var(--dark-color);
    color: white;
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
}

/* Button Liquid Effect */
.btn-liquid {
    position: relative;
    overflow: hidden;
    z-index: 1;
}

.btn-liquid::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.4), transparent 70%);
    transform: translate(-50%, -50%);
    transition: width 0.8s ease, height 0.8s ease;
    z-index: -1;
}

.btn-liquid:hover::before {
    width: 300px;
    height: 300px;
}

/* Forms - Modern Elegant Inputs */
.form-control,
.form-select,
textarea,
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="search"],
input[type="tel"],
input[type="url"] {
    background-color: var(--surface-color);
    color: var(--text-color);
    border: 2px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 0.75rem 1.25rem;
    font-size: var(--font-size-base);
    transition: all var(--ease-fluid);
    width: 100%;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.form-control:focus,
.form-select:focus,
textarea:focus {
    background-color: var(--surface-color);
    color: var(--text-color);
    border-color: var(--primary-color);
    outline: none;
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary-color) 12%, transparent),
                0 4px 12px rgba(0, 0, 0, 0.08);
    transform: translateY(-1px);
}

.form-control::placeholder {
    color: var(--text-muted);
    opacity: 0.7;
}

.form-label {
    color: var(--text-color);
    font-weight: var(--font-weight-medium);
    margin-bottom: 0.5rem;
    display: block;
}

/* Form Checks and Switches */
.form-check-label {
    color: var(--text-color);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.form-check-input {
    background-color: var(--surface-color);
    border: 2px solid var(--border-color);
    cursor: pointer;
}

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

.form-check-input:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 0.25rem var(--shadow-color);
}

.form-switch .form-check-input {
    /* Fixed grey track, not var(--text-muted) -- the knob above is a fixed
       white SVG circle, and paired with that fixed white, --text-muted's
       track measured under 3:1 (UI-component contrast, not text) in 7 of
       the 20 themes -- as low as 1.33:1 in Lightning, which made every
       *unchecked* switch app-wide (not just this one page) look identical
       to its own track, i.e. no visible knob at all. #495057 (8.2:1 with
       white, the same fixed grey already used elsewhere tonight for this
       exact failure mode) works in every theme. */
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
    background-color: #495057;
    border: 2px solid var(--border-color);
}

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

/* Tables - Modern Clean Design */
.table {
    width: 100%;
    color: var(--text-color);
    border-collapse: separate;
    border-spacing: 0;
    border-radius: var(--radius-lg);
    overflow: hidden;
}

/* Colour (background + text) is owned by the "TABLE READABILITY FIXES"
   rule further down this file — this rule sets layout/typography only.
   Do NOT reintroduce a `background:` gradient here: `background` is a
   shorthand that sets background-image, and the readability rule below
   only sets `background-color`, which cannot override an image. A
   gradient here therefore paints *over* the readable tint and leaves
   dark text on a dark gradient. */
.table thead th {
    padding: 1rem 1.25rem;
    font-weight: var(--font-weight-semibold);
    text-align: left;
    border-bottom: 2px solid var(--border-color);
    letter-spacing: 0.015em;
}

.table thead th:first-child {
    border-top-left-radius: var(--radius-lg);
}

.table thead th:last-child {
    border-top-right-radius: var(--radius-lg);
}

.table tbody td {
    color: var(--text-color);
    background: var(--surface-color);
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--border-color);
    transition: all var(--ease-fluid);
}

.table tbody tr:hover {
    background: color-mix(in srgb, var(--primary-color) 8%, var(--surface-color));
    transform: scale(1.001);
}

.table tbody tr:hover td {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.table-striped tbody tr:nth-of-type(odd) {
    background-color: color-mix(in srgb, var(--surface-color) 97%, var(--border-color));
}

/* Badges - Modern Pill Design */
.badge {
    display: inline-block;
    padding: 0.45em 0.95em;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    line-height: 1;
    color: white;
    text-align: center;
    white-space: nowrap;
    vertical-align: baseline;
    border-radius: 999px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    letter-spacing: 0.01em;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1) inset;
    transition: all var(--ease-fluid);
}

.badge.bg-primary {
    background-color: var(--primary-color);
}

.badge.bg-secondary {
    background-color: var(--secondary-color);
}

.badge.bg-success {
    background-color: var(--success-color);
}

.badge.bg-danger {
    background-color: var(--danger-color);
}

.badge.bg-warning {
    background-color: var(--warning-color);
    color: #1a1a1a;
    text-shadow: none;
}

.badge.bg-info {
    background-color: var(--info-color);
}

/* Alerts */
.alert {
    padding: 1rem 1.25rem;
    margin-bottom: 1rem;
    border-radius: var(--radius-md);
    border-width: 1px;
    border-style: solid;
    border-left-width: 4px;
    color: var(--text-color);
}

.alert-success {
    background-color: color-mix(in srgb, var(--success-color) 20%, var(--surface-color));
    border-color: var(--success-color);
}

.alert-danger {
    background-color: color-mix(in srgb, var(--danger-color) 20%, var(--surface-color));
    border-color: var(--danger-color);
}

.alert-warning {
    background-color: color-mix(in srgb, var(--warning-color) 20%, var(--surface-color));
    border-color: var(--warning-color);
}

.alert-info {
    background-color: color-mix(in srgb, var(--info-color) 20%, var(--surface-color));
    border-color: var(--info-color);
}

/* Modals - Modern Elevated Design */
.modal-content {
    background-color: var(--surface-color);
    color: var(--text-color);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-2xl),
                0 0 0 1px rgba(255, 255, 255, 0.05) inset;
    backdrop-filter: blur(24px);
}

.modal-header {
    background-color: var(--surface-color);
    color: var(--text-color);
    border-bottom: 1px solid var(--border-color);
    padding: 1rem 1.5rem;
}

.modal-body {
    color: var(--text-color);
    padding: 1.5rem;
}

.modal-footer {
    background-color: var(--surface-color);
    border-top: 1px solid var(--border-color);
    padding: 1rem 1.5rem;
}

.modal-title {
    color: var(--text-color);
    font-weight: var(--font-weight-bold);
}

/* ------------------------------------------------------------------
   Touch-device modal scrolling fixes
   ------------------------------------------------------------------
   Symptom: on iPad/iPhone (and Chrome on those devices, which is also
   WebKit) long modals — e.g. the Add/Edit Audio Source "stream" form —
   could not be scrolled; dragging scrolled the PAGE behind the modal
   instead, leaving the footer Save button unreachable. Three independent
   WebKit behaviours conspire here, so we defend against all three. */

/* 1. Scrollable modals (`.modal-dialog-scrollable`) make `.modal-content` an
      `overflow: hidden` container clipping the scrolling `.modal-body`. WebKit
      silently disables scrolling inside an `overflow: auto` descendant of a
      `backdrop-filter`ed `overflow: hidden` ancestor, so the global glass blur
      on `.modal-content` killed the body's scroll. The panel background is
      already a solid surface colour, so dropping the blur costs nothing. */
.modal-dialog-scrollable .modal-content {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* 2. Keep touch momentum scrolling inside the modal body and stop the scroll
      from chaining to the page behind it (the "background scrolls, not the
      popup" symptom). */
.modal-body {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}

/* 3. Lock the background scroll while a modal is open. Bootstrap's `.modal-open`
      only sets `overflow: hidden` on <body>, but on this layout the document
      scroller is <html> (body is a min-height:100vh flex column), so the page
      behind stays scrollable on iOS. `:has()` is supported on the modern
      iPadOS/iOS Safari and Chromium this targets. */
html:has(.modal.show) {
    overflow: hidden;
}

/* 4. Modals that wrap .modal-header/.modal-body/.modal-footer in a <form> so
      one submit handler can collect every field (Add/Edit Audio Source,
      Radio Receiver, Stream Profile, etc.) break the flex chain Bootstrap's
      scrollable modal depends on: .modal-body's `flex: 1 1 auto` only does
      anything when .modal-body is a direct child of the flex container
      .modal-content. A plain <form> in between is not a flex container, so
      .modal-body never gets a bounded height, `overflow-y: auto` has
      nothing to do, and .modal-content's own `overflow: hidden` just clips
      the tail of the form instead of scrolling it -- the symptom reported
      as "this page isn't scrollable" on the Edit Audio Source modal. Make
      the form itself a flex column filling .modal-content's bounded height
      so the header/body/footer children behave exactly as if there were no
      form wrapper at all. */
.modal-dialog-scrollable .modal-content > form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

/* Dropdowns - Modern Glass Effect */
.dropdown-menu {
    background-color: color-mix(in srgb, var(--surface-color) 96%, transparent);
    border: 1px solid color-mix(in srgb, var(--border-color) 70%, transparent);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-xl),
                0 0 0 1px rgba(255, 255, 255, 0.05) inset;
    backdrop-filter: blur(28px) saturate(200%);
    -webkit-backdrop-filter: blur(28px) saturate(200%);
    padding: 0.5rem;
}

/* Navbar dropdown menus - match navbar transparency */
.navbar .dropdown-menu {
    background-color: color-mix(in srgb, var(--surface-color) 92%, transparent);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    margin-top: 0.5rem;
}

/* Scrollable dropdown for long menus. Applied automatically by
   templates/components/navbar.html to any section with >10 items. */
.navbar .dropdown-menu-scrollable {
    max-height: 80vh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.dropdown-header {
    color: var(--text-secondary);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    font-size: 0.75rem;
    letter-spacing: 0.05em;
}

.dropdown-item {
    color: var(--text-color);
    padding: 0.625rem 1.25rem;
    border-radius: var(--radius-lg);
    transition: all var(--ease-fluid);
    margin-bottom: 0.25rem;
}

.dropdown-item:hover,
.dropdown-item:focus {
    background-color: color-mix(in srgb, var(--primary-color) 12%, var(--surface-color));
    color: var(--text-color);
    transform: translateX(4px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

/* List Groups */
.list-group-item {
    background-color: var(--surface-color);
    color: var(--text-color);
    border: 1px solid var(--border-color);
    padding: 0.75rem 1.25rem;
}

.list-group-item:hover {
    background-color: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));
}


/* 6. UTILITIES (Spacing, Text, Display, etc.) */

/* Spacing Utilities */
.m-0 { margin: 0; }
.m-1 { margin: var(--spacing-xs); }
.m-2 { margin: var(--spacing-sm); }
.m-3 { margin: var(--spacing-md); }
.m-4 { margin: var(--spacing-lg); }
.m-5 { margin: var(--spacing-xl); }

.mt-0 { margin-top: 0; }
.mt-1 { margin-top: var(--spacing-xs); }
.mt-2 { margin-top: var(--spacing-sm); }
.mt-3 { margin-top: var(--spacing-md); }
.mt-4 { margin-top: var(--spacing-lg); }
.mt-5 { margin-top: var(--spacing-xl); }

.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: var(--spacing-xs); }
.mb-2 { margin-bottom: var(--spacing-sm); }
.mb-3 { margin-bottom: var(--spacing-md); }
.mb-4 { margin-bottom: var(--spacing-lg); }
.mb-5 { margin-bottom: var(--spacing-xl); }

.p-0 { padding: 0; }
.p-1 { padding: var(--spacing-xs); }
.p-2 { padding: var(--spacing-sm); }
.p-3 { padding: var(--spacing-md); }
.p-4 { padding: var(--spacing-lg); }
.p-5 { padding: var(--spacing-xl); }

/* Text Utilities */
.text-left { text-align: left; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-justify { text-align: justify; }

.text-uppercase { text-transform: uppercase; }
.text-lowercase { text-transform: lowercase; }
.text-capitalize { text-transform: capitalize; }

.font-weight-light { font-weight: 300; }
.font-weight-normal { font-weight: var(--font-weight-normal); }
.font-weight-medium { font-weight: var(--font-weight-medium); }
.font-weight-semibold { font-weight: var(--font-weight-semibold); }
.font-weight-bold { font-weight: var(--font-weight-bold); }

/* Display Utilities */
.d-none { display: none; }
.d-block { display: block; }
.d-inline { display: inline; }
.d-inline-block { display: inline-block; }
.d-flex { display: flex; }
.d-inline-flex { display: inline-flex; }
.d-grid { display: grid; }

/* Flexbox Utilities */
.flex-row { flex-direction: row; }
.flex-column { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.flex-nowrap { flex-wrap: nowrap; }

.justify-content-start { justify-content: flex-start; }
.justify-content-end { justify-content: flex-end; }
.justify-content-center { justify-content: center; }
.justify-content-between { justify-content: space-between; }
.justify-content-around { justify-content: space-around; }

.align-items-start { align-items: flex-start; }
.align-items-end { align-items: flex-end; }
.align-items-center { align-items: center; }
.align-items-baseline { align-items: baseline; }
.align-items-stretch { align-items: stretch; }

/* Admin action buttons (Admin Operations, System Upgrade, etc.): a shared
   minimum width so a row of buttons with different label lengths lines up
   instead of each hugging its own text. Promoted here after two pages
   defined it identically (tests/test_frontend_consistency.py catches new
   cross-page duplicates like that). */
.action-btn { min-width: 150px; }

/* Color Utilities.
   These paint *text*, so they use the readable `--*-ink` variants rather than
   the vivid `--*-color` fills — see "SEMANTIC TEXT INK" above. The `.bg-*`
   utilities below keep using `--*-color`, since there the colour is the
   background and white/near-black text sits on top of it. */
.text-primary { color: var(--primary-ink) !important; }
.text-secondary { color: var(--text-secondary) !important; }
.text-success { color: var(--success-ink) !important; }
.text-danger { color: var(--danger-ink) !important; }
.text-warning { color: var(--warning-ink) !important; }
.text-info { color: var(--info-ink) !important; }
.text-muted { color: var(--text-muted) !important; }

.bg-primary { background-color: var(--primary-color) !important; color: white; }
.bg-secondary { background-color: var(--secondary-color) !important; color: white; }
.bg-success { background-color: var(--success-color) !important; color: white; }
.bg-danger { background-color: var(--danger-color) !important; color: white; }
.bg-warning { background-color: var(--warning-color) !important; color: #1a1a1a !important; }
.bg-info { background-color: var(--info-color) !important; color: white; }
.bg-light { background-color: var(--light-color) !important; color: #1a1a1a !important; }
.bg-dark { background-color: var(--dark-color) !important; color: white; }

/* Bootstrap 5.3 text-bg-* utilities with proper contrast */
.text-bg-primary { background-color: var(--primary-color) !important; color: white !important; }
.text-bg-secondary { background-color: var(--secondary-color) !important; color: white !important; }
.text-bg-success { background-color: var(--success-color) !important; color: white !important; }
.text-bg-danger { background-color: var(--danger-color) !important; color: white !important; }
.text-bg-warning { background-color: var(--warning-color) !important; color: #1a1a1a !important; }
.text-bg-info { background-color: var(--info-color) !important; color: white !important; }
.text-bg-light { background-color: var(--light-color) !important; color: #1a1a1a !important; }
.text-bg-dark { background-color: var(--dark-color) !important; color: white !important; }

/* Section Headers - Modern Unified Design */
.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1.75rem;
    padding: 1.25rem 1.5rem;
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--primary-color) 12%, var(--surface-color)),
        color-mix(in srgb, var(--secondary-color) 10%, var(--surface-color)));
    border-radius: var(--radius-xl);
    border-left: 5px solid var(--primary-color);
    box-shadow: var(--shadow-sm);
    transition: all var(--ease-fluid);
}

.section-header:hover {
    box-shadow: var(--shadow-md);
    transform: translateX(2px);
}

.section-header h2,
.section-header h3,
.section-header .section-title {
    font-size: 1.25rem;
    font-weight: 600;
    margin: 0;
    color: var(--text-color);
}

.section-header .section-subtitle {
    font-size: 0.875rem;
    color: var(--text-secondary);
    margin-top: 0.25rem;
}

.section-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

/* Content Grid - Standard Layout */
.content-grid {
    display: grid;
    gap: 1.5rem;
}

.content-grid-2 {
    grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
}

.content-grid-3 {
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.content-grid-4 {
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

/* Info Boxes - Unified Design */
.info-box {
    padding: 1rem 1.25rem;
    border-radius: var(--radius-md);
    border-left: 4px solid var(--info-color);
    background: color-mix(in srgb, var(--info-color) 8%, var(--surface-color));
    color: var(--text-color);
    margin-bottom: 1rem;
}

.info-box.success {
    border-left-color: var(--success-color);
    background: color-mix(in srgb, var(--success-color) 8%, var(--surface-color));
}

.info-box.warning {
    border-left-color: var(--warning-color);
    background: color-mix(in srgb, var(--warning-color) 8%, var(--surface-color));
}

.info-box.danger {
    border-left-color: var(--danger-color);
    background: color-mix(in srgb, var(--danger-color) 8%, var(--surface-color));
}

.info-box-title {
    font-weight: 600;
    margin-bottom: 0.5rem;
    color: var(--text-color);
}

/* Stats Grid - Unified Design */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1.5rem;
    margin-bottom: 2rem;
}

/* Empty State - Unified Design */
.empty-state {
    text-align: center;
    padding: 3rem 2rem;
    border: 2px dashed var(--border-color);
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--surface-color) 50%, var(--bg-color));
}

.empty-state-icon {
    font-size: 3rem;
    color: var(--text-muted);
    margin-bottom: 1rem;
}

.empty-state-title {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--text-color);
    margin-bottom: 0.5rem;
}

.empty-state-text {
    color: var(--text-secondary);
    margin-bottom: 1.5rem;
}

/* Borderless variant. The Network, Zigbee and Screens pages each carried an
   identical page-local `.empty-state` rule with no dashed border or fill,
   which overrode the boxed design above. Expressed as a modifier so the two
   treatments can coexist without one silently shadowing the other. */
.empty-state-plain {
    border: none;
    background: none;
    padding: 3rem 1rem;
    color: var(--text-secondary);
}

.empty-state-plain i {
    font-size: 3rem;
    margin-bottom: 1rem;
    opacity: 0.5;
}

/* Status Badge - Unified Design
   (promoted from identical per-page CSS on the Certbot, Tailscale, and
   Icecast admin pages; page-level overrides still win the cascade) */
.status-badge {
    display: inline-block;
    padding: 0.375rem 0.75rem;
    border-radius: 0.25rem;
    font-size: 0.875rem;
    font-weight: 600;
    text-transform: uppercase;
}

.status-badge.success {
    /* Plain --surface-color, not tinted like the other three variants
       below -- the --*-ink colours are tuned against --surface-color
       itself (see the --success-ink comment above), and any tint at all
       moves the background away from that validated point. --success-ink
       (#198754) was measured at exactly 4.53:1 on #fff -- next to no
       headroom, and the pixel-sampled audit (which measures under
       antialiased glyph edges, not the nominal geometric ratio) reads it
       closer to 4.5 than the source comment's number suggests -- so it's
       the one variant that can't tolerate any tint at all, unlike the
       other three which hold up fine at 2%. (20% failed 47/80 probes
       across all four variants x 20 themes; every smaller tint tried
       (10/5/3/2/1%) still failed on success specifically in every light
       theme.) */
    background: var(--surface-color);
    color: var(--success-ink);
}

.status-badge.danger {
    background: color-mix(in srgb, var(--danger-color) 2%, var(--surface-color));
    color: var(--danger-ink);
}

.status-badge.warning {
    background: color-mix(in srgb, var(--warning-color) 2%, var(--surface-color));
    color: var(--warning-ink);
}

.status-badge.info {
    background: color-mix(in srgb, var(--info-color) 2%, var(--surface-color));
    color: var(--info-ink);
}

.status-badge.secondary {
    background: var(--border-color);
    color: var(--text-color);
}

/* Connection-state variants (promoted from the Network admin page, which had
   its own outlined treatment). */
.status-badge.connected {
    background: color-mix(in srgb, var(--success-color) 10%, transparent);
    color: var(--success-ink);
    border: 1px solid var(--success-color);
}

.status-badge.disconnected {
    background: color-mix(in srgb, var(--text-secondary) 10%, transparent);
    color: var(--text-secondary);
    border: 1px solid var(--border-color);
}

/* Sentence-case variant. The shared badge uppercases its text; several pages
   render badges whose content is already sentence-cased (hostnames, driver
   names, Bootstrap .badge pills) and had each redefined the base rule to undo
   the transform. Use this modifier instead of overriding `.status-badge`. */
.status-badge-plain {
    text-transform: none;
}

/* Inline spinner - Unified Design
   (promoted from identical per-page CSS on the Network and Zigbee admin
   pages; uses the global `spin` keyframes defined below)

   Pages MUST NOT redefine `.spinner` in a page-local <style> block — the page
   rule wins the cascade and the shared design stops applying, which is how the
   same class ended up meaning a 1rem inline spinner on one page and a 44px
   page loader on another. Use the `.spinner-lg` modifier below instead.
   Enforced by tests/test_frontend_consistency.py. */
.spinner {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    border: 2px solid rgba(0, 0, 0, 0.1);
    border-left-color: var(--primary-color);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

/* Large block spinner for full-panel loading states (dashboard tiles, the
   stats page's chart placeholders). Same design language, bigger. */
.spinner-lg {
    width: 44px;
    height: 44px;
    border-width: 3px;
}

/* SNR quality scale - shared color ramp for signal-strength meters
   (promoted from identical per-page CSS on Hardware Settings and
   System Health; s0 = no signal ... s5 = excellent) */
.snr-s0 { background: #484f58; }
.snr-s1 { background: #f85149; }
.snr-s2 { background: #f97316; }
.snr-s3 { background: #d29922; }
.snr-s4 { background: #84cc16; }
.snr-s5 { background: #3fb950; }

/* Metric card - shared summary-tile style (promoted from identical per-page
   CSS on the Analytics Dashboard and API Dashboard). */
.metric-card {
    background: var(--surface-color);
    border-radius: 12px;
    padding: 20px;
    box-shadow: var(--shadow-md);
    margin-bottom: 20px;
    border: 1px solid var(--border-color);
}

.metric-card h3 {
    font-size: 1.1rem;
    color: var(--text-secondary);
    margin-bottom: 10px;
}

.metric-value {
    font-size: 2.5rem;
    font-weight: bold;
    color: var(--primary-color);
}

.metric-value.is-error {
    color: var(--danger-color);
}

/* Border Utilities */
.border { border: 1px solid var(--border-color); }
.border-0 { border: 0; }
.border-top { border-top: 1px solid var(--border-color); }
.border-right { border-right: 1px solid var(--border-color); }
.border-bottom { border-bottom: 1px solid var(--border-color); }
.border-left { border-left: 1px solid var(--border-color); }

.rounded { border-radius: var(--radius-md); }
.rounded-sm { border-radius: var(--radius-sm); }
.rounded-lg { border-radius: var(--radius-lg); }
.rounded-circle { border-radius: 50%; }
.rounded-pill { border-radius: 999px; }

/* Shadow Utilities */
.shadow-sm { box-shadow: 0 2px 4px var(--shadow-color); }
.shadow { box-shadow: 0 4px 12px var(--shadow-color); }
.shadow-lg { box-shadow: 0 12px 32px var(--shadow-color); }


/* 7. LOADING STATES */

.loading-spinner {
    display: inline-block;
    width: 2rem;
    height: 2rem;
    border: 3px solid var(--border-color);
    border-top-color: var(--primary-color);
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.loading-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: color-mix(in srgb, var(--bg-color) 90%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    backdrop-filter: blur(4px);
}

.loading-message {
    background: color-mix(in srgb, var(--surface-color) 95%, transparent);
    backdrop-filter: blur(8px);
    border: 2px dashed var(--border-color);
    border-radius: var(--radius-lg);
    padding: 2rem;
    text-align: center;
}

/* Skeleton Loading */
.skeleton {
    background: linear-gradient(90deg,
        var(--border-color) 25%,
        color-mix(in srgb, var(--border-color) 50%, transparent) 50%,
        var(--border-color) 75%);
    background-size: 200% 100%;
    animation: skeleton-loading 1.5s ease-in-out infinite;
    border-radius: var(--radius-md);
}

@keyframes skeleton-loading {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.skeleton-text {
    height: 1rem;
    margin-bottom: 0.5rem;
}

.skeleton-header {
    height: 2rem;
    margin-bottom: 1rem;
    width: 60%;
}


/* 8. ERROR HANDLING */

.error-page {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 60vh;
    text-align: center;
    padding: 2rem;
}

.error-code {
    font-size: 6rem;
    font-weight: var(--font-weight-bold);
    background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    line-height: 1;
}

.error-message {
    font-size: 1.5rem;
    color: var(--text-secondary);
    margin: 1rem 0 2rem;
}

.error-alert {
    background: color-mix(in srgb, var(--danger-color) 15%, var(--surface-color));
    border-left: 4px solid var(--danger-color);
    color: var(--text-color);
    padding: 1rem 1.5rem;
    border-radius: var(--radius-md);
    margin-bottom: 1rem;
}

.error-icon {
    color: var(--danger-color);
    font-size: 3rem;
    margin-bottom: 1rem;
}


/* 9. ACCESSIBILITY */

/* Focus States */
*:focus,
*:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

.btn:focus,
.btn:focus-visible {
    box-shadow: 0 0 0 4px var(--shadow-color);
}

/* Skip to Main Content */
.skip-to-main {
    position: absolute;
    top: -100px;
    left: 0;
    background: var(--primary-color);
    color: white;
    padding: 0.5rem 1rem;
    z-index: 10000;
    transition: top 0.3s;
}

.skip-to-main:focus {
    top: 0;
}

/* Screen Reader Only */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* High Contrast Mode */
@media (prefers-contrast: high) {
    body {
        color: var(--text-color);
    }

    .card,
    .modal-content,
    .dropdown-menu {
        border: 2px solid var(--text-color);
    }

    a {
        text-decoration: underline;
    }

    .btn {
        border-width: 2px;
    }

    .form-check-input {
        border-width: 3px;
    }
}

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

    html {
        scroll-behavior: auto;
    }
}


/* 10. VISUAL EFFECTS (Animations, Shadows, etc.) */

/* Floating Orbs Background Effect - Subtle Ambient Accents */
.page-header .orb,
.hero-section .orb {
    position: absolute;
    border-radius: 50%;
    width: 100px;
    height: 100px;
    /* Use white/light colors so soft-light blend mode produces visible highlights on the
       vibrant header gradient. Previously used dark theme colors which were invisible. */
    background: radial-gradient(circle at 30% 30%,
        color-mix(in srgb, white 60%, transparent),
        color-mix(in srgb, var(--secondary-soft) 40%, transparent),
        transparent);
    pointer-events: none;
    mix-blend-mode: soft-light;
    animation: floatOrb 25s ease-in-out infinite;
    /* Was 0.25 but color-mix already sets transparency - element opacity multiplies it.
       Increased to a visible level so the net effect is actually perceptible. */
    opacity: 0.7;
    filter: blur(30px);
    z-index: 0;
}

/* Individual orb positioning - subtle accents */
.page-header .orb:nth-child(1) {
    top: -20px;
    left: 10%;
    width: 120px;
    height: 120px;
    animation-delay: 0s;
    opacity: 0.75;
}

.page-header .orb:nth-child(2) {
    top: 10px;
    right: 15%;
    width: 90px;
    height: 90px;
    animation-delay: -8s;
    opacity: 0.65;
}

.page-header .orb:nth-child(3) {
    bottom: -10px;
    left: 50%;
    width: 100px;
    height: 100px;
    animation-delay: -16s;
    opacity: 0.55;
}

@keyframes floatOrb {
    0%, 100% {
        transform: translate(0, 0) scale(1);
    }
    33% {
        transform: translate(15px, -10px) scale(1.05);
    }
    66% {
        transform: translate(-10px, 12px) scale(0.95);
    }
}

/* Page Shell Orbs - Ambient Background Accent for Content Pages
   Sized and tinted to provide a faint atmospheric glow without competing
   with foreground content. Earlier values (opacity 0.35–0.55, color-mix
   55%/35% with screen blend) produced enormous bright shapes that washed
   out text on every page — especially noticeable on high-contrast dark
   themes (lightning, midnight, obsidian) where bright soft-color variants
   blended onto a near-black background became dominant page features.
   Per-theme caps below further tame these on dark themes. */
.page-shell .orb {
    position: fixed;
    border-radius: 50%;
    pointer-events: none;
    mix-blend-mode: screen;
    animation: floatOrb 30s ease-in-out infinite;
    z-index: 0;
    background: radial-gradient(circle at 30% 30%,
        color-mix(in srgb, var(--primary-soft, var(--primary-color)) 30%, transparent),
        color-mix(in srgb, var(--secondary-soft, var(--secondary-color)) 18%, transparent),
        transparent 70%);
    filter: blur(80px);
    opacity: 0.18;
}

.page-shell .orb:nth-child(1) {
    width: 420px;
    height: 420px;
    top: 5%;
    left: -8%;
    animation-delay: 0s;
    opacity: 0.16;
}

.page-shell .orb:nth-child(2) {
    width: 340px;
    height: 340px;
    top: 10%;
    right: -5%;
    animation-delay: -6s;
    opacity: 0.13;
}

.page-shell .orb:nth-child(3) {
    width: 480px;
    height: 480px;
    top: 40%;
    left: 30%;
    animation-delay: -12s;
    opacity: 0.10;
}

.page-shell .orb:nth-child(4) {
    width: 300px;
    height: 300px;
    bottom: 15%;
    left: 5%;
    animation-delay: -18s;
    opacity: 0.14;
}

.page-shell .orb:nth-child(5) {
    width: 380px;
    height: 380px;
    bottom: 5%;
    right: 8%;
    animation-delay: -24s;
    opacity: 0.12;
}

/* High-contrast dark themes amplify orbs via screen blend on a near-black
   background — combined with bright soft-color variants this produces
   luminous shapes that dominate the page. Cap opacities so they read as
   subtle atmosphere rather than competing surfaces.
   The `:nth-child(n)` suffix (literal lowercase n — matches every child)
   bumps specificity above the per-orb `.page-shell .orb:nth-child(1)` …
   `:nth-child(5)` rules so these caps win without !important. */
:is([data-theme="lightning"],
    [data-theme="midnight"],
    [data-theme="obsidian"],
    [data-theme="charcoal"],
    [data-theme="slate"],
    [data-theme="nebula"],
    [data-theme="aurora"],
    [data-theme="dark"]) .page-shell .orb:nth-child(n) {
    opacity: 0.08;
    filter: blur(100px);
}

:is([data-theme="lightning"],
    [data-theme="midnight"],
    [data-theme="obsidian"],
    [data-theme="charcoal"],
    [data-theme="slate"],
    [data-theme="nebula"],
    [data-theme="aurora"],
    [data-theme="dark"]) .page-shell .orb:nth-child(3) {
    opacity: 0.05;
}

/* 3D Card Transforms */
.card-3d {
    transform-style: preserve-3d;
    perspective: 1000px;
    transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1);
}

.card-3d:hover {
    transform: rotateX(2deg) rotateY(-2deg) translateY(-8px) scale(1.02);
    box-shadow: 0 20px 50px rgba(32, 72, 133, 0.3),
                0 10px 25px rgba(32, 72, 133, 0.2),
                inset 0 1px 0 rgba(255, 255, 255, 0.3);
}

/* Enhanced Card Shadows */
.card {
    box-shadow: 0 4px 12px rgba(32, 72, 133, 0.12),
                0 2px 6px rgba(32, 72, 133, 0.08);
    transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
    border: 1px solid color-mix(in srgb, var(--primary-color) 10%, var(--border-color));
}

.card:hover {
    box-shadow: 0 12px 30px rgba(32, 72, 133, 0.18),
                0 6px 15px rgba(32, 72, 133, 0.12);
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--primary-color) 20%, var(--border-color));
}

/* Glass Card Effect */
.glass-effect {
    background: color-mix(in srgb, var(--surface-color) 85%, transparent);
    backdrop-filter: blur(10px);
    border: 1px solid color-mix(in srgb, var(--primary-color) 15%, transparent);
    box-shadow: 0 8px 32px rgba(32, 72, 133, 0.15),
                inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

/* Glowing Button Effect */
.btn-primary,
.btn-success,
.btn-info {
    box-shadow: 0 4px 12px color-mix(in srgb, var(--primary-color) 30%, transparent),
                0 2px 6px color-mix(in srgb, var(--primary-color) 20%, transparent);
    transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.btn-primary:hover,
.btn-success:hover,
.btn-info:hover {
    box-shadow: 0 8px 20px color-mix(in srgb, var(--primary-color) 40%, transparent),
                0 4px 12px color-mix(in srgb, var(--primary-color) 30%, transparent);
    transform: translateY(-2px);
}

/* Badge Glow */
.badge {
    box-shadow: 0 2px 8px color-mix(in srgb, currentColor 25%, transparent);
    font-weight: 600;
    letter-spacing: 0.02em;
}

/* Status Badge Animation */
.badge-animated {
    animation: badgePulse 2s ease-in-out infinite;
}

@keyframes badgePulse {
    0%, 100% {
        box-shadow: 0 2px 8px color-mix(in srgb, currentColor 25%, transparent);
    }
    50% {
        box-shadow: 0 4px 16px color-mix(in srgb, currentColor 40%, transparent),
                    0 0 20px color-mix(in srgb, currentColor 20%, transparent);
    }
}

/* Gradient Text */
.gradient-text {
    background: linear-gradient(135deg,
        var(--primary-color) 0%,
        var(--secondary-color) 50%,
        var(--primary-color) 100%);
    background-size: 200% 200%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: gradientTextFlow 4s ease infinite;
    font-weight: var(--font-weight-bold);
}

@keyframes gradientTextFlow {
    0%, 100% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
}

/* Icon Hover Effects */
.btn i,
.nav-link i,
.card-title i {
    transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
    display: inline-block;
}

.btn:hover i {
    transform: scale(1.2) rotate(5deg);
}

.nav-link:hover i {
    transform: scale(1.15);
}

.icon-bounce {
    animation: iconFloat 2s ease-in-out infinite;
}

@keyframes iconFloat {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-3px); }
}

/* Enhanced Focus States for Accessibility */
:focus-visible {
    outline: 2px solid var(--primary-soft);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible {
    outline: 2px solid var(--primary-soft);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary-color) 15%, transparent);
}

/* Smooth Selection Highlight */
::selection {
    background: color-mix(in srgb, var(--primary-color) 25%, transparent);
    color: var(--text-color);
}

/* Refined Input Styling */
.form-control,
.form-select {
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.form-control:hover:not(:focus),
.form-select:hover:not(:focus) {
    border-color: color-mix(in srgb, var(--primary-color) 30%, var(--border-color));
}

/* Subtle link underline animation */
a:not(.btn):not(.nav-link):not(.dropdown-item) {
    text-decoration: none;
    background-image: linear-gradient(currentColor, currentColor);
    background-size: 0% 1px;
    background-position: 0 100%;
    background-repeat: no-repeat;
    transition: background-size 0.25s ease;
}

a:not(.btn):not(.nav-link):not(.dropdown-item):hover {
    background-size: 100% 1px;
}

/* Card header accent line */
.card-header {
    position: relative;
}

.card-header::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 1rem;
    right: 1rem;
    height: 1px;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, var(--primary-color) 20%, transparent) 20%,
        color-mix(in srgb, var(--primary-color) 20%, transparent) 80%,
        transparent);
}

/* Enhanced Page Header Effects */
.page-header {
    position: relative;
    overflow: hidden;
}

.page-header::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: radial-gradient(circle at center,
        color-mix(in srgb, var(--primary-color) 15%, transparent) 0%,
        transparent 70%);
    animation: headerPulse 8s ease-in-out infinite;
    pointer-events: none;
    z-index: 0;
}

@keyframes headerPulse {
    0%, 100% {
        transform: translate(0, 0) scale(1);
        opacity: 0.5;
    }
    50% {
        transform: translate(-10%, -10%) scale(1.1);
        opacity: 0.8;
    }
}

/* Layer Section Slide-up Animation */
.layer-section {
    animation: slideUp 0.5s ease-out backwards;
}

@keyframes slideUp {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Map Card Enhancement */
.map-card {
    position: relative;
    overflow: hidden;
}

.map-card::before {
    content: '';
    position: absolute;
    top: -2px;
    left: -2px;
    right: -2px;
    bottom: -2px;
    background: linear-gradient(45deg,
        var(--primary-color),
        var(--secondary-color),
        var(--accent-color),
        var(--primary-color));
    background-size: 300% 300%;
    animation: gradientBorder 6s ease infinite;
    border-radius: inherit;
    z-index: -1;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.map-card:hover::before {
    opacity: 0.3;
}

@keyframes gradientBorder {
    0%, 100% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
}

/* Ripple Effect for Buttons */
@keyframes ripple {
    from {
        transform: scale(0);
        opacity: 1;
    }
    to {
        transform: scale(4);
        opacity: 0;
    }
}

.btn {
    position: relative;
    overflow: hidden;
}

/* Enhanced Snow Emergency Cards */
.snow-county-card {
    transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.snow-county-card:hover {
    transform: translateY(-4px) scale(1.05);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}

/* Staggered Fade-in for List Items */
.stagger-fade-in > * {
    animation: fadeIn 0.6s ease-in backwards;
}

.stagger-fade-in > *:nth-child(1) { animation-delay: 0.1s; }
.stagger-fade-in > *:nth-child(2) { animation-delay: 0.2s; }
.stagger-fade-in > *:nth-child(3) { animation-delay: 0.3s; }
.stagger-fade-in > *:nth-child(4) { animation-delay: 0.4s; }
.stagger-fade-in > *:nth-child(5) { animation-delay: 0.5s; }

/* Fade In Animation */
.fade-in {
    animation: fadeIn 0.6s ease-in;
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Slide In Animation */
.slide-in {
    animation: slideIn 0.6s cubic-bezier(0.23, 1, 0.32, 1);
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(-40px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

/* Pulse Animation */
.pulse {
    animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
    0%, 100% {
        transform: scale(1);
        opacity: 1;
    }
    50% {
        transform: scale(1.05);
        opacity: 0.9;
    }
}


/* 11. MAP STYLING */

#map {
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow:
        0 20px 60px var(--shadow-color),
        0 8px 20px var(--shadow-color),
        0 0 0 1px color-mix(in srgb, white 10%, transparent) inset;
    transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
    transform: translateZ(0);
}

#map:hover {
    box-shadow:
        0 30px 80px var(--shadow-color),
        0 12px 30px var(--shadow-color),
        0 0 0 1px color-mix(in srgb, white 20%, transparent) inset;
    transform: translateY(-2px) scale(1.001);
}

/* Map Card */
.map-card {
    position: relative;
}

.map-card::before {
    content: "";
    position: absolute;
    top: -2px;
    left: -2px;
    right: -2px;
    bottom: -2px;
    background: linear-gradient(45deg,
        var(--primary-color),
        var(--secondary-color),
        var(--primary-color));
    background-size: 400% 400%;
    border-radius: 18px;
    z-index: -1;
    opacity: 0;
    transition: opacity 0.5s ease;
    animation: borderGlow 8s ease infinite;
    filter: blur(8px);
}

.map-card:hover::before {
    opacity: 0.6;
}

@keyframes borderGlow {
    0%, 100% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
}

/* Leaflet chrome (zoom control, popups, info control) now lives in
   static/css/map.css alongside the rest of the shared map skin, so only
   pages that actually render a map download it. */

/* Map Layer Controls */
.layer-section {
    border: 2px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 1rem;
    background: color-mix(in srgb, var(--surface-color) 90%, transparent);
    backdrop-filter: blur(8px);
    box-shadow: 0 4px 16px var(--shadow-color);
    transition: all var(--transition-medium);
}

.layer-section:hover {
    border-color: var(--primary-color);
    transform: translateX(4px);
}

.layer-heading {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: var(--font-weight-bold);
    color: var(--primary-color);
}


/* 12. LOGO ENHANCEMENTS - VISIBILITY & CONTRAST */

/* Base logo styling with enhanced visibility.
   The canonical wordmark is shipped as a static SVG referenced via <img>
   (see templates/partials/logo_wordmark.html), so internal SVG classes
   like .logo-text-primary can't be restyled from this stylesheet. The
   SVG bakes in dark slate text (#1e293b / #64748b) which disappears
   against dark navbars/page backgrounds. To restore contrast on every
   theme without re-rasterizing the PNG companion, we apply a soft
   drop-shadow "halo" to the <img> itself; the filter uses the rendered
   alpha mask, so it traces the glyphs and the icon bars. Each theme can
   tune the halo via the --logo-halo custom property below. */
.logo-wordmark,
.brand-logo {
    /* Default halo: subtle dark shadow for light/colored navbars. */
    --logo-halo:
        drop-shadow(0 1px 1px rgba(255, 255, 255, 0.55))
        drop-shadow(0 0 2px rgba(0, 0, 0, 0.25));
    filter: var(--logo-halo);
    transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
    will-change: transform, filter;
}

/* Dark themes: swap to a light halo so the dark slate glyphs in the
   SVG pop against dark backgrounds instead of blending in. */
[data-theme="dark"] .logo-wordmark,
[data-theme="dark"] .brand-logo,
[data-theme="coffee"] .logo-wordmark,
[data-theme="coffee"] .brand-logo,
[data-theme="aurora"] .logo-wordmark,
[data-theme="aurora"] .brand-logo,
[data-theme="nebula"] .logo-wordmark,
[data-theme="nebula"] .brand-logo,
[data-theme="midnight"] .logo-wordmark,
[data-theme="midnight"] .brand-logo,
[data-theme="charcoal"] .logo-wordmark,
[data-theme="charcoal"] .brand-logo,
[data-theme="obsidian"] .logo-wordmark,
[data-theme="obsidian"] .brand-logo,
[data-theme="slate"] .logo-wordmark,
[data-theme="slate"] .brand-logo,
[data-theme="lightning"] .logo-wordmark,
[data-theme="lightning"] .brand-logo {
    --logo-halo:
        drop-shadow(0 0 1px rgba(255, 255, 255, 0.95))
        drop-shadow(0 0 4px rgba(255, 255, 255, 0.75))
        drop-shadow(0 0 10px rgba(255, 255, 255, 0.35));
}

/* Logo text with strong shadows for visibility on all backgrounds */
.logo-wordmark .logo-text-primary,
.brand-logo .logo-text-primary {
    fill: #ffffff;
    /* Multi-layered shadows for depth and contrast */
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3))
            drop-shadow(0 1px 2px rgba(0, 0, 0, 0.4));
}

.logo-wordmark .logo-text-secondary,
.brand-logo .logo-text-secondary {
    fill: rgba(255, 255, 255, 0.95);
    /* Lighter shadow for secondary text */
    filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.25))
            drop-shadow(0 0.5px 1px rgba(0, 0, 0, 0.3));
}

/* Logo bars with enhanced contrast */
.logo-wordmark .logo-bar,
.brand-logo .logo-bar {
    transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
    transform-origin: center;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.2));
}

.logo-wordmark .logo-underline,
.brand-logo .logo-underline {
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15));
}

/* Light themes - stronger shadows for maximum contrast on colored backgrounds */
[data-theme="cosmo"] .logo-wordmark .logo-text-primary,
[data-theme="spring"] .logo-wordmark .logo-text-primary,
[data-theme="red"] .logo-wordmark .logo-text-primary,
[data-theme="green"] .logo-wordmark .logo-text-primary,
[data-theme="blue"] .logo-wordmark .logo-text-primary,
[data-theme="purple"] .logo-wordmark .logo-text-primary,
[data-theme="pink"] .logo-wordmark .logo-text-primary,
[data-theme="orange"] .logo-wordmark .logo-text-primary,
[data-theme="yellow"] .logo-wordmark .logo-text-primary,
[data-theme="sunset"] .logo-wordmark .logo-text-primary,
[data-theme="tide"] .logo-wordmark .logo-text-primary,
[data-theme="cosmo"] .brand-logo .logo-text-primary,
[data-theme="spring"] .brand-logo .logo-text-primary,
[data-theme="red"] .brand-logo .logo-text-primary,
[data-theme="green"] .brand-logo .logo-text-primary,
[data-theme="blue"] .brand-logo .logo-text-primary,
[data-theme="purple"] .brand-logo .logo-text-primary,
[data-theme="pink"] .brand-logo .logo-text-primary,
[data-theme="orange"] .brand-logo .logo-text-primary,
[data-theme="yellow"] .brand-logo .logo-text-primary,
[data-theme="sunset"] .brand-logo .logo-text-primary,
[data-theme="tide"] .brand-logo .logo-text-primary {
    fill: #ffffff;
    filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.5))
            drop-shadow(0 2px 4px rgba(0, 0, 0, 0.6))
            drop-shadow(0 1px 2px rgba(0, 0, 0, 0.7));
}

[data-theme="cosmo"] .logo-wordmark .logo-text-secondary,
[data-theme="spring"] .logo-wordmark .logo-text-secondary,
[data-theme="red"] .logo-wordmark .logo-text-secondary,
[data-theme="green"] .logo-wordmark .logo-text-secondary,
[data-theme="blue"] .logo-wordmark .logo-text-secondary,
[data-theme="purple"] .logo-wordmark .logo-text-secondary,
[data-theme="pink"] .logo-wordmark .logo-text-secondary,
[data-theme="orange"] .logo-wordmark .logo-text-secondary,
[data-theme="yellow"] .logo-wordmark .logo-text-secondary,
[data-theme="sunset"] .logo-wordmark .logo-text-secondary,
[data-theme="tide"] .logo-wordmark .logo-text-secondary,
[data-theme="cosmo"] .brand-logo .logo-text-secondary,
[data-theme="spring"] .brand-logo .logo-text-secondary,
[data-theme="red"] .brand-logo .logo-text-secondary,
[data-theme="green"] .brand-logo .logo-text-secondary,
[data-theme="blue"] .brand-logo .logo-text-secondary,
[data-theme="purple"] .brand-logo .logo-text-secondary,
[data-theme="pink"] .brand-logo .logo-text-secondary,
[data-theme="orange"] .brand-logo .logo-text-secondary,
[data-theme="yellow"] .brand-logo .logo-text-secondary,
[data-theme="sunset"] .brand-logo .logo-text-secondary,
[data-theme="tide"] .brand-logo .logo-text-secondary {
    fill: rgba(255, 255, 255, 0.98);
    filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.45))
            drop-shadow(0 1px 3px rgba(0, 0, 0, 0.55))
            drop-shadow(0 0.5px 2px rgba(0, 0, 0, 0.65));
}

[data-theme="cosmo"] .logo-wordmark .logo-bar,
[data-theme="spring"] .logo-wordmark .logo-bar,
[data-theme="red"] .logo-wordmark .logo-bar,
[data-theme="green"] .logo-wordmark .logo-bar,
[data-theme="blue"] .logo-wordmark .logo-bar,
[data-theme="purple"] .logo-wordmark .logo-bar,
[data-theme="pink"] .logo-wordmark .logo-bar,
[data-theme="orange"] .logo-wordmark .logo-bar,
[data-theme="yellow"] .logo-wordmark .logo-bar,
[data-theme="sunset"] .logo-wordmark .logo-bar,
[data-theme="tide"] .logo-wordmark .logo-bar,
[data-theme="cosmo"] .brand-logo .logo-bar,
[data-theme="spring"] .brand-logo .logo-bar,
[data-theme="red"] .brand-logo .logo-bar,
[data-theme="green"] .brand-logo .logo-bar,
[data-theme="blue"] .brand-logo .logo-bar,
[data-theme="purple"] .brand-logo .logo-bar,
[data-theme="pink"] .brand-logo .logo-bar,
[data-theme="orange"] .brand-logo .logo-bar,
[data-theme="yellow"] .brand-logo .logo-bar,
[data-theme="sunset"] .brand-logo .logo-bar,
[data-theme="tide"] .brand-logo .logo-bar {
    filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.35))
            drop-shadow(0 1px 3px rgba(0, 0, 0, 0.45));
}

/* Dark themes - subtle glow for enhanced visibility */
[data-theme="dark"] .logo-wordmark .logo-text-primary,
[data-theme="coffee"] .logo-wordmark .logo-text-primary,
[data-theme="aurora"] .logo-wordmark .logo-text-primary,
[data-theme="nebula"] .logo-wordmark .logo-text-primary,
[data-theme="midnight"] .logo-wordmark .logo-text-primary,
[data-theme="charcoal"] .logo-wordmark .logo-text-primary,
[data-theme="obsidian"] .logo-wordmark .logo-text-primary,
[data-theme="slate"] .logo-wordmark .logo-text-primary,
[data-theme="lightning"] .logo-wordmark .logo-text-primary,
[data-theme="dark"] .brand-logo .logo-text-primary,
[data-theme="coffee"] .brand-logo .logo-text-primary,
[data-theme="aurora"] .brand-logo .logo-text-primary,
[data-theme="nebula"] .brand-logo .logo-text-primary,
[data-theme="midnight"] .brand-logo .logo-text-primary,
[data-theme="charcoal"] .brand-logo .logo-text-primary,
[data-theme="obsidian"] .brand-logo .logo-text-primary,
[data-theme="slate"] .brand-logo .logo-text-primary,
[data-theme="lightning"] .brand-logo .logo-text-primary {
    fill: #ffffff;
    filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.3))
            drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
}

[data-theme="dark"] .logo-wordmark .logo-text-secondary,
[data-theme="coffee"] .logo-wordmark .logo-text-secondary,
[data-theme="aurora"] .logo-wordmark .logo-text-secondary,
[data-theme="nebula"] .logo-wordmark .logo-text-secondary,
[data-theme="midnight"] .logo-wordmark .logo-text-secondary,
[data-theme="charcoal"] .logo-wordmark .logo-text-secondary,
[data-theme="obsidian"] .logo-wordmark .logo-text-secondary,
[data-theme="slate"] .logo-wordmark .logo-text-secondary,
[data-theme="lightning"] .logo-wordmark .logo-text-secondary,
[data-theme="dark"] .brand-logo .logo-text-secondary,
[data-theme="coffee"] .brand-logo .logo-text-secondary,
[data-theme="aurora"] .brand-logo .logo-text-secondary,
[data-theme="nebula"] .brand-logo .logo-text-secondary,
[data-theme="midnight"] .brand-logo .logo-text-secondary,
[data-theme="charcoal"] .brand-logo .logo-text-secondary,
[data-theme="obsidian"] .brand-logo .logo-text-secondary,
[data-theme="slate"] .brand-logo .logo-text-secondary,
[data-theme="lightning"] .brand-logo .logo-text-secondary {
    fill: rgba(255, 255, 255, 0.92);
    filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.25))
            drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
}

[data-theme="dark"] .logo-wordmark .logo-bar,
[data-theme="coffee"] .logo-wordmark .logo-bar,
[data-theme="aurora"] .logo-wordmark .logo-bar,
[data-theme="nebula"] .logo-wordmark .logo-bar,
[data-theme="midnight"] .logo-wordmark .logo-bar,
[data-theme="charcoal"] .logo-wordmark .logo-bar,
[data-theme="obsidian"] .logo-wordmark .logo-bar,
[data-theme="slate"] .logo-wordmark .logo-bar,
[data-theme="dark"] .brand-logo .logo-bar,
[data-theme="coffee"] .brand-logo .logo-bar,
[data-theme="aurora"] .brand-logo .logo-bar,
[data-theme="nebula"] .brand-logo .logo-bar,
[data-theme="midnight"] .brand-logo .logo-bar,
[data-theme="charcoal"] .brand-logo .logo-bar,
[data-theme="obsidian"] .brand-logo .logo-bar,
[data-theme="slate"] .brand-logo .logo-bar {
    filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.15))
            drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

/* Lightning Theme - Electric-yellow glow on logo bar */
[data-theme="lightning"] .logo-wordmark .logo-bar,
[data-theme="lightning"] .brand-logo .logo-bar {
    filter: drop-shadow(0 0 6px rgba(255, 235, 59, 0.55))
            drop-shadow(0 0 12px rgba(64, 196, 255, 0.35))
            drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
}

/* Hover effects */
.navbar-brand:hover .logo-wordmark .logo-text-primary,
.navbar-brand:hover .brand-logo .logo-text-primary {
    filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.4))
            drop-shadow(0 2px 6px rgba(0, 0, 0, 0.5))
            drop-shadow(0 0 12px rgba(255, 255, 255, 0.2));
}

.navbar-brand:hover .logo-wordmark .logo-bar,
.navbar-brand:hover .brand-logo .logo-bar {
    filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.3))
            drop-shadow(0 0 8px rgba(255, 255, 255, 0.15));
}

.navbar-brand:hover .logo-wordmark {
    transform: scale(1.02) translateY(-1px);
}

/* Floating Animation */
.logo-wordmark {
    animation: logoFloat 6s ease-in-out infinite;
}

@keyframes logoFloat {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-3px); }
}

.navbar-brand:hover .logo-wordmark {
    animation: none;
}

/* Accessibility - Reduce motion for users who prefer it */
@media (prefers-reduced-motion: reduce) {
    .logo-wordmark,
    .brand-logo {
        transition: none !important;
        animation: none !important;
    }
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    .logo-wordmark .logo-text-primary,
    .brand-logo .logo-text-primary,
    .logo-wordmark .logo-text-secondary,
    .brand-logo .logo-text-secondary {
        fill: #ffffff;
        filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.8))
                drop-shadow(0 2px 4px rgba(0, 0, 0, 0.9))
                drop-shadow(0 1px 2px rgba(0, 0, 0, 1));
    }
}


/* 13. RESPONSIVE DESIGN - iOS 26 Mobile-First Approach */

/* ========================================
   LARGE DESKTOP (1400px and above)
   ======================================== */
@media (min-width: 1400px) {
    .container {
        max-width: 1400px;
    }

    h1, .h1 { font-size: 3.5rem; }
    h2, .h2 { font-size: 2.75rem; }

    .page-header {
        padding: 3rem 3.5rem;
    }
}

/* ========================================
   DESKTOP (1200px and above)
   ======================================== */
@media (min-width: 1200px) {
    .container {
        max-width: 1320px;
    }

    h1, .h1 { font-size: 3rem; }
    h2, .h2 { font-size: 2.5rem; }
}

/* ========================================
   TABLET LANDSCAPE (992px and below)
   ======================================== */
@media (max-width: 991.98px) {
    :root {
        --glass-blur: 20px;
        --glass-blur-heavy: 32px;
    }

    .container,
    .container-fluid {
        padding-left: 1.25rem;
        padding-right: 1.25rem;
    }

    .navbar {
        padding: 0.75rem 1.25rem;
    }

    .page-header {
        padding: 1.75rem 1.5rem;
        margin-bottom: 1.75rem;
        border-radius: var(--radius-xl);
    }

    h1, .h1 { font-size: 2.25rem; }
    h2, .h2 { font-size: 1.875rem; }
    h3, .h3 { font-size: 1.5rem; }

    /* Grid adjustments */
    .stats-grid,
    .content-grid-3 {
        grid-template-columns: repeat(2, 1fr);
    }

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

/* ========================================
   TABLET PORTRAIT (768px and below)
   ======================================== */
@media (max-width: 767.98px) {
    html {
        font-size: 15px;
    }

    :root {
        --radius-sm: 0.625rem;
        --radius-md: 0.875rem;
        --radius-lg: 1rem;
        --radius-xl: 1.25rem;
        --radius-2xl: 1.5rem;
    }

    .container,
    .container-fluid {
        padding-left: 1rem;
        padding-right: 1rem;
    }

    /* iOS-style floating navbar on tablet */
    .navbar {
        padding: 0.625rem 1rem;
        margin: 0.5rem;
        border-radius: var(--radius-2xl);
        position: sticky;
        top: 0.5rem;
    }

    .navbar-brand .logo-wordmark,
    .navbar-brand .brand-logo {
        height: 64px;
    }

    /* Hamburger menu styling */
    .navbar-toggler {
        border: none;
        padding: 0.5rem;
        border-radius: var(--radius-lg);
        background: rgba(255, 255, 255, 0.15);
        backdrop-filter: blur(8px);
        -webkit-backdrop-filter: blur(8px);
    }

    .navbar-toggler:focus {
        box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
    }

    .navbar-collapse {
        background: linear-gradient(135deg,
            color-mix(in srgb, var(--vibrant-indigo) 90%, transparent),
            color-mix(in srgb, var(--vibrant-purple) 85%, transparent));
        backdrop-filter: blur(var(--glass-blur-heavy));
        -webkit-backdrop-filter: blur(var(--glass-blur-heavy));
        margin-top: 0.75rem;
        padding: 1rem;
        border-radius: var(--radius-xl);
        border: 1px solid rgba(255, 255, 255, 0.15);
    }

    .nav-link {
        padding: 0.875rem 1.25rem;
        margin-bottom: 0.25rem;
    }

    .page-header {
        padding: 1.5rem 1.25rem;
        margin-bottom: 1.5rem;
        border-radius: var(--radius-xl);
    }

    .page-header h1,
    .page-header .page-title {
        font-size: 1.5rem;
    }

    h1, .h1 { font-size: 2rem; }
    h2, .h2 { font-size: 1.625rem; }
    h3, .h3 { font-size: 1.375rem; }
    h4, .h4 { font-size: 1.125rem; }

    /* Card adjustments */
    .card {
        margin-bottom: 1rem;
        border-radius: var(--radius-xl);
    }

    .card:hover {
        transform: translateY(-4px) scale(1.005);
    }

    .card-header {
        padding: 1rem 1.25rem;
    }

    .card-body {
        padding: 1.25rem;
    }

    /* Button sizing */
    .btn {
        padding: 0.75rem 1.25rem;
        font-size: 0.9375rem;
        border-radius: var(--radius-lg);
    }

    .btn-lg {
        padding: 0.875rem 1.5rem;
    }

    .btn-sm {
        padding: 0.5rem 1rem;
        font-size: 0.8125rem;
    }

    /* Hide heavy animations */
    .orb,
    .card-3d:hover,
    .logo-wordmark::after,
    .card-header::before {
        display: none !important;
        animation: none !important;
    }

    #map {
        border-radius: var(--radius-lg);
        min-height: 300px;
    }

    /* Grid to single/double column */
    .stats-grid,
    .content-grid-3,
    .content-grid-4 {
        grid-template-columns: repeat(2, 1fr);
        gap: 0.875rem;
    }

    /* Footer adjustments */
    footer {
        padding: 2rem 0;
        margin-top: 3rem;
    }

    :root {
        --footer-badge-height: 20px;
    }

    .tech-stack-badges {
        gap: 0.5rem !important;
    }
}

/* ========================================
   MOBILE LARGE (576px and below)
   ======================================== */
@media (max-width: 575.98px) {
    html {
        font-size: 14px;
    }

    :root {
        --radius-sm: 0.5rem;
        --radius-md: 0.75rem;
        --radius-lg: 0.875rem;
        --radius-xl: 1rem;
        --radius-2xl: 1.25rem;
    }

    .container,
    .container-fluid {
        padding-left: 0.875rem;
        padding-right: 0.875rem;
    }

    .page-shell {
        padding: 0.75rem 0 2rem;
    }

    /* Floating pill navbar on mobile */
    .navbar {
        margin: 0.375rem;
        padding: 0.5rem 0.875rem;
        border-radius: var(--radius-2xl);
    }

    .navbar-brand {
        padding: 0.25rem 0.5rem;
        margin-right: 0.5rem;
    }

    .navbar-brand .logo-wordmark,
    .navbar-brand .brand-logo {
        height: 52px;
    }

    /* No negative horizontal margin here. The standard header is normally a
       direct child of the unpadded .page-shell, so a -0.125rem bleed makes it
       wider than the viewport and scrolls the whole document sideways. The
       .page-header-gradient variant never had one, which is why only pages on
       the standard header overflowed. */
    .page-header {
        padding: 1.25rem 1rem;
        margin-bottom: 1.25rem;
        border-radius: var(--radius-lg);
    }

    .page-header h1,
    .page-header .page-title {
        font-size: 1.375rem;
    }

    .page-header .page-subtitle {
        font-size: 0.875rem;
    }

    h1, .h1 { font-size: 1.75rem; }
    h2, .h2 { font-size: 1.5rem; }
    h3, .h3 { font-size: 1.25rem; }
    h4, .h4 { font-size: 1.125rem; }
    h5, .h5 { font-size: 1rem; }

    .card {
        margin-bottom: 0.875rem;
        border-radius: var(--radius-lg);
    }

    .card:hover {
        transform: translateY(-2px);
    }

    .card-header {
        padding: 0.875rem 1rem;
        font-size: 0.9375rem;
    }

    .card-body {
        padding: 1rem;
    }

    .card-footer {
        padding: 0.75rem 1rem;
    }

    /* Full-width buttons on mobile */
    .btn {
        width: 100%;
        padding: 0.875rem 1rem;
        font-size: 1rem;
        border-radius: var(--radius-lg);
        margin-bottom: 0.5rem;
    }

    .btn-group .btn {
        width: auto;
        margin-bottom: 0;
    }

    /* Inline button option */
    .btn-inline {
        width: auto !important;
        display: inline-flex !important;
    }

    /* Side-by-side buttons */
    .btn-row {
        display: flex;
        gap: 0.5rem;
    }

    .btn-row .btn {
        flex: 1;
        margin-bottom: 0;
    }

    /* Single column grid */
    .stats-grid,
    .content-grid-2,
    .content-grid-3,
    .content-grid-4 {
        grid-template-columns: 1fr;
        gap: 0.75rem;
    }

    .table {
        font-size: 0.875rem;
    }

    .table th,
    .table td {
        padding: 0.625rem 0.5rem;
    }

    .badge {
        font-size: 0.75rem;
        padding: 0.375em 0.625em;
        border-radius: var(--radius-sm);
    }

    /* Form inputs */
    .form-control,
    .form-select {
        padding: 0.75rem 1rem;
        font-size: 1rem;
        border-radius: var(--radius-lg);
    }

    .form-label {
        font-size: 0.9375rem;
        margin-bottom: 0.375rem;
    }

    /* Footer mobile */
    footer {
        padding: 1.5rem 0;
        margin-top: 2.5rem;
    }

    :root {
        --footer-badge-height: 18px;
    }

    .tech-stack-badges {
        gap: 0.4rem !important;
    }

    .footer-disclaimer {
        font-size: 0.75rem;
        padding: 1rem;
    }
}

/* ========================================
   MOBILE SMALL (400px and below)
   ======================================== */
@media (max-width: 399.98px) {
    html {
        font-size: 13px;
    }

    .container,
    .container-fluid {
        padding-left: 0.625rem;
        padding-right: 0.625rem;
    }

    .navbar {
        margin: 0.25rem;
        padding: 0.375rem 0.625rem;
    }

    .navbar-brand .logo-wordmark,
    .navbar-brand .brand-logo {
        height: 44px;
    }

    .page-header {
        padding: 1rem 0.875rem;
    }

    .page-header h1,
    .page-header .page-title {
        font-size: 1.25rem;
    }

    h1, .h1 { font-size: 1.5rem; }
    h2, .h2 { font-size: 1.375rem; }
    h3, .h3 { font-size: 1.125rem; }

    .card-header {
        padding: 0.75rem 0.875rem;
    }

    .card-body {
        padding: 0.875rem;
    }
}

/* ========================================
   TOUCH DEVICE OPTIMIZATIONS
   ======================================== */
@media (hover: none) and (pointer: coarse) {
    /* Larger touch targets */
    .btn {
        min-height: 44px;
        min-width: 44px;
    }

    .nav-link {
        min-height: 44px;
        display: flex;
        align-items: center;
    }

    /* Remove hover effects that don't work on touch */
    .card:hover {
        transform: none;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08),
            0 8px 32px rgba(0, 0, 0, 0.04);
    }

    .btn:hover {
        transform: none;
        filter: none;
    }

    /* Active states for touch feedback */
    .btn:active {
        transform: scale(0.97);
        filter: brightness(0.95);
    }

    .card:active {
        transform: scale(0.99);
    }

    .nav-link:active {
        transform: scale(0.98);
        background: rgba(255, 255, 255, 0.2);
    }
}

/* ========================================
   LANDSCAPE PHONE OPTIMIZATION
   ======================================== */
@media (max-height: 500px) and (orientation: landscape) {
    .navbar {
        padding: 0.375rem 1rem;
    }

    .navbar-brand .logo-wordmark,
    .navbar-brand .brand-logo {
        height: 44px;
    }

    .page-header {
        padding: 1rem 1.25rem;
        margin-bottom: 1rem;
    }

    .page-header h1,
    .page-header .page-title {
        font-size: 1.25rem;
    }

    footer {
        padding: 1rem 0;
    }
}

/* ========================================
   SAFE AREA INSETS (iPhone X+, etc.)
   ======================================== */
@supports (padding: max(0px)) {
    .navbar {
        padding-left: max(1rem, env(safe-area-inset-left));
        padding-right: max(1rem, env(safe-area-inset-right));
    }

    .container,
    .container-fluid {
        padding-left: max(0.875rem, env(safe-area-inset-left));
        padding-right: max(0.875rem, env(safe-area-inset-right));
    }

    footer {
        padding-bottom: max(1.5rem, env(safe-area-inset-bottom));
    }
}

/* Print Styles - Pure black/white for optimal printer output */
@media print {
    body {
        color: var(--text-color) !important;
        background: var(--surface-color) !important;
    }

    * {
        color: var(--text-color) !important;
        background: none !important;
        box-shadow: none !important;
        text-shadow: none !important;
    }

    a {
        text-decoration: underline !important;
    }

    .navbar,
    footer,
    .btn,
    .no-print {
        display: none !important;
    }

    .card {
        border: 1px solid var(--text-color);
        page-break-inside: avoid;
    }
}


/* 14. THEME-SPECIFIC OVERRIDES */

/* Dark Themes - Enhanced Visibility */
[data-theme="dark"] .logo-bar,
[data-theme="coffee"] .logo-bar,
[data-theme="midnight"] .logo-bar,
[data-theme="charcoal"] .logo-bar,
[data-theme="obsidian"] .logo-bar,
[data-theme="slate"] .logo-bar,
[data-theme="aurora"] .logo-bar,
[data-theme="nebula"] .logo-bar {
    filter: brightness(1.4) saturate(1.2);
}

/* Light Themes with Low Contrast - Enhanced Text */
[data-theme="yellow"],
[data-theme="orange"] {
    --text-color: #3e2723;
    --text-secondary: #5d4037;
}

/* Ensure card headers are visible in all themes */
[data-theme="yellow"] .card-header,
[data-theme="orange"] .card-header,
[data-theme="sunset"] .card-header,
[data-theme="pink"] .card-header,
[data-theme="spring"] .card-header {
    color: white;
}


/* 15. HELP PAGE STYLES */

/* Help Page Quick Links */
.quick-links-card {
    background: var(--surface-color);
    transition: all var(--transition-medium);
}

.help-quick-link {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem;
    border-radius: var(--radius-md);
    background: var(--surface-color);
    border: 2px solid var(--border-color);
    text-decoration: none;
    color: var(--text-color);
    transition: all var(--transition-medium);
}

.help-quick-link:hover {
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--primary-color) 5%, var(--surface-color));
    transform: translateX(4px);
    box-shadow: 0 4px 12px var(--shadow-color);
    text-decoration: none;
    color: var(--text-color);
}

.help-quick-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    font-size: 1.5rem;
    flex-shrink: 0;
    transition: all var(--transition-medium);
}

.help-quick-link:hover .help-quick-icon {
    transform: scale(1.1);
}

/* Operations Flow */
.operations-flow-card {
    background: var(--surface-color);
}

.operations-flow {
    list-style: none;
    padding: 0;
    margin: 0;
    position: relative;
}

.operations-flow li {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1rem 0;
    position: relative;
}

.operations-flow li:not(:last-child) {
    border-bottom: 1px dashed var(--border-color);
}

.operations-flow li:not(:last-child)::after {
    content: "";
    position: absolute;
    left: 20px;
    top: 60px;
    width: 2px;
    height: calc(100% - 40px);
    background: linear-gradient(180deg,
        var(--primary-color) 0%,
        var(--secondary-color) 100%);
    opacity: 0.3;
}

.flow-step {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    min-width: 40px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
    color: white;
    font-weight: var(--font-weight-bold);
    font-size: 1.125rem;
    box-shadow: 0 4px 12px var(--shadow-color);
    z-index: 1;
    position: relative;
}

/* Help Resource Cards */
.help-resource-card {
    background: var(--surface-color);
    border: 2px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    text-align: center;
    transition: all var(--transition-medium);
}

.help-resource-card:hover {
    border-color: var(--primary-color);
    transform: translateY(-4px);
    box-shadow: 0 8px 24px var(--shadow-color);
}

.help-resource-logo {
    width: 100%;
    max-width: 200px;
    height: auto;
    margin: 0 auto;
    display: block;
    border-radius: var(--radius-md);
    transition: all var(--transition-medium);
}

.help-resource-card:hover .help-resource-logo {
    transform: scale(1.05);
}

.help-resource-card h5 {
    color: var(--primary-color);
    font-weight: var(--font-weight-bold);
    margin-top: 1rem;
    margin-bottom: 0.5rem;
}

.help-resource-card p {
    color: var(--text-secondary);
    margin-bottom: 1rem;
}

.help-resource-card ul {
    padding-left: 0;
}

.help-resource-card li {
    margin-bottom: 0.5rem;
}

.help-resource-card a {
    color: var(--primary-color);
    transition: color var(--transition-fast);
}

.help-resource-card a:hover {
    color: var(--secondary-color);
}


/* PERFORMANCE OPTIMIZATIONS */

/* GPU Acceleration for Animations */
.card-3d,
.btn-liquid,
.logo-wordmark,
#map {
    will-change: transform;
    transform: translateZ(0);
    backface-visibility: hidden;
}

/* Optimize Heavy Elements */
.orb,
.parallax-bg {
    will-change: transform;
    transform: translateZ(0);
}


/* ============================================================================
   iOS 26 UTILITY CLASSES & MICRO-INTERACTIONS
   ============================================================================ */

/* === ANIMATION UTILITIES === */

/* Spring bounce animation */
@keyframes springBounce {
    0% { transform: scale(0.95); opacity: 0; }
    50% { transform: scale(1.02); }
    100% { transform: scale(1); opacity: 1; }
}

.animate-spring {
    animation: springBounce 0.5s var(--ease-spring) forwards;
}

/* Fade in up animation */
@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.animate-fade-in-up {
    animation: fadeInUp 0.6s var(--ease-ios) forwards;
}

/* Pulse glow animation */
@keyframes pulseGlow {
    0%, 100% {
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--vibrant-blue) 40%, transparent);
    }
    50% {
        box-shadow: 0 0 0 15px color-mix(in srgb, var(--vibrant-blue) 0%, transparent);
    }
}

.animate-pulse-glow {
    animation: pulseGlow 2s ease-in-out infinite;
}

/* Floating animation */
@keyframes float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-10px); }
}

.animate-float {
    animation: float 4s ease-in-out infinite;
}

/* === GRADIENT UTILITIES === */

.gradient-mesh {
    background: linear-gradient(135deg,
        var(--mesh-1) 0%,
        var(--mesh-2) 25%,
        var(--mesh-3) 50%,
        var(--mesh-4) 75%,
        var(--mesh-1) 100%);
    background-size: 400% 400%;
    animation: gradientShift 15s ease infinite;
}

@keyframes gradientShift {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

.gradient-vibrant {
    background: linear-gradient(135deg,
        var(--vibrant-blue) 0%,
        var(--vibrant-purple) 50%,
        var(--vibrant-pink) 100%);
}

.gradient-sunset {
    background: linear-gradient(135deg,
        var(--vibrant-pink) 0%,
        var(--vibrant-orange) 50%,
        var(--vibrant-yellow) 100%);
}

.gradient-ocean {
    background: linear-gradient(135deg,
        var(--vibrant-teal) 0%,
        var(--vibrant-blue) 50%,
        var(--vibrant-indigo) 100%);
}

.gradient-forest {
    background: linear-gradient(135deg,
        var(--vibrant-mint) 0%,
        var(--vibrant-green) 50%,
        var(--vibrant-teal) 100%);
}

/* Text gradient */
.text-gradient {
    background: linear-gradient(135deg,
        var(--vibrant-blue) 0%,
        var(--vibrant-purple) 50%,
        var(--vibrant-pink) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* === BLUR UTILITIES === */

.blur-sm { backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.blur-md { backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); }
.blur-lg { backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); }
.blur-xl { backdrop-filter: blur(40px); -webkit-backdrop-filter: blur(40px); }

/* === SHADOW UTILITIES (iOS-style colored shadows) === */

.shadow-glow-blue {
    box-shadow: 0 8px 32px color-mix(in srgb, var(--vibrant-blue) 35%, transparent);
}

.shadow-glow-purple {
    box-shadow: 0 8px 32px color-mix(in srgb, var(--vibrant-purple) 35%, transparent);
}

.shadow-glow-pink {
    box-shadow: 0 8px 32px color-mix(in srgb, var(--vibrant-pink) 35%, transparent);
}

.shadow-glow-green {
    box-shadow: 0 8px 32px color-mix(in srgb, var(--vibrant-green) 35%, transparent);
}

.shadow-glow-orange {
    box-shadow: 0 8px 32px color-mix(in srgb, var(--vibrant-orange) 35%, transparent);
}

/* Floating shadow (for elevated elements) */
.shadow-float {
    box-shadow:
        0 4px 6px -1px rgba(0, 0, 0, 0.1),
        0 10px 15px -3px rgba(0, 0, 0, 0.1),
        0 20px 25px -5px rgba(0, 0, 0, 0.1);
}

/* === INTERACTIVE UTILITIES === */

/* Scale on hover */
.hover-scale {
    transition: transform 0.3s var(--ease-spring);
}

.hover-scale:hover {
    transform: scale(1.05);
}

/* Lift on hover */
.hover-lift {
    transition: transform 0.3s var(--ease-spring), box-shadow 0.3s var(--ease-spring);
}

.hover-lift:hover {
    transform: translateY(-6px);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
}

/* Glow on hover */
.hover-glow {
    transition: box-shadow 0.4s var(--ease-ios);
}

.hover-glow:hover {
    box-shadow:
        0 0 20px color-mix(in srgb, var(--vibrant-blue) 30%, transparent),
        0 0 40px color-mix(in srgb, var(--vibrant-purple) 20%, transparent);
}

/* Press effect */
.press-effect {
    transition: transform 0.15s var(--ease-spring);
}

.press-effect:active {
    transform: scale(0.97);
}

/* === BADGE UTILITIES (iOS-style) === */

.badge-ios {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.375rem 0.875rem;
    font-size: 0.75rem;
    font-weight: var(--font-weight-semibold);
    border-radius: var(--radius-pill);
    background: linear-gradient(135deg,
        var(--vibrant-blue) 0%,
        var(--vibrant-purple) 100%);
    color: white;
    box-shadow: 0 2px 8px color-mix(in srgb, var(--vibrant-blue) 30%, transparent);
}

.badge-ios-success {
    background: linear-gradient(135deg,
        var(--vibrant-green) 0%,
        var(--vibrant-mint) 100%);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--vibrant-green) 30%, transparent);
}

.badge-ios-danger {
    background: linear-gradient(135deg,
        var(--vibrant-red) 0%,
        var(--vibrant-pink) 100%);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--vibrant-red) 30%, transparent);
}

.badge-ios-warning {
    background: linear-gradient(135deg,
        var(--vibrant-orange) 0%,
        var(--vibrant-yellow) 100%);
    color: #1a1a1a;
    box-shadow: 0 2px 8px color-mix(in srgb, var(--vibrant-orange) 30%, transparent);
}

/* === CHIP/TAG COMPONENT (iOS-style) === */

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 1rem;
    font-size: 0.875rem;
    font-weight: var(--font-weight-medium);
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--surface-color) 90%, var(--primary-color));
    border: 1px solid var(--border-color);
    color: var(--text-color);
    transition: all 0.3s var(--ease-spring);
    cursor: pointer;
}

.chip:hover {
    background: color-mix(in srgb, var(--vibrant-blue) 15%, var(--surface-color));
    border-color: var(--vibrant-blue);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.chip-active {
    background: linear-gradient(135deg,
        var(--vibrant-blue) 0%,
        var(--vibrant-purple) 100%);
    color: white;
    border-color: transparent;
    box-shadow: 0 4px 15px color-mix(in srgb, var(--vibrant-blue) 40%, transparent);
}

/* === TOGGLE SWITCH (iOS-style) === */

.toggle-switch {
    position: relative;
    width: 51px;
    height: 31px;
    appearance: none;
    -webkit-appearance: none;
    background: #e9e9eb;
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: background 0.3s var(--ease-ios);
}

.toggle-switch::before {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 27px;
    height: 27px;
    background: white;
    border-radius: 50%;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    transition: transform 0.3s var(--ease-spring);
}

.toggle-switch:checked {
    background: linear-gradient(135deg,
        var(--vibrant-green) 0%,
        var(--vibrant-mint) 100%);
}

.toggle-switch:checked::before {
    transform: translateX(20px);
}

/* === SKELETON LOADING (iOS-style) === */

.skeleton {
    background: linear-gradient(
        90deg,
        color-mix(in srgb, var(--text-color) 8%, transparent) 0%,
        color-mix(in srgb, var(--text-color) 15%, transparent) 50%,
        color-mix(in srgb, var(--text-color) 8%, transparent) 100%
    );
    background-size: 200% 100%;
    animation: skeletonShimmer 1.5s ease-in-out infinite;
    border-radius: var(--radius-md);
}

@keyframes skeletonShimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* === TOOLTIP (iOS-style) === */

[data-tooltip] {
    position: relative;
}

[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(10px);
    padding: 0.5rem 0.875rem;
    background: rgba(0, 0, 0, 0.85);
    backdrop-filter: blur(8px);
    color: white;
    font-size: 0.8125rem;
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
    border-radius: var(--radius-lg);
    opacity: 0;
    visibility: hidden;
    transition: all 0.3s var(--ease-spring);
    pointer-events: none;
    z-index: 1000;
}

[data-tooltip]:hover::after {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
}

/* === REDUCED MOTION === */

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

    .animate-spring,
    .animate-fade-in-up,
    .animate-pulse-glow,
    .animate-float,
    .gradient-mesh {
        animation: none !important;
    }
}

/* ============================================================================
   THEME READABILITY FIXES
   Ensures all elements are readable across all light and dark themes
   ============================================================================ */

/* === DARK THEME BUTTON FIXES === */

/* Fix .btn-light on dark themes - must have dark text on light background */
[data-theme="dark"] .btn-light,
[data-theme="coffee"] .btn-light,
[data-theme="aurora"] .btn-light,
[data-theme="nebula"] .btn-light,
[data-theme="midnight"] .btn-light,
[data-theme="charcoal"] .btn-light,
[data-theme="obsidian"] .btn-light,
[data-theme="slate"] .btn-light {
    background: linear-gradient(135deg,
        rgba(255, 255, 255, 0.95) 0%,
        rgba(248, 250, 252, 0.98) 100%);
    color: #1a1a2e !important;
    border: 1px solid rgba(0, 0, 0, 0.1);
}

[data-theme="dark"] .btn-light:hover,
[data-theme="coffee"] .btn-light:hover,
[data-theme="aurora"] .btn-light:hover,
[data-theme="nebula"] .btn-light:hover,
[data-theme="midnight"] .btn-light:hover,
[data-theme="charcoal"] .btn-light:hover,
[data-theme="obsidian"] .btn-light:hover,
[data-theme="slate"] .btn-light:hover {
    background: linear-gradient(135deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, 0.98) 100%);
    color: #0f0f1a !important;
}

/* Fix .btn-dark on light themes - ensure proper contrast */
[data-theme="cosmo"] .btn-dark,
[data-theme="spring"] .btn-dark,
[data-theme="red"] .btn-dark,
[data-theme="green"] .btn-dark,
[data-theme="blue"] .btn-dark,
[data-theme="purple"] .btn-dark,
[data-theme="pink"] .btn-dark,
[data-theme="orange"] .btn-dark,
[data-theme="yellow"] .btn-dark,
[data-theme="sunset"] .btn-dark,
[data-theme="tide"] .btn-dark {
    background: linear-gradient(135deg, #1a1a2e 0%, #2d2d44 100%);
    color: #ffffff !important;
}

/* === OUTLINE BUTTON VARIANTS - All themes === */

/* Outline Secondary */
.btn-outline-secondary {
    background: transparent;
    border: 2px solid var(--secondary-color);
    color: var(--secondary-color);
    box-shadow: none;
}

.btn-outline-secondary:hover {
    background: var(--secondary-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--secondary-color) 40%, transparent);
}

/* Outline Success */
.btn-outline-success {
    background: transparent;
    border: 2px solid var(--success-color);
    color: var(--success-color);
    box-shadow: none;
}

.btn-outline-success:hover {
    background: var(--success-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--success-color) 40%, transparent);
}

/* Outline Danger */
.btn-outline-danger {
    background: transparent;
    border: 2px solid var(--danger-color);
    color: var(--danger-color);
    box-shadow: none;
}

.btn-outline-danger:hover {
    background: var(--danger-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--danger-color) 40%, transparent);
}

/* Outline Warning */
.btn-outline-warning {
    background: transparent;
    border: 2px solid var(--warning-color);
    color: var(--warning-color);
    box-shadow: none;
}

.btn-outline-warning:hover {
    background: var(--warning-color);
    color: #1a1a1a;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--warning-color) 40%, transparent);
}

/* Outline Info */
.btn-outline-info {
    background: transparent;
    border: 2px solid var(--info-color);
    color: var(--info-color);
    box-shadow: none;
}

.btn-outline-info:hover {
    background: var(--info-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--info-color) 40%, transparent);
}

/* Outline Light - needs special handling */
.btn-outline-light {
    background: transparent;
    border: 2px solid var(--light-color);
    color: var(--text-color);
    box-shadow: none;
}

.btn-outline-light:hover {
    background: var(--light-color);
    color: #1a1a2e;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--light-color) 40%, transparent);
}

/* Outline Dark */
.btn-outline-dark {
    background: transparent;
    border: 2px solid var(--dark-color);
    color: var(--dark-color);
    box-shadow: none;
}

.btn-outline-dark:hover {
    background: var(--dark-color);
    color: white;
    box-shadow: 0 8px 25px color-mix(in srgb, var(--dark-color) 40%, transparent);
}

/* Dark theme outline button fixes */
[data-theme="dark"] .btn-outline-light,
[data-theme="coffee"] .btn-outline-light,
[data-theme="aurora"] .btn-outline-light,
[data-theme="nebula"] .btn-outline-light,
[data-theme="midnight"] .btn-outline-light,
[data-theme="charcoal"] .btn-outline-light,
[data-theme="obsidian"] .btn-outline-light,
[data-theme="slate"] .btn-outline-light {
    border-color: rgba(255, 255, 255, 0.6);
    color: rgba(255, 255, 255, 0.9);
}

[data-theme="dark"] .btn-outline-light:hover,
[data-theme="coffee"] .btn-outline-light:hover,
[data-theme="aurora"] .btn-outline-light:hover,
[data-theme="nebula"] .btn-outline-light:hover,
[data-theme="midnight"] .btn-outline-light:hover,
[data-theme="charcoal"] .btn-outline-light:hover,
[data-theme="obsidian"] .btn-outline-light:hover,
[data-theme="slate"] .btn-outline-light:hover {
    background: rgba(255, 255, 255, 0.95);
    color: #1a1a2e !important;
}

[data-theme="dark"] .btn-outline-dark,
[data-theme="coffee"] .btn-outline-dark,
[data-theme="aurora"] .btn-outline-dark,
[data-theme="nebula"] .btn-outline-dark,
[data-theme="midnight"] .btn-outline-dark,
[data-theme="charcoal"] .btn-outline-dark,
[data-theme="obsidian"] .btn-outline-dark,
[data-theme="slate"] .btn-outline-dark {
    border-color: var(--border-color);
    color: var(--text-color);
}

[data-theme="dark"] .btn-outline-dark:hover,
[data-theme="coffee"] .btn-outline-dark:hover,
[data-theme="aurora"] .btn-outline-dark:hover,
[data-theme="nebula"] .btn-outline-dark:hover,
[data-theme="midnight"] .btn-outline-dark:hover,
[data-theme="charcoal"] .btn-outline-dark:hover,
[data-theme="obsidian"] .btn-outline-dark:hover,
[data-theme="slate"] .btn-outline-dark:hover {
    background: var(--surface-color);
    color: var(--text-color);
}

/* === BACKGROUND UTILITY CLASS FIXES === */

/* .bg-light must always have dark text */
.bg-light {
    background-color: var(--light-color) !important;
    color: #212121 !important;
}

.bg-light * {
    color: inherit;
}

.bg-light .text-muted {
    color: #6b7280 !important;
}

/* For dark/coffee themes, --light-color is actually a dark hue.
   Use theme text variables so text stays readable on the darker surface. */
[data-theme="dark"] .bg-light,
[data-theme="coffee"] .bg-light {
    color: var(--text-color) !important;
}

[data-theme="dark"] .bg-light .text-muted,
[data-theme="coffee"] .bg-light .text-muted {
    color: var(--text-secondary) !important;
}

/* .bg-dark must always have light text */
.bg-dark {
    background-color: var(--dark-color) !important;
    color: #ffffff !important;
}

.bg-dark * {
    color: inherit;
}

.bg-dark .text-muted {
    color: #9ca3af !important;
}

/* .bg-warning needs dark text for readability */
.bg-warning {
    background-color: var(--warning-color) !important;
    color: #1a1a1a !important;
}

/* .bg-info may need white text depending on shade */
.bg-info {
    background-color: var(--info-color) !important;
    color: white !important;
}

/* === TEXT CLASS FIXES FOR DARK THEMES === */

/* .text-dark should be visible on dark themes */
[data-theme="dark"] .text-dark,
[data-theme="coffee"] .text-dark,
[data-theme="aurora"] .text-dark,
[data-theme="nebula"] .text-dark,
[data-theme="midnight"] .text-dark,
[data-theme="charcoal"] .text-dark,
[data-theme="obsidian"] .text-dark,
[data-theme="slate"] .text-dark {
    color: var(--text-color) !important;
}

/* .text-light should be visible on light themes */
[data-theme="cosmo"] .text-light,
[data-theme="spring"] .text-light,
[data-theme="red"] .text-light,
[data-theme="green"] .text-light,
[data-theme="blue"] .text-light,
[data-theme="purple"] .text-light,
[data-theme="pink"] .text-light,
[data-theme="orange"] .text-light,
[data-theme="yellow"] .text-light,
[data-theme="sunset"] .text-light,
[data-theme="tide"] .text-light {
    color: var(--text-muted) !important;
}

/* === BADGE READABILITY FIXES === */

/* Ensure all badges have proper text colors */
.badge.bg-primary,
.badge.bg-secondary,
.badge.bg-success,
.badge.bg-danger,
.badge.bg-info,
.badge.bg-dark {
    color: white !important;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.badge.bg-warning {
    color: #1a1a1a !important;
    text-shadow: none;
}

.badge.bg-light {
    color: #1a1a1a !important;
    text-shadow: none;
    background-color: var(--light-color) !important;
}

/* Dark theme badge fixes */
[data-theme="dark"] .badge.bg-light,
[data-theme="coffee"] .badge.bg-light,
[data-theme="aurora"] .badge.bg-light,
[data-theme="nebula"] .badge.bg-light,
[data-theme="midnight"] .badge.bg-light,
[data-theme="charcoal"] .badge.bg-light,
[data-theme="obsidian"] .badge.bg-light,
[data-theme="slate"] .badge.bg-light {
    background-color: rgba(255, 255, 255, 0.9) !important;
    color: #1a1a2e !important;
}

/* === ALERT READABILITY FIXES === */

/* Ensure alert text is always readable */
.alert {
    color: var(--text-color);
}

.alert-success {
    color: #065f46;
}

.alert-danger {
    color: #991b1b;
}

.alert-warning {
    color: #92400e;
}

.alert-info {
    color: #1e40af;
}

/* Dark theme alert text fixes */
[data-theme="dark"] .alert-success,
[data-theme="coffee"] .alert-success,
[data-theme="aurora"] .alert-success,
[data-theme="nebula"] .alert-success,
[data-theme="midnight"] .alert-success,
[data-theme="charcoal"] .alert-success,
[data-theme="obsidian"] .alert-success,
[data-theme="slate"] .alert-success,
[data-theme="lightning"] .alert-success {
    color: #6ee7b7;
    background-color: color-mix(in srgb, var(--success-color) 20%, var(--surface-color));
}

[data-theme="dark"] .alert-danger,
[data-theme="coffee"] .alert-danger,
[data-theme="aurora"] .alert-danger,
[data-theme="nebula"] .alert-danger,
[data-theme="midnight"] .alert-danger,
[data-theme="charcoal"] .alert-danger,
[data-theme="obsidian"] .alert-danger,
[data-theme="slate"] .alert-danger,
[data-theme="lightning"] .alert-danger {
    color: #fca5a5;
    background-color: color-mix(in srgb, var(--danger-color) 20%, var(--surface-color));
}

[data-theme="dark"] .alert-warning,
[data-theme="coffee"] .alert-warning,
[data-theme="aurora"] .alert-warning,
[data-theme="nebula"] .alert-warning,
[data-theme="midnight"] .alert-warning,
[data-theme="charcoal"] .alert-warning,
[data-theme="obsidian"] .alert-warning,
[data-theme="slate"] .alert-warning,
[data-theme="lightning"] .alert-warning {
    color: #fcd34d;
    background-color: color-mix(in srgb, var(--warning-color) 20%, var(--surface-color));
}

[data-theme="dark"] .alert-info,
[data-theme="coffee"] .alert-info,
[data-theme="aurora"] .alert-info,
[data-theme="nebula"] .alert-info,
[data-theme="midnight"] .alert-info,
[data-theme="charcoal"] .alert-info,
[data-theme="obsidian"] .alert-info,
[data-theme="slate"] .alert-info,
[data-theme="lightning"] .alert-info {
    color: #93c5fd;
    background-color: color-mix(in srgb, var(--info-color) 20%, var(--surface-color));
}

/* === CARD HEADER FIXES === */

/* Ensure card headers with bg-* classes have proper text contrast */
.card-header.bg-primary,
.card-header.bg-secondary,
.card-header.bg-success,
.card-header.bg-danger,
.card-header.bg-info,
.card-header.bg-dark {
    color: white !important;
}

.card-header.bg-primary *,
.card-header.bg-secondary *,
.card-header.bg-success *,
.card-header.bg-danger *,
.card-header.bg-info *,
.card-header.bg-dark * {
    color: white !important;
}

.card-header.bg-warning {
    color: #1a1a1a !important;
}

.card-header.bg-warning * {
    color: #1a1a1a !important;
}

.card-header.bg-light {
    color: #212121 !important;
}

.card-header.bg-light * {
    color: #212121 !important;
}

.card-header.bg-light .text-muted {
    color: #6b7280 !important;
}

/* === FORM CONTROL FIXES === */

/* Ensure form controls are visible on all themes */
.form-check-input {
    background-color: var(--surface-color);
    border: 2px solid var(--border-color);
}

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

/* Form switch track visibility on dark themes */
[data-theme="dark"] .form-check-input:not(:checked),
[data-theme="coffee"] .form-check-input:not(:checked),
[data-theme="aurora"] .form-check-input:not(:checked),
[data-theme="nebula"] .form-check-input:not(:checked),
[data-theme="midnight"] .form-check-input:not(:checked),
[data-theme="charcoal"] .form-check-input:not(:checked),
[data-theme="obsidian"] .form-check-input:not(:checked),
[data-theme="slate"] .form-check-input:not(:checked) {
    background-color: var(--surface-color);
    border-color: var(--border-color);
}

/* Form switch styling - ensure toggle knob is visible */
.form-switch .form-check-input {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23ffffff'/%3e%3c/svg%3e");
}

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

[data-theme="dark"] .form-switch .form-check-input:not(:checked),
[data-theme="coffee"] .form-switch .form-check-input:not(:checked),
[data-theme="aurora"] .form-switch .form-check-input:not(:checked),
[data-theme="nebula"] .form-switch .form-check-input:not(:checked),
[data-theme="midnight"] .form-switch .form-check-input:not(:checked),
[data-theme="charcoal"] .form-switch .form-check-input:not(:checked),
[data-theme="obsidian"] .form-switch .form-check-input:not(:checked),
[data-theme="slate"] .form-switch .form-check-input:not(:checked) {
    background-color: var(--light-color);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23555555'/%3e%3c/svg%3e");
}

/* Form labels always readable */
.form-label,
.form-check-label {
    color: var(--text-color);
}

/* Select dropdown arrow visibility */
.form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
}

[data-theme="dark"] .form-select,
[data-theme="coffee"] .form-select,
[data-theme="aurora"] .form-select,
[data-theme="nebula"] .form-select,
[data-theme="midnight"] .form-select,
[data-theme="charcoal"] .form-select,
[data-theme="obsidian"] .form-select,
[data-theme="slate"] .form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
}

/* === TABLE READABILITY FIXES === */

/* Ensure table headers are readable with a clearly visible tint */
.table thead th {
    color: var(--text-color);
    background-color: color-mix(in srgb, var(--surface-color) 82%, var(--primary-color));
    border-bottom: 2px solid var(--border-color);
}

/* Sortable column header links */
.sort-header {
    color: inherit;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    white-space: nowrap;
    transition: opacity 0.15s;
}
.sort-header:hover {
    opacity: 0.8;
    color: inherit;
}
.sort-header.sort-active {
    font-weight: var(--font-weight-bold, 700);
}
.sort-inactive {
    opacity: 0.35;
}

.table-dark {
    color: #ffffff !important;
    background-color: var(--dark-color) !important;
}

.table-dark th,
.table-dark td {
    color: #ffffff !important;
    border-color: rgba(255, 255, 255, 0.2) !important;
}

/* === LIST GROUP FIXES === */

.list-group-item {
    background-color: var(--surface-color);
    color: var(--text-color);
    border-color: var(--border-color);
}

.list-group-item-action:hover,
.list-group-item-action:focus {
    background-color: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));
    color: var(--text-color);
}

.list-group-item.active {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
    color: white;
}

/* Contextual list group items */
.list-group-item-primary {
    background-color: color-mix(in srgb, var(--primary-color) 20%, var(--surface-color));
    color: var(--text-color);
}

.list-group-item-success {
    background-color: color-mix(in srgb, var(--success-color) 20%, var(--surface-color));
    color: var(--text-color);
}

.list-group-item-danger {
    background-color: color-mix(in srgb, var(--danger-color) 20%, var(--surface-color));
    color: var(--text-color);
}

.list-group-item-warning {
    background-color: color-mix(in srgb, var(--warning-color) 20%, var(--surface-color));
    color: var(--text-color);
}

.list-group-item-info {
    background-color: color-mix(in srgb, var(--info-color) 20%, var(--surface-color));
    color: var(--text-color);
}

/* === DROPDOWN FIXES === */

.dropdown-menu {
    background-color: var(--surface-color);
    border-color: var(--border-color);
    box-shadow: var(--shadow-lg);
}

.dropdown-item {
    color: var(--text-color);
}

.dropdown-item:hover,
.dropdown-item:focus {
    background-color: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));
    color: var(--text-color);
}

.dropdown-item.active,
.dropdown-item:active {
    background-color: var(--primary-color);
    color: white;
}

.dropdown-divider {
    border-top-color: var(--border-color);
}

/* === MODAL FIXES === */

.modal-content {
    background-color: var(--surface-color);
    color: var(--text-color);
    border-color: var(--border-color);
}

.modal-header {
    border-bottom-color: var(--border-color);
}

.modal-footer {
    border-top-color: var(--border-color);
}

.btn-close {
    filter: var(--btn-close-filter, none);
}

[data-theme="dark"] .btn-close,
[data-theme="coffee"] .btn-close,
[data-theme="aurora"] .btn-close,
[data-theme="nebula"] .btn-close,
[data-theme="midnight"] .btn-close,
[data-theme="charcoal"] .btn-close,
[data-theme="obsidian"] .btn-close,
[data-theme="slate"] .btn-close,
[data-theme="lightning"] .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

/* === PAGINATION FIXES === */

.page-link {
    background-color: var(--surface-color);
    color: var(--primary-color);
    border-color: var(--border-color);
}

.page-link:hover {
    background-color: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));
    color: var(--primary-color);
    border-color: var(--border-color);
}

.page-item.active .page-link {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
    color: white;
}

.page-item.disabled .page-link {
    background-color: var(--surface-color);
    color: var(--text-muted);
    border-color: var(--border-color);
}

/* === BREADCRUMB FIXES === */

.breadcrumb {
    background-color: transparent;
}

.breadcrumb-item {
    color: var(--text-muted);
}

.breadcrumb-item a {
    color: var(--primary-color);
}

.breadcrumb-item.active {
    color: var(--text-color);
}

.breadcrumb-item + .breadcrumb-item::before {
    color: var(--text-muted);
}

/* === NAV TABS/PILLS FIXES === */

.nav-tabs .nav-link {
    color: var(--text-color);
    border-color: transparent;
}

.nav-tabs .nav-link:hover,
.nav-tabs .nav-link:focus {
    border-color: var(--border-color);
    color: var(--primary-color);
}

.nav-tabs .nav-link.active {
    background-color: var(--surface-color);
    border-color: var(--border-color) var(--border-color) var(--surface-color);
    color: var(--primary-color);
}

.nav-pills .nav-link {
    color: var(--text-color);
}

.nav-pills .nav-link:hover {
    background-color: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));
}

.nav-pills .nav-link.active {
    background-color: var(--primary-color);
    color: white;
}

/* === PROGRESS BAR FIXES === */

.progress {
    background-color: color-mix(in srgb, var(--text-color) 10%, var(--surface-color));
}

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

/* === TOOLTIP & POPOVER FIXES === */

.tooltip-inner {
    background-color: var(--dark-color);
    color: white;
}

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

.popover-header {
    background-color: color-mix(in srgb, var(--surface-color) 95%, var(--primary-color));
    border-bottom-color: var(--border-color);
    color: var(--text-color);
}

.popover-body {
    color: var(--text-color);
}

/* === ACCORDION FIXES === */

.accordion-item {
    background-color: var(--surface-color);
    border-color: var(--border-color);
}

.accordion-button {
    background-color: var(--surface-color);
    color: var(--text-color);
}

.accordion-button:not(.collapsed) {
    background-color: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));
    color: var(--primary-color);
}

.accordion-button:focus {
    border-color: var(--primary-color);
    box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--primary-color) 25%, transparent);
}

.accordion-button::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

[data-theme="dark"] .accordion-button::after,
[data-theme="coffee"] .accordion-button::after,
[data-theme="aurora"] .accordion-button::after,
[data-theme="nebula"] .accordion-button::after,
[data-theme="midnight"] .accordion-button::after,
[data-theme="charcoal"] .accordion-button::after,
[data-theme="obsidian"] .accordion-button::after,
[data-theme="slate"] .accordion-button::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

.accordion-body {
    background-color: var(--surface-color);
    color: var(--text-color);
}

/* === SPINNER FIXES === */

.spinner-border {
    color: var(--primary-color);
}

.spinner-grow {
    color: var(--primary-color);
}

/* === OFFCANVAS FIXES === */

.offcanvas {
    background-color: var(--surface-color);
    color: var(--text-color);
}

.offcanvas-header {
    border-bottom-color: var(--border-color);
}

/* === TOAST FIXES === */

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

.toast-header {
    background-color: color-mix(in srgb, var(--surface-color) 95%, var(--primary-color));
    color: var(--text-color);
    border-bottom-color: var(--border-color);
}

/* === INPUT GROUP FIXES === */

.input-group-text {
    background-color: color-mix(in srgb, var(--surface-color) 95%, var(--border-color));
    color: var(--text-color);
    border-color: var(--border-color);
}

/* === BOOTSTRAP CSS VARIABLE OVERRIDES FOR DARK THEMES ===
   Bootstrap 5.3 hard-codes its --bs-* CSS variables to light-theme values inside
   :root. EAS Station™ uses data-theme (not data-bs-theme), so Bootstrap never
   activates its own dark-mode palette. Override the relevant Bootstrap variables
   here so every Bootstrap component (cards, tables, alerts, accordions, etc.)
   adapts to the active theme palette. */

[data-theme="dark"],
[data-theme="coffee"],
[data-theme="aurora"],
[data-theme="nebula"],
[data-theme="midnight"],
[data-theme="charcoal"],
[data-theme="obsidian"],
[data-theme="slate"] {
    /* ── Core body ── */
    --bs-body-color: var(--text-color);
    --bs-body-bg: var(--bg-color);
    --bs-emphasis-color: var(--text-color);
    --bs-secondary-color: var(--text-secondary);
    --bs-tertiary-color: var(--text-muted);
    --bs-secondary-bg: var(--surface-color);
    --bs-tertiary-bg: color-mix(in srgb, var(--surface-color) 85%, var(--bg-color));

    /* ── Borders ── */
    --bs-border-color: var(--border-color);
    --bs-border-color-translucent: color-mix(in srgb, var(--border-color) 70%, transparent);

    /* ── Card ── */
    --bs-card-bg: var(--surface-color);
    --bs-card-color: var(--text-color);
    --bs-card-cap-bg: color-mix(in srgb, var(--primary-color) 14%, var(--surface-color));
    --bs-card-cap-color: var(--text-color);

    /* ── Subtle background tints (used by bg-*-subtle badges / highlights) ── */
    --bs-primary-bg-subtle: color-mix(in srgb, var(--primary-color) 20%, var(--surface-color));
    --bs-secondary-bg-subtle: color-mix(in srgb, var(--secondary-color) 20%, var(--surface-color));
    --bs-success-bg-subtle: color-mix(in srgb, var(--success-color) 20%, var(--surface-color));
    --bs-danger-bg-subtle: color-mix(in srgb, var(--danger-color) 20%, var(--surface-color));
    --bs-warning-bg-subtle: color-mix(in srgb, var(--warning-color) 20%, var(--surface-color));
    --bs-info-bg-subtle: color-mix(in srgb, var(--info-color) 20%, var(--surface-color));
    --bs-light-bg-subtle: var(--light-color);
    --bs-dark-bg-subtle: var(--dark-color);

    /* ── Subtle border tints ── */
    --bs-primary-border-subtle: color-mix(in srgb, var(--primary-color) 40%, var(--border-color));
    --bs-secondary-border-subtle: color-mix(in srgb, var(--secondary-color) 40%, var(--border-color));
    --bs-success-border-subtle: color-mix(in srgb, var(--success-color) 40%, var(--border-color));
    --bs-danger-border-subtle: color-mix(in srgb, var(--danger-color) 40%, var(--border-color));
    --bs-warning-border-subtle: color-mix(in srgb, var(--warning-color) 40%, var(--border-color));
    --bs-info-border-subtle: color-mix(in srgb, var(--info-color) 40%, var(--border-color));
    --bs-light-border-subtle: var(--border-color);
    --bs-dark-border-subtle: var(--border-color);

    /* ── Text-emphasis colors (used by text-*-emphasis utilities) ── */
    --bs-primary-text-emphasis: var(--primary-color);
    --bs-secondary-text-emphasis: var(--secondary-color);
    --bs-success-text-emphasis: var(--success-color);
    --bs-danger-text-emphasis: var(--danger-color);
    --bs-warning-text-emphasis: var(--warning-color);
    --bs-info-text-emphasis: var(--info-color);
    --bs-light-text-emphasis: var(--text-color);
    --bs-dark-text-emphasis: var(--text-color);

    /* ── Accordion ── */
    --bs-accordion-bg: var(--surface-color);
    --bs-accordion-color: var(--text-color);
    --bs-accordion-btn-color: var(--text-color);
    --bs-accordion-btn-bg: var(--surface-color);
    --bs-accordion-active-bg: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));
    --bs-accordion-active-color: var(--primary-color);
    --bs-accordion-border-color: var(--border-color);

    /* ── Modal ── */
    --bs-modal-bg: var(--surface-color);
    --bs-modal-color: var(--text-color);
    --bs-modal-border-color: var(--border-color);
    --bs-modal-header-bg: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));

    /* ── Dropdown ── */
    --bs-dropdown-bg: var(--surface-color);
    --bs-dropdown-color: var(--text-color);
    --bs-dropdown-border-color: var(--border-color);
    --bs-dropdown-link-color: var(--text-color);
    --bs-dropdown-link-hover-color: var(--text-color);
    --bs-dropdown-link-hover-bg: color-mix(in srgb, var(--primary-color) 15%, var(--surface-color));
    --bs-dropdown-header-color: var(--text-secondary);
    --bs-dropdown-divider-bg: var(--border-color);

    /* ── List group ── */
    --bs-list-group-bg: var(--surface-color);
    --bs-list-group-color: var(--text-color);
    --bs-list-group-border-color: var(--border-color);
    --bs-list-group-action-color: var(--text-color);
    --bs-list-group-action-hover-color: var(--text-color);
    --bs-list-group-action-hover-bg: color-mix(in srgb, var(--primary-color) 10%, var(--surface-color));

    /* ── Table ── */
    --bs-table-color: var(--text-color);
    --bs-table-bg: transparent;
    --bs-table-border-color: var(--border-color);
    --bs-table-striped-color: var(--text-color);
    --bs-table-striped-bg: color-mix(in srgb, var(--surface-color) 97%, var(--border-color));
    --bs-table-hover-color: var(--text-color);
    --bs-table-hover-bg: color-mix(in srgb, var(--primary-color) 8%, var(--surface-color));

    /* ── Pagination ── */
    --bs-pagination-bg: var(--surface-color);
    --bs-pagination-color: var(--text-color);
    --bs-pagination-border-color: var(--border-color);
    --bs-pagination-hover-bg: color-mix(in srgb, var(--primary-color) 15%, var(--surface-color));
    --bs-pagination-hover-color: var(--text-color);
    --bs-pagination-hover-border-color: var(--border-color);
    --bs-pagination-disabled-bg: var(--surface-color);
    --bs-pagination-disabled-color: var(--text-muted);
    --bs-pagination-disabled-border-color: var(--border-color);

    /* ── Input group ── */
    --bs-input-group-addon-bg: color-mix(in srgb, var(--surface-color) 90%, var(--border-color));
    --bs-input-group-addon-color: var(--text-color);
    --bs-input-group-addon-border-color: var(--border-color);

    /* ── Popover / Tooltip ── */
    --bs-tooltip-bg: var(--dark-color);
    --bs-tooltip-color: var(--text-color);
    --bs-popover-bg: var(--surface-color);
    --bs-popover-body-color: var(--text-color);
    --bs-popover-header-bg: color-mix(in srgb, var(--primary-color) 14%, var(--surface-color));
    --bs-popover-header-color: var(--text-color);
    --bs-popover-border-color: var(--border-color);

    /* ── Offcanvas ── */
    --bs-offcanvas-bg: var(--surface-color);
    --bs-offcanvas-color: var(--text-color);
    --bs-offcanvas-border-color: var(--border-color);

    /* ── Breadcrumb ── */
    --bs-breadcrumb-divider-color: var(--text-muted);
    --bs-breadcrumb-item-active-color: var(--text-muted);

    /* ── Nav / Tab ── */
    --bs-nav-tabs-border-color: var(--border-color);
    --bs-nav-tabs-link-hover-border-color: var(--border-color);
    --bs-nav-tabs-link-active-color: var(--primary-color);
    --bs-nav-tabs-link-active-bg: var(--surface-color);
    --bs-nav-tabs-link-active-border-color: var(--border-color) var(--border-color) var(--surface-color);

    /* ── Links ── */
    --bs-link-color: var(--primary-color);
    --bs-link-hover-color: color-mix(in srgb, var(--primary-color) 80%, white);
}

/* alert-light and alert-secondary need explicit dark-theme overrides because
   Bootstrap sets their local variables inline and the standard dark palette
   would produce near-invisible text otherwise. */
[data-theme="dark"] .alert-light,
[data-theme="coffee"] .alert-light,
[data-theme="aurora"] .alert-light,
[data-theme="nebula"] .alert-light,
[data-theme="midnight"] .alert-light,
[data-theme="charcoal"] .alert-light,
[data-theme="obsidian"] .alert-light,
[data-theme="slate"] .alert-light,
[data-theme="lightning"] .alert-light {
    --bs-alert-color: var(--text-color);
    --bs-alert-bg: color-mix(in srgb, var(--surface-color) 90%, var(--border-color));
    --bs-alert-border-color: var(--border-color);
    color: var(--text-color);
    background-color: color-mix(in srgb, var(--surface-color) 90%, var(--border-color));
    border-color: var(--border-color);
}

[data-theme="dark"] .alert-secondary,
[data-theme="coffee"] .alert-secondary,
[data-theme="aurora"] .alert-secondary,
[data-theme="nebula"] .alert-secondary,
[data-theme="midnight"] .alert-secondary,
[data-theme="charcoal"] .alert-secondary,
[data-theme="obsidian"] .alert-secondary,
[data-theme="slate"] .alert-secondary,
[data-theme="lightning"] .alert-secondary {
    --bs-alert-color: var(--text-secondary);
    --bs-alert-bg: color-mix(in srgb, var(--secondary-color) 15%, var(--surface-color));
    --bs-alert-border-color: color-mix(in srgb, var(--secondary-color) 30%, var(--border-color));
    color: var(--text-secondary);
    background-color: color-mix(in srgb, var(--secondary-color) 15%, var(--surface-color));
    border-color: color-mix(in srgb, var(--secondary-color) 30%, var(--border-color));
}

/* === DARK THEME CONTRAST FIXES ===
   Dark themes define pastel/bright semantic colors (e.g. success=#67ffd6, info=#adcfff,
   danger=#ffafbf) that are too light for white text to meet WCAG AA contrast (4.5:1).
   Override text color to dark for all semantic bg-* classes and card-header variants
   across every dark theme. */

/* Dark themes: badges with success/info/danger/secondary backgrounds need dark text */
[data-theme="dark"] .badge.bg-success,
[data-theme="coffee"] .badge.bg-success,
[data-theme="aurora"] .badge.bg-success,
[data-theme="nebula"] .badge.bg-success,
[data-theme="midnight"] .badge.bg-success,
[data-theme="charcoal"] .badge.bg-success,
[data-theme="obsidian"] .badge.bg-success,
[data-theme="slate"] .badge.bg-success,
[data-theme="dark"] .badge.bg-info,
[data-theme="coffee"] .badge.bg-info,
[data-theme="aurora"] .badge.bg-info,
[data-theme="nebula"] .badge.bg-info,
[data-theme="midnight"] .badge.bg-info,
[data-theme="charcoal"] .badge.bg-info,
[data-theme="obsidian"] .badge.bg-info,
[data-theme="slate"] .badge.bg-info,
[data-theme="dark"] .badge.bg-danger,
[data-theme="coffee"] .badge.bg-danger,
[data-theme="aurora"] .badge.bg-danger,
[data-theme="nebula"] .badge.bg-danger,
[data-theme="midnight"] .badge.bg-danger,
[data-theme="charcoal"] .badge.bg-danger,
[data-theme="obsidian"] .badge.bg-danger,
[data-theme="slate"] .badge.bg-danger,
[data-theme="dark"] .badge.bg-secondary,
[data-theme="coffee"] .badge.bg-secondary,
[data-theme="aurora"] .badge.bg-secondary,
[data-theme="nebula"] .badge.bg-secondary,
[data-theme="midnight"] .badge.bg-secondary,
[data-theme="charcoal"] .badge.bg-secondary,
[data-theme="obsidian"] .badge.bg-secondary,
[data-theme="slate"] .badge.bg-secondary {
    color: #0f172a !important;
    text-shadow: none;
}

/* Dark themes: card-headers with semantic bg-* need dark text + children */
[data-theme="dark"] .card-header.bg-success,
[data-theme="coffee"] .card-header.bg-success,
[data-theme="aurora"] .card-header.bg-success,
[data-theme="nebula"] .card-header.bg-success,
[data-theme="midnight"] .card-header.bg-success,
[data-theme="charcoal"] .card-header.bg-success,
[data-theme="obsidian"] .card-header.bg-success,
[data-theme="slate"] .card-header.bg-success,
[data-theme="dark"] .card-header.bg-info,
[data-theme="coffee"] .card-header.bg-info,
[data-theme="aurora"] .card-header.bg-info,
[data-theme="nebula"] .card-header.bg-info,
[data-theme="midnight"] .card-header.bg-info,
[data-theme="charcoal"] .card-header.bg-info,
[data-theme="obsidian"] .card-header.bg-info,
[data-theme="slate"] .card-header.bg-info,
[data-theme="dark"] .card-header.bg-danger,
[data-theme="coffee"] .card-header.bg-danger,
[data-theme="aurora"] .card-header.bg-danger,
[data-theme="nebula"] .card-header.bg-danger,
[data-theme="midnight"] .card-header.bg-danger,
[data-theme="charcoal"] .card-header.bg-danger,
[data-theme="obsidian"] .card-header.bg-danger,
[data-theme="slate"] .card-header.bg-danger,
[data-theme="dark"] .card-header.bg-secondary,
[data-theme="coffee"] .card-header.bg-secondary,
[data-theme="aurora"] .card-header.bg-secondary,
[data-theme="nebula"] .card-header.bg-secondary,
[data-theme="midnight"] .card-header.bg-secondary,
[data-theme="charcoal"] .card-header.bg-secondary,
[data-theme="obsidian"] .card-header.bg-secondary,
[data-theme="slate"] .card-header.bg-secondary {
    color: #0f172a !important;
}

[data-theme="dark"] .card-header.bg-success *,
[data-theme="coffee"] .card-header.bg-success *,
[data-theme="aurora"] .card-header.bg-success *,
[data-theme="nebula"] .card-header.bg-success *,
[data-theme="midnight"] .card-header.bg-success *,
[data-theme="charcoal"] .card-header.bg-success *,
[data-theme="obsidian"] .card-header.bg-success *,
[data-theme="slate"] .card-header.bg-success *,
[data-theme="dark"] .card-header.bg-info *,
[data-theme="coffee"] .card-header.bg-info *,
[data-theme="aurora"] .card-header.bg-info *,
[data-theme="nebula"] .card-header.bg-info *,
[data-theme="midnight"] .card-header.bg-info *,
[data-theme="charcoal"] .card-header.bg-info *,
[data-theme="obsidian"] .card-header.bg-info *,
[data-theme="slate"] .card-header.bg-info *,
[data-theme="dark"] .card-header.bg-danger *,
[data-theme="coffee"] .card-header.bg-danger *,
[data-theme="aurora"] .card-header.bg-danger *,
[data-theme="nebula"] .card-header.bg-danger *,
[data-theme="midnight"] .card-header.bg-danger *,
[data-theme="charcoal"] .card-header.bg-danger *,
[data-theme="obsidian"] .card-header.bg-danger *,
[data-theme="slate"] .card-header.bg-danger *,
[data-theme="dark"] .card-header.bg-secondary *,
[data-theme="coffee"] .card-header.bg-secondary *,
[data-theme="aurora"] .card-header.bg-secondary *,
[data-theme="nebula"] .card-header.bg-secondary *,
[data-theme="midnight"] .card-header.bg-secondary *,
[data-theme="charcoal"] .card-header.bg-secondary *,
[data-theme="obsidian"] .card-header.bg-secondary *,
[data-theme="slate"] .card-header.bg-secondary * {
    color: #0f172a !important;
}

/* Dark themes: general bg-success/info/danger/secondary utility classes */
[data-theme="dark"] .bg-success,
[data-theme="coffee"] .bg-success,
[data-theme="aurora"] .bg-success,
[data-theme="nebula"] .bg-success,
[data-theme="midnight"] .bg-success,
[data-theme="charcoal"] .bg-success,
[data-theme="obsidian"] .bg-success,
[data-theme="slate"] .bg-success,
[data-theme="dark"] .bg-info,
[data-theme="coffee"] .bg-info,
[data-theme="aurora"] .bg-info,
[data-theme="nebula"] .bg-info,
[data-theme="midnight"] .bg-info,
[data-theme="charcoal"] .bg-info,
[data-theme="obsidian"] .bg-info,
[data-theme="slate"] .bg-info,
[data-theme="dark"] .bg-danger,
[data-theme="coffee"] .bg-danger,
[data-theme="aurora"] .bg-danger,
[data-theme="nebula"] .bg-danger,
[data-theme="midnight"] .bg-danger,
[data-theme="charcoal"] .bg-danger,
[data-theme="obsidian"] .bg-danger,
[data-theme="slate"] .bg-danger {
    color: #0f172a !important;
}

/* Dark themes: text-bg-* utility pairs */
[data-theme="dark"] .text-bg-success,
[data-theme="coffee"] .text-bg-success,
[data-theme="aurora"] .text-bg-success,
[data-theme="nebula"] .text-bg-success,
[data-theme="midnight"] .text-bg-success,
[data-theme="charcoal"] .text-bg-success,
[data-theme="obsidian"] .text-bg-success,
[data-theme="slate"] .text-bg-success,
[data-theme="dark"] .text-bg-info,
[data-theme="coffee"] .text-bg-info,
[data-theme="aurora"] .text-bg-info,
[data-theme="nebula"] .text-bg-info,
[data-theme="midnight"] .text-bg-info,
[data-theme="charcoal"] .text-bg-info,
[data-theme="obsidian"] .text-bg-info,
[data-theme="slate"] .text-bg-info,
[data-theme="dark"] .text-bg-danger,
[data-theme="coffee"] .text-bg-danger,
[data-theme="aurora"] .text-bg-danger,
[data-theme="nebula"] .text-bg-danger,
[data-theme="midnight"] .text-bg-danger,
[data-theme="charcoal"] .text-bg-danger,
[data-theme="obsidian"] .text-bg-danger,
[data-theme="slate"] .text-bg-danger {
    color: #0f172a !important;
}

/* =========================================================================
   EAS Shared Visual System
   -------------------------------------------------------------------------
   Promoted from templates/about.html so every page can use the same
   gradient hero, section-card, icon-tile language. `.about-*` selectors
   are kept as aliases so the About page (and any future callers that
   reference the legacy names) continue to render identically.

   Depends on CSS custom properties defined above (--vibrant-*, --radius-*,
   --shadow-*, --surface-color, --text-color, --text-secondary,
   --border-color, --ease-spring) and the @keyframes `headerGlow` and
   `gradientShift` already defined in this file.
   ========================================================================= */

.eas-page, .about-page { position: relative; }

/* ---- Hero banner --------------------------------------------------------- */
.eas-hero {
    padding: 3rem 2.5rem 2.75rem;
    margin-bottom: 1.75rem;
    border-radius: var(--radius-2xl);
    overflow: hidden;
    position: relative;
    background: linear-gradient(135deg,
        var(--vibrant-indigo) 0%,
        var(--vibrant-purple) 45%,
        color-mix(in srgb, var(--vibrant-pink) 85%, var(--vibrant-orange)) 100%);
    color: #fff;
    box-shadow: var(--shadow-xl),
                0 0 0 1px rgba(255, 255, 255, 0.12) inset,
                0 0 48px color-mix(in srgb, var(--vibrant-purple) 35%, transparent);
}
.eas-hero::before {
    content: "";
    position: absolute; inset: -40% -20% auto auto;
    width: 70%; height: 180%;
    background: radial-gradient(ellipse at center,
        rgba(255,255,255,0.22), rgba(255,255,255,0.05) 50%, transparent 75%);
    animation: headerGlow 9s ease-in-out infinite;
    pointer-events: none;
}
.eas-hero::after {
    content: "";
    position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
    background: linear-gradient(90deg,
        var(--vibrant-pink), var(--vibrant-orange),
        var(--vibrant-yellow), var(--vibrant-green),
        var(--vibrant-blue), var(--vibrant-pink));
    background-size: 300% 100%;
    animation: gradientShift 8s linear infinite;
}
.eas-hero-inner {
    position: relative; z-index: 2;
    display: flex; flex-direction: column; align-items: center; text-align: center;
    gap: 1rem;
}
.eas-hero-logo {
    max-width: 680px;
    width: 100%;
    padding: 1.25rem 1.75rem;
    border-radius: var(--radius-xl);
    background: rgba(15, 23, 42, 0.55);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 14px 36px rgba(0, 0, 0, 0.28),
                0 0 0 1px rgba(255, 255, 255, 0.18) inset;
}
.eas-hero-title {
    font-size: clamp(1.9rem, 3.2vw, 2.6rem);
    font-weight: 800; letter-spacing: -0.02em;
    margin: 0;
    /* Explicit white: the global `h1 { color: var(--text-color) }` rule
       otherwise overrides the hero's inherited white and renders the title
       near-black on the gradient in light themes. */
    color: #ffffff;
    text-shadow: 0 2px 12px rgba(0,0,0,0.25);
}
.eas-hero-lead {
    font-size: 1.05rem; font-weight: 500;
    /* Full-opacity white: the hero gradient is theme-independent, so this
       lead measured the same ~3.85:1 in all 20 themes. The shadow below is
       what carries the remainder of the separation. */
    color: #ffffff;
    max-width: 720px; margin: 0 auto;
    text-shadow: 0 1px 3px rgba(0,0,0,0.35);
}

/* ---- Chip row (pill metadata) ------------------------------------------- */
.eas-chip-row {
    display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center;
    margin-top: 0.5rem;
}
.eas-chip {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.35rem 0.85rem;
    border-radius: 999px;
    background: rgba(255,255,255,0.14);
    border: 1px solid rgba(255,255,255,0.28);
    backdrop-filter: blur(8px);
    font-size: 0.78rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
    color: #fff;
}
.eas-chip i { opacity: 0.9; }

/* ---- Section cards ------------------------------------------------------ */
.eas-card,
.about-card {
    background: var(--surface-color, #fff);
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-md);
    padding: 1.75rem;
    margin-bottom: 1.5rem;
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 70%, transparent);
    position: relative;
}
.eas-section-head,
.about-section-head {
    display: flex; align-items: center; gap: 0.75rem;
    margin-bottom: 1.25rem;
}
.eas-section-icon,
.about-section-icon {
    width: 42px; height: 42px; border-radius: 12px;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 1.05rem;
    box-shadow: 0 6px 18px rgba(0,0,0,0.12);
    flex-shrink: 0;
}
.eas-section-icon.ico-primary,
.about-section-icon.ico-primary { background: linear-gradient(135deg, var(--vibrant-blue), var(--vibrant-indigo)); }
.eas-section-icon.ico-success,
.about-section-icon.ico-success { background: linear-gradient(135deg, var(--vibrant-green), var(--vibrant-teal)); }
.eas-section-icon.ico-info,
.about-section-icon.ico-info    { background: linear-gradient(135deg, var(--vibrant-teal), var(--vibrant-blue)); }
.eas-section-icon.ico-warning,
.about-section-icon.ico-warning { background: linear-gradient(135deg, var(--vibrant-orange), var(--vibrant-yellow)); color: #1a1a1a; }
.eas-section-icon.ico-danger,
.about-section-icon.ico-danger  { background: linear-gradient(135deg, var(--vibrant-red), var(--vibrant-pink)); }
.eas-section-icon.ico-purple,
.about-section-icon.ico-purple  { background: linear-gradient(135deg, var(--vibrant-purple), var(--vibrant-indigo)); }
.eas-section-title,
.about-section-title {
    font-size: 1.2rem; font-weight: 700; letter-spacing: -0.01em; margin: 0;
    color: var(--text-color);
}
.eas-section-sub,
.about-section-sub {
    font-size: 0.85rem; color: var(--text-secondary); margin: 0;
}

/* ---- Compliance grid (level-tinted tiles) ------------------------------- */
.eas-compliance-grid,
.compliance-grid {
    display: grid; gap: 0.85rem;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.eas-compliance-item,
.compliance-item {
    display: flex; gap: 0.85rem; padding: 1rem 1.1rem;
    border-radius: var(--radius-lg, 14px);
    border: 1px solid transparent;
    background: color-mix(in srgb, var(--border-color, #e5e7eb) 25%, transparent);
}
.eas-compliance-item.lvl-warn,
.compliance-item.lvl-warn   { background: color-mix(in srgb, var(--vibrant-orange) 12%, transparent); border-color: color-mix(in srgb, var(--vibrant-orange) 35%, transparent); }
.eas-compliance-item.lvl-danger,
.compliance-item.lvl-danger { background: color-mix(in srgb, var(--vibrant-red)    12%, transparent); border-color: color-mix(in srgb, var(--vibrant-red)    35%, transparent); }
.eas-compliance-item.lvl-legal,
.compliance-item.lvl-legal  { background: color-mix(in srgb, var(--vibrant-indigo) 10%, transparent); border-color: color-mix(in srgb, var(--vibrant-indigo) 30%, transparent); }
.eas-compliance-item.lvl-ethics,
.compliance-item.lvl-ethics { background: color-mix(in srgb, var(--vibrant-purple) 10%, transparent); border-color: color-mix(in srgb, var(--vibrant-purple) 30%, transparent); }
.eas-compliance-ico,
.compliance-ico {
    flex-shrink: 0; width: 36px; height: 36px; border-radius: 10px;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 0.95rem;
}
.eas-compliance-item.lvl-warn   .eas-compliance-ico,
.compliance-item.lvl-warn   .compliance-ico { background: var(--vibrant-orange); color: #1a1a1a; }
.eas-compliance-item.lvl-danger .eas-compliance-ico,
.compliance-item.lvl-danger .compliance-ico { background: var(--vibrant-red); }
.eas-compliance-item.lvl-legal  .eas-compliance-ico,
.compliance-item.lvl-legal  .compliance-ico { background: var(--vibrant-indigo); }
.eas-compliance-item.lvl-ethics .eas-compliance-ico,
.compliance-item.lvl-ethics .compliance-ico { background: var(--vibrant-purple); }
.eas-compliance-title,
.compliance-title { font-weight: 700; font-size: 0.92rem; margin: 0 0 0.2rem; color: var(--text-color); }
.eas-compliance-body,
.compliance-body  { font-size: 0.85rem; line-height: 1.5; color: var(--text-color); margin: 0; }
.eas-compliance-body a,
.compliance-body a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }

/* ---- Feature / service cards ------------------------------------------- */
.eas-feature-card,
.feature-card {
    background: var(--surface-color, #fff);
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 80%, transparent);
    border-radius: var(--radius-lg, 14px);
    padding: 1.25rem;
    transition: transform .25s var(--ease-spring, ease),
                box-shadow .25s var(--ease-spring, ease),
                border-color .25s ease;
    height: 100%;
    position: relative;
    overflow: hidden;
}
.eas-feature-card:hover,
.feature-card:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--vibrant-blue) 35%, transparent);
    box-shadow: 0 12px 28px rgba(0,0,0,0.08),
                0 0 0 1px color-mix(in srgb, var(--vibrant-blue) 25%, transparent) inset;
}
.eas-feature-card-icon,
.feature-card-icon {
    width: 44px; height: 44px; border-radius: 12px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 1.05rem; color: #fff;
    margin-bottom: 0.8rem;
    background: linear-gradient(135deg, var(--vibrant-blue), var(--vibrant-indigo));
    box-shadow: 0 6px 14px color-mix(in srgb, var(--vibrant-blue) 30%, transparent);
}
.eas-feature-card-title,
.feature-card-title { font-size: 0.98rem; font-weight: 700; margin: 0 0 0.35rem; color: var(--text-color); letter-spacing: -0.005em; }
.eas-feature-card-text,
.feature-card-text  { font-size: 0.85rem; color: var(--text-secondary); margin: 0; line-height: 1.5; }

/* Accent palette for service/feature icons */
.fc-blue   .eas-feature-card-icon,
.fc-blue   .feature-card-icon { background: linear-gradient(135deg, var(--vibrant-blue), var(--vibrant-indigo)); box-shadow: 0 6px 14px color-mix(in srgb, var(--vibrant-blue) 30%, transparent); }
.fc-green  .eas-feature-card-icon,
.fc-green  .feature-card-icon { background: linear-gradient(135deg, var(--vibrant-green), var(--vibrant-teal));  box-shadow: 0 6px 14px color-mix(in srgb, var(--vibrant-green) 30%, transparent); }
.fc-purple .eas-feature-card-icon,
.fc-purple .feature-card-icon { background: linear-gradient(135deg, var(--vibrant-purple), var(--vibrant-indigo)); box-shadow: 0 6px 14px color-mix(in srgb, var(--vibrant-purple) 30%, transparent); }
.fc-orange .eas-feature-card-icon,
.fc-orange .feature-card-icon { background: linear-gradient(135deg, var(--vibrant-orange), var(--vibrant-yellow)); color: #1a1a1a; box-shadow: 0 6px 14px color-mix(in srgb, var(--vibrant-orange) 30%, transparent); }
.fc-pink   .eas-feature-card-icon,
.fc-pink   .feature-card-icon { background: linear-gradient(135deg, var(--vibrant-pink), var(--vibrant-red));    box-shadow: 0 6px 14px color-mix(in srgb, var(--vibrant-pink) 30%, transparent); }
.fc-teal   .eas-feature-card-icon,
.fc-teal   .feature-card-icon { background: linear-gradient(135deg, var(--vibrant-teal), var(--vibrant-mint));   box-shadow: 0 6px 14px color-mix(in srgb, var(--vibrant-teal) 30%, transparent); }

/* ---- Capability pipeline ------------------------------------------------ */
.eas-pipeline,
.pipeline {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.85rem;
    align-items: stretch;
}
@media (max-width: 768px) {
    .eas-pipeline,
    .pipeline { grid-template-columns: repeat(2, 1fr); }
}
.eas-pipeline-step,
.pipeline-step { position: relative; }
.eas-pipeline-step + .eas-pipeline-step::before,
.pipeline-step + .pipeline-step::before {
    content: "\f054"; font-family: "Font Awesome 6 Free"; font-weight: 900;
    position: absolute; left: -0.75rem; top: 50%; transform: translateY(-50%);
    color: color-mix(in srgb, var(--text-secondary) 55%, transparent);
    font-size: 0.9rem;
}
@media (max-width: 768px) {
    .eas-pipeline-step + .eas-pipeline-step::before,
    .pipeline-step + .pipeline-step::before { display: none; }
}

/* ---- Tech stack grid ---------------------------------------------------- */
.eas-stack-grid,
.stack-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0.6rem;
}
/* Cards crediting an unusually large bundle of libraries (e.g. several
   packages behind one feature) get more room so their name/description
   aren't squeezed into the same width as a single-library card. */
.eas-stack-item-wide,
.stack-item-wide {
    grid-column: span 2;
}
@media (max-width: 480px) {
    .eas-stack-item-wide,
    .stack-item-wide { grid-column: span 1; }
}
.eas-stack-item,
.stack-item {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.75rem 0.9rem;
    border-radius: 12px;
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 70%, transparent);
    background: color-mix(in srgb, var(--surface-color, #fff) 88%, transparent);
    transition: transform .2s ease, border-color .2s ease;
}
.eas-stack-item:hover,
.stack-item:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--vibrant-blue) 35%, transparent); }
.eas-stack-item-ico,
.stack-item-ico {
    width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 0.85rem;
    background: linear-gradient(135deg, var(--vibrant-blue), var(--vibrant-indigo));
}
/* When the icon slot hosts an <img> (e.g. a project logo SVG from
   static/img/tech-stack-logos/), keep the SVG inside the 34×34 chip
   and tint it white via CSS filters so single-colour line-art marks
   stay readable on every gradient background. */
.stack-item-ico img {
    width: 22px; height: 22px;
    object-fit: contain;
    filter: brightness(0) invert(1);
}
.eas-stack-item-name,
.stack-item-name { font-weight: 700; font-size: 0.88rem; color: var(--text-color); }
.eas-stack-item-desc,
.stack-item-desc { font-size: 0.78rem; color: var(--text-secondary); }

/* ---- Maintainer identity (About page) ---------------------------------- */
.maintainer-identity {
    display: grid; grid-template-columns: auto 1fr auto; gap: 1.25rem;
    align-items: center;
    padding: 1.25rem;
    border-radius: var(--radius-lg, 14px);
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--vibrant-blue) 8%, transparent),
        color-mix(in srgb, var(--vibrant-purple) 8%, transparent));
    border: 1px solid color-mix(in srgb, var(--vibrant-indigo) 25%, transparent);
    margin-bottom: 1rem;
}
@media (max-width: 640px) { .maintainer-identity { grid-template-columns: 1fr; text-align: center; } }
.maintainer-avatar {
    width: 84px; height: 84px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--vibrant-blue), var(--vibrant-purple), var(--vibrant-pink));
    padding: 3px;
    box-shadow: 0 10px 26px color-mix(in srgb, var(--vibrant-purple) 35%, transparent);
}
.maintainer-avatar-inner {
    width: 100%; height: 100%; border-radius: 50%;
    background: var(--surface-color, #fff);
    display: inline-flex; align-items: center; justify-content: center;
    overflow: hidden;
}
.maintainer-avatar-inner img { width: 72%; height: 72%; object-fit: contain; }
.maintainer-avatar.has-photo { width: 96px; height: 96px; }
.maintainer-avatar.has-photo .maintainer-avatar-inner img { width: 100%; height: 100%; object-fit: cover; object-position: center 20%; }
.maintainer-name { font-size: 1.25rem; font-weight: 800; margin: 0; letter-spacing: -0.01em; }
.maintainer-callsign { font-weight: 500; color: var(--text-secondary); margin-left: 0.4rem; }
.maintainer-role { font-size: 0.85rem; color: var(--text-secondary); margin: 0.15rem 0 0.5rem; }
.maintainer-blurb { font-size: 0.9rem; margin: 0; color: var(--text-color); }
.maintainer-aside { text-align: center; font-size: 0.75rem; color: var(--text-secondary); }
.maintainer-aside img { max-width: 72px; display: block; margin: 0 auto 0.3rem; }

.role-chip {
    display: flex; gap: 0.75rem; align-items: flex-start;
    padding: 0.9rem 1rem;
    border-radius: 12px;
    background: color-mix(in srgb, var(--border-color, #e5e7eb) 18%, transparent);
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 70%, transparent);
    height: 100%;
}
.role-chip-ico {
    width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 0.9rem;
}
.role-chip-ico.ro-radio   { background: linear-gradient(135deg, var(--vibrant-blue), var(--vibrant-teal)); }
.role-chip-ico.ro-shield  { background: linear-gradient(135deg, var(--vibrant-red), var(--vibrant-pink)); }
.role-chip-ico.ro-bolt    { background: linear-gradient(135deg, var(--vibrant-orange), var(--vibrant-yellow)); color: #1a1a1a; }
.role-chip-ico.ro-flask   { background: linear-gradient(135deg, var(--vibrant-green), var(--vibrant-teal)); }
.role-chip h6 { margin: 0 0 0.2rem; font-size: 0.9rem; font-weight: 700; color: var(--text-color); }
.role-chip p  { margin: 0; font-size: 0.8rem; color: var(--text-secondary); line-height: 1.45; }

/* ---- Acknowledgments ---------------------------------------------------- */
.ack-group h6 {
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--text-secondary); margin: 0 0 0.6rem;
}
.ack-item {
    padding: 0.65rem 0.85rem; border-radius: 10px;
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 65%, transparent);
    margin-bottom: 0.4rem;
    background: color-mix(in srgb, var(--surface-color, #fff) 92%, transparent);
}
.ack-item strong { font-size: 0.88rem; }
.ack-item .muted { display: block; font-size: 0.78rem; color: var(--text-secondary); margin-top: 0.15rem; line-height: 1.4; }

/* ---- AMPR notice -------------------------------------------------------- */
.ampr-card {
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--vibrant-orange) 10%, var(--surface-color, #fff)),
        color-mix(in srgb, var(--vibrant-yellow) 10%, var(--surface-color, #fff)));
    border-left: 4px solid var(--vibrant-orange);
}
.ampr-heading {
    display: inline-flex; align-items: center; gap: 0.5rem;
    font-weight: 700; color: var(--text-color); margin-bottom: 0.5rem;
}

/* ---- Resource links ---------------------------------------------------- */
.eas-resource-link,
.resource-link {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.55rem 0.8rem;
    border-radius: 10px;
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 65%, transparent);
    color: var(--text-color); text-decoration: none;
    font-size: 0.9rem; font-weight: 500;
    transition: transform .2s ease, border-color .2s ease, background .2s ease;
    margin-bottom: 0.4rem;
    background: color-mix(in srgb, var(--surface-color, #fff) 90%, transparent);
}
.eas-resource-link:hover,
.resource-link:hover {
    transform: translateX(4px);
    border-color: color-mix(in srgb, var(--vibrant-blue) 40%, transparent);
    background: color-mix(in srgb, var(--vibrant-blue) 6%, var(--surface-color, #fff));
    color: var(--text-color);
}
.eas-resource-link i,
.resource-link i { color: var(--vibrant-blue); width: 18px; text-align: center; }

/* End of EAS Shared Visual System */

/* ==========================================================================
   RBDS / RDS Visualization System
   --------------------------------------------------------------------------
   Powers the structured RBDS station card, decoder health card, EWS banner,
   PTY badges, AF pills and group-type segmented bar emitted by
   static/js/rbds_visualization.js.

   Accessibility:
   - All status colours are paired with an icon + text label in the markup.
   - The heartbeat dot's pulse is suppressed under prefers-reduced-motion
     by the global rule at line ~3791.
   - The PS LCD panel relies on a monospace bitmap-style face but the live
     value is also exposed via aria-label so screen readers don't read the
     placeholder dashes.
   - High-contrast users get reinforced borders via the existing
     prefers-contrast: high block.
   ========================================================================== */

/* ---- Station card shell ---- */
.rbds-station {
    background: var(--surface-color, #fff);
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 80%, transparent);
    border-radius: var(--radius-lg, 14px);
    padding: 0.9rem 1rem;
    margin-top: 0.75rem;
    color: var(--text-color);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
}
.rbds-station__head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 0.75rem; flex-wrap: wrap;
    padding-bottom: 0.55rem;
    border-bottom: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 60%, transparent);
}
.rbds-station__id {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
    min-width: 0;
}
.rbds-station__icon {
    color: var(--vibrant-blue, #2563eb);
    font-size: 1rem;
}
.rbds-station__title {
    font-weight: 700;
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}
.rbds-station__call .rbds-call,
.rbds-station__call strong {
    font-size: 1rem;
    color: var(--text-color);
}
.rbds-station__pi .rbds-pi {
    background: color-mix(in srgb, var(--vibrant-blue, #2563eb) 12%, transparent);
    color: var(--text-color);
    border: 1px solid color-mix(in srgb, var(--vibrant-blue, #2563eb) 30%, transparent);
    border-radius: 999px;
    padding: 0.1rem 0.55rem;
    font-size: 0.8rem;
}
.rbds-station__status {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
}
.rbds-station__body {
    padding-top: 0.6rem;
    display: flex; flex-direction: column; gap: 0.55rem;
}
.rbds-station__pty {
    display: flex; flex-wrap: wrap; gap: 0.4rem;
}
.rbds-station__footer {
    margin-top: 0.55rem;
    padding-top: 0.5rem;
    border-top: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 60%, transparent);
    display: flex; flex-wrap: wrap; gap: 1rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
}
.rbds-station__footer i { margin-right: 0.3rem; }

/* ---- Heartbeat dot ---- */
.rbds-heartbeat {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    border: 1px solid transparent;
}
.rbds-heartbeat__dot {
    width: 0.55rem; height: 0.55rem;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 0 0 currentColor;
}
.rbds-heartbeat--live {
    color: var(--vibrant-green, #16a34a);
    background: color-mix(in srgb, var(--vibrant-green, #16a34a) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-green, #16a34a) 35%, transparent);
}
.rbds-heartbeat--live .rbds-heartbeat__dot {
    animation: rbds-pulse 1.6s ease-out infinite;
}
.rbds-heartbeat--stale {
    color: var(--vibrant-orange, #d97706);
    background: color-mix(in srgb, var(--vibrant-orange, #d97706) 14%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-orange, #d97706) 35%, transparent);
}
.rbds-heartbeat--idle {
    color: var(--text-secondary);
    background: color-mix(in srgb, var(--text-secondary) 10%, transparent);
    border-color: color-mix(in srgb, var(--text-secondary) 25%, transparent);
}
@keyframes rbds-pulse {
    0%   { box-shadow: 0 0 0 0 currentColor; opacity: 1; }
    70%  { box-shadow: 0 0 0 6px transparent; opacity: 0.55; }
    100% { box-shadow: 0 0 0 0 transparent; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
    .rbds-heartbeat--live .rbds-heartbeat__dot {
        animation: none;
    }
}

/* ---- Lock-state badge ---- */
.rbds-lock {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    border: 1px solid transparent;
}
.rbds-lock--locked {
    color: var(--vibrant-green, #16a34a);
    background: color-mix(in srgb, var(--vibrant-green, #16a34a) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-green, #16a34a) 35%, transparent);
}
.rbds-lock--locking {
    color: var(--vibrant-orange, #d97706);
    background: color-mix(in srgb, var(--vibrant-orange, #d97706) 14%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-orange, #d97706) 35%, transparent);
}
.rbds-lock--disabled {
    color: var(--text-secondary);
    background: color-mix(in srgb, var(--text-secondary) 10%, transparent);
    border-color: color-mix(in srgb, var(--text-secondary) 25%, transparent);
}

/* ---- PS LCD panel ---- */
.rbds-ps {
    display: flex; align-items: stretch; gap: 0.5rem;
}
.rbds-ps__label {
    flex-shrink: 0;
    background: color-mix(in srgb, var(--text-color) 10%, transparent);
    color: var(--text-secondary);
    border: 1px solid color-mix(in srgb, var(--text-color) 18%, transparent);
    border-radius: 6px;
    padding: 0.3rem 0.55rem;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    align-self: stretch;
    display: inline-flex; align-items: center;
}
.rbds-ps__lcd {
    flex-grow: 1;
    background: linear-gradient(180deg, #163326 0%, #0e2519 100%);
    color: #34d399;
    text-shadow: 0 0 4px rgba(52, 211, 153, 0.55);
    border: 1px solid #0a1c12;
    border-radius: 6px;
    padding: 0.3rem 0.7rem;
    font-family: "SFMono-Regular", "Menlo", "Consolas", "Liberation Mono", monospace;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-align: center;
    text-transform: uppercase;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rbds-ps__lcd--empty {
    color: rgba(52, 211, 153, 0.35);
    text-shadow: none;
    letter-spacing: 0.4em;
}
@media (prefers-contrast: high) {
    .rbds-ps__lcd {
        background: #000;
        color: #00ff88;
        border-color: #00ff88;
    }
}

/* ---- PTY badge (program type, category-coloured) ---- */
.rbds-pty {
    display: inline-flex; align-items: center; gap: 0.45rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    border: 1px solid transparent;
    color: var(--text-color);
}
.rbds-pty i { font-size: 0.85em; }
.rbds-pty__code {
    font-size: 0.72em;
    opacity: 0.7;
    font-family: "SFMono-Regular", "Menlo", "Consolas", monospace;
}
.rbds-pty--emergency {
    background: color-mix(in srgb, var(--vibrant-red, #dc2626) 14%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-red, #dc2626) 45%, transparent);
    color: color-mix(in srgb, var(--vibrant-red, #dc2626) 80%, var(--text-color));
}
.rbds-pty--weather {
    background: color-mix(in srgb, var(--vibrant-orange, #d97706) 14%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-orange, #d97706) 45%, transparent);
    color: color-mix(in srgb, var(--vibrant-orange, #d97706) 90%, var(--text-color));
}
.rbds-pty--news {
    background: color-mix(in srgb, var(--vibrant-blue, #2563eb) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-blue, #2563eb) 40%, transparent);
    color: color-mix(in srgb, var(--vibrant-blue, #2563eb) 90%, var(--text-color));
}
.rbds-pty--sports {
    background: color-mix(in srgb, var(--vibrant-green, #16a34a) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-green, #16a34a) 40%, transparent);
    color: color-mix(in srgb, var(--vibrant-green, #16a34a) 90%, var(--text-color));
}
.rbds-pty--talk {
    background: color-mix(in srgb, var(--vibrant-purple, #8b5cf6) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-purple, #8b5cf6) 40%, transparent);
    color: color-mix(in srgb, var(--vibrant-purple, #8b5cf6) 90%, var(--text-color));
}
.rbds-pty--music {
    background: color-mix(in srgb, var(--vibrant-teal, #0d9488) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-teal, #0d9488) 40%, transparent);
    color: color-mix(in srgb, var(--vibrant-teal, #0d9488) 90%, var(--text-color));
}
.rbds-pty--religion {
    background: color-mix(in srgb, var(--vibrant-indigo, #4f46e5) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-indigo, #4f46e5) 40%, transparent);
    color: color-mix(in srgb, var(--vibrant-indigo, #4f46e5) 90%, var(--text-color));
}
.rbds-pty--neutral {
    background: color-mix(in srgb, var(--text-secondary) 10%, transparent);
    border-color: color-mix(in srgb, var(--text-secondary) 30%, transparent);
    color: var(--text-color);
}

/* ---- Service flag chips ---- */
.rbds-flags {
    display: flex; flex-wrap: wrap; gap: 0.35rem;
}
.rbds-flag {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.74rem;
    font-weight: 600;
    border: 1px solid color-mix(in srgb, var(--text-secondary) 25%, transparent);
    background: color-mix(in srgb, var(--text-secondary) 8%, transparent);
    color: var(--text-color);
}
.rbds-flag i { font-size: 0.85em; opacity: 0.85; }
.rbds-flag--info.rbds-flag--active {
    color: color-mix(in srgb, var(--vibrant-blue, #2563eb) 90%, var(--text-color));
    background: color-mix(in srgb, var(--vibrant-blue, #2563eb) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-blue, #2563eb) 40%, transparent);
}
.rbds-flag--warning.rbds-flag--active {
    color: color-mix(in srgb, var(--vibrant-orange, #d97706) 90%, var(--text-color));
    background: color-mix(in srgb, var(--vibrant-orange, #d97706) 14%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-orange, #d97706) 45%, transparent);
}
.rbds-flag--audio.rbds-flag--active {
    color: color-mix(in srgb, var(--vibrant-teal, #0d9488) 90%, var(--text-color));
    background: color-mix(in srgb, var(--vibrant-teal, #0d9488) 12%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-teal, #0d9488) 40%, transparent);
}
.rbds-flag--inactive {
    opacity: 0.7;
}

/* ---- Now-Playing strip (RT+) ---- */
.rbds-rtplus {
    background: color-mix(in srgb, var(--vibrant-blue, #2563eb) 5%, var(--surface-color, #fff));
    border: 1px solid color-mix(in srgb, var(--vibrant-blue, #2563eb) 22%, transparent);
    border-radius: 8px;
    padding: 0.55rem 0.75rem;
}
.rbds-rtplus__head {
    display: flex; align-items: center; gap: 0.4rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin-bottom: 0.35rem;
}
.rbds-rtplus__paused {
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    background: color-mix(in srgb, var(--text-secondary) 18%, transparent);
    border-radius: 999px;
    font-size: 0.7rem;
    text-transform: lowercase;
    letter-spacing: 0;
}
.rbds-rtplus__row {
    display: flex; gap: 0.6rem;
    padding: 0.18rem 0;
    font-size: 0.85rem;
    border-top: 1px dashed color-mix(in srgb, var(--vibrant-blue, #2563eb) 18%, transparent);
}
.rbds-rtplus__row:first-of-type { border-top: none; }
.rbds-rtplus__label {
    flex-shrink: 0;
    font-family: "SFMono-Regular", "Menlo", "Consolas", monospace;
    font-size: 0.75rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    min-width: 6.5rem;
}
.rbds-rtplus__value {
    font-weight: 600;
    color: var(--text-color);
    word-break: break-word;
}

/* ---- Plain Radio Text (fallback) ---- */
.rbds-rt {
    margin: 0;
    padding: 0.55rem 0.75rem;
    background: color-mix(in srgb, var(--text-secondary) 5%, transparent);
    border-left: 3px solid color-mix(in srgb, var(--vibrant-blue, #2563eb) 35%, transparent);
    border-radius: 0 6px 6px 0;
    font-size: 0.9rem;
    color: var(--text-color);
}
.rbds-rt i { color: var(--text-secondary); margin-right: 0.25rem; }

/* ---- Hint blocks ---- */
.rbds-hint {
    margin: 0;
    font-size: 0.83rem;
    color: var(--text-secondary);
    font-style: italic;
}
.rbds-hint i { margin-right: 0.35rem; }

/* ---- Section heading inside details ---- */
.rbds-section-h {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin: 0 0 0.4rem 0;
}
.rbds-section-h i { margin-right: 0.35rem; }

/* ---- Details accordion ---- */
.rbds-details,
.rbds-eon {
    margin-top: 0.25rem;
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 70%, transparent);
    border-radius: 8px;
    background: color-mix(in srgb, var(--text-secondary) 4%, transparent);
}
.rbds-details > summary,
.rbds-eon > summary {
    list-style: none;
    cursor: pointer;
    padding: 0.5rem 0.75rem;
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--text-color);
    user-select: none;
    border-radius: 8px;
}
.rbds-details > summary:focus-visible,
.rbds-eon > summary:focus-visible {
    outline: 2px solid var(--vibrant-blue, #2563eb);
    outline-offset: 2px;
}
.rbds-details > summary::-webkit-details-marker,
.rbds-eon > summary::-webkit-details-marker { display: none; }
.rbds-details > summary::before,
.rbds-eon > summary::before {
    content: "\f054";
    font-family: "Font Awesome 6 Free";
    font-weight: 900;
    margin-right: 0.45rem;
    font-size: 0.75em;
    transition: transform 0.2s ease;
    display: inline-block;
}
.rbds-details[open] > summary::before,
.rbds-eon[open] > summary::before {
    transform: rotate(90deg);
}
@media (prefers-reduced-motion: reduce) {
    .rbds-details[open] > summary::before,
    .rbds-eon[open] > summary::before { transition: none; }
}
.rbds-details__body {
    padding: 0.5rem 0.75rem 0.75rem;
    border-top: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 70%, transparent);
    display: flex; flex-direction: column; gap: 0.85rem;
}
.rbds-identity__table th { width: 38%; font-weight: 500; }
.rbds-eon__table { font-size: 0.82rem; margin: 0; }
.rbds-eon > .table-responsive { padding: 0.5rem 0.75rem 0.75rem; }

/* ---- Alternative Frequencies ---- */
.rbds-af__list {
    display: flex; flex-wrap: wrap; gap: 0.3rem;
}
.rbds-af-pill {
    display: inline-flex; align-items: center;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--text-secondary) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--text-secondary) 25%, transparent);
    color: var(--text-color);
    font-size: 0.78rem;
    font-family: "SFMono-Regular", "Menlo", "Consolas", monospace;
}
.rbds-af-pill--tuned {
    background: color-mix(in srgb, var(--vibrant-blue, #2563eb) 14%, transparent);
    border-color: color-mix(in srgb, var(--vibrant-blue, #2563eb) 40%, transparent);
    font-weight: 700;
}
.rbds-af__count {
    font-size: 0.72rem;
    margin-left: 0.4rem;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--vibrant-green, #16a34a) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--vibrant-green, #16a34a) 35%, transparent);
    color: var(--vibrant-green, #16a34a);
}

/* ---- EWS banner (extends Bootstrap .alert-danger) ---- */
.rbds-ews-banner {
    border-left: 4px solid var(--vibrant-red, #dc2626);
}

/* ---- Decoder Health card ---- */
.rbds-health {
    display: flex; flex-direction: column; gap: 1rem;
}
.rbds-health__heartbeat {
    display: flex; justify-content: flex-end;
}
.rbds-health__section {
    display: flex; flex-direction: column; gap: 0.45rem;
}

/* Group-type segmented bar */
.rbds-gt-bar {
    display: flex;
    width: 100%;
    height: 22px;
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 60%, transparent);
    background: color-mix(in srgb, var(--text-secondary) 5%, transparent);
}
.rbds-gt-seg {
    display: block;
    min-width: 2px;
    border-right: 1px solid rgba(255, 255, 255, 0.4);
}
.rbds-gt-seg:last-child { border-right: none; }
.rbds-gt--a { background: var(--vibrant-blue,   #2563eb); }
.rbds-gt--b { background: var(--vibrant-teal,   #0d9488); }
.rbds-gt--c { background: var(--vibrant-purple, #8b5cf6); }
.rbds-gt--d { background: var(--vibrant-orange, #d97706); }
.rbds-gt--e { background: var(--vibrant-pink,   #db2777); }
.rbds-gt--f { background: var(--vibrant-green,  #16a34a); }
.rbds-gt-legend {
    list-style: none; padding: 0; margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.25rem 0.85rem;
    font-size: 0.78rem;
}
.rbds-gt-legend__item {
    display: flex; align-items: center; gap: 0.45rem;
}
.rbds-gt-legend__sw {
    display: inline-block;
    width: 0.85rem; height: 0.85rem;
    border-radius: 3px;
    flex-shrink: 0;
}
.rbds-gt-legend__code {
    font-weight: 700;
    min-width: 2.5rem;
}
.rbds-gt-legend__desc {
    color: var(--text-secondary);
    flex-grow: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rbds-gt-legend__count {
    font-family: "SFMono-Regular", "Menlo", "Consolas", monospace;
    font-weight: 600;
}

/* BLER stacked bar */
.rbds-bler-bar {
    display: flex;
    width: 100%;
    height: 18px;
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--border-color, #e5e7eb) 60%, transparent);
    background: color-mix(in srgb, var(--text-secondary) 5%, transparent);
}
.rbds-bler-seg { display: block; min-width: 1px; }
.rbds-bler-seg--ok   { background: var(--vibrant-green,  #16a34a); }
.rbds-bler-seg--fec1 { background: var(--vibrant-teal,   #0d9488); }
.rbds-bler-seg--fecb { background: var(--vibrant-blue,   #2563eb); }
.rbds-bler-seg--bad  { background: var(--vibrant-red,    #dc2626); }
.rbds-bler-legend {
    display: flex; flex-wrap: wrap; gap: 0.5rem 1rem;
    font-size: 0.78rem;
    color: var(--text-color);
}
.rbds-bler-legend__item { display: inline-flex; align-items: center; gap: 0.35rem; }
.rbds-bler-sw {
    display: inline-block; width: 0.85rem; height: 0.85rem; border-radius: 3px;
}
.rbds-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.4rem 1rem;
    margin: 0;
    font-size: 0.82rem;
}
.rbds-stats > div {
    display: flex; justify-content: space-between; gap: 0.5rem;
    padding: 0.2rem 0;
    border-bottom: 1px dashed color-mix(in srgb, var(--border-color, #e5e7eb) 60%, transparent);
}
.rbds-stats dt {
    color: var(--text-secondary);
    margin: 0; font-weight: 500;
}
.rbds-stats dd {
    margin: 0;
    text-align: right;
}

/* End of RBDS Visualization System */

/* ========================================
   DISPLAY-UNITS SELECTOR (EASUnits)
   ======================================== */
.eas-units-disclosure {
    position: relative;
}
.eas-units-disclosure > summary {
    list-style: none;
    cursor: pointer;
    user-select: none;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.eas-units-disclosure > summary::-webkit-details-marker { display: none; }
.eas-units-disclosure[open] > summary { box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.35); }

.eas-units-popover {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 1000;
    min-width: 220px;
    padding: 10px 12px;
    border-radius: 10px;
    /* Use the theme's defined surface colour.  --bg-secondary is undefined in
       every palette, so this previously fell back to a fixed dark-navy on ALL
       themes — dark popover + light-theme dark text = unreadable on Cosmo and
       the other light themes. --surface-color tracks the active theme. */
    background: var(--surface-color, rgba(20, 24, 36, 0.96));
    border: 1px solid var(--border-color, rgba(127, 127, 127, 0.3));
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.eas-units-selector {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.eas-units-row {
    display: grid;
    grid-template-columns: 70px 1fr;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 0.82rem;
}
.eas-units-row-label {
    color: var(--text-muted, #8b949e);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-size: 0.72rem;
}
.eas-units-select {
    min-width: 0;
    width: 100%;
}

@media (max-width: 575.98px) {
    .eas-units-popover {
        right: 0;
        left: auto;
        min-width: 200px;
        max-width: calc(100vw - 1.5rem);
    }
}

/* ============================================================================
   Standard Data Table (.eas-table)
   ----------------------------------------------------------------------------
   Reusable, mobile-friendly table pattern for list/index pages (Received
   Alerts, Audio Archive, Logs, etc.). Apply `.eas-table` to a `<table>` and
   give every `<td>` a `data-label="<column header>"` attribute. On screens
   <= 767.98px, each row collapses into a card with each cell on its own
   line, preceded by its column label — no markup duplication required.

   Pair with `.eas-table-filters` for the filter bar above the table, and
   `.eas-table-toolbar` for the chip row of active filters.
   ========================================================================== */

.eas-table {
    width: 100%;
    margin-bottom: 0;
}

.eas-table thead th {
    white-space: nowrap;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    /* Mixed toward --text-color rather than plain --text-secondary: at this
       size (0.78rem) WCAG AA needs 4.5:1, and --text-secondary alone lands
       at 4.04 against the header tint in the dark theme. The uppercase +
       letterspacing still reads as a header without relying on dimness. */
    color: color-mix(in srgb, var(--text-color) 80%, var(--text-secondary, var(--text-muted)));
    background: color-mix(in srgb, var(--surface-color) 90%, var(--border-color));
    border-bottom: 2px solid var(--border-color);
    padding: 0.65rem 0.75rem;
    vertical-align: middle;
}

.eas-table tbody td {
    vertical-align: middle;
    padding: 0.75rem;
    border-top: 1px solid var(--border-color);
}

.eas-table tbody tr:hover {
    background: color-mix(in srgb, var(--primary-color) 6%, var(--surface-color));
}

/* Active filter chip row that sits above the table */
.eas-table-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border-color);
    background: color-mix(in srgb, var(--surface-color) 96%, var(--border-color));
}

.eas-table-toolbar .filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--primary-color) 18%, var(--surface-color));
    color: var(--text-color);
    font-size: 0.78rem;
    border: 1px solid var(--border-color);
}

.eas-table-toolbar .filter-chip a {
    color: inherit;
    line-height: 1;
    opacity: 0.7;
}
.eas-table-toolbar .filter-chip a:hover { opacity: 1; text-decoration: none; }

/* Mobile: stack each row as a labeled card. No markup duplication —
   uses the `data-label` attribute on each `<td>`. */
@media (max-width: 767.98px) {
    .eas-table thead {
        /* Visually hide but keep accessible to screen readers */
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    .eas-table,
    .eas-table tbody,
    .eas-table tr,
    .eas-table td {
        display: block;
        width: 100%;
    }

    .eas-table tbody tr {
        border: 1px solid var(--border-color);
        border-radius: var(--radius-md, 0.5rem);
        margin: 0.5rem 0.75rem;
        background: var(--surface-color);
        padding: 0.25rem 0;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
    }

    .eas-table tbody tr:hover { background: var(--surface-color); }

    .eas-table tbody td {
        display: grid;
        grid-template-columns: minmax(7rem, 35%) 1fr;
        gap: 0.5rem;
        align-items: baseline;
        border-top: none;
        border-bottom: 1px dashed color-mix(in srgb, var(--border-color) 60%, transparent);
        padding: 0.5rem 0.85rem;
    }

    .eas-table tbody td:last-child {
        border-bottom: none;
    }

    .eas-table tbody td::before {
        content: attr(data-label);
        font-size: 0.7rem;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        font-weight: 600;
        color: var(--text-muted);
    }

    /* If a cell has no data-label (e.g. actions column), let it span both
       columns and center its contents. */
    .eas-table tbody td:not([data-label])::before { content: none; }
    .eas-table tbody td:not([data-label]) {
        grid-template-columns: 1fr;
        justify-items: end;
    }

    .eas-table-toolbar { padding: 0.5rem 0.85rem; }
}

/* End of Consolidated Styles */

/* ============================================================================
   Telemetry Status Strip + Header Pills (.status-strip / .status-pill)
   ----------------------------------------------------------------------------
   Shared appliance-style chrome for live monitoring pages (System Health,
   GNSS & Time Dashboard). Both pages previously carried their own near
   identical copies under `health-*` and `gps-*` prefixes, which had drifted
   apart — different surface tokens, two different greens for "OK", and
   different idle colours for the heartbeat dot. Defined once here instead.

   Anatomy:
       .status-strip            grid of tiles, sits directly under the header
         .status-tile           one metric; severity via .sev-* on the tile
           .lbl                 small uppercase caption (may contain an <i>)
           .val                 large mono readout
           .sub                 one-line context string
       .status-pill             pill for the page header's actions slot
       .live-dot                heartbeat dot; add .ping after a good poll

   Two palettes on purpose: tiles sit on the page surface and use the
   saturated set; pills and the dot sit on the header gradient and use
   lightened variants over a dark scrim, so they stay legible on every theme.
   ========================================================================== */

.status-strip {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 8px;
    margin: 0 0 18px 0;
}

/* Opt-in weighting for strips whose first and third tiles are the ones an
   operator triages first (the GNSS page's Sync and PPS Lock). */
.status-strip.status-strip-emphasis {
    grid-template-columns: 2fr 1fr 2fr 1fr 1fr 1fr 1fr;
}

.status-tile {
    position: relative;
    padding: 10px 12px;
    border: 1px solid var(--border-color, rgba(127, 127, 127, .22));
    border-left: 3px solid var(--text-muted, #8b949e);
    border-radius: 6px;
    background: var(--surface-color, rgba(127, 127, 127, .04));
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    transition: border-left-color 0.45s ease, background-color 0.45s ease;
}

.status-tile .lbl {
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.10em;
    text-transform: uppercase;
    color: var(--text-muted, #8b949e);
    display: flex;
    align-items: center;
    gap: 5px;
}

.status-tile .lbl i { font-size: 0.74rem; opacity: 0.7; }

.status-tile .val {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 1.18rem;
    font-weight: 700;
    line-height: 1.05;
    color: var(--text-color);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.status-tile .sub {
    font-size: 0.68rem;
    color: var(--text-muted, #8b949e);
    font-family: var(--font-mono, ui-monospace, monospace);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Emphasised tile — heavier rail and a larger readout so it reads first. */
.status-tile.is-primary {
    border-left-width: 5px;
    padding: 12px 14px;
}
.status-tile.is-primary .lbl { font-size: 0.72rem; }
.status-tile.is-primary .val { font-size: 1.55rem; }
.status-tile.is-primary .sub { font-size: 0.74rem; }

/* Severity tinting — left rail plus value colour. */
.status-tile.sev-ok    { border-left-color: #3fb950; }
.status-tile.sev-ok    .val { color: #3fb950; }
.status-tile.sev-warn  { border-left-color: #d29922; background: rgba(210, 153, 34, 0.06); }
.status-tile.sev-warn  .val { color: #f6c343; }
.status-tile.sev-fault { border-left-color: #f85149; background: rgba(248, 81, 73, 0.07); }
.status-tile.sev-fault .val { color: #f85149; }
.status-tile.sev-info  { border-left-color: #58a6ff; }
.status-tile.sev-info  .val { color: #58a6ff; }
.status-tile.sev-unknown .val { color: var(--text-muted, #8b949e); }

@keyframes status-tile-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.status-tile { animation: status-tile-in 0.35s ease both; }
.status-tile:nth-child(2) { animation-delay: 0.05s; }
.status-tile:nth-child(3) { animation-delay: 0.10s; }
.status-tile:nth-child(4) { animation-delay: 0.15s; }
.status-tile:nth-child(5) { animation-delay: 0.20s; }
.status-tile:nth-child(6) { animation-delay: 0.25s; }
.status-tile:nth-child(7) { animation-delay: 0.30s; }

@media (prefers-reduced-motion: reduce) {
    .status-tile { animation: none; }
}

@media (max-width: 1180px) {
    .status-strip,
    .status-strip.status-strip-emphasis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
    .status-strip,
    .status-strip.status-strip-emphasis {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 6px;
    }
    .status-tile { padding: 8px 10px; }
    .status-tile .val { font-size: 1.02rem; }
    .status-tile.is-primary { padding: 8px 10px; }
    .status-tile.is-primary .val { font-size: 1.15rem; }
}

/* ── Header pills ────────────────────────────────────────────────────────
   Live status chips that ride in the standard page header's actions slot.
   Lightened palette over a dark scrim: the header gradient is theme-driven,
   so the saturated tile colours are not reliably legible on top of it. */
.status-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.74rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    border: 1px solid currentColor;
    background: rgba(0, 0, 0, 0.22);
    font-family: var(--font-mono, ui-monospace, monospace);
    transition: color 0.3s ease, border-color 0.3s ease;
}
.status-pill.ok     { color: #6ee07a; }
.status-pill.warn   { color: #f6c343; }
.status-pill.danger { color: #ff7b72; }
.status-pill.info   { color: #79c0ff; }
.status-pill.muted  { color: rgba(255, 255, 255, 0.78); }
.status-pill i { font-size: 0.72rem; opacity: 0.85; }

/* ── Heartbeat dot ───────────────────────────────────────────────────────
   Pulses green once per successful poll, then settles back to idle. */
.live-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.45);
    flex-shrink: 0;
    vertical-align: middle;
}

@keyframes status-data-ping {
    0%   { box-shadow: 0 0 0 0   rgba(63, 185, 80, 0.80); background: #3fb950; }
    70%  { box-shadow: 0 0 0 8px rgba(63, 185, 80, 0);    background: #3fb950; }
    100% { box-shadow: 0 0 0 0   rgba(63, 185, 80, 0);    background: rgba(255, 255, 255, 0.45); }
}
.live-dot.ping { animation: status-data-ping 0.75s ease forwards; }

@media (prefers-reduced-motion: reduce) {
    .live-dot.ping { animation: none; }
}
