/* Dashboard CSS - Modern sidebar layout */
/* Updated: v17 design overhaul with dark green gradient background */

/* Disable all transitions during page load to prevent visual glitches */
html.no-transition,
html.no-transition *,
html.no-transition *::before,
html.no-transition *::after {
    transition: none !important;
}

/* Turbo Drive progress bar */
.turbo-progress-bar {
    height: 3px;
    background-color: var(--primary-color);
}

/* Accessibility utility - visually hide content but keep accessible to screen readers */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

:root {
    /* Sidebar */
    --sidebar-width: 260px;
    --sidebar-bg: #1a1d21;
    --sidebar-hover: #2a2d31;
    --sidebar-active: #3a3d41;

    /* Primary Colors */
    --primary-color: #4CAF50;
    --primary-light: #81C784;
    --primary-dark: #388E3C;
    --primary-hover: #388E3C;
    --primary-glow: rgba(76, 175, 80, 0.15);

    /* Text Colors */
    --text-primary: #111827;
    --text-secondary: #6b7280;
    --text-on-dark: #f3f4f6;
    --text-on-sidebar: #ffffff;

    /* Backgrounds - John Deere green gradient */
    --bg-main: radial-gradient(ellipse at 50% 30%, #367C2B 0%, #2d5a27 20%, #1a3d1a 50%, #0f2810 100%);
    --bg-card: #eeedea;
    --bg-card-hover: #efeeeb;

    /* Borders & Shadows */
    --border-color: rgba(0,0,0,0.06);
    --shadow-sm: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);
    --shadow-md: 0 4px 8px rgba(0,0,0,0.1), 0 2px 4px rgba(0,0,0,0.06), 0 10px 20px rgba(0,0,0,0.08);
    --shadow-lg: 0 10px 25px rgba(0,0,0,0.15), 0 6px 12px rgba(0,0,0,0.1), 0 20px 40px rgba(0,0,0,0.12);
    --shadow-xl: 0 20px 40px rgba(0,0,0,0.2), 0 10px 20px rgba(0,0,0,0.12);
    --shadow-inset: inset 0 2px 4px rgba(0,0,0,0.04);

    /* Status Colors */
    --success-color: #22c55e;
    --completed: #16a34a;
    --ready: #3b82f6;
    --scheduled: #f59e0b;
    --warning-color: #f59e0b;
    --danger-color: #ef4444;
    --danger-hover: #dc2626;
    --danger-dark: #b91c1c;
    --info-color: #3b82f6;

    /* Additional UI Colors */
    --text-dark: #374151;
    --bg-hover: #e5e7eb;
    --white-10: rgba(255,255,255,0.1);
    --white-20: rgba(255,255,255,0.2);
    --white-40: rgba(255,255,255,0.4);
    --white-80: rgba(255,255,255,0.8);

    /* Focus ring — green primary glow, used on all focusable inputs */
    --focus-ring: rgba(76, 175, 80, 0.2);

    /* Animation */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

    /* Status Background/Text Pairs */
    --success-bg: #f0fdf4;
    --success-text: #166534;
    --danger-bg: #fef2f2;
    --danger-text: #991b1b;
    --warning-bg: #fffbeb;
    --warning-text: #92400e;
    --info-bg: #eff6ff;
    --info-text: #1e40af;

    /* Gray Scale (Tailwind) */
    --gray-50: #f9fafb;
    --gray-100: #f3f4f6;
    --gray-200: #e5e7eb;
    --gray-300: #d1d5db;
    --gray-400: #9ca3af;
    --gray-500: #6b7280;
    --gray-600: #4b5563;
    --gray-700: #374151;
    --gray-800: #1f2937;
    --gray-900: #111827;

    /* ============================================================
       MOBILE PRIMITIVES — additive layer per
       .planning/mobile-optimization/primitives-spec.md
       Token-merge plan: .planning/mobile-optimization/token-merge.md
       Source of truth: .planning/mobile-optimization/sandbox.html
       Strategy: additive + alias (zero risk to existing rules).
       NOTE: --text-dark is intentionally NOT aliased here (collision
       with 30+ existing usages). Sandbox rules using var(--text-dark)
       must be rewritten to var(--text-primary) when ported.
       ============================================================ */

    /* Spec aliases → existing tokens (zero-risk repointing) */
    --primary:       var(--primary-color);
    --bg-green-grad: var(--bg-main);
    --bg-cream:      var(--bg-card);
    --bg-sidebar:    var(--sidebar-bg);
    --text-muted:    var(--text-secondary);
    --text-light:    var(--gray-400);
    --border:        var(--border-color);
    --danger:        var(--danger-color);
    --warning:       var(--warning-color);
    --success:       var(--primary);

    /* Fluid type scale */
    --text-2xs:  10px;
    --text-xs:   clamp(0.75rem,  0.72rem + 0.15vw, 0.8125rem);
    --text-sm:   clamp(0.8125rem,0.78rem + 0.18vw, 0.875rem);
    --text-base: clamp(0.9375rem,0.9rem  + 0.2vw,  1rem);
    --text-lg:   clamp(1rem,     0.96rem + 0.25vw, 1.125rem);
    --text-xl:   clamp(1.125rem, 1.05rem + 0.4vw,  1.25rem);
    --text-2xl:  clamp(1.25rem,  1.15rem + 0.55vw, 1.5rem);
    --text-3xl:  clamp(1.5rem,   1.35rem + 0.8vw,  1.875rem);
    --text-4xl:  clamp(1.75rem,  1.55rem + 1.1vw,  2.25rem);

    /* Fluid space scale */
    --space-1:  clamp(0.25rem,  0.23rem + 0.1vw,  0.3125rem);
    --space-2:  clamp(0.5rem,   0.46rem + 0.2vw,  0.625rem);
    --space-3:  clamp(0.75rem,  0.7rem  + 0.25vw, 0.9375rem);
    --space-4:  clamp(1rem,     0.93rem + 0.35vw, 1.25rem);
    --space-5:  clamp(1.25rem,  1.15rem + 0.5vw,  1.5rem);
    --space-6:  clamp(1.5rem,   1.38rem + 0.6vw,  1.875rem);
    --space-8:  clamp(2rem,     1.82rem + 0.9vw,  2.5rem);
    --space-10: clamp(2.5rem,   2.25rem + 1.25vw, 3.25rem);

    /* Sizing */
    --tap-min:   36px;
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;

    /* Transitions */
    --transition-fast: 0.15s;
    --transition-base: 0.2s;

    /* Line heights */
    --lh-tight:  1.1;
    --lh-snug:   1.2;
    --lh-normal: 1.3;
    --lh-body:   1.45;
}

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

html {
    overflow-x: clip; /* clip (not hidden) prevents 125vw body from creating horizontal scroll on mobile */
    max-width: 100%; /* was 100vw — 100vw clips body's 125vw zoom compensation causing gap at narrow widths */
    color-scheme: light;
    scrollbar-color: #3a3a3a #1a1a1a;
    background: var(--bg-main); /* Fill gaps revealed by body zoom: 0.8 */
    background-color: #0f2810; /* Solid fallback AFTER shorthand — background shorthand resets color to transparent, this restores it */
    background-attachment: fixed; /* Match body so gradient renders identically */
    min-height: 100%;
}

html::-webkit-scrollbar {
    width: 10px;
}

html::-webkit-scrollbar-track {
    background: #1a1a1a;
}

html::-webkit-scrollbar-thumb {
    background: #3a3a3a;
    border-radius: 5px;
}

html::-webkit-scrollbar-thumb:hover {
    background: #4a4a4a;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
    background: var(--bg-main);
    background-color: #0f2810; /* Solid fallback AFTER shorthand — prevents white flash during Turbo Drive body swap */
    background-attachment: fixed;
    min-height: 125vh;  /* 100vh / 0.8 — compensate zoom so body fills viewport height */
    width: 125vw;       /* 100vw / 0.8 — compensate zoom so body fills viewport width */
    overflow-x: hidden;
    scrollbar-color: #3a3a3a #1a1a1a;
    zoom: 0.8;
}

body::-webkit-scrollbar {
    width: 10px;
}

body::-webkit-scrollbar-track {
    background: #1a1a1a;
}

body::-webkit-scrollbar-thumb {
    background: #3a3a3a;
    border-radius: 5px;
}

body::-webkit-scrollbar-thumb:hover {
    background: #4a4a4a;
}

/* ============================================
   PULL-TO-REFRESH
   Mobile pull-to-refresh indicator
   ============================================ */
.ptr-container {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 0;
    overflow: hidden;
    z-index: 9998;
    background: var(--sidebar-bg);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    transition: none;
    padding-top: env(safe-area-inset-top, 0);
}

.ptr-indicator {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 0 10px;
    color: var(--success-color);
    font-size: 13px;
    font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}

.ptr-arrow {
    transition: transform 0.2s ease;
}

.ptr-spinner {
    display: none;
    animation: ptr-spin 0.8s linear infinite;
}

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

.ptr-pulling .ptr-text::after { content: "Pull to refresh"; }
.ptr-ready .ptr-text::after { content: "Release to refresh"; }
.ptr-ready .ptr-arrow { transform: rotate(180deg); }
.ptr-refreshing .ptr-text::after { content: "Refreshing\2026"; }
.ptr-refreshing .ptr-arrow { display: none; }
.ptr-refreshing .ptr-spinner { display: block; }

.ptr-container.ptr-refreshing {
    transition: height 0.3s ease;
}

@media (min-width: 1025px) {
    .ptr-container { left: 280px; }
}

/* ============================================
   LOGO STYLING
   Transparent logo for sidebar, clean header logo
   ============================================ */
.sidebar-header .logo-img {
    max-width: 240px;
    filter: drop-shadow(0 2px 8px rgba(0, 180, 230, 0.3));
}


/* .page-title styles merged into header section below */

.page-title-icon {
    margin-right: 12px;
    opacity: 0.9;
}

/* App Container */
.app-container {
    display: flex;
    min-height: 125vh;  /* 100vh / 0.8 — compensate body zoom */
    position: relative; /* Required for z-index to work */
    z-index: 100; /* Below action bars (1200) and header (1100), above base content */
}

/* Sidebar */
.sidebar {
    width: var(--sidebar-width);
    background: var(--sidebar-bg);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    height: max(125vh, 125dvh);  /* 100vh/0.8 — compensate body zoom:0.8 so sidebar fills viewport */
    overflow: hidden; /* Contain children properly */
    z-index: 9999;
    transition: transform 0.3s ease;
    font-size: 17.5px; /* 14px / 0.8 zoom — keeps sidebar text visually 14px despite body zoom:0.8 */
}

.sidebar-header {
    padding: 10px 10px;
    padding-top: calc(10px + env(safe-area-inset-top, 0));
    background: transparent;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    flex-shrink: 0; /* Prevent header from shrinking */
    overflow: visible;
}

.logo {
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: visible;
}

.logo-img {
    max-width: 280px;
    max-height: 100px;
    width: auto;
    height: auto;
    object-fit: contain;
}

.logo-icon {
    width: 40px;
    height: 40px;
    color: var(--primary-color);
}

.logo-text {
    font-size: 24px;
    font-weight: 700;
    color: var(--text-on-sidebar);
    letter-spacing: 1px;
}

/* Sidebar Search */
.sidebar-search {
    padding: 12px 16px;
    position: relative;
    background: var(--sidebar-bg);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    overflow: visible; /* Allow dropdown to extend beyond container */
    flex-shrink: 0; /* Prevent search from shrinking */
}

.sidebar-search-input-wrapper {
    position: relative;
}

.sidebar-search input {
    width: 100%;
    padding: 10px 36px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    color: #fff;
    font-size: 16px; /* Must be ≥16px — iOS Safari auto-zooms on inputs <16px */
}

.sidebar-search input::placeholder {
    color: rgba(255, 255, 255, 0.4);
}

.sidebar-search input:focus {
    outline: none;
    border-color: var(--primary-color);
    background: rgba(255, 255, 255, 0.12);
}

.sidebar-search .search-icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    color: rgba(255, 255, 255, 0.4);
    pointer-events: none;
}

.sidebar-search .search-clear {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.4);
    cursor: pointer;
    display: none;
    font-size: 18px;
    line-height: 1;
    padding: 4px;
}

.sidebar-search .search-clear:hover {
    color: rgba(255, 255, 255, 0.8);
}

.sidebar-search.has-value .search-clear {
    display: block;
}

/* Search filtering styles */
.nav-item.search-hidden {
    display: none !important;
}

.nav-item.search-match .nav-title,
.nav-item.search-match .nav-description {
    color: var(--primary-color);
}

/* Navigation */
.sidebar-nav {
    flex: 1 1 0; /* flex-grow: 1, flex-shrink: 1, flex-basis: 0 - takes remaining space */
    height: 0; /* Combined with flex-basis: 0 for proper scrollable flex child */
    padding: 16px 12px;
    padding-bottom: 32px; /* Extra bottom padding so last item can scroll fully into view */
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch; /* Smooth scrolling on iOS */
    overscroll-behavior: contain; /* Prevent scroll chaining to parent */
    touch-action: pan-y; /* Allow only vertical touch scrolling */
    scroll-padding-bottom: 16px; /* Ensure last items scroll fully into view */
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.25) #1a1d21;
}

/* WebKit scrollbar styling for sidebar */
.sidebar-nav::-webkit-scrollbar {
    width: 6px;
}

.sidebar-nav::-webkit-scrollbar-track {
    background: #1a1d21;
}

.sidebar-nav::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.25);
    border-radius: 3px;
}

.sidebar-nav::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.4);
}

.sidebar-nav::-webkit-scrollbar-button {
    display: none;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 16px;
    border-radius: 8px;
    text-decoration: none;
    color: #ffffff !important;
    transition: background-color 0.2s ease, color 0.2s ease;
    margin-bottom: 1px;
}

.nav-item:hover {
    background: rgba(255, 255, 255, 0.05);
    color: #ffffff;
}

.nav-item.active {
    background: rgba(76, 175, 80, 0.15);
    color: var(--primary-color);
}

.nav-item.active .nav-icon {
    color: var(--primary-color);
}

.nav-icon {
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    transform: translateY(1px);
}

.nav-icon svg {
    width: 100%;
    height: 100%;
}

.nav-content {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.nav-title {
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Navigation Badge (e.g., "Preview", "New", "Beta") */
.nav-badge {
    font-size: 9px;
    font-weight: 600;
    text-transform: uppercase;
    padding: 2px 5px;
    border-radius: 3px;
    letter-spacing: 0.3px;
    flex-shrink: 0;
    line-height: 1;
}

.nav-badge--info {
    background: rgba(59, 130, 246, 0.2);
    color: #60a5fa;
}

.nav-badge--warning {
    background: rgba(245, 158, 11, 0.2);
    color: #fbbf24;
}

.nav-badge--success {
    background: rgba(34, 197, 94, 0.2);
    color: #4ade80;
}

.nav-badge--danger {
    background: rgba(239, 68, 68, 0.2);
    color: #f87171;
}

/* Locked feature styling for trial users */
.locked-feature {
    opacity: 0.6;
    cursor: not-allowed;
}

.locked-feature:hover {
    opacity: 0.7;
}

.nav-description {
    display: none; /* Hide descriptions for compact sidebar like v16 mockup */
}

/* Category labels for sidebar sections */
.nav-label {
    font-size: 11px;
    font-weight: 700;
    color: rgba(255,255,255,0.6);
    text-transform: uppercase;
    letter-spacing: 1.5px;
    padding: 6px 16px 4px;
    display: block;
}

.sidebar-nav > .nav-label:first-child {
    padding-top: 0;
}

.nav-divider {
    height: 1px;
    background: rgba(255,255,255,0.1);
    margin: 6px 0;
}

/* Sidebar Footer */
.sidebar-footer {
    padding: 16px;
    border-top: 1px solid rgba(255,255,255,0.1);
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0; /* Prevent footer from being compressed */
    min-height: 72px; /* Ensure minimum height for touch targets */
    background: var(--sidebar-bg); /* Ensure background matches sidebar */
    z-index: 10000; /* Above sidebar content (9999) to prevent nav-item overlap */
}

/* Sidebar copyright notice */
.sidebar-copyright {
    /* Bottom padding: adding the FULL safe-area inset (34px on notched iPhones)
       left a dead band below the text (user request 2026-08-16). Static text only
       needs to clear the home-indicator pill graphic, not the whole gesture zone,
       so subtract 20px from the inset; devices without an inset keep 10px. */
    padding: 6px 16px max(10px, calc(env(safe-area-inset-bottom, 0px) - 20px));
    font-size: 10px;
    color: rgba(255,255,255,0.25);
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}
.sidebar-copyright a {
    color: rgba(255,255,255,0.25);
    text-decoration: none;
}
.sidebar-copyright a:hover {
    color: rgba(255,255,255,0.5);
}

.user-info {
    display: flex;
    align-items: center;
    gap: 12px;
}

.user-avatar {
    width: 40px;
    height: 40px;
    background: var(--primary-color);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-weight: 600;
    font-size: 14px;
}

.user-details {
    display: flex;
    flex-direction: column;
}

.user-name {
    font-size: 14px;
    font-weight: 500;
    color: #e5e7eb;
}

.user-role {
    font-size: 12px;
    color: #9ca3af;
    text-transform: capitalize;
}

.logout-btn {
    padding: 8px;
    border-radius: 8px;
    color: #9ca3af;
    transition: all 0.2s;
}

.logout-btn:hover {
    background: var(--sidebar-hover);
    color: var(--danger-color);
}

.logout-btn svg {
    width: 20px;
    height: 20px;
}

/* Mobile logout button shown in top header at ≤1024px */
.mobile-logout-btn {
    display: none;
    align-items: center;
    justify-content: center;
    padding: 8px;
    min-width: 44px;
    min-height: 44px;
    border-radius: 8px;
    color: #9ca3af;
    transition: all 0.2s;
}

.mobile-logout-btn:hover {
    background: rgba(255,255,255,0.1);
    color: var(--danger-color);
}

.mobile-logout-btn svg {
    width: 22px;
    height: 22px;
}

/* Main Content */
.main-content {
    flex: 1;
    margin-left: var(--sidebar-width);
    display: flex;
    flex-direction: column;
    min-height: 125vh;  /* 100vh / 0.8 — compensate body zoom */
    max-width: calc(125vw - var(--sidebar-width));  /* 100vw/0.8 — compensate body zoom so content fills viewport */
    padding-bottom: 100px; /* Space for fixed form-actions footer */
}

/* Top Header */
.top-header {
    background: transparent;
    padding: 20px 28px;
    padding-top: calc(20px + env(safe-area-inset-top, 0));
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: none;
    position: relative;
    z-index: 9999; /* Beat celebration overlay (9998) so header buttons remain accessible */
}

.header-left {
    display: flex;
    align-items: center;
    gap: 16px;
    min-width: 0; /* Allow flex children to shrink */
    flex: 1 1 auto;
}

.menu-toggle {
    display: none;
    background: none;
    border: none;
    padding: 8px;
    cursor: pointer;
    border-radius: 8px;
    color: var(--text-on-dark);
}

@media (hover: hover) {
    .menu-toggle:hover {
        background: rgba(255, 255, 255, 0.1);
    }
}

.menu-toggle svg {
    width: 24px;
    height: 24px;
    fill: currentColor;
}

.page-title {
    font-size: 28px;
    font-weight: 800;
    color: var(--text-on-dark);
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
    letter-spacing: -0.5px;
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    min-width: 0;
    line-height: 1; /* prevent extra vertical space that makes centering look off */
}

.page-title-text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    line-height: 1.4; /* overflow:hidden clips to the line box — Segoe UI needs ≥1.33em for full descenders (g, y, p) */
}

.header-right {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* Dashboard only (approved 2026-09-19): the default 20px header padding plus
   24px content padding read as a wide empty band around the page title.
   Keyed off the dashboard's own wrapper so other pages keep the defaults
   until each is reviewed. The phone version lives in the 640px block. */
body:has(.mobile-dashboard) .top-header {
    padding-top: calc(12px + env(safe-area-inset-top, 0));
    padding-bottom: 12px;
}
body:has(.mobile-dashboard) .content-area {
    padding-top: 12px;
}

/* Content Area */
.content-area {
    flex: 1;
    padding: 24px 44px;
    padding-bottom: 100px;  /* Extra padding for sticky action bar at bottom */
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    overflow-x: hidden;
    box-sizing: border-box;
    /* V17 Styling - Green gradient background */
    background: radial-gradient(ellipse at 50% 30%, #367C2B 0%, #2d5a27 20%, #1a3d1a 50%, #0f2810 100%);
    background-attachment: fixed;
}

/* Cards */
.card {
    background: var(--bg-card);
    border-radius: 16px;
    border: 1px solid var(--border-color);
    padding: 24px;
    margin-bottom: 20px;
    box-shadow: var(--shadow-lg);
    transition: box-shadow 0.2s var(--ease-out), transform 0.2s var(--ease-out);
}

.card:hover {
    box-shadow: var(--shadow-xl);
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
}

.card-title {
    font-size: 18px;
    font-weight: 600;
    color: #111827;
}

/* Metrics Grid */
.metrics-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 24px;
    margin-bottom: 24px;
}

.metric-card {
    background: var(--bg-card);
    border-radius: 12px;
    border: 1px solid var(--border-color);
    padding: 24px;
    display: flex;
    flex-direction: column;
}

.metric-card.primary {
    background: linear-gradient(135deg, var(--primary-color), var(--primary-dark));
    color: white;
    border: none;
}

.metric-card.primary .metric-label,
.metric-card.primary .metric-change {
    color: rgba(255,255,255,0.8);
}

.metric-icon {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 16px;
}

.metric-icon svg {
    width: 24px;
    height: 24px;
}

.metric-icon.green {
    background: rgba(34, 197, 94, 0.1);
    color: var(--success-color);
}

.metric-icon.blue {
    background: rgba(59, 130, 246, 0.1);
    color: var(--info-color);
}

.metric-icon.yellow {
    background: rgba(245, 158, 11, 0.1);
    color: var(--warning-color);
}

.metric-icon.red {
    background: rgba(239, 68, 68, 0.1);
    color: var(--danger-color);
}

.metric-value {
    font-size: 32px;
    font-weight: 700;
    color: #111827;
    margin-bottom: 4px;
}

.metric-card.primary .metric-value {
    color: white;
}

.metric-label {
    font-size: 14px;
    color: var(--text-secondary);
}

.metric-change {
    font-size: 12px;
    margin-top: 8px;
    display: flex;
    align-items: center;
    gap: 4px;
}

.metric-change.up {
    color: var(--success-color);
}

.metric-change.down {
    color: var(--danger-color);
}

/* ── Overview Panel — stat info rows (Stats, Time Mgmt, Payroll, etc.) ── */
.ov-panel {
    margin-bottom: 16px;
    background: var(--bg-card);
    border-radius: 16px;
    border: 1px solid var(--border-color);
    overflow: hidden;
}
.ov-panel-title {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 20px;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border-color);
    background: rgba(0,0,0,0.02);
}
.ov-panel-title svg { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.6; }
.ov-panel-cols {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    padding: 14px 16px;
    gap: 0;
}
.ov-col { display: flex; flex-direction: column; gap: 6px; }
.ov-col:not(:first-child) { padding-left: 14px; border-left: 1px solid rgba(0,0,0,0.06); }
.ov-col:not(:last-child)  { padding-right: 14px; }

/* All inventory stat cards equal size — no orphan spanning */
@media (max-width: 600px) {
    .ov-panel-cols--inventory .ov-col:last-child:nth-child(odd) {
        grid-column: auto;
        border-left: none !important;
        padding-left: 0 !important;
    }
    .ov-panel-cols {
        padding: 8px 10px;
    }
    .ov-col:not(:first-child) { padding-left: 8px; }
    .ov-col:not(:last-child)  { padding-right: 8px; }
    .ov-stat {
        flex-direction: column;
        align-items: flex-start;
        padding: 7px 8px;
        gap: 2px;
    }
    .ov-stat-label {
        font-size: 11px;
        gap: 4px;
        white-space: normal;
    }
    .ov-stat-value {
        font-size: 20px;
    }
}
.ov-stat {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 14px;
    border-radius: 8px;
    background: #ffffff;
    border: 2px solid transparent;
    min-width: 0;
}
.ov-stat-label {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-secondary);
    white-space: nowrap;
    flex-shrink: 0;
}
.ov-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ov-stat-value {
    font-size: 22px;
    font-weight: 600;
    white-space: nowrap;
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
}
/* Info dropdown */
.ov-stat[data-stat-key] { cursor: pointer; }
.ov-stat[data-stat-key]:hover { filter: brightness(0.97); }
.ov-stat[data-stat-key].stat-row-open { border-radius: 8px 8px 0 0; }
.ov-stat-expand-panel {
    position: absolute;
    z-index: 500;
    background: #fafafa;
    border-left: 2px solid transparent;
    border-right: 2px solid transparent;
    border-bottom: 2px solid transparent;
    border-top: none;
    border-radius: 0 0 8px 8px;
    box-shadow: 0 6px 18px rgba(0,0,0,0.1);
    overflow: hidden;
    max-height: 0;
    transition: max-height 0.22s ease;
}
.ov-stat-expand-panel.open { max-height: 500px; }
.ov-stat-expand-inner { padding: 10px 14px 13px; }
.ov-stat-expand-what { font-size: 13px; color: #374151; line-height: 1.5; margin-bottom: 8px; }
.ov-stat-expand-formula-label { font-size: 10px; font-weight: 700; letter-spacing: 1.2px; text-transform: uppercase; color: #6b7280; margin-bottom: 5px; }
.ov-stat-expand-formula { background: #f3f4f6; border-radius: 6px; padding: 7px 10px; font-size: 13px; color: #1f2937; font-family: monospace; margin-bottom: 8px; }
.ov-stat-expand-note { border-left: 3px solid #d97706; padding-left: 8px; font-size: 12px; font-style: italic; color: #6b7280; line-height: 1.5; }
.ov-stat-expand-feeds { font-size: 11px; color: #6b7280; margin-top: 6px; }
.ov-stat-expand-feeds strong { color: #374151; }
/* Clickable filter variant (no dropdown — triggers table filter) */
.ov-stat[data-action] { cursor: pointer; position: relative; }
.ov-stat[data-action].active { box-shadow: 0 0 0 3px rgba(34,197,94,0.25); }
.ov-stat[data-action].active::after {
    content: '✓';
    position: absolute;
    top: 6px;
    left: 6px;
    background: var(--primary-color);
    color: white;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    font-size: 11px;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* Secondary value line (e.g. earnings below hours) */
.ov-stat-sub { font-size: 12px; font-weight: 500; color: #6b7280; text-align: right; }

/* Tables */
.data-table {
    width: 100%;
    border-collapse: collapse;
}

.data-table th,
.data-table td {
    padding: 12px 16px;
    text-align: left;
    border-bottom: 1px solid var(--border-color);
}

.data-table th {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--text-secondary);
    background: #f9fafb;
}

/* Sortable table headers */
.data-table.sortable th.sortable-header {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    transition: background-color 0.15s ease;
}

.data-table.sortable th.sortable-header:hover {
    background: #e5e7eb;
}

.data-table.sortable th .sort-icon {
    color: #9ca3af;
    margin-left: 6px;
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
}

.data-table.sortable th .sort-icon svg {
    width: 12px;
    height: 12px;
}

.data-table.sortable th[data-sort-direction="asc"] .sort-icon,
.data-table.sortable th[data-sort-direction="desc"] .sort-icon {
    color: var(--primary-color);
}

.data-table tbody tr {
    transition: background-color 0.15s ease;
}

.data-table tbody tr:hover {
    background: #f9fafb;
}

/* Clickable table rows */
.data-table tbody tr.clickable-row {
    cursor: pointer;
}

.data-table tbody tr.clickable-row:hover {
    background: #f0f9ff;
}

.data-table tbody tr.clickable-row:active {
    background: #e0f2fe;
}

/* Status Badges */
.badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 500;
}

.badge-success {
    background: rgba(34, 197, 94, 0.1);
    color: var(--success-color);
}

.badge-warning {
    background: rgba(245, 158, 11, 0.1);
    color: var(--warning-color);
}

.badge-danger {
    background: rgba(239, 68, 68, 0.1);
    color: var(--danger-color);
}

.badge-info {
    background: rgba(59, 130, 246, 0.1);
    color: var(--info-color);
}

.badge-neutral {
    background: rgba(107, 114, 128, 0.1);
    color: #6b7280;
}

.badge-purple {
    background: rgba(124, 58, 237, 0.12);
    color: #6d28d9;
}

/* Status badges — job/entity state indicators */
.badge-ready { background: rgba(59, 130, 246, 0.12); color: #1d4ed8; }
.badge-completed { background: rgba(22, 163, 74, 0.12); color: #15803d; }
.badge-scheduled { background: rgba(245, 158, 11, 0.12); color: #b45309; }
.badge-progress { background: rgba(124, 58, 237, 0.12); color: #6d28d9; }
.badge-active { background: #d1fae5; color: #065f46; }
.badge-inactive { background: #f3f4f6; color: #6b7280; }

/* ============================================
   FILTER CHIPS (above a table/list)
   Canonical primitive — see docs/style-guide-mockup.html "Filter chips".
   Lives here, not per-page: the Kind chips (?kind= convention) are rendered on
   Spraying Jobs / Dispatch / the completion-reports queue / the invoice list,
   and pages that never defined their own .filter-chip were painting them as
   bare underlined <a> links. Pages with a page-scoped .filter-chip block in
   {% block extra_css %} still win — that block is emitted after this file.
   ============================================ */
.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border: 1px solid rgba(0, 0, 0, 0.12);
    border-radius: 8px;
    background: #fff;
    color: #374151;
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

/* Hover-capable devices only — on iOS a tap sets :hover and it sticks, leaving
   the tapped chip looking selected. */
@media (hover: hover) and (pointer: fine) {
    .filter-chip:hover { background: #f5f5f5; border-color: rgba(0, 0, 0, 0.2); color: #111827; }
}

.filter-chip.active,
.filter-chip.active:hover {
    background: var(--primary-color, #4CAF50);
    border-color: var(--primary-color, #4CAF50);
    color: #fff;
}

/* Group wrapper for a set of mutually exclusive chips (Kind: All / Spray / Mapping) */
.filter-chip-group {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

/* Label on a chip group — same treatment as the FROM/TO captions on the date
   filters, so it reads as a caption and not as another (unselectable) chip. */
.filter-chip-caption {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: #9ca3af;
    flex-shrink: 0;
}

/* Rig assignment badges */
.rig-badge { display: inline-flex; align-items: center; padding: 2px 10px; border-radius: 9999px; font-size: 11px; font-weight: 600; }
.rig-badge-red { background: rgba(239, 68, 68, 0.12); color: #b91c1c; }
.rig-badge-orange { background: rgba(249, 115, 22, 0.12); color: #c2410c; }
.rig-badge-gray { background: rgba(107, 114, 128, 0.12); color: #374151; }

/* Job card positioning context */
.job-card {
    position: relative; /* Create positioning context for absolute children */
    background: white;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    margin-bottom: 12px;
    padding: 0; /* Padding handled by children */
    cursor: pointer;
    transition: all 0.15s ease;
}

.job-card:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    border-color: #d1d5db;
}

.job-card-header {
    position: relative; /* Positioning context for reorder buttons */
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 60px 12px 16px; /* Extra right padding for reorder buttons */
}

.job-badges {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
}

/* DriftWatch concern badges */
.badge-driftwatch-bees {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 600;
    background-color: #fd7e14; /* Orange - bee concerns */
    color: white;
}

.badge-driftwatch-crops {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 600;
    background-color: #dc3545; /* Red - specialty crop concerns */
    color: white;
}

/* Job reorder buttons - styles moved to inline template CSS in job_dispatch.html */

/* Queue number + checkbox column — shared between dispatch and dashboard home */
.job-select-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    flex-shrink: 0;
}

/* Queue number badge — shared between dispatch page and dashboard home jobs list */
.queue-number-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    border-radius: 10px;
    background: var(--accent-green, #2d6a4f);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    padding: 0 5px;
    margin-bottom: 2px;
    flex-shrink: 0;
}

/* Buttons — desktop base. Mobile compact overrides live in @media (max-width: 640px). */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 20px;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    border: none;
    transition: all 0.2s;
    text-decoration: none;
}

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

.btn-primary:hover {
    background: var(--primary-dark);
}

.btn-secondary {
    background: #f3f4f6;
    color: #374151;
    border: 1px solid #d1d5db;
}

.btn-secondary:hover {
    background: #e5e7eb;
}

.btn-danger {
    background: var(--danger-color);
    color: white;
    border: 1px solid var(--danger-dark);
}

.btn-danger:hover {
    background: var(--danger-dark);
}

.btn-lg {
    padding: 12px 24px;
    font-size: 15px;
}

.btn svg {
    width: 18px;
    height: 18px;
}

.btn-small {
    padding: 6px 12px;
    font-size: 13px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border-radius: 8px;
    background: var(--bg-card);
    color: #374151;
    border: 1px solid var(--border-color);
}

.btn-small:hover {
    background: #e5e7eb;
}

/* Buttons that are really <a> elements: .btn clears the UA underline, these
   three never did, so their labels drew with a line through them. Found by
   sweeping all 22 phone pages after the same fix on .admin-banner-btn
   (2026-10-02): "Show pending only" on Products, the 25 row buttons on
   Notifications, and the sidebar logout. */
a.logout-btn,
a.btn-small,
a.btn-icon {
    text-decoration: none;
}

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

.btn-small.btn-primary:hover {
    background: var(--primary-dark);
}

/* Button Loading States */
.btn.is-loading {
    position: relative;
    pointer-events: none;
    opacity: 0.75;
    cursor: wait;
}

.btn.is-loading::after {
    content: '';
    position: absolute;
    width: 16px;
    height: 16px;
    top: 50%;
    left: 50%;
    margin-left: -8px;
    margin-top: -8px;
    border: 2px solid transparent;
    border-top-color: currentColor;
    border-radius: 50%;
    animation: btn-spinner 0.6s linear infinite;
}

.btn.is-loading .btn-text,
.btn.is-loading svg:not(.spinner-icon) {
    visibility: hidden;
}

/* For buttons with text content (show spinner alongside dimmed text) */
.btn.is-loading-inline {
    pointer-events: none;
    opacity: 0.85;
}

.btn.is-loading-inline::before {
    content: '';
    width: 14px;
    height: 14px;
    border: 2px solid transparent;
    border-top-color: currentColor;
    border-radius: 50%;
    animation: btn-spinner 0.6s linear infinite;
    margin-right: 8px;
    flex-shrink: 0;
}

@keyframes btn-spinner {
    to { transform: rotate(360deg); }
}

/* Disabled button state */
.btn:disabled,
.btn.disabled {
    opacity: 0.5;
    pointer-events: none;
    cursor: not-allowed;
}

/* Form Actions - Full-Width Sticky Bottom Bar
   Desktop sizing restored. Mobile compact (4px padding, 30px buttons)
   is in the @media (max-width: 640px) block. */
.form-actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    padding: 16px 20px;
    position: fixed;
    bottom: 0;
    left: var(--sidebar-width);
    right: 0;
    margin: 0;
    width: auto;
    max-width: none;
    background: linear-gradient(145deg, #1e293b 0%, #0f172a 100%);
    border-radius: 14px 14px 0 0;
    box-shadow:
        0 -10px 40px rgba(0, 0, 0, 0.3),
        0 0 0 1px rgba(255, 255, 255, 0.08) inset;
    z-index: 1300; /* Above filter dropdowns (1001/1002) and other overlays */
    box-sizing: border-box;
}

/* When form-actions has multiple buttons (delete, cancel, etc), use row layout */
.form-actions:has(.btn-secondary),
.form-actions:has(.btn-delete),
.form-actions:has(.actions-right) {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}

/* Single primary button - full width */
.form-actions > .btn-primary:only-child,
.form-actions > .btn-lg:only-child,
.form-actions > button.btn:only-child,
.form-actions > a.btn:only-child {
    width: 100%;
}

/* Required field hint - below breadcrumb on form pages */
.required-hint {
    font-size: 12px;
    color: #6b7280;
    margin: -8px 0 16px 0;
}

/* Right side buttons group */
.form-actions .actions-right {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1;
    justify-content: center;
}

/* Left-aligned form actions (for delete-only zones) */
.form-actions.form-actions-left {
    flex-direction: row;
    justify-content: flex-start;
}

/* Inline variant — use inside expandable panels/slide-downs where fixed footer would escape the container */
.form-actions.form-actions-inline {
    position: static;
    background: transparent;
    padding: 0;
    border-top: none;
    box-shadow: none;
    margin-top: 16px;
    left: auto;
    right: auto;
    bottom: auto;
    z-index: auto;
    border-radius: 0;
}

/* Danger zone styling */
.danger-zone {
    margin-top: 20px;
    border-color: #fecaca;
    background: #fef2f2;
}

.danger-zone .form-actions {
    background: transparent;
    box-shadow: none;
    padding: 0;
    margin: 0;
    position: relative;
    border-radius: 0;
}

.form-actions .btn,
.form-actions .btn-cancel,
.form-actions .btn-save,
.form-actions .btn-delete,
.form-actions a.btn {
    border-radius: 10px;
    padding: 12px 20px;
    font-size: 14px;
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    transition: all 0.2s ease;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    border: none;
}

.form-actions .btn-lg {
    padding: 12px 24px;
    font-size: 14px;
}

.form-actions .btn-primary,
.form-actions .btn-save {
    background: linear-gradient(145deg, #22c55e 0%, #16a34a 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(34, 197, 94, 0.4);
}

.form-actions .btn-primary:hover,
.form-actions .btn-save:hover {
    background: linear-gradient(145deg, #16a34a 0%, #15803d 100%);
    box-shadow: 0 6px 20px rgba(34, 197, 94, 0.5);
    transform: translateY(-2px);
}

.form-actions .btn-secondary,
.form-actions .btn-cancel,
.form-actions .btn-outline,
.form-actions a.btn-secondary {
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.15);
    box-shadow: none;
}

.form-actions .btn-secondary:hover,
.form-actions .btn-cancel:hover,
.form-actions .btn-outline:hover,
.form-actions a.btn-secondary:hover {
    background: rgba(255, 255, 255, 0.15);
    color: white;
    border-color: rgba(255, 255, 255, 0.25);
    box-shadow: none;
}

.form-actions .btn-success {
    background: linear-gradient(145deg, #3b82f6 0%, #2563eb 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

.form-actions .btn-success:hover {
    background: linear-gradient(145deg, #2563eb 0%, #1d4ed8 100%);
    box-shadow: 0 6px 20px rgba(59, 130, 246, 0.5);
    transform: translateY(-2px);
}

.form-actions .btn-warning {
    background: linear-gradient(145deg, #f59e0b 0%, #d97706 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);
}

.form-actions .btn-warning:hover {
    background: linear-gradient(145deg, #d97706 0%, #b45309 100%);
    box-shadow: 0 6px 20px rgba(245, 158, 11, 0.5);
    transform: translateY(-2px);
}

.form-actions .btn-delete {
    background: linear-gradient(145deg, #ef4444 0%, #dc2626 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(239, 68, 68, 0.4);
}

.form-actions .btn-delete:hover {
    background: linear-gradient(145deg, #dc2626 0%, #b91c1c 100%);
    box-shadow: 0 6px 20px rgba(239, 68, 68, 0.5);
    transform: translateY(-2px);
}

.form-actions .btn-info {
    background: linear-gradient(145deg, #3b82f6 0%, #2563eb 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

.form-actions .btn-info:hover {
    background: linear-gradient(145deg, #2563eb 0%, #1d4ed8 100%);
    box-shadow: 0 6px 20px rgba(59, 130, 246, 0.5);
    transform: translateY(-2px);
}

.form-actions .btn-teal {
    background: linear-gradient(145deg, #0891b2 0%, #0e7490 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(8, 145, 178, 0.4);
}

.form-actions .btn-teal:hover {
    background: linear-gradient(145deg, #0e7490 0%, #155e75 100%);
    box-shadow: 0 6px 20px rgba(8, 145, 178, 0.5);
    transform: translateY(-2px);
}

.form-actions .btn-purple {
    background: linear-gradient(145deg, #7c3aed 0%, #6d28d9 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(124, 58, 237, 0.4);
}

.form-actions .btn-purple:hover {
    background: linear-gradient(145deg, #6d28d9 0%, #5b21b6 100%);
    box-shadow: 0 6px 20px rgba(124, 58, 237, 0.5);
    transform: translateY(-2px);
}

.form-actions .btn-cyan {
    background: linear-gradient(145deg, #0284c7 0%, #0369a1 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(2, 132, 199, 0.4);
}

.form-actions .btn-cyan:hover {
    background: linear-gradient(145deg, #0369a1 0%, #075985 100%);
    box-shadow: 0 6px 20px rgba(2, 132, 199, 0.5);
    transform: translateY(-2px);
}

.form-actions .btn-rose {
    background: linear-gradient(145deg, #db2777 0%, #be185d 100%);
    color: white;
    border: none;
    box-shadow: 0 4px 12px rgba(219, 39, 119, 0.4);
}

.form-actions .btn-rose:hover {
    background: linear-gradient(145deg, #be185d 0%, #9d174d 100%);
    box-shadow: 0 6px 20px rgba(219, 39, 119, 0.5);
    transform: translateY(-2px);
}

/* Amber/gold filled action — distinct from btn-warning's deeper orange. Uses dark
   text for contrast on the bright gold. Used for reversible "archive" style actions. */
.form-actions .btn-amber {
    background: linear-gradient(145deg, #fcd34d 0%, #fbbf24 100%);
    color: #78350f;
    border: none;
    box-shadow: 0 4px 12px rgba(251, 191, 36, 0.4);
}

.form-actions .btn-amber:hover {
    background: linear-gradient(145deg, #fbbf24 0%, #f59e0b 100%);
    color: #78350f;
    box-shadow: 0 6px 20px rgba(251, 191, 36, 0.5);
    transform: translateY(-2px);
}

/* Icon buttons in form actions */
.form-actions .btn svg,
.form-actions .btn-save svg,
.form-actions .btn-cancel svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

/* Form actions with left and right sections */
.form-actions > div:first-child:not(:last-child) {
    margin-right: auto;
}

/* Field detail footer — spread every action evenly across the full bar width.
   Desktop only: `display:contents` dissolves the left/right wrappers so all six
   buttons become direct flex children of the bar, then space-between gives equal
   gaps edge-to-edge. Mobile (<=640px) keeps the existing wrapping behaviour. */
@media (min-width: 641px) {
    .form-actions.field-detail-actions {
        flex-direction: row;
        justify-content: center;
        align-items: center;
        gap: 18px;
    }
    .form-actions.field-detail-actions > .actions-left,
    .form-actions.field-detail-actions > .actions-right {
        display: contents;
    }
}

/* Field detail footer — flat fills, no colored glow (box-shadow) on the buttons. */
.form-actions.field-detail-actions .btn,
.form-actions.field-detail-actions a.btn,
.form-actions.field-detail-actions .btn:hover,
.form-actions.field-detail-actions a.btn:hover {
    box-shadow: none;
}

/* Tablet: sidebar slides off at 640px — footer must go full-width */
@media (max-width: 640px) {
    :root {
        --sidebar-width: 0px; /* sidebar hidden — modal/footer span full width */
    }
    .form-actions {
        left: 0;
    }
}

/* Mobile responsive form actions */
@media (max-width: 640px) {
    .form-actions {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        transform: none;
        margin: 0;
        border-radius: 16px 16px 0 0;
        padding: 6px 12px;
        padding-bottom: env(safe-area-inset-bottom, 0);
        width: 100%;
        max-width: 100%;
        gap: 6px;
        z-index: 1200; /* Same as mobileActionBar - fixed action bar at bottom */
    }

    .form-actions .btn,
    .form-actions .btn-cancel,
    .form-actions .btn-save,
    .form-actions a.btn {
        padding: 10px 16px;
        font-size: 14px;
        flex: 1;
    }

    .form-actions .btn-lg {
        padding: 12px 16px;
    }

    /* On mobile with delete button — compact row wrap, matching billing hub style */
    .form-actions:has(.btn-delete) {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        align-items: center;
        gap: 8px;
    }

    .form-actions:has(.btn-delete) .btn-delete {
        flex: 0 0 auto;
    }

    .form-actions:has(.btn-delete) .actions-right {
        flex: 0 0 auto;
        width: auto;
        justify-content: center;
    }

    /* Allow actions-right to wrap on mobile so buttons don't overflow */
    .form-actions .actions-right {
        flex-wrap: wrap;
        gap: 8px;
        justify-content: center;
    }

    /* Buttons in actions-right should use natural width (not stretch) so they wrap properly */
    .form-actions .actions-right .btn,
    .form-actions .actions-right a.btn {
        flex: 0 0 auto;
        min-width: 0;
        font-size: 12px;
        padding: 10px 10px;
    }
}

/* Prevent narrow screen overflow */
.form-card,
.form-grid {
    max-width: 100%;
    overflow-x: hidden;
    box-sizing: border-box;
}

/* Standard page content container — 900px default, centered.
   Use .form-container on all form/detail/settings pages.
   Pages needing a different width override with inline style="max-width:Xpx". */
.form-container,
.settings-container,
.page-container {
    max-width: 900px;
    margin: 0 auto;
    box-sizing: border-box;
}

.form-group input,
.form-group select,
.form-group textarea,
.form-control {
    max-width: 100%;
    box-sizing: border-box;
    /* html sets a dark scrollbar-color for the page chrome; it inherits into every
       descendant, so a scrollbar inside a light form field renders as a black box.
       Reset it here so inner field scrollbars use the native light scrollbar. */
    scrollbar-color: auto;
}

/* Auto-growing textarea: sized to its content by JS, so it never scrolls
   (and never paints an inner scrollbar). */
textarea.autogrow {
    overflow-y: hidden;
    resize: vertical;
}

/* JS sizes this to its content; the floor keeps an empty field from collapsing. */
textarea.autogrow:not([style*="height"]) {
    min-height: 5.5em;
}

/* Ensure long text wraps on narrow screens */
.form-card label,
.form-card .help-text,
.form-group label,
.form-group .help-text {
    word-wrap: break-word;
    overflow-wrap: break-word;
}

/* Narrow screen form adjustments */
@media (max-width: 480px) {
    .form-group {
        width: 100%;
    }

    .form-grid {
        display: block;
    }

    .form-grid > * {
        margin-bottom: 16px;
    }

    /* Ensure tables don't overflow */
    table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* =============================================
   Narrow Screen Header Actions → Sticky Footer
   Optimized for:
   - Tablets/small laptops: <= 768px
   - iPhone 13 Pro Max: 428px CSS width
   - iPhone 13: 390px CSS width
   ============================================= */

/* Action Bar - Sticky footer at bottom on ALL screen sizes */
.mobile-action-bar {
    display: flex;  /* Always visible - sticky footer on all screens */
    position: fixed;
    bottom: 0;
    left: var(--sidebar-width);  /* Match sidebar width - start after sidebar */
    right: 0;
    background: linear-gradient(180deg, #1e293b 0%, #151c28 100%);
    padding: 16px 32px;
    padding-bottom: calc(16px + env(safe-area-inset-bottom, 0));
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.05);
    z-index: 1200;
    gap: 16px;
    justify-content: flex-start;  /* Back button stays left */
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* Split layout: secondary buttons left, primary button right */
.mobile-action-bar .btn-secondary + .btn-primary {
    margin-left: auto;
}

/* If no secondary button present, push primary button to the right */
.mobile-action-bar:not(:has(.btn-secondary)) {
    justify-content: flex-end;
}

/* Show header buttons on desktop (1025px+) */
@media (min-width: 1025px) {
    .header-right .btn {
        display: inline-flex !important;
    }
}

/* Hide header buttons on mobile/tablet - buttons are in sticky footer */
@media (max-width: 1023px) {
    .header-right .btn {
        display: none !important;
    }
}


/* Mobile action bar button styling */
.mobile-action-bar .btn {
    flex: 0 1 auto;
    min-width: 140px;
    max-width: 220px;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 14px 28px;
    border-radius: 12px;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.3px;
    transition: all 0.2s ease;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.mobile-action-bar .btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
}

.mobile-action-bar .btn:active {
    transform: translateY(0);
}

/* Primary button in action bar */
.mobile-action-bar .btn-primary {
    background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
    border: none;
    color: white;
}

.mobile-action-bar .btn-primary:hover {
    background: linear-gradient(135deg, #16a34a 0%, #15803d 100%);
}

/* Secondary button in action bar */
.mobile-action-bar .btn-secondary {
    background: rgba(255, 255, 255, 0.95);
    border: none;
    color: #1e293b;
}

.mobile-action-bar .btn-secondary:hover {
    background: #ffffff;
}

/* Danger/Delete button in action bar */
.mobile-action-bar .btn-danger {
    background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
    border: none;
    color: white;
}

.mobile-action-bar .btn-danger:hover {
    background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
}

/* Warning/Edit button in action bar (orange) */
.mobile-action-bar .btn-warning {
    background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%) !important;
    border: none !important;
    color: white !important;
    font-weight: 600;
}

.mobile-action-bar .btn-warning:hover {
    background: linear-gradient(135deg, #d97706 0%, #b45309 100%) !important;
    box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);
}

/* Action button (medium blue) - for secondary actions like Move, Transfer */
.mobile-action-bar .btn-action {
    background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important;
    border: none !important;
    color: white !important;
    font-weight: 600;
}

.mobile-action-bar .btn-action:hover {
    background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%) !important;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

/* Info button (purple) - for additional actions */
.mobile-action-bar .btn-info {
    background: linear-gradient(135deg, #a78bfa 0%, #8b5cf6 100%);
    border: none;
    color: white;
    font-weight: 600;
}

.mobile-action-bar .btn-info:hover {
    background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);
    box-shadow: 0 4px 12px rgba(139, 92, 246, 0.4);
}

/* Teal button - for more actions if needed */
.mobile-action-bar .btn-teal {
    background: linear-gradient(135deg, #2dd4bf 0%, #14b8a6 100%);
    border: none;
    color: white;
    font-weight: 600;
}

.mobile-action-bar .btn-teal:hover {
    background: linear-gradient(135deg, #14b8a6 0%, #0d9488 100%);
    box-shadow: 0 4px 12px rgba(20, 184, 166, 0.4);
}

/* Add padding to bottom of content to prevent overlap with action bar */
.content-area {
    padding-bottom: 90px !important;
}

/* Tablet and small screens (640px and below) - additional optimizations */
@media (max-width: 640px) {
    /* Page title adjustments - allow flex shrink */
    .page-title {
        font-size: 20px;
        flex: 1 1 auto;
        min-width: 0;
        overflow: hidden;
        white-space: nowrap;
    }

    /* Ellipsis must be on the text span, not the flex container */
    .page-title-text {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        flex: 1;
        min-width: 0;
        display: block;
    }

    /* Summary cards - 2 column grid */
    .summary-row {
        grid-template-columns: repeat(2, 1fr) !important;
        gap: 10px !important;
    }

    .summary-card {
        padding: 14px !important;
    }

    .summary-card .value {
        font-size: 22px !important;
    }

    .summary-card .label {
        font-size: 11px !important;
    }

    /* Cards - tighter on mobile */
    .card {
        padding: 16px !important;
        margin-bottom: 12px !important;
        border-radius: 12px !important;
    }

    /* Admin banner - more compact */
    .admin-banner {
        padding: 8px 16px !important;
        gap: 8px !important;
        font-size: 13px !important;
    }
    .admin-banner-icon { display: none !important; }
    .admin-banner-content { gap: 4px !important; font-size: 13px !important; }

    /* Tab nav margin tighter */
    .tab-nav { margin-bottom: 12px !important; }

    /* Tab navigation - wrap to next row on overflow instead of horizontal scroll */
    .tab-nav {
        display: flex !important;
        overflow-x: visible !important;
        flex-wrap: wrap !important;
        gap: 4px !important;
        padding: 4px !important;
    }

    .tab-btn {
        flex: 1 1 auto !important;
        padding: 8px 12px !important;
        font-size: 13px !important;
        white-space: nowrap;
    }

    .tab-btn svg {
        width: 16px !important;
        height: 16px !important;
        margin-right: 6px !important;
    }

    /* Content area - prevent overflow */
    .content-area {
        padding: 14px 24px !important;
        padding-bottom: 150px !important;
        width: 100%;
        max-width: 100%;
        overflow-x: hidden;
        box-sizing: border-box;
    }

    /* Header - prevent overflow */
    .top-header {
        max-width: 100%;
        overflow: hidden;
        padding: 12px 16px !important;
        padding-top: calc(12px + env(safe-area-inset-top, 0)) !important;
    }

    .header-right {
        flex-shrink: 1;
        min-width: 0;
    }
}

/* iPhone 13 Pro Max (428px) and similar */
@media (max-width: 430px) {
    .page-title {
        font-size: 18px;
    }



    .top-header {
        padding: 10px 12px !important;
        padding-top: calc(10px + env(safe-area-inset-top, 0)) !important;
    }

    .content-area {
        padding: 12px 16px !important;
        padding-bottom: 140px !important;
    }

    /* Summary cards tighter */
    .summary-row {
        gap: 8px !important;
    }

    .summary-card {
        padding: 12px !important;
    }

    .summary-card .value {
        font-size: 20px !important;
    }

    .summary-card .label {
        font-size: 10px !important;
    }

    /* Tab buttons smaller */
    .tab-btn {
        padding: 8px 12px !important;
        font-size: 12px !important;
    }

    .tab-btn svg {
        width: 14px !important;
        height: 14px !important;
        margin-right: 4px !important;
    }

    /* Mobile action bar - styles consolidated in dedicated responsive section */
}

/* iPhone 13 (390px) and smaller */
@media (max-width: 400px) {
    .page-title {
        font-size: 16px;
    }



    .top-header {
        padding: 8px 10px !important;
        padding-top: calc(8px + env(safe-area-inset-top, 0)) !important;
    }

    /* Ensure header-right shrinks to give title more space */
    .header-right {
        flex-shrink: 2;
    }
}

/* Very small screens (375px and below - iPhone SE) */
@media (max-width: 375px) {


    .page-title {
        font-size: 15px;
    }

    .top-header {
        padding: 8px !important;
        padding-top: calc(8px + env(safe-area-inset-top, 0)) !important;
        gap: 8px;
    }

    .content-area {
        padding: 10px 12px !important;
        padding-bottom: 140px !important;
    }

    /* Summary cards even tighter */
    .summary-row {
        gap: 6px !important;
    }

    .summary-card {
        padding: 10px !important;
    }

    .summary-card .value {
        font-size: 18px !important;
    }

    .summary-card .label {
        font-size: 9px !important;
        letter-spacing: 0.3px;
    }

    /* Tab buttons smallest */
    .tab-btn {
        padding: 6px 10px !important;
        font-size: 11px !important;
    }

    .tab-btn svg {
        width: 12px !important;
        height: 12px !important;
        margin-right: 3px !important;
    }

    /* Mobile action bar styles moved to dedicated responsive section below */
}

/* =============================================
   Responsive Tables & Overflow Prevention
   ============================================= */
@media (max-width: 640px) {
    /* Make all tables horizontally scrollable */
    .card,
    .data-table-wrapper,
    .table-container {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Tables should not force page width - removed min-width to prevent horizontal scroll */
    table,
    .data-table {
        width: 100%;
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Prevent any element from causing overflow */
    .content-area * {
        max-width: 100%;
    }

    /* But allow tables to be wider and scroll */
    .content-area table,
    .content-area .data-table {
        max-width: none;
    }

    /* Allow crosshair elements to have explicit dimensions */
    .content-area .mobile-crosshair,
    .content-area .mobile-crosshair * {
        max-width: none;
    }

    /* Allow Leaflet map internals to have explicit dimensions */
    .content-area .leaflet-pane,
    .content-area .leaflet-pane * {
        max-width: none;
    }

    /* Ensure cards don't overflow */
    .card {
        max-width: 100%;
        box-sizing: border-box;
    }

    /* Search boxes should fit */
    .search-box,
    .search-box input {
        max-width: 100%;
        box-sizing: border-box;
    }

    /* Inventory report tables: prevent forced 600px min-width */
    .report-group-content .items-table,
    .usage-table-card .items-table {
        min-width: auto;
    }
}

@media (max-width: 430px) {
    /* Even tighter table constraints for phones */
    table th,
    table td,
    .data-table th,
    .data-table td {
        padding: 8px 6px !important;
        font-size: 12px !important;
    }

    /* Hide less important columns on very small screens */
    .hide-on-mobile {
        display: none !important;
    }

    /* Compact inventory tables on phones */
    .items-table:not(.responsive-stack) th,
    .items-table:not(.responsive-stack) td {
        padding: 8px 5px !important;
        font-size: 11px !important;
        white-space: nowrap;
    }

    .items-table:not(.responsive-stack) th {
        text-transform: none;
        letter-spacing: 0;
    }
}

/* Filters */
.filters-bar {
    display: flex;
    gap: 16px;
    margin-bottom: 24px;
    flex-wrap: wrap;
}

.filter-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.filter-label {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
}

.filter-select {
    padding: 8px 12px;
    border: 1px solid var(--border-color);
    border-radius: 8px;
    background: white;
    font-size: 14px;
    min-width: 150px;
}

/* Tabs */
.tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border-color);
    margin-bottom: 24px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none; /* Firefox */
}

.tabs::-webkit-scrollbar {
    display: none; /* Chrome/Safari */
}

.tab {
    padding: 12px 24px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
    background: none;
    border: none;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: all 0.2s;
    flex-shrink: 0;
    white-space: nowrap;
}

.tab:hover {
    color: #111827;
}

.tab.active {
    color: var(--primary-color);
    border-bottom-color: var(--primary-color);
}

/* Tab Nav — Segmented pill style (canonical, white & green)
   .tab-navigation is the current canonical class; .tab-nav is the legacy alias.
   mobile-tokens.css Issue 11 targets .tab-nav to apply underline style, so pages
   that want the pill style must use .tab-navigation. */
.tab-nav,
.tab-navigation {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    gap: 4px;
    background: var(--bg-card);
    padding: 4px;
    border-radius: 10px;
    margin-bottom: 20px;
    border: 1px solid var(--border-color);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.tab-nav::-webkit-scrollbar,
.tab-navigation::-webkit-scrollbar {
    display: none;
}

.tab-btn {
    padding: 10px 16px;
    background: transparent;
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.2s;
    text-decoration: none;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    white-space: nowrap;
}

.tab-btn:hover {
    background: #f3f4f6;
    color: #111827;
}

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

.tab-btn svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

/* Activity Feed */
.activity-list {
    list-style: none;
}

.activity-item {
    display: flex;
    gap: 16px;
    padding: 16px 0;
    border-bottom: 1px solid var(--border-color);
}

.activity-item:last-child {
    border-bottom: none;
}

.activity-icon {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.activity-icon.spray {
    background: rgba(59, 130, 246, 0.1);
    color: var(--info-color);
}

.activity-icon.completed {
    background: rgba(34, 197, 94, 0.1);
    color: var(--success-color);
}

.activity-icon.alert {
    background: rgba(239, 68, 68, 0.1);
    color: var(--danger-color);
}

.activity-icon svg {
    width: 20px;
    height: 20px;
}

.activity-content {
    flex: 1;
}

.activity-title {
    font-size: 14px;
    font-weight: 500;
    color: #111827;
    margin-bottom: 4px;
}

.activity-description {
    font-size: 13px;
    color: var(--text-secondary);
}

.activity-time {
    font-size: 12px;
    color: var(--text-secondary);
    white-space: nowrap;
}

/* Map Container */
.map-container {
    height: calc(100vh - 140px);
    min-height: 400px;
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid var(--border-color);
    position: relative;
    z-index: 1;
}

.map-container #map {
    height: 100%;
    width: 100%;
}

/* Mobile viewport fixes */
@media (max-width: 640px) {
    .map-container {
        height: auto;
        min-height: 500px;
        max-height: calc(100vh - 200px);
    }
}

@media (max-width: 480px) {
    .map-container {
        height: 55vh;
        min-height: 350px;
        max-height: 500px;
    }
}

/* Leaflet z-index override - ensure header/sidebar appears above map */
.leaflet-container {
    z-index: 1;
    touch-action: manipulation;  /* Allow taps for popups, prevent double-tap zoom */
}
.leaflet-control-attribution {
    display: none !important;
}

/* Fix Leaflet zoom control layout — body { zoom: 0.8 } causes mobile Safari to
   render the +/− buttons side-by-side instead of stacked. Force vertical block layout. */
.leaflet-control-zoom.leaflet-bar {
    display: block !important;
    width: auto !important;
    height: auto !important;
}
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
    display: block !important;
    float: none !important;
    width: 30px !important;
    height: 30px !important;
    line-height: 30px !important;
    text-align: center !important;
    font-size: 18px !important;
}
.leaflet-top .leaflet-control {
    margin-top: 10px !important;
    margin-left: 10px !important;
}

.leaflet-pane {
    z-index: 400;
}

/* Ensure marker pane is above overlay pane for proper click handling */
.leaflet-marker-pane {
    z-index: 600 !important;
}

.leaflet-top,
.leaflet-bottom,
.leaflet-control {
    z-index: 800 !important;
}

/* Ensure popup pane appears above controls and other UI elements on all screen sizes */
.leaflet-popup-pane {
    z-index: 1200 !important;
}

/* Map touch handling for iOS PWA
   Prevents page zoom when interacting with maps - Leaflet handles gestures instead */
#field-map,
#field-map-container,
#master-map,
#map {
    touch-action: manipulation;  /* Allow taps for popups, prevent double-tap zoom */
}

/* Map Legend */
.map-legend {
    position: absolute;
    bottom: 24px;
    left: 24px;
    background: var(--bg-card);
    border-radius: 8px;
    padding: 16px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    z-index: 900;
}

.legend-title {
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 12px;
}

.legend-item {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    margin-bottom: 8px;
}

.legend-color {
    width: 20px;
    height: 20px;
    border-radius: 4px;
}

@media (max-width: 640px) {
    .map-legend {
        bottom: 10px;
        left: 10px;
        padding: 8px 10px;
        border-radius: 6px;
    }
    .legend-title {
        font-size: 11px;
        margin-bottom: 6px;
    }
    .legend-item {
        font-size: 11px;
        gap: 5px;
        margin-bottom: 4px;
    }
    .legend-color {
        width: 12px;
        height: 12px;
        border-radius: 2px;
        flex-shrink: 0;
    }
}

/* Responsive */
@media (max-width: 640px) {
    .app-container {
        min-height: 100vh;
    }

    .main-content {
        min-height: 100vh;
    }

    .sidebar {
        transform: translateX(-100%);
        height: max(125vh, 125dvh);  /* zoom:0.8 still active for mouse users — compensate */
        max-height: -webkit-fill-available; /* iOS Safari: fills to actual visible area */
        pointer-events: none; /* Disable interaction when hidden to prevent overlap detection */
    }

    .sidebar.open {
        transform: translateX(0);
        z-index: 9999;
        pointer-events: auto; /* Re-enable interaction when open */
        width: 260px; /* Restore width — --sidebar-width is 0px on mobile so base rule gives no width */
    }

    .main-content {
        margin-left: 0;
        width: 100%;
        max-width: 100%;  /* Override the calc() that subtracts sidebar width */
        min-width: 0;     /* Allow flex item to shrink below content size */
    }

    .content-area {
        width: 100%;
        max-width: 100%;
        min-width: 0;
    }

    .menu-toggle {
        display: block;
    }

    /* Raise top-header above the open sidebar (z-index: 9999) so hamburger stays clickable.
       .app-container creates a stacking context at z-index: 100, so .top-header's z-index
       must beat the sidebar (9999) within that same stacking context. */
    .top-header {
        z-index: 10000 !important;
    }

    /* When sidebar is open, drop the header behind the sidebar instead of hiding elements.
       Previously used visibility:hidden on .page-title, but iOS captures a page snapshot
       for navigation transitions before the JS-driven sidebar-close repaint lands — that
       snapshot showed a blank title. Lowering z-index keeps the element rendered
       (just covered by the sidebar at z-index:9999), so snapshots never show a missing title. */
    .sidebar.open ~ .main-content .top-header {
        z-index: 0 !important;
    }

    /* Hide sticky footer bar when sidebar is open — prevents it showing below/beside sidebar */
    .sidebar.open ~ .main-content .form-actions {
        display: none;
    }

    /* When sidebar is hidden, action bar goes full width */
    .mobile-action-bar {
        left: 0;
    }

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

    /* Ensure sidebar footer is always visible on mobile */
    .sidebar-footer {
        padding: 16px;
        flex-shrink: 0;
        min-height: 72px;
    }

    /* Make sidebar nav scrollable but keep footer visible */
    .sidebar-nav {
        flex: 1 1 0;
        height: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 32px; /* Extra bottom padding for last item visibility */
    }

    /* Show mobile logout in header since sidebar is hidden */
    .mobile-logout-btn {
        display: flex;
    }
}

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

    .content-area {
        padding: 12px 16px;
    }

    /* Remove sticky-footer padding on mobile — dashboard has no footer; pages with footers use has-footer class */
    .main-content {
        padding-bottom: 0;
    }

    /* Compress top header on phones */
    .top-header {
        padding: 10px 16px;
    }

    /* Smaller page title on phones */
    .page-title {
        font-size: 20px;
        letter-spacing: -0.3px;
    }

    /* Tighter cards on phones */
    .card {
        padding: 16px;
        margin-bottom: 12px;
    }

    .card-header {
        margin-bottom: 10px;
    }

    .metric-card {
        padding: 16px;
    }

    .metrics-grid {
        gap: 12px;
        margin-bottom: 12px;
    }

    .filters-bar {
        flex-direction: column;
    }

    .data-table {
        font-size: 13px;
    }

    .data-table th,
    .data-table td {
        padding: 8px 12px;
    }
}

/* Reset zoom only for actual phones (≤480px CSS pixels).
   iPhones = 375-430px, Android = 360-412px — all under 480px.
   Laptops narrowed to narrow window = always wider than 480px.
   Zoom reset needed on real phones because iOS Safari ignores overflow-x:clip,
   so 125vw body creates horizontal scroll. Phones get zoom:1 + width:100vw fix.
   Narrowed laptop windows stay at zoom:0.8 and never hit this rule. */
@media (max-width: 480px) {
    body {
        zoom: 1;
        width: 100vw;
        min-height: 100vh;
        /* Use clip (not hidden) — clip does NOT force overflow-y:auto (CSS spec).
           hidden forces overflow-y:auto on body, making body a 2nd scroll container
           alongside html's viewport scroll → two scrollbars on iOS. clip avoids this. */
        overflow-x: clip;
    }

    /* Remove zoom:0.8 compensation — these were sized at 125vh/125vw to fill the
       viewport after zoom shrinks everything to 80%. With zoom:1 they overshoot
       by 25%, creating ~400px of empty scroll space that pushes content out of view. */
    .app-container {
        min-height: 100vh !important;
    }

    .main-content {
        min-height: 100vh !important;
        max-width: 100% !important;
    }

    .sidebar {
        font-size: 14px; /* zoom is 1, no compensation needed */
        /* Anchor to viewport edges instead of height:100dvh — iOS Safari doesn't
           reliably recompute dvh for fixed elements after toolbar/keyboard
           transitions, so a stale (smaller) height left an intermittent gap at
           the bottom of the open menu with the page showing through. */
        top: 0;
        bottom: 0;
        height: auto;
        max-height: none; /* Override -webkit-fill-available from 768px rule */
    }

    .nav-item {
        padding: 5px 13px;
        gap: 10px;
    }

    .nav-label {
        padding: 5px 13px 3px;
    }
}

/* Extend phone-mode zoom reset to the full ≤640px touch range.
   The 480px block above resets zoom:1 for actual phones (≤480px CSS px).
   Devices in the 481–640px range (some Androids, landscape narrow phones)
   kept zoom:0.8 so narrowed laptop windows would still see the desktop scale.
   But on touch devices (pointer:coarse), iOS Safari treats position:fixed
   coordinates in the zoomed coordinate space — bottom:0 lands below the
   visual viewport, making fixed footers invisible.
   pointer:coarse excludes desktop browsers narrowed to <640px (pointer:fine). */
@media (max-width: 640px) and (pointer: coarse) {
    body {
        zoom: 1;
        width: 100vw;
        min-height: 100vh;
        overflow-x: clip;
    }

    .app-container {
        min-height: 100vh !important;
    }

    .main-content {
        min-height: 100vh !important;
        max-width: 100% !important;
    }

    /* Sidebar drawer: anchor to viewport edges — zoom is 1 here, so bottom:0 is
       safe. Sizing with dvh / -webkit-fill-available left an intermittent gap at
       the bottom of the open menu on iOS (stale viewport-unit values after
       toolbar/keyboard transitions are not recomputed for fixed elements). */
    .sidebar {
        top: 0;
        bottom: 0;
        height: auto;
        max-height: none;
    }

    /* iOS Safari composites a background-attachment:fixed layer against the
       LAYOUT viewport, not the visible one, so on a scrolled page it paints the
       green gradient as a dead band across the bottom of the screen while the
       content scrolls underneath it. The gradient scrolls with the page here —
       visually identical on a phone, and the band goes away. */
    .content-area {
        background-attachment: scroll !important;
    }

    /* The hamburger lives in .top-header, so a header that scrolls away takes
       the only route to the sidebar with it — on a phone you had to scroll all
       the way back up to change page. Pin it. (Pages with a mobile static
       footer already do this inside their own scroll container.)
       touch-action: none — same as .mobile-static-footer: a drag starting on the
       sticky header rubber-bands the scroller and pulls the header down with it. */
    body:not(:has(.mobile-static-footer)) .top-header {
        position: sticky;
        top: 0;
        z-index: 200;
        background: var(--sidebar-bg);
        touch-action: none;
    }
}


/* iOS Safari sticky footer — add/edit form pages only.
   JS in base.html moves .form-actions (identified by .autosave-hide save button) to the
   end of .main-content (outside the card) and adds .mobile-static-footer.
   .main-content becomes the scroll container; position:sticky keeps the footer pinned
   to the bottom of its visible area — no position:fixed, no compositor bug.
   List pages are skipped (their form-actions buttons lack .autosave-hide).
   :has() supported on iOS 16+ which is the same range affected by this bug. */
@media (max-width: 640px) and (pointer: coarse) {
    html:has(.mobile-static-footer),
    body:has(.mobile-static-footer) {
        height: 100dvh !important;
        overflow: hidden !important;
        /* Same failure the .content-area rule above fixes, one level up. html and
           body still carry background-attachment: fixed (the base html/body rules),
           which iOS Safari composites against the LAYOUT viewport. Any desync
           between that and the visible viewport — e.g. a programmatic window scroll
           on this locked layout — makes Safari repaint the gradient over the content
           and leave only the tile band it thinks is visible (BR 2026-09-09: the job
           detail page rendered as one strip of the weather card on a green field
           after Save). On this layout html/body are exactly 100dvh and never
           scroll, so scroll vs fixed is pixel-identical here — it only removes the
           fixed-attachment compositing layer that can produce the dead band. */
        background-attachment: scroll !important;
    }

    body:has(.mobile-static-footer) .main-content {
        height: 100dvh !important;
        min-height: 0 !important;
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch !important;
        padding-bottom: 0 !important;
        display: flex !important;
        flex-direction: column !important;
        /* No rubber-band bounce: overscrolling at either end dragged the whole
           content — including the sticky header/footer — with the finger
           (touch-action on the bars only stops gestures that START on them). */
        overscroll-behavior-y: none !important;
    }

    /* Keep header visible while scrolling.
       touch-action: none — same as .mobile-static-footer below: a press-and-hold
       drag starting on the sticky header panned .main-content and iOS rubber-band
       overscroll dragged the header down with the content. */
    body:has(.mobile-static-footer) .main-content .top-header {
        position: sticky !important;
        top: 0 !important;
        z-index: 200 !important;
        background: var(--sidebar-bg) !important;
        touch-action: none;
    }

    /* content-area grows to fill remaining height */
    body:has(.mobile-static-footer) .main-content > .content-area {
        flex: 1 !important;
        min-height: 0 !important;
        /* ...and scrolls inside it. This box is squeezed to the space between the
           header and the footer, so it has to be the thing that scrolls. A page
           that set overflow: visible on it (Create Mix Template, Checklist
           Template) let the form spill out of the box instead: the footer, which
           comes straight after the box, was left in the middle of the screen with
           the form running underneath it (Jason, 2026-10-12). */
        overflow-y: auto !important;
    }

    /* Form pages (.msf-form) used to take the card background here (cream
       content-area, 2026-07-19) so the gap above the footer didn't flash the
       dark page bg. Removed 2026-08-15 at the user's call: every other page
       shows white cards on the green ground, and the cream family (Add
       Customer etc.) stuck out — including making the white breadcrumb text
       invisible. Form pages now match the rest of the app. */

    /* Sticky inside .main-content scroll container — stays at bottom of visible area.
       touch-action: none — a press-and-hold drag starting on the footer was panning
       the .main-content scroll container, and iOS rubber-band overscroll drags sticky
       elements with the content, so the footer itself followed the finger up/down
       (BR: spray job footer scrollable). Pan gestures on the footer now do nothing;
       button taps are unaffected. */
    .mobile-static-footer {
        position: sticky !important;
        bottom: 0 !important;
        transform: none !important;
        left: 0 !important;
        right: auto !important;
        width: 100% !important;
        touch-action: none;
    }

    /* While the iOS keyboard is up (html.dc-kb-open stamped by base.html JS),
       the sticky footer would pin to the bottom of the shrunken visible area —
       parked right above the keyboard, eating half the typing space. Hide it
       until dismiss. display needs !important to beat page-level grids like
       .spray-job-actions { display: grid !important }. */
    html.dc-kb-open .mobile-static-footer {
        display: none !important;
    }
}

/* Prevent iOS Safari auto-zoom on form inputs
   iOS zooms when font-size < 16px on input focus.
   Using bare `input` catches ALL types including inputs without an explicit
   type attribute (they default to text behavior but `input[type="text"]`
   won't match them in CSS) and date/time/url/datetime-local inputs. */
@media (max-width: 640px) {
    input,
    select,
    textarea,
    .form-control,
    .combobox-input,
    .combobox-search {
        font-size: 16px !important;
    }

    /* Strip iOS native form chrome on date/time/number inputs.
       iOS Safari adds internal padding and styling to these field types that
       breaks our consistent input height. -webkit-appearance: none is the
       canonical reset. Per primitives-spec §5.4. */
    input[type="date"],
    input[type="time"],
    input[type="datetime-local"],
    input[type="month"],
    input[type="week"],
    input[type="number"] {
        -webkit-appearance: none;
        appearance: none;
    }
}

/* Overlay for mobile */
.sidebar-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0,0,0,0.5);
    z-index: 9998;
}

.sidebar-overlay.active {
    display: block;
}

/* Lock body scroll when sidebar is open on mobile */
body.sidebar-open {
    overflow: hidden;
    /* NOTE: Do NOT use position:fixed — iOS Safari removes fixed body and
       miscalculates the visual viewport, leaving the page zoomed in.
       Scroll blocking is handled by JS touchmove prevention instead. */
    width: 100%;
    touch-action: none; /* Prevent any touch scrolling on body */
}

body.sidebar-open .app-container {
    touch-action: none; /* Also lock the app container */
}

body.sidebar-open .main-content {
    touch-action: none; /* Lock main content area */
}

/* Hide hamburger when sidebar is open so it doesn't overlap the logo */
body.sidebar-open .menu-toggle {
    visibility: hidden;
}

/* Ensure sidebar scrolls independently on mobile */
@media (max-width: 640px) {
    .sidebar.open {
        touch-action: pan-y; /* Allow only vertical scrolling on sidebar */
    }

    .sidebar.open .sidebar-nav {
        overscroll-behavior: contain;
        touch-action: pan-y;
        -webkit-overflow-scrolling: touch;
        overflow-y: auto;
        overflow-x: hidden;
    }

    .sidebar-overlay.active {
        touch-action: none; /* Prevent scrolling through overlay */
    }
}

/* Alert/inventory box */
.alert-box {
    padding: 16px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    gap: 12px;
}

.alert-box.success {
    background: rgba(34, 197, 94, 0.1);
    color: var(--success-color);
}

.alert-box.warning {
    background: rgba(245, 158, 11, 0.1);
    color: var(--warning-color);
}

.alert-box.danger {
    background: rgba(239, 68, 68, 0.1);
    color: var(--danger-color);
}

.alert-box svg {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

/* ===========================================
   Auto-Save Styles
   =========================================== */

/* Status indicator in header */
.autosave-status {
    font-size: 12px;
    padding: 4px 10px;
    border-radius: 4px;
    margin-left: 12px;
    vertical-align: middle;
    display: inline-flex;
    align-items: center;
    transition: all 0.2s ease;
}

.autosave-status.status-saved {
    color: #059669;
    background: #d1fae5;
}

.autosave-status.status-saving {
    color: #d97706;
    background: #fef3c7;
}

.autosave-status.status-unsaved {
    color: #6b7280;
    background: #f3f4f6;
}

.autosave-status.status-error {
    color: #ffffff;
    background: #dc2626;
    font-weight: 600;
    padding: 6px 14px;
    font-size: 13px;
    border: 2px solid #b91c1c;
    animation: pulse-error 1.5s ease-in-out infinite;
    box-shadow: 0 2px 8px rgba(220, 38, 38, 0.4);
}

@keyframes pulse-error {
    0%, 100% {
        transform: scale(1);
        box-shadow: 0 2px 8px rgba(220, 38, 38, 0.4);
    }
    50% {
        transform: scale(1.02);
        box-shadow: 0 4px 16px rgba(220, 38, 38, 0.6);
    }
}

/* Field-level errors */
.form-control.has-error,
input.has-error,
select.has-error,
textarea.has-error {
    border-color: #dc2626 !important;
    background-color: #fef2f2 !important;
}

.form-control.has-error:focus {
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1) !important;
}

.field-error {
    color: #dc2626;
    font-size: 12px;
    margin-top: 4px;
    display: flex;
    align-items: center;
    gap: 4px;
}

.field-error::before {
    content: '';
    width: 12px;
    height: 12px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23dc2626' d='M13,13H11V7H13M13,17H11V15H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z'/%3E%3C/svg%3E");
    background-size: contain;
    flex-shrink: 0;
}

/* Progress Bar Component */
.progress-container {
    width: 100%;
    margin-top: 20px;
    text-align: center;
}

.progress-bar {
    width: 100%;
    height: 8px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 4px;
    overflow: hidden;
    margin-bottom: 8px;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
}

.progress-bar-fill {
    height: 100%;
    background: linear-gradient(90deg, #4CAF50 0%, #66BB6A 100%);
    border-radius: 4px;
    transition: width 0.3s ease-in-out;
    box-shadow: 0 0 10px rgba(76, 175, 80, 0.5);
}

.progress-text {
    font-size: 14px;
    color: #2c3e50;  /* Dark blue-gray text */
    font-weight: 600;  /* Slightly bolder for readability */
    text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);  /* Light shadow for contrast */
}

/* Animation for indeterminate progress */
@keyframes progress-indeterminate {
    0% {
        transform: translateX(-100%);
    }
    100% {
        transform: translateX(400%);
    }
}

.progress-bar-fill.indeterminate {
    width: 25% !important;
    animation: progress-indeterminate 1.5s ease-in-out infinite;
    background: linear-gradient(90deg, transparent 0%, #4CAF50 50%, transparent 100%);
}

/* Django errorlist styling */
.errorlist {
    list-style: none;
    padding: 0;
    margin: 0 0 16px 0;
}

.errorlist li {
    color: #dc2626;
    font-size: 13px;
    padding: 8px 12px;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 6px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.errorlist li::before {
    content: '';
    width: 16px;
    height: 16px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23dc2626' d='M13,13H11V7H13M13,17H11V15H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z'/%3E%3C/svg%3E");
    background-size: contain;
    flex-shrink: 0;
}

/* Form-level error banner */
.form-errors {
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 20px;
}

.form-errors-title {
    color: #991b1b;
    font-weight: 600;
    font-size: 14px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.form-errors-list {
    list-style: disc;
    padding-left: 20px;
    margin: 0;
    color: #dc2626;
    font-size: 13px;
}

.form-errors-list li {
    margin-bottom: 4px;
}

/* Success message styling */
.form-success {
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 20px;
    color: #166534;
    font-size: 14px;
    display: flex;
    align-items: center;
    gap: 12px;
}

.form-success::before {
    content: '';
    width: 20px;
    height: 20px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%2322c55e' d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M10,17L5,12L6.41,10.59L10,14.17L17.59,6.58L19,8L10,17Z'/%3E%3C/svg%3E");
    background-size: contain;
    flex-shrink: 0;
}

/* Draft badge */
.draft-badge {
    background: #fef3c7;
    color: #92400e;
    padding: 3px 8px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-left: 10px;
    vertical-align: middle;
}

/* Publish button styling */
.btn-publish {
    background: linear-gradient(135deg, #059669 0%, #047857 100%);
    color: white;
    border: none;
}

.btn-publish:hover {
    background: linear-gradient(135deg, #047857 0%, #065f46 100%);
}

.btn-publish:disabled {
    background: #9ca3af;
    cursor: not-allowed;
}

/* ===== ENVIRONMENT INDICATOR BADGE ===== */
.env-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4px 12px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin: 8px auto 0 auto;
}

.env-badge--dev {
    background-color: #dbeafe;
    color: #1d4ed8;
    border: 1px solid #93c5fd;
}

.env-badge--demo {
    background-color: #fef3c7;
    color: #b45309;
    border: 1px solid #fcd34d;
}

.sidebar-version-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 4px auto 0 auto;
    font-size: 11px;
    font-weight: 600;
    color: rgba(255,255,255,0.4);
    text-decoration: none;
    letter-spacing: 0.3px;
    transition: color 0.15s;
}

.sidebar-version-badge:hover {
    color: rgba(255,255,255,0.8);
    text-decoration: underline;
}

/* =====================================================
   NARROW SCREEN RESPONSIVE FIXES
   Supports: 360px (Mini/budget), 375px (SE), 390px (12-15), 430px (Pro Max)
   ===================================================== */

/* Mobile Action Bar - Wrap and shrink at narrow widths */
@media (max-width: 640px) {
    .mobile-action-bar {
        flex-wrap: wrap;
        justify-content: center;
        gap: 6px;
        padding: 10px 12px;
    }

    .mobile-action-bar .btn {
        min-width: 0;
        max-width: none;
        flex: 1 1 auto;
        padding: 8px 6px;
        font-size: 11px;
        gap: 3px;
    }

    /* Back button - full width, horizontal layout */
    .mobile-action-bar .btn:first-child {
        flex: 0 0 100%;
        order: -1;
    }

    /* Action buttons (not Back) - vertical icon + label stacked */
    .mobile-action-bar .btn:not(:first-child) {
        flex: 1 1 0;
        min-width: 0;
        padding: 8px 4px;
        flex-direction: column;      /* Stack icon above label */
        gap: 2px;
    }

    /* Icons sized for tapping */
    .mobile-action-bar .btn:not(:first-child) svg {
        width: 20px;
        height: 20px;
    }

    /* Label text below icon */
    .mobile-action-bar .btn:not(:first-child) .btn-label {
        font-size: 10px;
        line-height: 1;
    }

    /* Increase content padding when action bar buttons wrap */
    .content-area {
        padding-bottom: 150px !important;
    }
}

/* Even narrower screens - more compact */
@media (max-width: 400px) {
    .mobile-action-bar {
        padding: 8px 8px;
        gap: 4px;
    }

    .mobile-action-bar .btn:not(:first-child) {
        padding: 6px 2px;
    }

    .mobile-action-bar .btn:not(:first-child) svg {
        width: 18px;
        height: 18px;
    }

    .mobile-action-bar .btn:not(:first-child) .btn-label {
        font-size: 9px;
    }
}

/* Tiny screens - allow horizontal scroll as last resort */
@media (max-width: 320px) {
    .mobile-action-bar {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        justify-content: flex-start;
    }

    .mobile-action-bar .btn {
        flex: 0 0 auto;
        min-width: 60px;
    }

    .mobile-action-bar .btn:first-child {
        flex: 0 0 auto;
        order: 0;
    }
}

/* Responsive filter bar - used across multiple pages */
.filters-responsive {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

@media (max-width: 640px) {
    .filters-responsive {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 12px;
    }
    .filters-responsive > div,
    .filters-responsive > select {
        min-width: auto !important;
        width: 100%;
    }
    .filters-responsive select,
    .filters-responsive input {
        min-width: auto !important;
        width: 100%;
    }
}

@media (max-width: 430px) {
    .filters-responsive {
        grid-template-columns: 1fr;
        gap: 10px;
    }
}

/* Responsive stat boxes */
.stat-boxes-responsive {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

@media (max-width: 430px) {
    .stat-boxes-responsive {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(70px, 1fr));
        gap: 8px;
    }
    .stat-boxes-responsive > * {
        min-width: auto;
        padding: 8px 12px;
    }
}

/* Responsive legend/info bar */
.legend-responsive {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

@media (max-width: 640px) {
    .legend-responsive {
        flex-direction: column;
        gap: 6px;
    }
    .legend-responsive span {
        font-size: 12px;
    }
}

/* =====================================================
   RESPONSIVE TWO-LINE TABLE ROW PATTERN
   Strategy: Stack secondary info below primary info
   Reference: users.html card layout pattern
   ===================================================== */

/* At 430px: Convert table rows to stacked card layout */
@media (max-width: 430px) {
    /* Table becomes block layout */
    .data-table.responsive-stack thead {
        display: none;
    }

    /* tbody must be block so it inherits the table's 100% block width;
       without this, tbody stays table-row-group and creates an anonymous
       table sized to content, leaving empty space on the right */
    .data-table.responsive-stack tbody {
        display: block;
        width: 100%;
    }

    .data-table.responsive-stack tbody tr {
        display: block;
        padding: 12px;
        margin-bottom: 8px;
        background: var(--bg-card);
        border: 1px solid var(--border-color);
        border-radius: 8px;
    }

    .data-table.responsive-stack tbody td {
        display: block;
        padding: 4px 0;
        border: none;
    }

    /* Primary cell (first cell) - prominent */
    .data-table.responsive-stack tbody td:first-child {
        font-weight: 600;
        font-size: 14px;
        margin-bottom: 8px;
        padding-bottom: 8px;
        border-bottom: 1px dashed var(--border-color);
    }

    /* Secondary cells - inline with labels */
    .data-table.responsive-stack tbody td:not(:first-child):not(.actions-cell)::before {
        content: attr(data-label) ': ';
        font-weight: 500;
        color: var(--text-secondary);
        font-size: 11px;
    }

    /* Actions cell - full width button row */
    .data-table.responsive-stack tbody td.actions-cell {
        margin-top: 8px;
        padding-top: 8px;
        border-top: 1px dashed var(--border-color);
        display: flex;
        gap: 8px;
        justify-content: flex-end;
    }

    /* Hide secondary columns that have data-label but show inline */
    .data-table.responsive-stack tbody td.hide-on-mobile {
        display: none;
    }
}

/* At 360px: Even tighter spacing */
@media (max-width: 360px) {
    .data-table.responsive-stack tbody tr {
        padding: 10px;
        margin-bottom: 6px;
    }

    .data-table.responsive-stack tbody td:first-child {
        font-size: 13px;
    }

    .data-table.responsive-stack tbody td:not(:first-child)::before {
        font-size: 10px;
    }
}

/* ============================================
   PDF Viewer Modal for PWA
   Prevents navigation trap on iOS standalone mode
   ============================================ */
.pdf-viewer-modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #fff;
    z-index: 10000;
    display: flex;
    flex-direction: column;
}

.pdf-viewer-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    background: #1e293b;
    color: white;
    flex-shrink: 0;
}

.pdf-viewer-title {
    font-weight: 600;
    font-size: 16px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pdf-viewer-close {
    display: flex;
    align-items: center;
    gap: 8px;
    background: #dc2626;
    color: white;
    border: none;
    padding: 10px 20px;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
}

.pdf-viewer-close:hover {
    background: #b91c1c;
}

.pdf-viewer-close:active {
    background: #991b1b;
}

.pdf-viewer-actions {
    display: flex;
    gap: 12px;
    flex-shrink: 0;
}

.pdf-viewer-print {
    display: flex;
    align-items: center;
    gap: 8px;
    background: #2563eb;
    color: white;
    border: none;
    padding: 10px 20px;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
}

.pdf-viewer-print:hover {
    background: #1d4ed8;
}

.pdf-viewer-print:active {
    background: #1e40af;
}

.pdf-viewer-frame {
    flex: 1;
    /* Without min-height:0 a flex child keeps its content (intrinsic) height,
       so the PDF iframe overflows past the fixed container's bottom and the
       end of the last page can't be scrolled to. This clamps it to the
       available space so the iframe's own scrollbar reaches every page. */
    min-height: 0;
    border: none;
    width: 100%;
    background: #f1f5f9;
}

/* ===========================================================================
   Admin Banners (View-as-Tenant & Impersonation)
   =========================================================================== */

.admin-banner {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 24px;
    position: sticky;
    top: 0;
    z-index: 100;
}

.admin-banner-icon {
    flex-shrink: 0;
}

.admin-banner-content {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.admin-banner-content strong {
    font-weight: 600;
}

.admin-banner-badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 500;
}

.admin-banner-btn {
    padding: 8px 16px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    border: none;
    /* these are <a> elements, so without this the UA underline draws through the
       label and the button reads as a link with a background (2026-10-02) */
    text-decoration: none;
    transition: all 0.2s;
    flex-shrink: 0;
}

/* --link: no fill at all, just a hairline-underlined label — review sheet
   option 34, picked by Jason 2026-10-02. Used by the credential-expiry,
   pending-submission and profile-incomplete CTAs. The colour is inherited from
   the banner, so each severity gets its own without a second declaration; the
   view-as-tenant / impersonation / dev-tenant buttons keep their filled look
   because they do not carry this class. */
.admin-banner-btn--link {
    background: none;
    border: 0;
    border-radius: 0;
    padding: 0 2px;
    min-height: 44px;
    color: inherit;
    font-size: 14px;
    font-weight: 700;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 5px;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}

a.admin-banner-btn--link:hover {
    text-decoration-thickness: 2px;
}

/* View-as-Tenant Banner (Blue - Read-Only) */
.admin-banner--viewing {
    background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
    border-bottom: 2px solid #3b82f6;
    color: #1e40af;
}

.admin-banner--viewing .admin-banner-badge {
    background: #1e40af;
    color: white;
}

.admin-banner--viewing .admin-banner-btn {
    background: #1e40af;
    color: white;
}

.admin-banner--viewing .admin-banner-btn:hover {
    background: #1e3a8a;
}

/* Impersonation Banner (Yellow/Amber - Warning) */
.admin-banner--impersonating {
    background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
    border-bottom: 2px solid #f59e0b;
    color: #92400e;
}

.admin-banner--impersonating .admin-banner-badge {
    background: rgba(146, 64, 14, 0.15);
    color: #92400e;
}

.admin-banner--impersonating .admin-banner-badge--warning {
    background: #92400e;
    color: white;
}

.admin-banner--impersonating .admin-banner-btn--warning {
    background: #f59e0b;
    color: #78350f;
}

.admin-banner--impersonating .admin-banner-btn--warning:hover {
    background: #d97706;
}

/* Superuser Member Mode Banner (Green - Working in tenant) */
.admin-banner--member-mode {
    background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);
    border-bottom: 2px solid #22c55e;
    color: #166534;
}

.admin-banner--member-mode .admin-banner-badge--member {
    background: rgba(22, 101, 52, 0.15);
    color: #166534;
}

.admin-banner--member-mode .admin-banner-btn--member {
    background: #166534;
    color: white;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
}

.admin-banner--member-mode .admin-banner-btn--member:hover {
    background: #15803d;
}

/* Dev Environment Tenant Selector Banner (Purple - Dev only) */
.admin-banner--dev-tenant {
    background: linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 100%);
    border-bottom: 2px solid #a855f7;
    color: #581c87;
}

.admin-banner--dev-tenant select {
    background: rgba(88, 28, 135, 0.1);
    border-color: rgba(88, 28, 135, 0.3);
    color: #581c87;
}

.admin-banner--dev-tenant select:focus {
    outline: none;
    border-color: #a855f7;
    box-shadow: 0 0 0 2px rgba(168, 85, 247, 0.2);
}

.admin-banner--dev-tenant .admin-banner-btn--dev {
    background: #7c3aed;
    color: white;
}

.admin-banner--dev-tenant .admin-banner-btn--dev:hover {
    background: #6d28d9;
}

/* Legal change-notice strip (Phase 222) - neutral, informational.
   Shown to every member of an account that has not yet accepted the current
   agreements, up to the accept-by date; the owner/admin variant carries one
   --link to the documents, the member variant carries no control at all.
   Markup: dashboard/includes/_terms_change_notice.html. Grey on purpose: it
   is a notice, not a warning (yellow) and not a failure (red). */
.admin-banner--notice {
    background: var(--gray-100);
    border-bottom: 1px solid var(--gray-300);
    border-left: 4px solid var(--gray-500);
    color: var(--gray-800);
}

.admin-banner--notice .admin-banner-btn--link {
    color: var(--gray-900);
}

/* On a phone the nowrap link took over half the row and squeezed the sentence
   into a narrow column. Below 640px the sentence takes the full row and the
   link drops under it. */
@media (max-width: 640px) {
    .admin-banner--notice {
        flex-wrap: wrap;
    }
    .admin-banner--notice .admin-banner-content {
        flex: 1 1 100%;
    }
    .admin-banner--notice .admin-banner-btn--link {
        white-space: normal;
    }
}

/* Read-only pages of a blocked account (Phase 222, D-62).
   After the accept-by date an account that has not accepted can still open
   its spray-record pages, and nothing else. On exactly those requests
   base.html puts `terms-read-only` on <body> (context processor
   terms_change_notice -> terms_read_only) and the strip above says the
   account is read-only.

   COSMETIC ONLY. The control is the server: every one of these requests is
   refused by the terms gate (apps/core/terms_gate.py), proven per control in
   apps/core/tests/test_terms_blocked_writes.py. A selector missing here leaves
   a button that does nothing; it never lets a write through.

   Built from the markup of spraying_jobs.html, spray_job_detail.html and its
   partials, and application_record_audit.html — without editing them. NOT
   hidden, on purpose: navigation, filters, export, print, download, billing
   and support controls.

   Two things on the record ARE hidden although they only read, because the
   gate refuses them and they led nowhere but the accept page (owner,
   2026-10-11): Export KML, which stays closed since opening it stamps the
   boundary as released, and the 48-hour spray window card, whose forecast
   request is refused. */

/* Job list: Add Spray Job, Bulk Add, Mark Ready to Spray */
body.terms-read-only .content-area a[href*="/dashboard/jobs/add/"],
body.terms-read-only [data-action="openBulkAddPicker"],
body.terms-read-only [data-action="bulkMarkReadyToSpray"],
/* Job / spray record footer: Delete, Edit, Duplicate, Save, Partial, Complete,
   Billing Review, Cancel & Bill Chain */
body.terms-read-only [data-action="deleteSprayJob"],
body.terms-read-only #openSoftDeleteBtn,
body.terms-read-only .spray-job-actions a[href$="/edit/"],
body.terms-read-only [data-action="duplicateJob"],
body.terms-read-only [data-action="saveDetails"],
body.terms-read-only [data-action="openPartialCompleteModal"],
body.terms-read-only [data-action="submitPartialComplete"],
body.terms-read-only [data-action="originalMarkComplete"],
body.terms-read-only [data-action="regenerateInvoice"],
body.terms-read-only [data-action="cancelAndBillChain"],
body.terms-read-only [data-action="openCancelChainModal"],
/* Completion card: checklists, weather fetch, "Now" */
body.terms-read-only [data-action="openPreflightChecklist"],
body.terms-read-only [data-action="openPostflightChecklist"],
body.terms-read-only [data-action="resumeChecklist"],
body.terms-read-only [data-action="fetchStartWeather"],
body.terms-read-only [data-action="fetchStopWeather"],
body.terms-read-only [data-action="setStartTimeNow"],
body.terms-read-only [data-action="setStopTimeNow"],
/* Commission splits */
body.terms-read-only #split-override-btn,
body.terms-read-only #split-save-btn,
body.terms-read-only #helper-split-override-btn,
body.terms-read-only #helper-split-save-btn,
/* Notes and attachments */
body.terms-read-only [data-notes-action="add-note"],
body.terms-read-only [data-notes-action="add-file"],
body.terms-read-only [data-notes-action="save-note"],
body.terms-read-only [data-notes-action="edit-note"],
body.terms-read-only [data-notes-action="delete-note"],
body.terms-read-only [data-notes-action="detach-file"],
/* NOTAM */
body.terms-read-only [data-action="generateNotam"],
body.terms-read-only [data-action="autoFileNotam"],
body.terms-read-only [data-action="markNotamFiled"],
body.terms-read-only [data-action="submitNotamFiled"],
body.terms-read-only [data-action="reapplyNotam"],
body.terms-read-only [data-action="saveFaaId"],
body.terms-read-only button[onclick^="dismissCancelAlert"],
/* Products: rate pencil, invoice line buttons */
body.terms-read-only .mix-edit-btn,
body.terms-read-only button[onclick^="window.saveRateEdit"],
body.terms-read-only button[onclick^="window._regenerateLine"],
body.terms-read-only button[onclick^="window._createSupplemental"],
/* Boundary card: Export KML and the one option that belongs to it, push to a
   drone account */
body.terms-read-only #export-kml-btn,
body.terms-read-only label[for="export-include-hazards"],
body.terms-read-only #push-drone-btn,
body.terms-read-only #push-cloud-btn,
/* 48-hour spray window: the whole card, so no empty frame is left */
body.terms-read-only #job-spray-window,
/* Inspection report: the two "fix it" links that open an edit form */
body.terms-read-only a.fix-accordion-link[href$="/edit/"] {
    display: none !important;
}

/* Shown, because they carry information, but not operable */
body.terms-read-only #billing-mode-select,
body.terms-read-only input[data-notes-action="toggle-spray-job"] {
    pointer-events: none;
    opacity: 0.6;
}

/* Tenant Expiration Banner Levels */
.admin-banner--expiration-info {
    background: linear-gradient(135deg, #e0f2fe 0%, #bae6fd 100%);
    border-bottom: 2px solid #0ea5e9;
    color: #0369a1;
}

.admin-banner--expiration-warning {
    background: linear-gradient(135deg, #fef9c3 0%, #fde047 100%);
    border-bottom: 2px solid #eab308;
    color: #854d0e;
}

.admin-banner--expiration-critical {
    background: linear-gradient(135deg, #fed7aa 0%, #fdba74 100%);
    border-bottom: 2px solid #f97316;
    color: #9a3412;
}

.admin-banner--expiration-expired {
    background: linear-gradient(135deg, #fecaca 0%, #fca5a5 100%);
    border-bottom: 2px solid #ef4444;
    color: #991b1b;
}

.admin-banner--expiration-expired strong {
    font-size: 1.1em;
}

/* Read-only mode: Forms visible but disabled */
.content-area.viewing-as-tenant form:not(.exit-form):not(#filter-form) {
    pointer-events: none;
    opacity: 0.7;
}

.content-area.viewing-as-tenant form:not(.exit-form):not(#filter-form) button,
.content-area.viewing-as-tenant form:not(.exit-form):not(#filter-form) input,
.content-area.viewing-as-tenant form:not(.exit-form):not(#filter-form) select,
.content-area.viewing-as-tenant form:not(.exit-form):not(#filter-form) textarea {
    cursor: not-allowed;
}

.content-area.viewing-as-tenant .btn:not(.exit-form .btn):not(.admin-banner-btn):not(#filter-form .btn) {
    pointer-events: none;
    opacity: 0.5;
}

/* Info button style for tenant detail page */
.btn-info {
    background: #0ea5e9;
    color: white;
    border: none;
}

.btn-info:hover {
    background: #0284c7;
}

/* ============================================================================ */
/* Mobile Polygon Drawing - Crosshair + Button System                          */
/* Similar to Google Earth / DJI mapping apps                                   */
/* ============================================================================ */

/* Map container must have position:relative for absolute children */
#field-map-container {
    position: relative !important;
}

#field-map {
    width: 100%;
    height: 400px;
    min-height: 300px;
    border-radius: 8px;
    border: 1px solid var(--border-color);
}

/* Taller map on larger screens */
@media (min-height: 700px) {
    #field-map {
        height: 500px;
    }
}

@media (min-height: 900px) {
    #field-map {
        height: 600px;
    }
}

/* Crosshair overlay - fixed at center of map */
.mobile-crosshair {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    z-index: 1000;
}

.mobile-crosshair.hidden {
    display: none;
}

/* Each bar is a bare 50px box that draws only its two outer arms, leaving a 22px gap
   across the middle. The centre circle is 18px across (12px + 3px border each side), so
   the gap clears it by 2px and you can see the imagery under the point you're placing.
   The arms carry their own box-shadow — putting it on the 50px box would blur a dark
   smudge straight through the gap we just opened. */
.mobile-crosshair .crosshair-h {
    position: absolute;
    width: 50px;
    height: 3px;
    left: -25px;
    top: -1.5px;
}

.mobile-crosshair .crosshair-h::before,
.mobile-crosshair .crosshair-h::after {
    content: '';
    position: absolute;
    top: 0;
    width: 14px;
    height: 3px;
    background: var(--crosshair-color, #3b82f6);
    box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
}
.mobile-crosshair .crosshair-h::before { left: 0; }
.mobile-crosshair .crosshair-h::after { right: 0; }

.mobile-crosshair .crosshair-v {
    position: absolute;
    width: 3px;
    height: 50px;
    left: -1.5px;
    top: -25px;
}

.mobile-crosshair .crosshair-v::before,
.mobile-crosshair .crosshair-v::after {
    content: '';
    position: absolute;
    left: 0;
    width: 3px;
    height: 14px;
    background: var(--crosshair-color, #3b82f6);
    box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
}
.mobile-crosshair .crosshair-v::before { top: 0; }
.mobile-crosshair .crosshair-v::after { bottom: 0; }

.mobile-crosshair .crosshair-center {
    position: absolute;
    width: 12px;
    height: 12px;
    border: 3px solid #3b82f6;
    border-radius: 50%;
    left: -6px;
    top: -6px;
    background: rgba(59, 130, 246, 0.2);
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
}

/* Mobile draw controls container - minimal floating design */
.mobile-draw-controls {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    display: none; /* Hidden by default, shown on mobile */
    gap: 12px;
    z-index: 1001; /* Above map tiles (400) and controls (800), below popups */
    padding: 0;
    background: transparent; /* No container background - buttons float individually */
    border-radius: 0;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* Shown state - use display flex */
.mobile-draw-controls.shown {
    display: flex !important;
}

.mobile-draw-controls.hidden {
    display: none !important;
}

/* Mobile draw buttons - floating pill design */
.btn-mobile-draw {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 14px 24px;
    border: none;
    border-radius: 24px; /* Pill shape */
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    white-space: nowrap;
    min-height: 48px; /* iOS accessibility touch target */
    min-width: 48px;
}

.btn-mobile-draw svg {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

.btn-mobile-draw:active {
    transform: scale(0.96);
}

.btn-mobile-draw:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.btn-mobile-draw.hidden {
    display: none !important;
}

/* Button colors - solid fills with colored shadows */
.btn-mobile-draw.btn-primary {
    background: #3b82f6;
    color: white;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1);
}

.btn-mobile-draw.btn-primary:hover:not(:disabled) {
    background: #2563eb;
    box-shadow: 0 6px 16px rgba(59, 130, 246, 0.5), 0 2px 4px rgba(0, 0, 0, 0.15);
}

.btn-mobile-draw.btn-success {
    background: #22c55e;
    color: white;
    box-shadow: 0 4px 12px rgba(34, 197, 94, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1);
}

.btn-mobile-draw.btn-success:hover:not(:disabled) {
    background: #16a34a;
    box-shadow: 0 6px 16px rgba(34, 197, 94, 0.5), 0 2px 4px rgba(0, 0, 0, 0.15);
}

.btn-mobile-draw.btn-warning {
    background: #f59e0b;
    color: white;
    box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1);
}

.btn-mobile-draw.btn-warning:hover:not(:disabled) {
    background: #d97706;
    box-shadow: 0 6px 16px rgba(245, 158, 11, 0.5), 0 2px 4px rgba(0, 0, 0, 0.15);
}

.btn-mobile-draw.btn-danger {
    background: #ef4444;
    color: white;
    box-shadow: 0 4px 12px rgba(239, 68, 68, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1);
}

.btn-mobile-draw.btn-danger:hover:not(:disabled) {
    background: #dc2626;
    box-shadow: 0 6px 16px rgba(239, 68, 68, 0.5), 0 2px 4px rgba(0, 0, 0, 0.15);
}

/* Hide default Leaflet.Draw toolbar on mobile/tablet - COMPLETELY */
@media (max-width: 1024px) and (pointer: coarse) {
    /* Hide ALL Leaflet.Draw controls */
    .leaflet-draw.leaflet-control,
    .leaflet-draw-toolbar,
    .leaflet-draw-section,
    .leaflet-draw-toolbar-top,
    .leaflet-draw-toolbar-notop,
    .leaflet-draw-actions,
    .leaflet-draw-tooltip {
        display: none !important;
        visibility: hidden !important;
        opacity: 0 !important;
        pointer-events: none !important;
    }

    /* Show mobile draw controls */
    .mobile-draw-controls:not(.force-hidden) {
        display: flex;
    }
}

/* force-hidden must also beat the inline display:flex that
   initMobileDrawControls() puts on the boundary bar — otherwise the boundary
   Draw button stays visible under the obstacle bar and the two overlap. */
.mobile-draw-controls.force-hidden {
    display: none !important;
}

/* Show default toolbar on desktop */
@media (min-width: 1025px) {
    .mobile-draw-controls {
        display: none !important;
    }

    .mobile-crosshair {
        display: none !important;
    }
}

/* Responsive adjustments for phones - stack buttons vertically on left */
@media (max-width: 640px) {
    .mobile-draw-controls {
        /* Position on left side below other map controls */
        bottom: auto !important;
        top: 260px !important;
        left: 10px !important;
        right: auto !important;
        transform: none !important;
        flex-direction: column !important;
        gap: 6px !important;
        max-width: none !important;
        align-items: flex-start !important;
    }

    /* Compact square buttons - icon only (tablet size) */
    .btn-mobile-draw {
        padding: 6px !important;
        font-size: 12px !important;
        min-height: 32px !important;
        min-width: 32px !important;
        width: 32px !important;
        height: 32px !important;
        border-radius: 6px !important;
        justify-content: center !important;
    }

    .btn-mobile-draw svg {
        width: 16px !important;
        height: 16px !important;
    }

    /* Hide text on tablet/phone - icon only */
    .btn-mobile-draw .btn-text {
        display: none !important;
    }
}

/* Phone-specific adjustments - move to bottom-center to avoid left-side control overlap */
@media (max-width: 480px) {
    .mobile-draw-controls {
        /* Bottom-center: clear of all topleft Leaflet controls */
        top: auto !important;
        bottom: 44px !important;
        left: 50% !important;
        right: auto !important;
        transform: translateX(-50%) !important;
        flex-direction: row !important;
        gap: 10px !important;
        align-items: center !important;
    }

    .btn-mobile-draw {
        min-height: 44px !important;
        min-width: 44px !important;
        width: 44px !important;
        height: 44px !important;
        border-radius: 8px !important;
    }

    .btn-mobile-draw svg {
        width: 20px !important;
        height: 20px !important;
    }
}

/* Mobile point number labels */
.mobile-point-label {
    background: #1e293b !important;
    border: none !important;
    border-radius: 50% !important;
    padding: 0 !important;
    width: 20px !important;
    height: 20px !important;
    line-height: 20px !important;
    text-align: center !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    color: white !important;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3) !important;
}

.mobile-point-label::before {
    display: none !important;
}

/* ==========================================================================
   Mobile Tap Targets
   Ensures interactive elements are at least 44x44px on touch devices
   per Apple/Google accessibility guidelines
   ========================================================================== */

@media (max-width: 640px) {
    /* Icon-only buttons need minimum tap target */
    .btn-icon,
    .action-btn,
    .btn-remove,
    .btn-delete,
    .btn-edit,
    .icon-btn,
    button[class*="icon"],
    a[class*="icon"] {
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* form-actions delete is a text button, not an icon — undo the icon-only rule */
    .form-actions .btn-delete {
        min-width: unset;
        min-height: unset;
        width: auto;
        display: flex;
    }

    /* Table action buttons */
    .data-table .btn-icon,
    .data-table .action-btn,
    .table .btn-icon,
    .table .action-btn {
        min-width: 44px;
        min-height: 44px;
        padding: 10px;
    }

    /* Expand/collapse toggle buttons */
    .expand-btn,
    .collapse-btn,
    .toggle-btn {
        min-width: 44px;
        min-height: 44px;
    }

    /* Checkbox and radio labels need larger tap area */
    input[type="checkbox"],
    input[type="radio"] {
        min-width: 20px;
        min-height: 20px;
    }

    /* .pp-option excluded: the parking-point picker rows are cards with their
       own padding, not compact list items (see mobile-tokens.css R43). */
    label:has(input[type="checkbox"]):not(.toggle-switch):not(.pp-option),
    label:has(input[type="radio"]):not(.toggle-switch):not(.pp-option),
    .checkbox-item,
    .radio-item {
        min-height: 44px;
        display: flex;
        align-items: center;
        padding: 8px 0;
    }

    /* Toggle switches must keep their fixed dimensions — never enlarge for touch targets */
    .toggle-switch {
        display: inline-block !important;
        min-height: 26px !important;
        height: 26px !important;
        padding: 0 !important;
    }

    /* Close buttons in modals */
    .modal-close,
    .close-btn,
    [class*="close"] {
        min-width: 44px;
        min-height: 44px;
    }

    /* Filter chips and tags */
    .filter-chip,
    .tag,
    .badge-action {
        min-height: 44px;
        padding: 10px 16px;
    }

    /* Dropdown items */
    .dropdown-item,
    .select-option,
    .menu-item {
        min-height: 44px;
        padding: 12px 16px;
    }
}

/* ============================================
   UTILITY CLASSES
   Tailwind-style utilities (4px base scale)
   ============================================ */

/* Margin Bottom */
.mb-1 { margin-bottom: 4px; }
.mb-2 { margin-bottom: 8px; }
.mb-3 { margin-bottom: 12px; }
.mb-4 { margin-bottom: 16px; }
.mb-5 { margin-bottom: 20px; }
.mb-6 { margin-bottom: 24px; }
.mb-8 { margin-bottom: 32px; }

/* Margin Top */
.mt-1 { margin-top: 4px; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 12px; }
.mt-4 { margin-top: 16px; }
.mt-5 { margin-top: 20px; }
.mt-6 { margin-top: 24px; }
.mt-8 { margin-top: 32px; }

/* Padding (all sides) */
.p-1 { padding: 4px; }
.p-2 { padding: 8px; }
.p-3 { padding: 12px; }
.p-4 { padding: 16px; }
.p-5 { padding: 20px; }
.p-6 { padding: 24px; }

/* Padding X (horizontal) */
.px-1 { padding-left: 4px; padding-right: 4px; }
.px-2 { padding-left: 8px; padding-right: 8px; }
.px-3 { padding-left: 12px; padding-right: 12px; }
.px-4 { padding-left: 16px; padding-right: 16px; }

/* Padding Y (vertical) */
.py-1 { padding-top: 4px; padding-bottom: 4px; }
.py-2 { padding-top: 8px; padding-bottom: 8px; }
.py-3 { padding-top: 12px; padding-bottom: 12px; }
.py-4 { padding-top: 16px; padding-bottom: 16px; }

/* Gap (for flexbox/grid) */
.gap-1 { gap: 4px; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 12px; }
.gap-4 { gap: 16px; }
.gap-6 { gap: 24px; }

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

/* Padding Top/Bottom */
.pt-1 { padding-top: 4px; }
.pt-2 { padding-top: 8px; }
.pt-3 { padding-top: 12px; }
.pt-4 { padding-top: 16px; }
.pb-1 { padding-bottom: 4px; }
.pb-2 { padding-bottom: 8px; }
.pb-3 { padding-bottom: 12px; }
.pb-4 { padding-bottom: 16px; }

/* Padding Left/Right */
.pl-2 { padding-left: 8px; }
.pl-4 { padding-left: 16px; }
.pr-2 { padding-right: 8px; }
.pr-4 { padding-right: 16px; }

/* Margin Auto */
.mx-auto { margin-left: auto; margin-right: auto; }
.ml-auto { margin-left: auto; }
.mr-auto { margin-right: auto; }

/* Reset Utilities */
.m-0 { margin: 0; }
.p-0 { padding: 0; }
.mb-0 { margin-bottom: 0; }
.mt-0 { margin-top: 0; }

/* ============================================
   EMPTY STATE (child selectors for legacy templates)
   Base .empty-state definition is in GLOBAL EMPTY STATE COMPONENT section below
   ============================================ */

.empty-state svg {
    width: 64px;
    height: 64px;
    margin-bottom: 16px;
    opacity: 0.5;
}

.empty-state h3,
.empty-state .empty-state-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 8px;
}

.empty-state p,
.empty-state .empty-state-message {
    font-size: 14px;
    color: var(--text-secondary);
    margin-bottom: 16px;
}

.empty-state .btn {
    margin-top: 8px;
}

/* Empty State Size Variants */
.empty-state--compact { padding: 40px 20px; }
.empty-state--sm { padding: 20px; }
.empty-state--full { grid-column: 1 / -1; }

/* ===== Breadcrumb Navigation =====
   Desktop sizing restored. Mobile compact (4px padding) is in the
   @media (max-width: 640px) block. */
.breadcrumb-nav {
    padding: 10px 20px;
    margin: -4px -44px 20px -44px;
    background: rgba(0, 0, 0, 0.2);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    border-top: 1px solid rgba(255, 255, 255, 0.04);
}

.breadcrumb-list {
    display: flex !important;
    align-items: center;
    list-style: none !important;
    padding: 0 !important;
    margin: 0 !important;
    flex-wrap: nowrap;
    gap: 0;
    max-width: 1200px;
    margin-left: auto !important;
    margin-right: auto !important;
    padding-left: 24px !important;
}

.breadcrumb-item {
    display: flex;
    align-items: center;
    font-size: 13px;
    letter-spacing: 0.02em;
    /* Default flex-shrink: 1 + default min-width: auto (= min-content) means
       items shrink down to the width of their longest unbreakable word — so
       single-word crumbs like "Dashboard" stay intact, while multi-word crumbs
       like "Cimarron Plus Herbicide" wrap at the space. Center-align text inside
       so the wrapped lines split residual flex slack symmetrically — keeps the
       trailing slash close to the wrapped item instead of leaving a right-side
       gap when the longer line is shorter than the flex-allocated box. */
    text-align: center;
    justify-content: center;
}

.breadcrumb-item a {
    color: rgba(255, 255, 255, 0.5);
    text-decoration: none;
    transition: all 0.2s ease;
    padding: 3px 0;
    font-weight: 400;
}

.breadcrumb-item a:hover {
    color: #fff;
}

.breadcrumb-item--current span {
    color: rgba(255, 255, 255, 0.92);
    font-weight: 500;
    display: inline-block;
    padding: 3px 0;
}

/* Slash separator between items */
.breadcrumb-item + .breadcrumb-item::before {
    content: "/";
    color: rgba(255, 255, 255, 0.25);
    font-size: 13px;
    font-weight: 300;
    margin: 0 10px;
    flex-shrink: 0;
}

/* Mobile adjustments */
@media (max-width: 640px) {
    .breadcrumb-nav {
        margin-left: -20px;
        margin-right: -20px;
        padding: 8px 16px;
        background: transparent !important;
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        border-top: none !important;
        border-bottom: none !important;
    }
    .breadcrumb-list {
        display: flex !important;
        flex-wrap: nowrap !important;
        align-items: center !important;
        padding-left: 4px !important;
    }
    .breadcrumb-item {
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        text-align: center;
        font-size: 12px;
    }
    .breadcrumb-item a,
    .breadcrumb-item span {
        display: inline-flex !important;
        align-items: center !important;
        justify-content: center !important;
        text-align: center;
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        max-width: none;
        padding: 0 !important;
        min-height: 0 !important;
    }
    .breadcrumb-item + .breadcrumb-item::before {
        align-self: center;
        margin: 0 4px;
        font-size: 12px;
        flex-shrink: 0;
    }
}
@media (max-width: 480px) {
    .breadcrumb-nav {
        margin-left: -12px;
        margin-right: -12px;
        padding: 8px 10px;
    }
    .breadcrumb-list {
        padding-left: 2px !important;
    }
}

/* =============================================
   Mobile Touch Targets - WCAG 2.1 AA Compliance
   Ensure minimum 44×44px touch targets on mobile
   ============================================= */
@media (max-width: 767px) {
    /* Navigation items - increase from 40px to 44px */
    .nav-item {
        min-height: 44px;
        padding: 12px 16px; /* Increase vertical padding from 8px to 12px */
    }

    /* Sidebar search input */
    #sidebar-search-input {
        min-height: 44px;
    }

    /* No magnifier on a phone: the mobile primitives override this input's
       padding, so the icon ended up sitting on top of the placeholder. */
    .sidebar-search .search-icon {
        display: none;
    }

    /* All buttons and interactive elements */
    .btn,
    button,
    input[type="button"],
    input[type="submit"],
    .btn-sm,
    .btn-primary,
    .btn-secondary,
    .btn-danger,
    .btn-success,
    .btn-warning,
    .btn-info {
        min-height: 44px;
        min-width: 44px;
        padding: 10px 16px;
    }

    /* Form inputs and select elements */
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="number"],
    input[type="tel"],
    input[type="url"],
    input[type="search"],
    input[type="date"],
    input[type="time"],
    input[type="datetime-local"],
    textarea,
    select,
    .form-control {
        min-height: 44px;
    }

    /* Action bar buttons */
    #mobileActionBar .btn {
        min-height: 44px;
        min-width: 44px;
    }

    /* Table action buttons */
    .action-btn,
    .table-action,
    .btn-icon {
        min-height: 44px;
        min-width: 44px;
        padding: 10px;
    }

    /* Pagination links */
    .pagination .page-link {
        min-height: 44px;
        min-width: 44px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* Checkbox and radio labels (clickable area) */
    .form-check-label,
    .custom-control-label {
        min-height: 44px;
        display: flex;
        align-items: center;
    }

    /* Tab navigation */
    .nav-tabs .nav-link,
    .nav-pills .nav-link {
        min-height: 44px;
        padding: 10px 16px;
    }

    /* Card action links */
    .card-link,
    .list-group-item-action {
        min-height: 44px;
        padding: 12px 16px;
    }

    /* Specific fixes for elements that were still failing */
    .logout-btn,
    a.logout-btn {
        min-height: 44px !important;
        min-width: 44px !important;
        padding: 12px 16px !important;
    }

    .admin-banner-btn,
    a.admin-banner-btn {
        min-height: 44px !important;
        padding: 12px 16px !important;
    }

    /* the bare-link CTA keeps the 44px tap target, drops the block padding */
    .admin-banner-btn--link,
    a.admin-banner-btn--link {
        padding: 0 2px !important;
    }

    .alert-item {
        min-height: 44px !important;
        min-width: 44px !important;
        padding: 12px 16px !important;
    }

    /* Tab buttons — sizing handled by mobile primitives spec block at end of file.
       Spec sizing (30px height, 3px 12px padding) is intentional per
       primitives-spec §5.3. The !important overrides removed 2026-04-25. */

    /* Filter chips — sizing handled by mobile primitives spec block.
       Spec sizing (30px height, 3px 12px padding) is intentional per
       primitives-spec §5.3. The !important overrides removed 2026-04-25. */

    /* Generic links in content areas — exclude block-level card links to avoid layout breakage */
    .content-area a:not([class*="card"]):not(.btn):not(.nav-item):not(.filter-pill):not(.prio-pill),
    .card-body a:not([class*="card"]):not(.btn):not(.nav-item):not(.filter-pill):not(.prio-pill),
    .main-content a:not([class*="card"]):not(.btn):not(.nav-item):not(.filter-pill):not(.prio-pill) {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        padding: 12px 8px;
    }

    /* Leaflet map controls are <a> tags — exempt from tap-target inflation
       above, or they stretch to 30x44 rectangles (width stays pinned at 30px
       by .leaflet-touch). Leaflet's own touch styles keep them 30x30.
       Scoped to .leaflet-control (not the whole .leaflet-container) so popup
       links (e.g. .field-popup-btn, padding 7px 14px) keep their own padding. */
    .content-area .leaflet-control a,
    .card-body .leaflet-control a,
    .main-content .leaflet-control a {
        /* !important: the generic rule's :not() chain carries 5-class specificity */
        min-height: 0 !important;
        padding: 0 !important;
    }

}

/* Breadcrumb anchors in the 641-767px gap: the mobile breadcrumb reset
   (max-width: 640px) doesn't reach this band and WCAG tap-target inflation
   makes <a>-crumbs 44px tall while the current <span>-crumb stays at its
   natural height — producing a staircase. Keep the base 3px vertical padding
   so anchor height matches the current crumb's span. */
@media (min-width: 641px) and (max-width: 767px) {
    .breadcrumb-item a {
        min-height: 0 !important;
        padding: 3px 0 !important;
    }
}

/* =============================================
   Mobile Overflow Prevention
   Prevent horizontal scroll on mobile devices
   ============================================= */
@media (max-width: 767px) {
    /* box-sizing only — removed max-width:100% which was clipping body's 125vw zoom compensation */
    * {
        box-sizing: border-box;
    }

    /* Main content areas must not overflow */
    .main-content,
    .content-area,
    .page-content,
    .card-body,
    .form-container {
        overflow-x: hidden;
        max-width: 100%;
    }

    /* Form elements should not cause overflow */
    input,
    select,
    textarea,
    .form-control,
    .form-group {
        max-width: 100%;
        box-sizing: border-box;
    }

    /* Ensure all containers respect viewport */
    .container,
    .row,
    .col {
        max-width: 100%;
        overflow-x: hidden;
    }
}

/* =============================================
   Mobile Text Truncation
   Ensure proper ellipsis on text overflow
   ============================================= */
@media (max-width: 767px) {
    /* Card titles and headers should truncate gracefully */
    .card-title,
    .card-header-title,
    .page-title,
    h1, h2, h3, h4, h5, h6 {
        overflow: hidden;
        text-overflow: ellipsis;
        word-wrap: break-word;
        overflow-wrap: break-word;
    }

    /* Table cells should not cause overflow */
    td, th {
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 200px;
        word-wrap: break-word;
    }

    /* Labels and field names */
    label,
    .field-label,
    .form-label {
        overflow: hidden;
        text-overflow: ellipsis;
        word-wrap: break-word;
    }

    /* List items and navigation items */
    .list-item,
    .nav-item span,
    .menu-item span {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Card content and descriptions */
    .card-body p,
    .card-text,
    .description,
    .summary-text {
        overflow-wrap: break-word;
        word-wrap: break-word;
        word-break: break-word;
    }

    /* Buttons should not have text overflow */
    .btn,
    button {
        overflow: hidden;
        text-overflow: ellipsis;
    }
}

/* ========================================
   HELP SYSTEM STYLES
   ======================================== */

/* Floating Help Button
   Desktop 56px restored. Mobile 36px button / 30px icon in the @media (max-width: 640px)
   block below. */
.floating-help-button {
    position: fixed;
    bottom: 24px;
    right: 24px;
    width: 56px;
    height: 56px;
    padding: 0; /* UA stylesheet adds default button padding that squeezes the SVG */
    background: var(--primary-color);
    border: none;
    border-radius: 50%;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 8px 24px rgba(76, 175, 80, 0.2);
    color: white;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.2s, box-shadow 0.2s, bottom 0.2s;
    z-index: 1350; /* Above form-actions (1300) and action bars (1200) */
}

/* Footer/bottom bar overlap prevention — JS sets --footer-clearance dynamically */
body.has-footer .floating-help-button,
body.has-bottom-bar .floating-help-button {
    bottom: calc(var(--footer-clearance, 80px) + env(safe-area-inset-bottom, 0));
}

.floating-help-button:hover {
    transform: scale(1.1);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2), 0 10px 30px rgba(76, 175, 80, 0.3);
}

.floating-help-button:active {
    transform: scale(0.95);
}

.floating-help-button svg {
    width: 28px;
    height: 28px;
}

/* Mobile: 36px button, 24px icon */
@media (max-width: 640px) {
    .floating-help-button {
        width: 36px;
        height: 36px;
        min-width: 36px;
        min-height: 36px;
        bottom: 16px;
        right: 16px;
        /* Tap-only control that lives OUTSIDE the .main-content scroller — a
           pan starting here sleds the whole page on iOS (rubber-band drags the
           sticky header/footer). Taps unaffected. */
        touch-action: none;
    }

    body.has-footer .floating-help-button,
    body.has-bottom-bar .floating-help-button {
        bottom: calc(var(--footer-clearance, 80px) + env(safe-area-inset-bottom, 0));
    }

    .floating-help-button svg {
        width: 18px;
        height: 18px;
    }
}

/* Help Modal */
.help-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease-out, visibility 0.2s ease-out;
}

.help-modal[style*="display: flex"] {
    opacity: 1;
    visibility: visible;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.help-modal-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(4px);
}

.help-modal-content {
    position: relative;
    background: white;
    border-radius: 16px;
    width: 94%;
    max-width: 960px;
    max-height: 92vh;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    animation: dcModalSlideUp 0.3s ease-out;
    will-change: transform, opacity;
}

/* Uniquely named on purpose. @keyframes names are global and the LAST one
   defined wins: base.html's reorder banner also defines `slideUp`, with a
   translateX(-50%) for its own centring, and it loads after this file — so the
   help popup borrowed it and opened half its width to the left for a frame.
   `slideUp` stays below for anything that still uses the old name. */
@keyframes dcModalSlideUp {
    from {
        opacity: 0;
        transform: translateY(40px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

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

/* Header — close button only */
.help-modal-header {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 12px 16px 0;
}

/* Page title bar — below chat, above tabs */
.help-page-title-bar {
    padding: 12px 24px 0;
}

.help-page-title-bar h2 {
    font-size: 20px;
    font-weight: 700;
    color: var(--text-primary);
    margin: 0;
}

.help-modal-close-btn {
    background: none;
    border: none;
    padding: 8px;
    cursor: pointer;
    color: var(--text-secondary);
    border-radius: 8px;
    transition: background 0.2s, color 0.2s;
}

.help-modal-close-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.help-modal-close-btn svg {
    width: 24px;
    height: 24px;
}

/* AI Chat Tab */
.help-tab--ai {
    margin-left: auto; /* push to right side */
}

.help-tab-content--ai.help-tab-content.active {
    display: flex;
    flex-direction: column;
    min-height: 420px;
}

.help-ai-chat {
    display: flex;
    flex-direction: column;
    flex: 1;
}

.help-chat-messages {
    flex: 1;
    min-height: 320px;
    max-height: 520px;
    overflow-y: auto;
    padding: 12px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: #fafafa;
    border-radius: 8px;
    margin-bottom: 2px;
}

.help-chat-messages:empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

/* Chat bubble icon */
.help-chat-messages:empty::before {
    content: '';
    display: block;
    width: 40px;
    height: 40px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 24 24' fill='none' stroke='%23c4b5fd' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'/%3E%3C/svg%3E") center/contain no-repeat;
    opacity: 0.9;
}

/* Prompt text */
.help-chat-messages:empty::after {
    content: 'Ask me anything about this page';
    color: #9ca3af;
    font-size: 13px;
    text-align: center;
    padding: 0 24px;
    line-height: 1.5;
}

.help-chat-msg {
    max-width: 88%;
    padding: 12px 16px;
    border-radius: 12px;
    font-size: 14px;
    line-height: 1.5;
    word-break: break-word;
}

.help-chat-msg--user {
    align-self: flex-end;
    background: var(--primary-color);
    color: #fff;
    border-bottom-right-radius: 4px;
}

.help-chat-msg--ai {
    align-self: flex-start;
    background: #f4f4f4;
    color: var(--text-primary);
    border-bottom-left-radius: 4px;
}
.help-chat-msg--ai p { margin: 0 0 10px; line-height: 1.55; }
.help-chat-msg--ai p:last-child { margin-bottom: 0; }
.help-chat-msg--ai ul,
.help-chat-msg--ai ol {
    margin: 6px 0 10px;
    padding-left: 20px;
}
.help-chat-msg--ai li { margin-bottom: 6px; line-height: 1.5; }
.help-chat-msg--ai li:last-child { margin-bottom: 0; }
.help-chat-msg--ai strong { font-weight: 600; }
.help-chat-msg--ai .ai-heading { font-weight: 700; margin: 10px 0 4px; }
.help-chat-msg--ai .ai-heading--1 { font-size: 15px; }
.help-chat-msg--ai .ai-heading--2 { font-size: 13.5px; text-transform: uppercase; letter-spacing: 0.03em; color: #444; }
.help-chat-msg--ai .ai-heading--3 { font-size: 13px; color: #555; }
.help-chat-msg--ai hr { border: none; border-top: 1px solid #ddd; margin: 10px 0; }
.help-chat-msg--ai code {
    background: rgba(0,0,0,0.07);
    border-radius: 3px;
    padding: 1px 4px;
    font-size: 0.9em;
}

/* Typing indicator */
.help-chat-typing {
    display: inline-flex;
    gap: 4px;
    align-items: center;
    padding: 2px 0;
}

.help-chat-typing span {
    display: inline-block;
    width: 7px;
    height: 7px;
    background: #999;
    border-radius: 50%;
    animation: help-chat-bounce 1.2s infinite ease-in-out;
}

.help-chat-typing span:nth-child(1) { animation-delay: 0s; }
.help-chat-typing span:nth-child(2) { animation-delay: 0.2s; }
.help-chat-typing span:nth-child(3) { animation-delay: 0.4s; }

@keyframes help-chat-bounce {
    0%, 80%, 100% { transform: translateY(0); }
    40% { transform: translateY(-6px); }
}

.help-chat-input-row {
    display: flex;
    gap: 8px;
    padding: 10px 14px 14px;
    align-items: center;
    border-top: 1px solid var(--border-color);
}

.help-chat-input-row input {
    flex: 1;
    padding: 10px 14px;
    border: 1px solid #d1d5db;
    border-radius: 8px;
    font-size: 14px;
    background: white;
    color: #111827;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.help-chat-input-row input:focus {
    outline: none;
    border-color: #4CAF50;
    box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.2);
}

.help-chat-send-btn {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: var(--primary-color);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.2s, transform 0.15s, box-shadow 0.2s;
    padding: 0;
    box-shadow: 0 2px 8px rgba(54, 124, 43, 0.35);
}

.help-chat-send-btn svg {
    width: 16px;
    height: 16px;
}

.help-chat-send-btn:hover {
    background: var(--primary-dark, #1a6b30);
    transform: scale(1.08);
    box-shadow: 0 4px 12px rgba(54, 124, 43, 0.45);
}

.help-chat-send-btn:active {
    transform: scale(0.95);
}

.help-chat-send-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    box-shadow: none;
}

/* Tabs */
.help-modal-tabs {
    display: flex;
    gap: 8px;
    padding: 16px 24px 0;
    border-bottom: 2px solid var(--border-color);
}

.help-tab {
    padding: 10px 20px;
    background: none;
    border: none;
    border-bottom: 3px solid transparent;
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 14px;
    cursor: pointer;
    transition: color 0.2s, border-color 0.2s;
    margin-bottom: -2px;
}

.help-tab:hover {
    color: var(--text-primary);
}

.help-tab.active {
    color: var(--primary-color);
    border-bottom-color: var(--primary-color);
}

/* Body */
.help-modal-body {
    flex: 1;
    overflow-y: auto;
    padding: 24px;
    scrollbar-color: #c0c0c0 #f0f0f0;
}
.help-modal-body::-webkit-scrollbar {
    width: 8px;
}
.help-modal-body::-webkit-scrollbar-track {
    background: #f0f0f0;
    border-radius: 4px;
}
.help-modal-body::-webkit-scrollbar-thumb {
    background: #c0c0c0;
    border-radius: 4px;
}
.help-modal-body::-webkit-scrollbar-thumb:hover {
    background: #a0a0a0;
}

/* Weather schedule grid — white scrollbar */
.sw-scroll-wrapper::-webkit-scrollbar { width: 10px; height: 10px; }
.sw-scroll-wrapper::-webkit-scrollbar-track { background: rgba(255,255,255,0.2); border: 1px solid rgba(0,0,0,0.5); border-radius: 4px; }
.sw-scroll-wrapper::-webkit-scrollbar-thumb { background: white !important; border-radius: 3px; border: 1px solid rgba(0,0,0,0.5); }
.sw-scroll-wrapper::-webkit-scrollbar-thumb:hover { background: #f0f0f0 !important; }

/* Loading State */
.help-loading {
    display: none;  /* Hidden by default */
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 60px 24px;
}

.help-loading.active {
    display: flex;  /* Show when active */
}

.help-loading .spinner {
    width: 40px;
    height: 40px;
    border: 4px solid var(--border-color);
    border-top-color: var(--primary-color);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

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

/* ---------------------------------------------------------------------------
   Map loading overlay — "this map is fetching something"

   A map that is merely EMPTY is indistinguishable from a map that is broken,
   so any map that goes blank while it waits has to say so. The shape comes
   from master_map.html, which had the only version of this worth copying:
   a dim scrim over the map, and a dark card carrying a green spinner and a
   line of text that names what is being fetched.

   It lives here, not in a page's <style>, because three pages had already
   written their own before it existed: master_map.html (this one, verbatim),
   flight_log_map.html (.map-loading) and drone_cloud/cloud_fields.html
   (.aa-map-loading). Use THIS one in anything new, and fold those three in
   when you are next in them — a fourth private copy is how the first three
   happened.

   The host must be position:relative (every map wrapper already is), and the
   z-index clears Leaflet's controls (1000) so the overlay is not drawn under
   the zoom buttons.
   --------------------------------------------------------------------------- */
.map-loading-overlay {
    position: absolute;
    inset: 0;
    z-index: 1001;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(2px);
}

/* [hidden] loses to the display:flex above — the same trap documented on
   .info-banner and the splitter's method nav. */
.map-loading-overlay[hidden] {
    display: none !important;
}

.map-loading-inner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 18px 28px;
    background: #1a2820;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 8px;
    color: #e8f5e9;
    font-size: 15px;
    font-weight: 500;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
}

.map-loading-spinner {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    color: var(--primary-color, #4caf50);
    animation: spin 1s linear infinite;
}

.help-loading p {
    margin-top: 16px;
    color: var(--text-secondary);
    font-size: 14px;
}

/* Tab Content */
.help-tab-content {
    display: none;
}

.help-tab-content.active {
    display: block;
}

.help-content-area {
    font-size: 15px;
    line-height: 1.7;
    color: var(--text-primary);
}

.help-content-area p {
    margin-bottom: 16px;
}

.help-content-area ul,
.help-content-area ol {
    margin-left: 24px;
    margin-bottom: 16px;
}

.help-content-area li {
    margin-bottom: 8px;
}

.help-content-area strong {
    font-weight: 600;
    color: var(--text-primary);
}

/* Help visuals: small drawn diagrams inside help pages (Spray Season first).
   Drawn, not screenshots, so they stay right when the page around them
   changes and scale cleanly on a phone. */
.help-content-area .hv {
    margin: 4px 0 20px;
    padding: 14px 16px 10px;
    background: #f6f5f2;
    border: 1px solid #e2e0db;
    border-radius: 12px;
}
.help-content-area .hv svg { display: block; width: 100%; height: auto; max-width: 640px; margin: 0 auto; }
.help-content-area .hv figcaption { margin-top: 8px; font-size: 13px; line-height: 1.5; color: #6b7280; }
.help-content-area .hv-eq { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; font-size: 14px; }
.help-content-area .hv-box { background: #fff; border: 1px solid #d8d6d0; border-radius: 10px; padding: 8px 12px; text-align: center; line-height: 1.3; }
.help-content-area .hv-box b { display: block; font-size: 18px; color: #111827; font-variant-numeric: tabular-nums; }
.help-content-area .hv-box small { font-size: 12px; color: #6b7280; }
.help-content-area .hv-box.hv-res { border-color: #4CAF50; background: rgba(76,175,80,.10); }
.help-content-area .hv-op { font-size: 20px; font-weight: 700; color: #6b7280; }
.help-content-area .hv-pill { display: inline-block; font-size: 11px; font-weight: 800; border-radius: 999px; padding: 2px 9px; }

.help-content-area h3 {
    font-size: 18px;
    font-weight: 600;
    margin-top: 24px;
    margin-bottom: 12px;
    color: var(--text-primary);
}

.help-content-area h4 {
    font-size: 16px;
    font-weight: 600;
    margin-top: 20px;
    margin-bottom: 10px;
    color: var(--text-primary);
}

.help-content-area kbd {
    display: inline-block;
    padding: 3px 8px;
    font-size: 12px;
    font-family: monospace;
    background: var(--bg-hover);
    border: 1px solid var(--border-color);
    border-radius: 4px;
    box-shadow: 0 1px 0 rgba(0,0,0,0.2);
}

/* Related Links */
.help-related-links {
    margin-top: 32px;
    padding-top: 24px;
    border-top: 2px solid var(--border-color);
}

.help-related-links h3 {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: 16px;
    color: var(--text-primary);
}

.help-related-list {
    display: grid;
    gap: 12px;
}

.help-related-item {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    background: var(--bg-hover);
    border-radius: 8px;
    text-decoration: none;
    color: var(--text-primary);
    transition: background 0.2s, transform 0.2s;
    cursor: pointer;
}

.help-related-item:hover {
    background: var(--border-color);
    transform: translateX(4px);
}

.help-related-item-icon {
    width: 20px;
    height: 20px;
    margin-right: 12px;
    color: var(--primary-color);
    flex-shrink: 0;
}

.help-related-item-text {
    flex: 1;
}

.help-related-item-title {
    font-weight: 600;
    margin-bottom: 2px;
}

.help-related-item-description {
    font-size: 13px;
    color: var(--text-secondary);
}

/* Mobile Responsive */
@media (max-width: 640px) {
    /* Use inset shorthand for reliable full-viewport coverage on iOS Safari */
    .help-modal {
        inset: 0;
        width: auto;
        height: auto;
        /* Safe-area padding so flex centering lands inside the notch/home-indicator zone */
        padding-top: env(safe-area-inset-top, 0px);
        padding-bottom: env(safe-area-inset-bottom, 0px);
        /* Block all touch scroll from reaching the background page.
           iOS ignores body{overflow:hidden} — touch-action:none is the reliable fix.
           Scroll containers inside re-enable pan-y individually. */
        touch-action: none;
        /* Disable backdrop blur — causes a split-page rendering artifact during animation */
        backdrop-filter: none;
    }

    .help-modal-overlay {
        backdrop-filter: none;
    }

    .help-modal-content {
        width: 95%;
        /* Stay within the safe area — env() values already subtracted from the flex container */
        max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 20px);
        border-radius: 12px;
        /* Replace slideUp (which starts 40px below center) with a simple fade on mobile */
        animation: fadeIn 0.2s ease-out;
    }

    .help-modal-header {
        padding: 8px 12px 0;
    }

    .help-page-title-bar h2 {
        font-size: 17px;
    }

    .help-chat-input-row {
        padding: 10px 12px 12px;
        background: #f8fafc;
        border-top: 1px solid #e5e7eb;
        gap: 10px;
    }

    .help-chat-messages {
        padding: 10px 12px;
    }

    .help-modal-tabs {
        padding: 12px 16px 0;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        flex-shrink: 0;
    }

    .help-modal-tabs::-webkit-scrollbar {
        display: none;
    }

    #help-modal-get-support-btn {
        display: none !important;
    }

    .help-tab--ai {
        margin-left: 0;
    }

    .help-modal-body {
        padding: 16px;
        touch-action: pan-y;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }

    .help-chat-messages {
        touch-action: pan-y;
        overscroll-behavior: contain;
    }

    .help-content-area {
        font-size: 14px;
    }

    /* AI chat — prevent iOS auto-zoom + polished input appearance on mobile */
    .help-chat-input-row input {
        font-size: 16px;
        padding: 12px 16px;
        border: 1.5px solid #d1d5db;
        border-radius: 12px;
        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.07);
        min-height: 48px;
    }

    .help-chat-input-row input:focus {
        border-color: #4CAF50;
        box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.15), 0 1px 4px rgba(0, 0, 0, 0.07);
    }

    /* Keep the chat area from pushing below the modal on small screens */
    .help-tab-content--ai.help-tab-content.active {
        min-height: 0;
    }

    .help-chat-messages {
        min-height: 200px;
        max-height: 300px;
    }
}

/* Bug Report Tab */
#help-tab-bug-report {
    padding: 4px 0;
    position: relative; /* anchor for bug-submit-overlay */
}

.bug-report-intro {
    margin-bottom: 18px;
    font-size: 14px;
    color: var(--text-secondary);
}

#bug-report-form {
    display: block;
    width: 100%;
}

.bug-report-field {
    display: block;
    width: 100%;
    margin-bottom: 16px;
}

.bug-report-field label {
    display: block;
    width: 100%;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 6px;
}

.bug-report-optional {
    font-weight: 400;
    color: var(--text-secondary);
}

.bug-report-field textarea,
#bug-description {
    display: block;
    width: 100%;
    box-sizing: border-box;
    background: var(--bg-hover);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-primary);
    font-size: 14px;
    line-height: 1.5;
    padding: 10px 12px;
    resize: vertical;
    font-family: inherit;
    transition: border-color 0.2s;
    min-height: 110px;
}

.bug-report-field textarea:focus,
#bug-description:focus {
    outline: none;
    border-color: var(--primary-color);
}

.bug-report-field input[type="file"],
#bug-screenshot {
    display: block;
    width: 100%;
    box-sizing: border-box;
    font-size: 13px;
    color: var(--text-secondary);
    cursor: pointer;
    padding: 4px 0;
}

.bug-report-status {
    display: block;
    font-size: 13px;
    padding: 10px 14px;
    border-radius: 6px;
    margin-bottom: 14px;
}

.bug-report-status--success {
    background: rgba(72, 187, 120, 0.15);
    color: #48bb78;
    border: 1px solid rgba(72, 187, 120, 0.3);
}

.bug-report-status--error {
    background: rgba(245, 101, 101, 0.15);
    color: #fc8181;
    border: 1px solid rgba(245, 101, 101, 0.3);
}

.bug-add-screenshot-btn {
    display: inline-block;
    margin-top: 8px;
    padding: 6px 14px;
    background: transparent;
    border: 1px dashed var(--border-color);
    border-radius: 6px;
    color: var(--text-secondary);
    font-size: 13px;
    cursor: pointer;
    transition: border-color 0.2s, color 0.2s;
}

.bug-add-screenshot-btn:hover {
    border-color: var(--primary-color);
    color: var(--primary-color);
}

.bug-screenshot-list {
    display: none;
    margin-bottom: 6px;
}

.bug-screenshot-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 10px;
    background: var(--bg-hover);
    border-radius: 6px;
    margin-bottom: 4px;
    font-size: 13px;
}

.bug-screenshot-name {
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    margin-right: 8px;
}

.bug-screenshot-remove {
    background: none;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 12px;
    padding: 0 2px;
    flex-shrink: 0;
    line-height: 1;
}

.bug-screenshot-remove:hover {
    color: #fc8181;
}

.bug-screenshot-auto {
    font-size: 11px;
    color: var(--text-secondary);
    font-weight: 400;
}

.bug-screenshot-capturing {
    font-size: 12px;
    color: var(--text-secondary);
    padding: 4px 0;
    font-style: italic;
}

.bug-report-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 4px;
}

/* ============================================
   BACKUP SELECTION UI (Phase 7)
   ============================================ */

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 24px;
}

.section-header h2 {
    font-size: 24px;
    font-weight: 700;
    color: #111827;
}

/* Backup List Table */
.backup-list-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--bg-card);
    border-radius: 12px;
    overflow: hidden;
    margin-bottom: 24px;
}

.backup-list-table thead {
    background: #f9fafb;
    border-bottom: 1px solid var(--border-color);
}

.backup-list-table th {
    padding: 12px 16px;
    text-align: left;
    font-size: 13px;
    font-weight: 600;
    color: #374151;
}

.backup-list-table th.sortable {
    cursor: pointer;
    user-select: none;
}

.backup-list-table th.sortable:hover {
    background: #f3f4f6;
}

.backup-list-table td {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
    font-size: 14px;
}

.backup-list-table tbody tr {
    transition: background 0.15s;
}

.backup-list-table tbody tr:hover {
    background: rgba(34, 197, 94, 0.05);
}

.backup-list-table tbody tr.selected {
    background: #dbeafe;
}

.backup-list-table tbody tr:last-child td {
    border-bottom: none;
}

.backup-list-table .col-select {
    width: 40px;
}

.backup-list-table .col-date {
    width: 200px;
}

.backup-list-table .col-size {
    width: 100px;
}

.backup-list-table .col-records {
    width: 100px;
}

.backup-list-table .col-actions {
    width: 200px;
}

/* Backup Actions */
.backup-actions {
    display: flex;
    gap: 12px;
    justify-content: flex-start;
}

/* Tenant Multi-Select (Phase 10-01) */
.tenant-table th:first-child,
.tenant-table td:first-child {
    width: 40px;
    text-align: center;
}

input[type="checkbox"].tenant-select {
    width: 18px;
    height: 18px;
    cursor: pointer;
}

input[type="checkbox"].tenant-select:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.selection-counter-container {
    display: none;
    margin-bottom: 16px;
    padding: 12px 16px;
    background: #dbeafe;
    border-left: 4px solid #3b82f6;
    border-radius: 8px;
}

.selection-counter-container.visible {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.selection-counter-text {
    font-size: 14px;
    font-weight: 600;
    color: #1e40af;
}

.selection-counter-container.warning {
    background: #fef3c7;
    border-color: #f59e0b;
}

.selection-counter-container.warning .selection-counter-text {
    color: #92400e;
}

.clear-selection-btn {
    padding: 6px 12px;
    font-size: 13px;
    background: white;
    border: 1px solid #d1d5db;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.15s;
}

.clear-selection-btn:hover {
    background: #f3f4f6;
}

.tenant-table tbody tr.selected {
    background: rgba(59, 130, 246, 0.08);
}

.loading-indicator {
    background: var(--bg-card);
    border-radius: 12px;
    padding: 40px 20px;
    text-align: center;
    color: var(--text-secondary);
    margin-bottom: 24px;
}

.progress-text {
    display: inline-block;
    margin-left: 8px;
    color: var(--primary-color);
    font-weight: 600;
}

/* Preview Panel */
.preview-panel {
    position: fixed;
    right: 0;
    top: 0;
    width: 400px;
    height: 100vh;
    background: white;
    box-shadow: -4px 0 20px rgba(0, 0, 0, 0.15);
    z-index: 10001; /* Above sidebar (9999) to prevent logo bleed-through */
    overflow-y: auto;
    animation: slideIn 0.3s ease-out;
}

@keyframes slideIn {
    from {
        transform: translateX(100%);
    }
    to {
        transform: translateX(0);
    }
}

.preview-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px;
    border-bottom: 1px solid var(--border-color);
    background: var(--bg-card);
}

.preview-header h3 {
    font-size: 20px;
    font-weight: 700;
    color: #111827;
    margin: 0;
}

.btn-close {
    background: none;
    border: none;
    font-size: 28px;
    cursor: pointer;
    color: var(--text-secondary);
    padding: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    transition: background 0.2s, color 0.2s;
}

.btn-close:hover {
    background: var(--bg-hover);
    color: #111827;
}

#preview-content {
    padding: 20px;
}

.preview-metadata {
    margin-bottom: 24px;
}

.preview-metadata p {
    margin-bottom: 8px;
    font-size: 14px;
    color: #374151;
}

.preview-metadata strong {
    display: inline-block;
    width: 120px;
    color: #111827;
}

.preview-records h4 {
    font-size: 16px;
    font-weight: 600;
    color: #111827;
    margin-bottom: 12px;
}

.record-counts-table {
    width: 100%;
    border-collapse: collapse;
}

.record-counts-table thead {
    background: #f9fafb;
}

.record-counts-table th {
    padding: 8px 12px;
    text-align: left;
    font-size: 12px;
    font-weight: 600;
    color: #374151;
    border-bottom: 1px solid var(--border-color);
}

.record-counts-table td {
    padding: 8px 12px;
    font-size: 13px;
    border-bottom: 1px solid var(--border-color);
}

.record-counts-table tbody tr:last-child td {
    border-bottom: none;
}

/* Comparison Modal */
.modal {
    position: fixed;
    top: 0;
    left: var(--sidebar-width); /* offset past sidebar so modal centers in content area */
    width: calc(100% - var(--sidebar-width));
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
}

.modal-content {
    background: white;
    border-radius: 12px;
    width: 90%;
    max-width: 800px;
    max-height: 90vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: var(--shadow-xl);
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px 24px;
    border-bottom: 1px solid var(--border-color);
    background: var(--bg-card);
}

.modal-header h3 {
    font-size: 20px;
    font-weight: 700;
    color: #111827;
    margin: 0;
}

#comparison-content {
    padding: 24px;
    overflow-y: auto;
}

.comparison-summary {
    margin-bottom: 24px;
}

.comparison-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--bg-card);
    border-radius: 8px;
    overflow: hidden;
}

.comparison-table thead {
    background: #f9fafb;
}

.comparison-table th {
    padding: 12px 16px;
    text-align: left;
    font-size: 13px;
    font-weight: 600;
    color: #374151;
    border-bottom: 1px solid var(--border-color);
}

.comparison-table td {
    padding: 12px 16px;
    font-size: 14px;
    border-bottom: 1px solid var(--border-color);
}

.comparison-table tbody tr:last-child td {
    border-bottom: none;
}

.comparison-table .positive {
    color: #10b981;
    font-weight: 600;
}

.comparison-table .negative {
    color: #ef4444;
    font-weight: 600;
}

.comparison-table .neutral {
    color: #6b7280;
}

/* Responsive Design */
@media (max-width: 640px) {
    .preview-panel {
        width: 100%;
    }

    .backup-list-table {
        font-size: 12px;
    }

    .backup-list-table th,
    .backup-list-table td {
        padding: 8px;
    }

    .backup-actions {
        flex-direction: column;
    }

    .modal {
        left: 0;
        width: 100%;
    }

    .modal-content {
        width: 95%;
        max-height: 85vh;
    }

    .section-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }
}

/* =============================================
   Restore Wizard (Phase 8)
   ============================================= */
.restore-wizard-container {
    background: var(--bg-card);
    border-radius: 12px;
    border: 1px solid var(--border-color);
    padding: 24px;
    margin-top: 24px;
}

/* Step Indicator */
.wizard-step-indicator-container {
    display: flex;
    justify-content: space-between;
    margin-bottom: 32px;
    position: relative;
}

.wizard-step-indicator-container::before {
    content: '';
    position: absolute;
    top: 20px;
    left: 60px;
    right: 60px;
    height: 2px;
    background: #e5e7eb;
    z-index: 0;
}

.wizard-step-indicator {
    display: flex;
    flex-direction: column;
    align-items: center;
    position: relative;
    z-index: 1;
    flex: 1;
}

.wizard-step-indicator .step-circle {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #e5e7eb;
    color: #6b7280;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    margin-bottom: 8px;
}

.wizard-step-indicator.current .step-circle {
    background: #3b82f6;
    color: white;
}

.wizard-step-indicator.completed .step-circle {
    background: #10b981;
    color: white;
}

.wizard-step-indicator .step-label {
    font-size: 13px;
    color: #6b7280;
    text-align: center;
}

.wizard-step-indicator.current .step-label {
    color: #111827;
    font-weight: 600;
}

/* Wizard Header */
.wizard-header {
    display: flex;
    justify-content: space-between;
    align-items: start;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--border-color);
    margin-bottom: 32px;
}

.wizard-backup-info {
    flex: 1;
}

.wizard-backup-info h3 {
    font-size: 18px;
    font-weight: 700;
    margin-bottom: 8px;
}

.wizard-backup-info .metadata {
    display: flex;
    gap: 16px;
    font-size: 14px;
    color: var(--text-secondary);
}

.wizard-cancel-btn {
    background: #ef4444;
    color: white;
    border: none;
    padding: 8px 16px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.wizard-cancel-btn:hover {
    background: #dc2626;
}

/* Mode Selection Cards */
.mode-selection-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
    margin-bottom: 32px;
}

.mode-card {
    background: white;
    border: 2px solid var(--border-color);
    border-radius: 12px;
    padding: 24px;
    cursor: pointer;
    transition: all 0.2s;
    text-align: center;
}

.mode-card:hover {
    border-color: #3b82f6;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.1);
}

.mode-card.selected {
    border-color: #3b82f6;
    background: rgba(59, 130, 246, 0.05);
}

.mode-card .icon {
    font-size: 48px;
    margin-bottom: 16px;
}

.mode-card h3 {
    font-size: 18px;
    font-weight: 700;
    margin-bottom: 8px;
}

.mode-card .description {
    font-size: 14px;
    color: var(--text-secondary);
    margin-bottom: 16px;
    line-height: 1.5;
}

.mode-card .badge {
    display: inline-block;
    padding: 4px 12px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    margin-bottom: 16px;
}

.mode-card .badge.destructive {
    background: #fee2e2;
    color: #991b1b;
}

.mode-card .badge.safe {
    background: #dcfce7;
    color: #166534;
}

.mode-card .select-btn {
    width: 100%;
    padding: 10px;
    border: none;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.mode-card[data-mode="restore"] .select-btn {
    background: #f3f4f6;
    color: #374151;
}

.mode-card[data-mode="clone"] .select-btn {
    background: #3b82f6;
    color: white;
}

/* Wizard Navigation */
.wizard-navigation {
    display: flex;
    justify-content: space-between;
    padding-top: 24px;
    border-top: 1px solid var(--border-color);
}

.wizard-nav-btn {
    padding: 10px 24px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    border: none;
}

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

.wizard-back-btn {
    background: #f3f4f6;
    color: #374151;
}

.wizard-back-btn:hover:not(:disabled) {
    background: #e5e7eb;
}

.wizard-next-btn {
    background: #3b82f6;
    color: white;
}

.wizard-next-btn:hover:not(:disabled) {
    background: #2563eb;
}

/* Wizard Step Titles */
.wizard-step-title {
    font-size: 20px;
    font-weight: 700;
    margin-bottom: 8px;
}

.wizard-step-description {
    font-size: 14px;
    color: var(--text-secondary);
    margin-bottom: 24px;
}

/* Clone Configuration (Step 2) */
.clone-config-form {
    max-width: 500px;
    margin: 0 auto;
}

.form-group {
    margin-bottom: 24px;
}

.form-group label {
    display: block;
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 8px;
}

.subdomain-input-wrapper {
    position: relative;
    display: flex;
    align-items: center;
}

.subdomain-input-wrapper input {
    flex: 1;
    padding: 12px 50px 12px 16px;
    border: 2px solid var(--border-color);
    border-radius: 8px;
    font-size: 14px;
}

.subdomain-input-wrapper input:focus {
    outline: none;
    border-color: #3b82f6;
}

.validation-indicator {
    position: absolute;
    right: 16px;
    font-size: 20px;
}

.validation-indicator .success-icon {
    color: #10b981;
}

.validation-indicator .error-icon {
    color: #ef4444;
}

.validation-indicator .warning-icon {
    color: #f59e0b;
}

.validation-message {
    font-size: 13px;
    margin-top: 6px;
    min-height: 20px;
}

.validation-message.checking {
    color: #6b7280;
}

.validation-message.success {
    color: #10b981;
}

.validation-message.error {
    color: #ef4444;
}

.validation-message.warning {
    color: #f59e0b;
}

.help-text {
    font-size: 12px;
    color: var(--text-secondary);
    margin-top: 6px;
}

.original-subdomain-info {
    background: #f9fafb;
    padding: 12px;
    border-radius: 6px;
    font-size: 14px;
    margin-top: 16px;
}

/* Confirmation Step (Step 3) */
.warning-banner, .info-banner {
    padding: 20px;
    border-radius: 8px;
    margin-bottom: 24px;
    display: flex;
    gap: 16px;
}

.warning-banner {
    background: #fef2f2;
    border: 2px solid #fca5a5;
}

.info-banner {
    background: #eff6ff;
    border: 2px solid #93c5fd;
}

/* The `display: flex` above outranks the UA's [hidden] { display: none }, so a
   banner the markup hides with the attribute still paints -- an empty blue box.
   The splitter's re-apply banner sat visible-and-empty under step 3 this way. */
.warning-banner[hidden], .info-banner[hidden] {
    display: none !important;
}

.warning-icon, .info-icon {
    font-size: 32px;
    line-height: 1;
}

.warning-content h3, .info-content h3 {
    font-size: 16px;
    font-weight: 700;
    margin-bottom: 8px;
    color: #991b1b;
}

.info-content h3 {
    color: #1e40af;
}

.warning-content p, .info-content p {
    font-size: 14px;
    line-height: 1.5;
    margin: 0;
}

.backup-details {
    background: #f9fafb;
    padding: 20px;
    border-radius: 8px;
    margin-bottom: 24px;
}

.backup-details h4 {
    font-size: 14px;
    font-weight: 700;
    margin-bottom: 12px;
}

.details-table {
    width: 100%;
}

.details-table tr {
    line-height: 2;
}

.details-table td:first-child {
    font-weight: 600;
    color: var(--text-secondary);
    width: 120px;
}

.type-to-confirm {
    margin-top: 24px;
}

.type-to-confirm label {
    display: block;
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 8px;
}

.type-to-confirm input {
    width: 100%;
    max-width: 400px;
    padding: 12px 16px;
    border: 2px solid var(--border-color);
    border-radius: 8px;
    font-size: 14px;
}

.type-to-confirm input:focus {
    outline: none;
    border-color: #ef4444;
}

.confirm-match-indicator {
    font-size: 13px;
    margin-top: 6px;
    font-weight: 600;
}

.confirm-match-indicator.success {
    color: #10b981;
}

.confirm-match-indicator.error {
    color: #ef4444;
}

.final-confirm-actions {
    text-align: center;
    margin-top: 32px;
}

.wizard-confirm-btn {
    padding: 14px 40px;
    background: #3b82f6;
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
}

.wizard-confirm-btn:hover:not(:disabled) {
    background: #2563eb;
}

.wizard-confirm-btn:disabled {
    background: #9ca3af;
    cursor: not-allowed;
}

/* Wizard Mobile Responsive */
@media (max-width: 640px) {
    .mode-selection-grid {
        grid-template-columns: 1fr;
    }

    .wizard-step-indicator-container {
        gap: 0;
    }

    .wizard-step-indicator .step-label {
        font-size: 11px;
    }

    .wizard-backup-info .metadata {
        flex-direction: column;
        gap: 4px;
    }
}

/* ==========================================
   Global Restore Progress Tracker (Phase 09-02)
   ========================================== */

.restore-progress-global {
    margin-bottom: 1rem;
    max-width: 100%;
}

.restore-task-card {
    background: #2a2a2a;
    border: 1px solid #3a3a3a;
    border-radius: 8px;
    margin-bottom: 0.5rem;
    overflow: hidden;
}

.restore-task-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
    cursor: pointer;
    transition: background 0.2s ease;
    gap: 1rem;
    flex-wrap: wrap;
}

.restore-task-header:hover {
    background: #2f2f2f;
}

.restore-task-title {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.restore-mode-badge {
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

.restore-mode-badge.restore {
    background: #dc3545;
    color: white;
}

.restore-mode-badge.clone {
    background: #0d6efd;
    color: white;
}

.restore-task-title strong {
    color: #fff;
    font-size: 14px;
}

.restore-task-status {
    flex: 1;
    min-width: 250px;
}

.progress-bar-container {
    position: relative;
    height: 24px;
    background: #1a1a1a;
    border-radius: 4px;
    overflow: hidden;
    margin-bottom: 4px;
}

.progress-bar-container .progress-bar-fill {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: linear-gradient(90deg, #28a745 0%, #20c997 100%);
    transition: width 0.3s ease;
}

.progress-bar-container .progress-text {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: white;
    font-weight: bold;
    font-size: 12px;
    z-index: 1;
}

.current-stage-text {
    font-size: 12px;
    color: #aaa;
}

.expand-toggle {
    background: none;
    border: none;
    color: #aaa;
    font-size: 18px;
    cursor: pointer;
    transition: transform 0.2s ease, color 0.2s ease;
    padding: 4px 8px;
}

.expand-toggle:hover {
    color: #fff;
}

.expand-toggle.expanded {
    transform: rotate(180deg);
}

.restore-task-details {
    border-top: 1px solid #3a3a3a;
    padding: 1rem;
    background: #1f1f1f;
}

.stage-checklist {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.stage-item {
    padding: 6px 10px;
    border-radius: 4px;
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.stage-item.complete {
    color: #28a745;
    background: rgba(40, 167, 69, 0.1);
}

.stage-item.current {
    color: #0d6efd;
    background: rgba(13, 110, 253, 0.1);
    font-weight: bold;
}

.stage-item.pending {
    color: #6c757d;
    background: rgba(108, 117, 125, 0.1);
}

.restore-task-meta {
    display: flex;
    gap: 1.5rem;
    font-size: 12px;
    color: #aaa;
}

.restore-task-meta span {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Mobile Responsive */
@media (max-width: 640px) {
    .restore-task-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .restore-task-status {
        width: 100%;
        min-width: unset;
    }

    .stage-checklist {
        grid-template-columns: 1fr;
    }

    .restore-task-meta {
        flex-direction: column;
        gap: 0.5rem;
    }
}

/* Toast notification styles (Phase 09-03) */
.restore-toast {
    position: fixed;
    top: 80px;
    right: 20px;
    padding: 1rem 1.5rem;
    border-radius: 8px;
    color: white;
    font-weight: 500;
    box-shadow: 0 4px 12px rgba(0,0,0,0.3);
    z-index: 10000;
    animation: slideIn 0.3s ease;
}

.restore-toast-success {
    background: #28a745;
}

.restore-toast-error {
    background: #dc3545;
}

.restore-toast-info {
    background: #0d6efd;
}

.restore-toast-fade {
    opacity: 0;
    transition: opacity 0.3s ease;
}

@keyframes slideIn {
    from {
        transform: translateX(400px);
    }
    to {
        transform: translateX(0);
    }
}

/* Restore failure modal styles (Phase 09-03) */
.restore-failure-modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0,0,0,0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10001;
}

.restore-failure-content {
    background: #2a2a2a;
    padding: 2rem;
    border-radius: 8px;
    max-width: 500px;
    color: white;
}

.restore-failure-content h3 {
    color: #dc3545;
    margin-top: 0;
}

.failure-actions {
    margin-top: 1.5rem;
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.btn-resume {
    background: #28a745;
}

.btn-rollback {
    background: #dc3545;
}

.failure-actions .btn-dismiss {
    background: #6c757d;
}

.failure-actions button {
    padding: 0.5rem 1rem;
    border: none;
    border-radius: 4px;
    color: white;
    cursor: pointer;
    font-weight: 500;
}

.failure-actions button:hover {
    opacity: 0.9;
}

/* ==========================================
   Cancel Task Button (Phase 10-03)
   ========================================== */

.cancel-task-btn {
    padding: 4px 8px;
    background: #ef4444;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    transition: background 0.2s ease;
    margin-left: 8px;
}

.cancel-task-btn:hover {
    background: #dc2626;
}

.retry-task-btn {
    padding: 4px 10px;
    background: #f59e0b;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    transition: background 0.2s ease;
    margin-left: 8px;
}

.retry-task-btn:hover {
    background: #d97706;
}

.dismiss-task-btn {
    padding: 4px 8px;
    background: #6b7280;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    transition: background 0.2s ease;
    margin-left: 8px;
}

.dismiss-task-btn:hover {
    background: #4b5563;
}

.retry-all-btn {
    background: #f59e0b;
    color: white;
    border: 1px solid #d97706;
}

.retry-all-btn:hover {
    background: #d97706;
}

.restore-progress-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color);
}

.restore-progress-header h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
}

/* ==========================================
   Bulk Completion Banner (Phase 10-04)
   ========================================== */

.bulk-completion-banner {
    display: none;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px;
    margin-bottom: 16px;
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.completion-content {
    display: flex;
    align-items: center;
    gap: 12px;
}

.completion-icon {
    font-size: 28px;
    color: white;
    font-weight: bold;
}

.completion-text {
    color: white;
    font-size: 15px;
}

.completion-text strong {
    font-weight: 700;
}

.completion-actions {
    display: flex;
    gap: 8px;
}

.completion-actions .btn-sm {
    background: rgba(255, 255, 255, 0.2);
    color: white;
    border: 1px solid rgba(255, 255, 255, 0.3);
}

.completion-actions .btn-sm:hover {
    background: rgba(255, 255, 255, 0.3);
}

.completion-actions .retry-all-btn {
    background: #f59e0b;
    border: 1px solid #d97706;
}

.completion-actions .retry-all-btn:hover {
    background: #d97706;
}

/* ==========================================
   Bulk Restore Modal (Phase 10-02)
   ========================================== */

.bulk-restore-modal-content {
    max-width: 800px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
}

.bulk-restore-body {
    flex: 1;
    overflow-y: auto;
    padding: 1.5rem;
}

.quick-action-section {
    background: #2a2a2a;
    border: 1px solid #3a3a3a;
    border-radius: 8px;
    padding: 1.5rem;
    margin-bottom: 1.5rem;
}

.quick-action-section h4 {
    margin: 0 0 0.5rem 0;
    color: #fff;
    font-size: 16px;
}

.quick-action-section .help-text {
    color: #aaa;
    font-size: 14px;
    margin-bottom: 1rem;
}

.date-picker-row {
    display: flex;
    gap: 1rem;
    align-items: center;
}

.date-picker-row input[type="date"] {
    flex: 1;
    padding: 8px 12px;
    background: #1a1a1a;
    border: 1px solid #3a3a3a;
    border-radius: 4px;
    color: #fff;
    font-size: 14px;
}

.tenant-backup-list {
    margin-bottom: 1.5rem;
}

.tenant-backup-list h4 {
    margin: 0 0 1rem 0;
    color: #fff;
    font-size: 16px;
}

.tenant-assignment-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem;
    background: #2a2a2a;
    border: 1px solid #3a3a3a;
    border-radius: 4px;
    margin-bottom: 0.5rem;
}

.tenant-name {
    font-weight: 600;
    color: #fff;
    min-width: 150px;
}

.backup-info {
    flex: 1;
    font-size: 14px;
}

.backup-info.has-backup {
    color: #28a745;
}

.backup-info.no-backup {
    color: #dc3545;
}

.auto-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 6px;
    background: #0d6efd;
    color: white;
    font-size: 10px;
    font-weight: 700;
    border-radius: 3px;
    letter-spacing: 0.5px;
}

.btn-change-backup {
    padding: 6px 12px;
    background: #3a3a3a;
    color: #fff;
    border: 1px solid #4a4a4a;
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    transition: background 0.2s ease;
}

.btn-change-backup:hover {
    background: #4a4a4a;
}

.bulk-warnings {
    background: #fff3cd;
    border: 1px solid #ffc107;
    border-radius: 4px;
    padding: 1rem;
    color: #856404;
}

.bulk-warnings .warning-content {
    font-size: 14px;
}

.bulk-actions-container {
    text-align: center;
}

/* ==========================================
   GLOBAL EMPTY STATE COMPONENT
   ========================================== */

.empty-state {
    text-align: center;
    padding: 80px 20px;
    max-width: 500px;
    margin: 0 auto;
    color: var(--text-secondary);
}

/* Small variant (for compact spaces like modals, dropdowns) */
.empty-state-sm {
    padding: 40px 20px;
    max-width: 350px;
    margin: 0 auto;
    text-align: center;
}

/* Large variant (for full-page empty states) */
.empty-state-lg {
    padding: 120px 20px;
    max-width: 600px;
}

.empty-state-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 80px;
    height: 80px;
    margin: 0 auto 24px;
    color: rgba(0, 0, 0, 0.2);
}

.empty-state-icon svg {
    width: 100%;
    height: 100%;
}

.empty-state-sm .empty-state-icon {
    width: 48px;
    height: 48px;
    margin-bottom: 16px;
}

.empty-state-lg .empty-state-icon {
    width: 96px;
    height: 96px;
    margin-bottom: 32px;
}

.empty-state-title {
    font-size: 20px;
    font-weight: 600;
    color: #111827;
    margin-bottom: 12px;
    letter-spacing: -0.01em;
}

.empty-state-sm .empty-state-title {
    font-size: 16px;
    margin-bottom: 8px;
}

.empty-state-lg .empty-state-title {
    font-size: 24px;
    margin-bottom: 16px;
}

.empty-state-description {
    font-size: 15px;
    line-height: 1.6;
    color: var(--text-secondary);
    margin-bottom: 32px;
}

.empty-state-sm .empty-state-description {
    font-size: 13px;
    margin-bottom: 20px;
}

.empty-state-lg .empty-state-description {
    font-size: 16px;
    line-height: 1.7;
    margin-bottom: 40px;
}

.empty-state-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 24px;
    background: var(--primary-color);
    color: white;
    border: 1px solid var(--primary-color);
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    transition: all 0.2s;
    cursor: pointer;
}

.empty-state-sm .empty-state-cta {
    padding: 8px 16px;
    font-size: 13px;
    gap: 6px;
}

.empty-state-lg .empty-state-cta {
    padding: 14px 28px;
    font-size: 15px;
    gap: 10px;
}

.empty-state-cta:hover {
    background: var(--primary-dark);
    border-color: var(--primary-dark);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(56, 142, 60, 0.3);
    color: white;
}

.empty-state-cta svg {
    width: 18px;
    height: 18px;
}

.empty-state-sm .empty-state-cta svg {
    width: 16px;
    height: 16px;
}

.empty-state-lg .empty-state-cta svg {
    width: 20px;
    height: 20px;
}

/* Dark background variant (for sections on the green/dark dashboard background) */
.empty-state.dark-bg .empty-state-icon {
    color: rgba(255, 255, 255, 0.3);
}

.empty-state.dark-bg .empty-state-title {
    color: rgba(255, 255, 255, 0.95);
}

.empty-state.dark-bg .empty-state-description {
    color: rgba(255, 255, 255, 0.7);
}

.empty-state.dark-bg .empty-state-cta {
    background: rgba(255, 255, 255, 0.15);
    color: white;
    border: 1px solid rgba(255, 255, 255, 0.2);
    backdrop-filter: blur(10px);
}

.empty-state.dark-bg .empty-state-cta:hover {
    background: rgba(255, 255, 255, 0.25);
    border-color: rgba(255, 255, 255, 0.3);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    color: white;
}

/* light-bg is now the default — kept as alias for backward compatibility */

/* ==========================================
   TRIAL BANNER STYLES
   ========================================== */

/* Pulsing animation for red trial banner */
@keyframes pulse {
    0%, 100% {
        transform: scale(1);
        opacity: 1;
    }
    50% {
        transform: scale(1.02);
        opacity: 0.95;
    }
}

/* Banner container */
.trial-banner {
    position: sticky;
    top: 0;
    z-index: 1000;
    padding: 16px 24px;
    display: flex;
    align-items: center;
    gap: 16px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}

.trial-banner-yellow {
    background: #f97316;
    color: #fff;
}

.trial-banner-orange {
    background: #ff9800;
    color: #fff;
}

.trial-banner-red {
    background: #dc3545;
    color: #fff;
    animation: pulse 2s ease-in-out infinite;
}

/* Respect user motion preferences (WCAG 2.1) */
@media (prefers-reduced-motion: reduce) {
    .trial-banner-red {
        animation: none;
        border: 3px solid #fff;
    }
}

.trial-banner-content {
    display: flex;
    align-items: center;
    gap: 16px;
    flex: 1;
    flex-wrap: wrap;
}

.trial-banner-icon {
    font-size: 24px;
    flex-shrink: 0;
}

.trial-banner-text {
    flex: 1;
    font-size: 15px;
    line-height: 1.4;
}

.trial-banner-text strong {
    font-weight: 700;
}

.trial-countdown {
    font-weight: 600;
    white-space: nowrap;
}

.trial-banner-actions {
    display: flex;
    gap: 12px;
    align-items: center;
    flex-shrink: 0;
}

.btn-upgrade {
    background: #fff;
    color: #dc3545;
    padding: 10px 24px;
    border-radius: 6px;
    font-weight: 600;
    text-decoration: none;
    font-size: 15px;
    transition: all 0.2s;
    border: 2px solid transparent;
    min-height: 44px;
    min-width: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn-upgrade:hover {
    background: #f8f8f8;
    border-color: #fff;
}

.trial-banner-yellow .btn-upgrade {
    color: #333;
}

.trial-banner-orange .btn-upgrade {
    color: #ff9800;
}

.btn-dismiss {
    background: transparent;
    border: 1px solid currentColor;
    color: inherit;
    padding: 8px 16px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 14px;
    font-weight: 500;
    transition: all 0.2s;
}

.btn-dismiss:hover {
    background: rgba(255,255,255,0.1);
}

/* Mobile responsive */
@media (max-width: 640px) {
    .trial-banner {
        padding: 12px 16px;
        flex-direction: column;
        align-items: flex-start;
    }

    .trial-banner-content {
        gap: 12px;
    }

    .trial-banner-icon {
        font-size: 20px;
    }

    .trial-banner-text {
        font-size: 14px;
    }

    .trial-banner-actions {
        width: 100%;
        justify-content: flex-start;
    }

    .btn-upgrade {
        flex: 1;
        text-align: center;
    }
}

/* Info message links — ensure readability on dark background */
.django-messages .message a {
    color: white;
    text-decoration: underline;
    font-weight: 600;
}
.django-messages .message a:hover {
    opacity: 0.85;
}

/* =====================================================
   GLOBAL MOBILE COMPACTION — iPhone 14 (390px) + all phones
   Tightens padding, spacing, and font sizes on ALL pages
   so more content fits without pinch-zooming.
   ===================================================== */

/* ── Phones (≤640px) ── */
@media (max-width: 640px) {
    /* Cards — reduce generous desktop padding */
    .card {
        padding: 16px !important;
        margin-bottom: 12px !important;
    }
    .card-header {
        margin-bottom: 10px !important;
    }
    .card-title {
        font-size: 16px !important;
    }

    /* Stat cards */
    .stat-card {
        padding: 12px 14px !important;
    }
    .stat-card-number {
        font-size: 26px !important;
    }
    .stat-card-label {
        font-size: 10px !important;
    }
    .stat-cards-row {
        gap: 8px !important;
        margin-bottom: 12px !important;
    }

    /* Section headers */
    .section-header {
        margin-bottom: 14px !important;
    }
    .section-header h2 {
        font-size: 20px !important;
    }

    /* Filters bar */
    .filters-bar {
        gap: 8px !important;
        margin-bottom: 14px !important;
    }
    .filter-select {
        min-width: 120px !important;
        padding: 6px 10px !important;
        font-size: 13px !important;
    }

    /* Tab nav spacing */
    .tab-nav {
        margin-bottom: 12px !important;
    }

    /* Reduce gap between stacked form fields */
    .form-row,
    .form-grid {
        gap: 10px !important;
    }

    /* Btn — slightly more compact.
       Exception: icon-only buttons (.btn-reorder, .btn-icon, [data-icon-only])
       use padding:0 with fixed w/h — the !important here must not apply to them. */
    .btn:not(.btn-reorder):not(.btn-icon):not([data-icon-only]) {
        padding: 10px 16px !important;
        font-size: 13px !important;
    }
    .btn-sm:not(.btn-reorder):not(.btn-icon):not([data-icon-only]) {
        padding: 6px 10px !important;
        font-size: 12px !important;
    }
}

/* ── Phones (≤430px — iPhone 13 Pro Max, 14 Plus) ── */
@media (max-width: 430px) {
    .card {
        padding: 12px !important;
        margin-bottom: 8px !important;
        border-radius: 12px !important;
    }
    .card-header {
        margin-bottom: 8px !important;
    }
    .card-title {
        font-size: 14px !important;
    }

    /* Stat cards — very compact */
    .stat-card {
        padding: 10px 10px !important;
    }
    .stat-card-number {
        font-size: 22px !important;
        margin-bottom: 2px !important;
    }
    .stat-card-label {
        font-size: 9px !important;
        letter-spacing: 0.5px !important;
    }
    .stat-cards-row {
        gap: 6px !important;
        margin-bottom: 8px !important;
    }

    /* Section headers */
    .section-header {
        margin-bottom: 10px !important;
    }
    .section-header h2 {
        font-size: 17px !important;
    }

    /* Filters */
    .filters-bar {
        gap: 6px !important;
        margin-bottom: 10px !important;
    }
    .filter-select {
        min-width: 0 !important;
        padding: 5px 8px !important;
        font-size: 12px !important;
    }

    /* Tab nav */
    .tab-nav {
        margin-bottom: 8px !important;
    }

    /* Buttons — same icon-only exception as 768px block */
    .btn:not(.btn-reorder):not(.btn-icon):not([data-icon-only]) {
        padding: 9px 12px !important;
        font-size: 12px !important;
    }

    /* Form rows */
    .form-row,
    .form-grid {
        gap: 8px !important;
    }
    .form-grid > * {
        margin-bottom: 8px !important;
    }
}

/* ── iPhone 14 (390px) and similar ── */
@media (max-width: 400px) {
    .card {
        padding: 10px !important;
        margin-bottom: 6px !important;
        border-radius: 10px !important;
    }
    .card-header {
        margin-bottom: 6px !important;
    }
    .card-title {
        font-size: 13px !important;
    }

    .stat-card {
        padding: 8px !important;
    }
    .stat-card-number {
        font-size: 20px !important;
    }

    .section-header {
        margin-bottom: 8px !important;
    }
    .section-header h2 {
        font-size: 16px !important;
    }
}

/* =====================================================
   SUB-PAGE FORM COMPACTION — .form-card only (≤480px / ≤400px).
   Form-group / form-group label / help-text moved to the mobile
   primitives spec block below — the spec is the canonical source
   for those classes.
   17 form templates define .form-card in inline <style> blocks;
   !important is required to override their inline rules.
   ===================================================== */
@media (max-width: 480px) {
    .form-card {
        padding: 14px !important;
        margin-bottom: 10px !important;
    }
    .form-card h3 {
        font-size: 14px !important;
        margin-bottom: 12px !important;
        padding-bottom: 8px !important;
    }

    /* Help / description text under fields */
    .help-text,
    .field-help,
    .field-description,
    .form-group small,
    .form-group > p {
        font-size: 11px !important;
        line-height: 1.3 !important;
        margin-top: 3px !important;
    }

    /* Form row gaps */
    .form-row {
        gap: 8px !important;
    }
}

/* Aggressive .form-card compaction for small iPhones (≤400px). */
@media (max-width: 400px) {
    .form-card {
        padding: 10px !important;
        margin-bottom: 8px !important;
    }
    .form-card h3 {
        font-size: 13px !important;
        margin-bottom: 8px !important;
        padding-bottom: 6px !important;
    }
}

/* ============================================================
   MOBILE PRIMITIVES APPLICATION — spec sizing on shared
   component classes, mobile only (<=640px, the dashboard's
   canonical mobile breakpoint). Desktop above 640px keeps
   the original V17 sizing.

   The spec is the highest-authority styling on mobile. Per-page
   inline <style> blocks have higher specificity than this file-level
   block, so every sizing/typography property below uses !important
   to make the spec genuinely override bespoke per-page CSS without
   requiring page-by-page sweeps. Color/background/display rules are
   left without !important so pages can still theme/conditionally hide.

   Source: .planning/mobile-optimization/primitives-spec.md
   Sandbox: .planning/mobile-optimization/sandbox.html
   ============================================================ */
@media (max-width: 640px) {
    /* ============================================================
       SANDBOX ALIGNMENT — every sizing rule below references the
       exact line in .planning/mobile-optimization/sandbox.html.
       If sandbox changes, this block follows.
       ============================================================ */

    /* ===== Buttons — sandbox.html L219-266 ===== */
    .btn {
        gap: var(--space-2) !important;
        padding: 3px 12px !important;
        border-radius: var(--radius-md) !important;
        font-size: var(--text-sm) !important;
        font-weight: 600 !important;
        line-height: var(--lh-snug) !important;
        min-height: 30px !important;
        transition: all var(--transition-fast);
        white-space: nowrap !important;
    }
    .btn-sm {
        min-height: 28px !important;
        padding: 2px 10px !important;
        font-size: 11px !important;
    }
    .btn-lg {
        min-height: 44px !important;
        padding: 6px 18px !important;
        font-size: var(--text-base) !important;
    }
    .btn-icon {
        width: var(--tap-min) !important;
        height: var(--tap-min) !important;
        min-height: var(--tap-min) !important;
        min-width: var(--tap-min) !important;
        padding: 0 !important;
        justify-content: center;
    }

    /* ===== Decorative left-edge accents that read as "dark shadow" on mobile ===== */
    .gs-header::before {
        display: none !important;
    }
    .timeclock,
    .notam-card,
    .notam-alerts-card,
    .inventory-alerts-card,
    .credential-alerts-card {
        border-left-width: 2px !important;
    }

    /* ===== Cards — sandbox.html L288-345 =====
       Sandbox: background #fff, border 1px solid var(--border),
       border-radius --radius-md (10px), padding 6px var(--space-3),
       box-shadow 0 4px 12px rgba(0,0,0,0.1).
       (Background not forced — dashboard's cream gradient is intentional;
       sandbox white is its own choice.)

       NOTE: We deliberately do NOT use [class*="-card"] wildcard here.
       That wildcard matched nested elements like .job-card-header,
       .job-card-body, .job-card-stats — giving each its own border +
       padding + shadow and creating goofy nested boxes inside the
       outer card. Enumerate explicit OUTER card classes only. */
    .card,
    .timeclock,
    .getting-started-card,
    .metric-card,
    .goal-card,
    .pilot-stats-card,
    .inventory-alerts-card,
    .plan-day-card,
    .map-card,
    .products-card,
    .mode-card,
    .restore-task-card,
    .ov-panel,
    .summary-card {
        border-radius: var(--radius-md) !important;
        padding: 6px var(--space-3) !important;
        margin-bottom: 6px !important;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1) !important;
    }
    /* Card head — sandbox L297-321 */
    .card-head {
        margin-bottom: 4px !important;
        gap: var(--space-2) !important;
    }
    .card-header {
        margin-bottom: 4px !important;
    }
    .card-title {
        font-size: var(--text-sm) !important;
        font-weight: 700 !important;
        line-height: var(--lh-snug) !important;
        margin-bottom: 2px !important;
    }
    .card-meta {
        font-size: var(--text-xs) !important;
    }
    .card-body {
        font-size: var(--text-xs) !important;
    }

    /* ===== Job card — sandbox.html sj-card pattern (per user 2026-04-26) =====
       2-row CSS grid:
         Row 1 col 1: .job-card-body (field name + customer + meta)
         Row 1 col 2: .job-card-right (status pill at top, View Details at bottom)
         Row 2 col 1: .field-shape-preview (polygon at bottom-left)
       Right column spans both grid rows so status sits at top, View
       Details at bottom (justify-content: space-between).

       Selector matches a.job-card / .main-content a.job-card /
       .content-area a.job-card with !important to BEAT the existing
       display:flex !important rule at spraying_jobs.html line 2236
       (which has higher specificity than .job-card alone). */
    .job-card,
    a.job-card,
    .main-content a.job-card,
    .content-area a.job-card {
        position: relative;
        display: grid !important;
        grid-template-columns: 1fr auto !important;
        grid-template-rows: auto auto !important;
        gap: 4px var(--space-2) !important;
        padding: var(--space-3) !important;
        border-radius: var(--radius-md) !important;
        margin-bottom: 6px !important;
        border-left-width: 3px !important;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1) !important;
        align-items: start !important;
    }
    .job-card .job-card-body {
        grid-column: 1 !important;
        grid-row: 1 !important;
        min-width: 0 !important;
    }
    .job-card .field-shape-preview {
        grid-column: 1 !important;
        grid-row: 2 !important;
        width: 36px !important;
        height: 36px !important;
        margin: 0 !important;
        align-self: end !important;
    }
    .job-card .job-card-right {
        grid-column: 2 !important;
        grid-row: 1 / 3 !important;
        display: flex !important;
        flex-direction: column !important;
        align-items: flex-end !important;
        gap: 4px !important;
        min-height: 100% !important;
        width: max-content !important;
        max-width: 140px !important;
    }
    /* View Details sticks to bottom of right column, badges stack tight at top */
    .job-card .view-details-btn {
        margin-top: auto !important;
    }
    /* Body content flows horizontally — match sandbox sj-card pattern.
       .job-card-top (field/customer/phone) and .job-card-meta (acres/date/crop/mix)
       should flex-wrap inline rather than stacking vertically. */
    .job-card .job-card-top {
        display: flex !important;
        flex-wrap: wrap !important;
        align-items: baseline !important;
        gap: 4px !important;
    }
    .job-card .job-card-meta {
        display: flex !important;
        flex-wrap: wrap !important;
        align-items: center !important;
        gap: 4px 8px !important;
    }
    .job-card .job-meta-item {
        display: inline-flex !important;
        align-items: center !important;
        gap: 3px !important;
    }
    /* Status pill — first child of right column, sandbox pill style */
    .job-card .job-status-badge {
        position: static !important;
        margin: 0 !important;
        padding: 3px 10px !important;
        border-radius: 999px !important;
        font-size: var(--text-2xs) !important;
        font-weight: 700 !important;
        letter-spacing: 0.5px !important;
        text-transform: uppercase !important;
        white-space: nowrap !important;
        display: inline-flex !important;
    }
    /* Padding on header / body — none, grid handles layout */
    .job-card-header {
        padding: 0 !important;
        display: contents !important;
    }

    /* Selected state — sandbox style: green outline replaces selection
       checkbox so card layout stays put. */
    .job-card.selected {
        outline: 2px solid var(--primary-color) !important;
        outline-offset: -1px !important;
        box-shadow: 0 0 0 1px var(--primary-glow), 0 4px 12px rgba(0, 0, 0, 0.1) !important;
    }
    /* Drop the left-padding for selection-mode checkbox column —
       outline handles the visual indicator now, no checkbox needed. */
    .selection-mode .job-card {
        padding-left: var(--space-3) !important;
    }
    .job-card-title {
        font-size: var(--text-sm) !important;
        font-weight: 700 !important;
        line-height: var(--lh-snug) !important;
    }
    .job-card-meta {
        font-size: var(--text-xs) !important;
        margin: 2px 0 6px !important;
    }
    .job-card-stats {
        gap: var(--space-3) !important;
        font-size: var(--text-xs) !important;
    }
    .job-card-stat-label {
        font-size: var(--text-2xs) !important;
        text-transform: uppercase !important;
        letter-spacing: 0.5px !important;
    }

    /* ===== Forms — sandbox.html L427-486 =====
       Sandbox .form-input/.form-textarea/.form-select:
         font-size 16px (iOS zoom prevention — set elsewhere)
         padding 6px 10px
         border-radius --radius-md
         min-height var(--tap-min) (36px)
       Sandbox .form-label: --text-xs / 600 weight (no margin — uses parent gap)
       Sandbox .form-field: gap 2px, margin-bottom 3px */
    .form-control,
    .form-group input:not([type="checkbox"]):not([type="radio"]),
    .form-group select,
    .form-group textarea {
        padding: 6px 10px !important;
        border-radius: var(--radius-md) !important;
        min-height: var(--tap-min) !important;
    }
    .form-group label {
        font-size: var(--text-xs) !important;
        font-weight: 600 !important;
        margin-bottom: 2px !important;
    }
    .form-group {
        margin-bottom: 3px !important;
    }
    .form-help,
    .form-error {
        font-size: var(--text-xs) !important;
    }

    /* ===== Badges — sandbox.html L1611-1626 =====
       Smaller annotation chip (smaller than .pill). */
    .badge {
        gap: 3px !important;
        padding: 2px 6px !important;
        font-size: var(--text-2xs) !important;
        font-weight: 700 !important;
        letter-spacing: 0.5px !important;
        text-transform: uppercase !important;
        border-radius: 4px !important;
        line-height: var(--lh-snug) !important;
    }
    .rig-badge {
        padding: 2px 6px !important;
        font-size: var(--text-2xs) !important;
        letter-spacing: 0.5px !important;
        border-radius: 4px !important;
    }

    /* ===== Pills — sandbox.html L353-367 =====
       LARGER than badge: --text-xs, fully rounded (999px), 3px 8px padding.
       Used for primary card status (sandbox card-head, etc.). */
    .pill {
        gap: 4px !important;
        padding: 3px 8px !important;
        font-size: var(--text-xs) !important;
        font-weight: 700 !important;
        border-radius: 999px !important;
        text-transform: uppercase !important;
        letter-spacing: 0.5px !important;
    }

    /* ===== Banner — sandbox.html L1404-1419 ===== */
    .banner {
        padding: var(--space-2) var(--space-3) !important;
        border-radius: var(--radius-md) !important;
        gap: var(--space-2) !important;
        font-size: var(--text-xs) !important;
        margin-bottom: 6px !important;
    }

    /* ===== Alert / info boxes (close to sandbox banner) ===== */
    .alert-box {
        padding: var(--space-3) !important;
        border-radius: var(--radius-md) !important;
        gap: var(--space-2) !important;
        font-size: var(--text-xs) !important;
        line-height: var(--lh-body) !important;
    }
    .alert-box svg {
        width: 18px !important;
        height: 18px !important;
    }

    /* ===== Tabs underline — sandbox.html L1085-1107 ===== */
    .tabs {
        gap: var(--space-3) !important;
        margin-bottom: var(--space-3) !important;
    }
    .tab {
        padding: 8px 2px !important;
        font-size: var(--text-xs) !important;
        font-weight: 600 !important;
        min-height: 36px !important;
    }

    /* ===== Tabs pill — sandbox.html L1108-1129 =====
       Sandbox: padding 5px 12px, font-size --text-xs, border-radius 999px,
       min-height 30px. */
    .tab-nav {
        gap: 6px !important;
        padding: 0 !important;
        border-radius: 0 !important;
        margin-bottom: var(--space-3) !important;
    }
    .tab-btn {
        padding: 5px 12px !important;
        border-radius: 999px !important;
        font-size: var(--text-xs) !important;
        font-weight: 600 !important;
        min-height: 30px !important;
    }
    .tab-btn svg {
        width: 14px !important;
        height: 14px !important;
    }

    /* ===== Filter bar (mobile) — sandbox.html L491-496 ===== */
    .filters-bar {
        gap: var(--space-2) !important;
        margin-bottom: var(--space-3) !important;
    }
    .filter-group {
        gap: 2px !important;
    }
    .filter-label {
        font-size: var(--text-2xs) !important;
        font-weight: 700 !important;
        text-transform: uppercase !important;
        letter-spacing: 0.5px !important;
    }
    .filter-select {
        padding: 6px 10px !important;
        border-radius: var(--radius-md) !important;
        font-size: 16px !important;
        min-width: 0 !important;
        min-height: var(--tap-min) !important;
    }

    /* ===== Modals — sandbox.html L501-513 ===== */
    .modal {
        left: 0 !important;
        width: 100% !important;
        padding: env(safe-area-inset-top) env(safe-area-inset-right)
                 env(safe-area-inset-bottom) env(safe-area-inset-left) !important;
    }
    .modal-content {
        border-radius: var(--radius-md) !important;
        max-width: calc(100% - var(--space-4)) !important;
        max-height: 90dvh !important;
    }
    .modal-header {
        padding: var(--space-3) !important;
        padding-bottom: 4px !important;
        margin-bottom: 4px !important;
    }
    .modal-header h3 {
        font-size: var(--text-base) !important;
        font-weight: 700 !important;
    }

    /* ===== Empty state — sandbox.html L790-802 ===== */
    .empty-state {
        padding: var(--space-8) var(--space-4) !important;
        border-radius: var(--radius-md) !important;
    }
    .empty-state svg {
        width: 48px !important;
        height: 48px !important;
        margin-bottom: var(--space-2) !important;
        opacity: 0.5;
    }
    .empty-state h3,
    .empty-state .empty-state-title {
        font-size: var(--text-base) !important;
        margin-bottom: var(--space-1) !important;
    }
    .empty-state p,
    .empty-state .empty-state-message {
        font-size: var(--text-xs) !important;
        margin-bottom: var(--space-3) !important;
        line-height: var(--lh-body) !important;
    }
    .empty-state--compact { padding: var(--space-6) var(--space-4) !important; }
    .empty-state--sm { padding: var(--space-4) !important; }

    /* ===== Section title — sandbox.html L142-156 =====
       Sandbox section-title: --text-xl, weight 800. */
    .section-header {
        margin-bottom: var(--space-3) !important;
    }
    .section-header h2 {
        font-size: var(--text-xl) !important;
        font-weight: 800 !important;
        line-height: var(--lh-snug) !important;
    }

    /* ===== Metrics — sandbox.html L1330-1364 ===== */
    .metrics-grid,
    .metric-grid {
        gap: 6px !important;
        margin-bottom: var(--space-3) !important;
    }
    .metric-card,
    .metric {
        border-radius: var(--radius-md) !important;
        padding: 6px var(--space-3) !important;
        min-height: 82px !important;
    }
    .metric-icon {
        width: 36px !important;
        height: 36px !important;
        border-radius: var(--radius-md) !important;
        margin-bottom: var(--space-2) !important;
    }
    .metric-icon svg {
        width: 18px !important;
        height: 18px !important;
    }
    .metric-value {
        font-size: var(--text-2xl) !important;
        font-weight: 800 !important;
        line-height: var(--lh-tight) !important;
    }
    .metric-label {
        font-size: var(--text-2xs) !important;
        font-weight: 700 !important;
        letter-spacing: 0.5px !important;
        text-transform: uppercase !important;
        margin-bottom: 4px !important;
    }
    .metric-change,
    .metric-trend {
        font-size: var(--text-xs) !important;
        font-weight: 600 !important;
        margin-top: 4px !important;
    }

    /* ===== Breadcrumbs — sandbox.html L1169-1185 =====
       Sandbox uses --text-xs, not --text-2xs. */
    .breadcrumb-nav {
        padding: 4px var(--space-3) !important;
    }
    .breadcrumb-item {
        font-size: var(--text-xs) !important;
    }
    .breadcrumb-item + .breadcrumb-item::before {
        font-size: var(--text-xs) !important;
    }

    /* ===== Data tables ===== */
    .data-table th,
    .data-table td {
        padding: var(--space-2) var(--space-3) !important;
    }
    .data-table th {
        font-size: var(--text-2xs) !important;
        letter-spacing: 0.5px !important;
        font-weight: 700 !important;
        text-transform: uppercase !important;
    }
    .data-table tbody td {
        font-size: var(--text-xs) !important;
    }

    /* ===== Progress — sandbox.html L1241-1257 ===== */
    .progress-container {
        margin-top: var(--space-3) !important;
    }
    .progress-bar,
    .progress {
        height: 8px !important;
        border-radius: 999px !important;
    }
    .progress-fill {
        border-radius: 999px !important;
    }
    .progress-text {
        font-size: var(--text-xs) !important;
        font-weight: 600 !important;
    }

    /* ===== Spinner — sandbox.html L1266-1276 ===== */
    .spinner {
        width: 20px !important;
        height: 20px !important;
        border-width: 3px !important;
    }
    .spinner-lg {
        width: 32px !important;
        height: 32px !important;
        border-width: 4px !important;
    }

    /* ===== Toasts — sandbox.html L922-942 ===== */
    .toast {
        gap: var(--space-2) !important;
        padding: var(--space-2) var(--space-3) !important;
        border-radius: var(--radius-md) !important;
        font-size: var(--text-xs) !important;
        margin-bottom: 6px !important;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1) !important;
        border-left: 4px solid var(--primary) !important;
    }

    /* ===== Accordion — sandbox.html L1134-1164 ===== */
    .accordion-item {
        border-radius: var(--radius-md) !important;
        margin-bottom: 3px !important;
    }
    .accordion-header {
        padding: var(--space-2) var(--space-3) !important;
        font-size: var(--text-xs) !important;
        font-weight: 600 !important;
        min-height: 36px !important;
    }
    .accordion-body {
        padding: 0 var(--space-3) var(--space-3) !important;
        font-size: var(--text-xs) !important;
    }

    /* ===== Pagination — sandbox.html L1190-1209 ===== */
    .pagination {
        gap: 4px !important;
    }
    .pagination button,
    .pagination .page-link {
        min-width: 32px !important;
        height: 32px !important;
        padding: 0 8px !important;
        font-size: var(--text-xs) !important;
        font-weight: 600 !important;
        border-radius: var(--radius-sm) !important;
    }

    /* ===== Steps — sandbox.html L1214-1236 ===== */
    .steps {
        gap: 4px !important;
    }
    .step-dot {
        height: 3px !important;
        border-radius: 2px !important;
    }
    .step-labels {
        gap: 4px !important;
        margin-top: 6px !important;
        font-size: var(--text-2xs) !important;
    }

    /* ===== Timeline — sandbox.html L1299-1325 ===== */
    .timeline-time {
        font-size: var(--text-2xs) !important;
        font-weight: 700 !important;
        text-transform: uppercase !important;
        letter-spacing: 0.5px !important;
    }
    .timeline-title {
        font-size: var(--text-xs) !important;
        font-weight: 600 !important;
        margin: 2px 0 !important;
    }
    .timeline-desc {
        font-size: var(--text-xs) !important;
    }

    /* ===== Autosave — sandbox.html L1458-1471 =====
       Sandbox: padding 3px 8px, border-radius 999px (fully rounded). */
    .autosave-status,
    .autosave {
        gap: 6px !important;
        font-size: var(--text-2xs) !important;
        padding: 3px 8px !important;
        border-radius: 999px !important;
        margin-left: var(--space-2) !important;
        letter-spacing: 0.5px !important;
        font-weight: 700 !important;
        text-transform: uppercase !important;
    }

    /* ===== Danger zone — sandbox.html L1442-1453 ===== */
    .danger-zone {
        margin-top: var(--space-3) !important;
        border-radius: var(--radius-md) !important;
        padding: var(--space-3) !important;
    }
    .danger-zone-title {
        font-size: var(--text-sm) !important;
        font-weight: 700 !important;
        margin-bottom: var(--space-1) !important;
    }

    /* ===== Locked — sandbox.html L1494-1503 ===== */
    .locked,
    .locked-feature {
        padding: var(--space-5) var(--space-3) !important;
        border-radius: var(--radius-md) !important;
    }
    .locked-icon {
        font-size: var(--text-3xl) !important;
        margin-bottom: 4px !important;
    }
    .locked-title {
        font-size: var(--text-base) !important;
        font-weight: 700 !important;
        margin-bottom: 2px !important;
    }
    .locked-desc {
        font-size: var(--text-xs) !important;
        margin-bottom: var(--space-3) !important;
    }

    /* ===== FAB — sandbox.html L1476-1489 ===== */
    .help-fab,
    .fab {
        width: 36px !important;
        height: 36px !important;
        border-radius: 50% !important;
        font-size: 20px !important;
        font-weight: 700 !important;
    }

    /* ===== Sticky form action bar (.form-actions) — mobile =====
       Tighter padding (4px vert) + 30px buttons = ~38px total bar height. */
    .form-actions {
        gap: 6px !important;
        padding: 4px var(--space-3) !important;
        padding-bottom: env(safe-area-inset-bottom, 0px) !important;
        border-radius: var(--radius-md) var(--radius-md) 0 0 !important;
    }
    /* Buttons in the form-actions bar use canonical sandbox size (30px min-height). */
    .form-actions .btn,
    .form-actions button.btn,
    .form-actions a.btn {
        min-height: 30px !important;
        padding: 3px 14px !important;
        font-size: var(--text-sm) !important;
    }
    /* Reduce .main-content padding-bottom that reserves space for the bar */
    body.has-footer .main-content,
    .main-content:has(.form-actions) {
        padding-bottom: calc(52px + env(safe-area-inset-bottom, 0)) !important;
    }
    /* When using inner-scroll layout, footer is in-flow — no padding needed */
    body:has(.mobile-static-footer) .main-content {
        padding-bottom: 0 !important;
    }

    /* ===== Top header — mobile cleanup ===== */
    #support-get-btn,
    .mobile-logout-btn {
        display: none !important;
    }
    .menu-toggle {
        padding: 4px !important;
        min-height: 36px !important;
        min-width: 36px !important;
        border-radius: var(--radius-sm) !important;
    }
    .menu-toggle svg {
        width: 22px !important;
        height: 22px !important;
    }

    /* ===== Page title — sandbox.html L121-126 =====
       Sandbox: --text-3xl, 800 weight. The sandbox's mb --space-2 is NOT
       carried over: the title sits in .top-header's centred flex row, and a
       bottom margin there lifts the icon + text ~4px above the hamburger. */
    .page-title {
        font-size: var(--text-3xl) !important;
        font-weight: 800 !important;
        line-height: var(--lh-tight) !important;
        gap: var(--space-2) !important;
        display: flex !important;
        align-items: center !important;
        min-width: 0 !important;
        flex: 1 1 auto !important;
    }
    .page-title-text {
        display: inline-block !important;
        overflow: hidden !important;
        text-overflow: ellipsis !important;
        white-space: nowrap !important;
        min-width: 0 !important;
        line-height: 1.4 !important; /* overflow:hidden clips to the line box — Segoe UI needs ≥1.33em for descenders */
    }
    .page-title-icon {
        width: 24px !important;
        height: 24px !important;
        flex-shrink: 0 !important;
    }

    .top-header {
        padding: var(--space-2) var(--space-3) !important;
        padding-top: calc(var(--space-2) + env(safe-area-inset-top, 0)) !important;
    }
    /* Dashboard only (approved 2026-09-19): with the phone title at 16px the
       header and content padding read as a big empty band around it. Tighter
       top bar and a smaller gap to the first card. Other pages keep the
       values above until each is reviewed. */
    body:has(.mobile-dashboard) .top-header {
        padding-top: calc(var(--space-1) + env(safe-area-inset-top, 0)) !important;
        padding-bottom: var(--space-1) !important;
    }
    body:has(.mobile-dashboard) .content-area {
        padding-top: var(--space-2) !important;
    }
    .header-left {
        gap: var(--space-2) !important;
        flex: 1 1 auto !important;
        min-width: 0 !important;
    }
    .header-right {
        gap: var(--space-2) !important;
    }
}

@media (max-width: 640px) {
    .panels-row {
        flex-direction: column;
    }
    .panel-recent {
        order: 1;
    }
    .panel-upcoming {
        order: 2;
    }

    /* Products submit bar: button on top, text below */
    .products-submit-bar {
        flex-direction: column !important;
        align-items: center !important;
        gap: 6px !important;
    }
    .products-submit-btn {
        order: 1;
        flex: unset !important;
        justify-content: center !important;
    }
    .products-submit-text {
        order: 2;
        flex: unset !important;
        text-align: center !important;
        align-items: center !important;
    }
    .products-submit-spacer {
        display: none !important;
    }
}

@media (max-width: 640px) {
    /* 3 compact stat cards in one row inside season summary */
    .season-summary-content {
        padding-left: 8px !important;
        padding-right: 8px !important;
    }
    .season-summary-content .ov-panel-cols {
        grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
        gap: 5px !important;
        padding: 0 !important;
    }
    .season-summary-content .ov-col,
    .season-summary-content .ov-col:not(:first-child),
    .season-summary-content .ov-col:not(:last-child) {
        padding-left: 0 !important;
        padding-right: 0 !important;
        border-left: none !important;
        min-width: 0;
    }
    .season-summary-content .ov-stat {
        flex-direction: column !important;
        align-items: center !important;
        padding: 6px 7px !important;
        gap: 2px !important;
    }
    .season-summary-content .ov-stat > div {
        text-align: center !important;
    }
    .season-summary-content .ov-stat-label {
        font-size: 9px !important;
        gap: 3px !important;
        white-space: normal !important;
        line-height: 1.2 !important;
    }
    .season-summary-content .ov-dot {
        width: 6px !important;
        height: 6px !important;
    }
    .season-summary-content .ov-stat-value {
        font-size: 18px !important;
    }
    .season-summary-content .ov-stat-sub {
        font-size: 10px !important;
    }
}

/* ============================================================
   BOUNDARY HISTORY + SPLITS (field_detail.html) — Phase 160 Plan 08
   ============================================================ */
.bh-list { display: flex; flex-direction: column; gap: 10px; }

.bh-row {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid #e5e7eb;
    border-radius: 12px;
    background: #fafafa;
}

.bh-row-current { border-color: #86efac; background: #f0fdf4; }

.bh-row-main { min-width: 0; }

.bh-row-name-line {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
}

.bh-set-name { font-weight: 600; font-size: 14px; color: #111827; }

.bh-row-meta { font-size: 12px; color: #6b7280; margin-top: 4px; }

.bh-row-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Inline "i" help affordance pattern -- no longer used by the boundary-
   history panel itself (Promote/Revert were collapsed into a single Restore
   action 2026-08-08 and no longer need one), kept for reuse elsewhere.
   Sized to stay a 24px tap target on mobile while reading as a quiet
   secondary mark, not a button. */
.bh-help {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    /* Sits like an exponent: top-aligned and tucked against the button it
       annotates, pulling back the row's 8px flex gap so it reads as attached
       to that button rather than as a separate action. */
    align-self: flex-start;
    margin: 1px 2px 0 -5px;
    padding: 0;
    border: 1px solid #cbd5e1;
    border-radius: 50%;
    background: #fff;
    color: #64748b;
    font-family: Georgia, "Times New Roman", serif;
    font-style: italic;
    font-weight: 700;
    font-size: 9px;
    line-height: 1;
    cursor: pointer;
}

.bh-help:hover { border-color: #94a3b8; color: #1f2937; }

.bh-help[aria-expanded="true"] {
    background: #1f2937;
    border-color: #1f2937;
    color: #fff;
}

.bh-help-text {
    margin: 0;
    padding: 10px 12px;
    border-left: 3px solid #cbd5e1;
    border-radius: 0 8px 8px 0;
    background: #f8fafc;
    color: #334155;
    font-size: 13px;
    line-height: 1.5;
}

.bh-help-text strong { color: #1f2937; }

/* Compare button reads as pressed while its ghost overlay is on the map */
.bh-row-actions [data-action="bhCompare"].active {
    background: #f97316;
    border-color: #f97316;
    color: #fff;
}

.bh-row-edit {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-end;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed #d1d5db;
}

.bh-edit-field { display: flex; flex-direction: column; gap: 4px; min-width: 140px; }
.bh-edit-field label { font-size: 11px; font-weight: 600; color: #6b7280; }

.bh-edit-input {
    padding: 6px 8px;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    font: inherit;
    font-size: 13px;
}

.bh-edit-actions { display: flex; gap: 8px; margin-left: auto; }

.bh-members {
    margin-top: 8px;
    padding: 8px 10px;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
}

.bh-member-row {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: #374151;
    cursor: pointer;
}

/* Restore confirm dialog's boundary/hazards checkboxes -- rawHtml message
   body, same row layout as .bh-members. */
.bh-restore-checks {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    margin-top: 12px;
}
.bh-restore-checks label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    cursor: pointer;
}
.bh-restore-hint {
    margin: 8px 0 0;
    font-size: 12px;
    color: #6b7280;
}

/* Compare diff line (BOUNDARY-COMPARE) -- transient, only shown while this
   row's ghost overlay is on the map. Orange to match the ghost outline/
   active Compare button (#f97316) so "this text is about the orange thing
   on the map" reads without extra explanation. word-break so the acres/
   obstacle/no-spray counts never force horizontal scroll at 390px. */
.bh-diff-line {
    margin-top: 8px;
    padding: 8px 10px;
    border-left: 3px solid #f97316;
    border-radius: 0 8px 8px 0;
    background: #fff7ed;
    color: #7c2d12;
    font-size: 12px;
    line-height: 1.5;
    word-break: break-word;
}

.bh-diff-line strong { color: #9a3412; }

.bh-diff-line .bh-diff-restore-note {
    display: block;
    margin-top: 4px;
    color: #9a3412;
}

/* Minimal search combobox for the quality/source inline edit fields --
   in-page (not modal-hosted), so a simple anchored dropdown is enough. */
.bh-combo { position: relative; min-width: 160px; }
.bh-combo-input {
    width: 100%;
    box-sizing: border-box;
    padding: 6px 8px;
    border: 1px solid #cbd5e1;
    border-radius: 6px;
    font: inherit;
    font-size: 13px;
}
.bh-combo-list {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 20;
    margin: 2px 0 0;
    padding: 4px;
    list-style: none;
    background: #fff;
    border: 1px solid #cbd5e1;
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.12);
    max-height: 200px;
    overflow-y: auto;
}
.bh-combo-option { padding: 6px 8px; border-radius: 6px; font-size: 13px; cursor: pointer; }
.bh-combo-option:hover, .bh-combo-option.selected { background: #f0fdf4; color: #15803d; }
.bh-combo-empty { padding: 6px 8px; font-size: 12px; color: #9ca3af; }

/* Splits grid — mobile-first: 1 column, 3 on tablet/desktop */
.bh-splits-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}

@media (min-width: 641px) {
    .bh-splits-grid { grid-template-columns: repeat(3, 1fr); }
}

.bh-splits-subheading {
    font-size: 12px;
    font-weight: 600;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin: 16px 0 8px;
}

.bh-splits-grid-retired { margin-top: 4px; }

.bh-split-card {
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    padding: 10px;
    background: #fff;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.bh-split-card-retired {
    opacity: 0.55;
    background: #f3f4f6;
    pointer-events: none;
}

/* Retired cards are pointer-events:none (nothing on them is pushable) --
   the per-card re-apply link (Phase 160 Plan 11) is the one deliberate
   exception, so it needs pointer-events re-enabled on itself specifically. */
.bh-split-card-retired .bh-split-reapply {
    pointer-events: auto;
    width: 100%;
    justify-content: center;
}

.bh-split-thumb {
    width: 100%;
    aspect-ratio: 200 / 140;
    background: #eef2f5;
    border-radius: 6px;
    overflow: hidden;
}

.bh-split-thumb .field-shape-svg { width: 100%; height: 100%; }

.bh-split-name { font-weight: 600; font-size: 13px; color: #111827; }
.bh-split-meta { font-size: 12px; color: #6b7280; }

/* Per-split actions (Phase 160 Plan 10) -- stacked full-width buttons, usable
   one-handed on mobile; the grid itself is already 1-col/3-col responsive. */
.bh-split-actions {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 4px;
}
.bh-split-actions .btn { width: 100%; justify-content: center; }

/* Boundary-set grouping heading above each Splits sub-grid (current set,
   then one per retired set) -- distinct from .bh-splits-subheading (the
   "Previous boundaries" umbrella label) so a greyed retired card always has
   a set name directly above it to explain itself. */
.bh-split-group-heading {
    font-size: 13px;
    font-weight: 600;
    color: #374151;
    margin: 12px 0 8px;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* Which boundary set a retired split came from -- shown ON the card itself
   so it explains itself even scrolled away from its group heading. */
.bh-split-set-tag {
    font-size: 11px;
    color: #6b7280;
    background: #f3f4f6;
    border-radius: 4px;
    padding: 2px 6px;
    width: fit-content;
}

/* Phone tab strip — review sheet option AD04, approved 2026-10-02. The old phone
   rules (max-width:480) hid every label and made the strip a sideways icon
   scroller; an admin only ever has six cells (Overview, Financial, Payroll,
   Pilots, Fleet, Coops — StatsView.dispatch keeps everyone else out), and six
   fit one row at 390px with room to spare. Same frosted card as the approved
   .tab-navigation.icon-tabs-card look in base.html, restated for .stats-tabs
   because that strip has its own markup and its own CSS, copied into BOTH
   stats.html and financial.html (Financial mirrors the strip, every cell but
   the active one linking back to Stats). Living here means one copy for both;
   every declaration is !important because each page's own rules load after
   this file. Superuser counts differ — 8 cells on Stats, 7 on Financial — and
   both trip the :has() switch below. */
@media (max-width: 640px) and (pointer: coarse) {
    .stats-tabs {
        display: flex !important;
        flex-wrap: nowrap !important;
        overflow-x: visible !important;
        gap: 0 !important;
        margin: 2px 0 12px !important;
        padding: 2px 6px !important;
        background: rgba(10, 20, 12, 0.45) !important;
        border: 0 !important;
        border-radius: 14px !important;
        -webkit-backdrop-filter: blur(10px);
        backdrop-filter: blur(10px);
    }
    .stats-tab {
        flex: 1 1 0 !important;
        min-width: 0 !important;
        max-width: none !important;
        height: 42px !important;
        min-height: 0 !important;
        padding: 4px 2px 0 !important;
        flex-direction: column !important;
        justify-content: flex-start !important;
        align-items: center !important;
        gap: 3px !important;
        background: none !important;
        border: 0 !important;
        border-radius: 0 !important;
        box-shadow: none !important;
        color: #b9c6bc !important;
        font-size: 10px !important;
        font-weight: 600 !important;
        line-height: 1.05 !important;
        white-space: nowrap !important;
        overflow: hidden !important;
        text-decoration: none !important;
    }
    .stats-tab-text { display: block !important; }
    .stats-tab svg {
        width: 16px !important; height: 16px !important;
        margin: 0 !important; flex: none; color: #9fb0a4 !important;
    }
    .stats-tab.active {
        color: #ffffff !important;
        font-weight: 700 !important;
        background: linear-gradient(#66E06B, #66E06B) bottom center / 56% 2px no-repeat !important;
    }
    .stats-tab.active svg { color: #66E06B !important; }
    .stats-tabs .admin-only { display: none !important; }

    /* Superuser only: Backups and System make it eight cells, which will not fit
       one row. Sheet option SD07 — two rows of four, icon beside the label, the
       active cell a pill (an underline would float below a short cell). The
       :has() count switch means nothing has to know who is logged in. */
    .stats-tabs:has(.stats-tab:nth-child(7)) {
        flex-wrap: wrap !important;
        padding: 2px 4px !important;
        border-radius: 12px !important;
    }
    .stats-tabs:has(.stats-tab:nth-child(7)) .stats-tab {
        flex: 1 1 25% !important;
        max-width: 25% !important;
        height: 32px !important;
        padding: 0 2px !important;
        flex-direction: row !important;
        justify-content: center !important;
        gap: 5px !important;
        font-size: 10.5px !important;
    }
    .stats-tabs:has(.stats-tab:nth-child(7)) .stats-tab svg { width: 15px !important; height: 15px !important; }
    .stats-tabs:has(.stats-tab:nth-child(7)) .stats-tab.active {
        background: rgba(255, 255, 255, 0.13) !important;
        border-radius: 9px !important;
    }
}


/* =================================================================
   PHONE SIDEBAR DENSITY — Jason, 2026-10-04 (review sheet board SB04)
   "keep the order and the style, shrink the gap between the buttons,
   get rid of the search pages option."

   The gap between the buttons is not a margin — it is the 12px of
   vertical padding the WCAG block above (max-width: 767px) puts on
   every .nav-item, which makes a 48px row around a 24px icon.  At
   7px the row is 38px, so eleven of the twenty-one items are on
   screen at once instead of eight (iPhone 14, 390x844, measured with
   the 47px status-bar inset).  min-height has to come down with it or
   the 44px floor keeps the row at 48.

   Gated on (pointer: coarse) as well as the width, so a narrow
   desktop window keeps the roomy rows and the search box.  The search
   markup and its JS stay in place — only the phone stops drawing it.
================================================================= */
@media (max-width: 640px) and (pointer: coarse) {
    .sidebar-search {
        display: none;
    }

    .sidebar-nav .nav-item {
        min-height: 0;
        padding: 7px 16px;
    }
}
