
@theme {
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: "Roboto Mono", monospace;
}

@font-face {
  font-family: 'Inter';
  src: url('fonts/inter-300.ttf') format('truetype');
  font-weight: 300;
  font-style: normal;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/inter-400.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/inter-500.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/inter-600.ttf') format('truetype');
  font-weight: 600;
  font-style: normal;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/inter-700.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
}
@font-face {
  font-family: 'Roboto Mono';
  src: url('fonts/roboto-mono-400.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
}
@font-face {
  font-family: 'Roboto Mono';
  src: url('fonts/roboto-mono-500.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
}

/* PWA Main Stylesheet */
:root {
  --bg-color: #0A090E;
  --bg-alt: #0A0C10;
  --bg-card: #010101;
  --text-main: #FFFFFF;
  --text-muted: #94A3B8;

  /* Ambient Terracotta/Warm grey accent shadows */
  --ambient-shadow: rgba(0, 0, 0, 0.4);
  --ambient-hover: rgba(255, 255, 255, 0.04);
  --grid-color: rgba(255, 255, 255, 0.015);
  --border-color: #334155;

  /* HSL Color Palette */
  --accent-pink: hsl(345, 80%, 60%);
  --accent-orange: hsl(25, 90%, 55%);
  --accent-mint: hsl(150, 70%, 55%);
  --accent-purple: hsl(270, 80%, 65%);
  --accent-yellow: hsl(45, 95%, 55%);
  --accent-blue: hsl(220, 85%, 60%);
  --accent-teal: hsl(180, 80%, 50%);
  --accent-red: hsl(0, 85%, 60%);
  --accent-indigo: hsl(255, 85%, 65%);

  /* Pipeline specific accent variables */
  --receipts-accent: var(--accent-pink);
  --income-accent: var(--accent-mint);
  --mileage-accent: var(--accent-teal);
  --triage-accent: var(--accent-red);

  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono: 'Roboto Mono', monospace;

  --transition-smooth: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
  --transition-fast: all 0.15s ease;

  /* Viewport virtual offset */
  --view-offset: 100;
  /* in % (0 for Settings, 100 for Ingestion center deck, 200 for Workbook) */
}

/* Light Theme: Nordic Fog and Aurora Glass Specification */
:root[data-theme="light"] {
  --bg-color: #D4DCE8;
  /* Base Workspace Canvas - Misty Steel Blue Tint */
  --bg-alt: #C3CBD9;
  --bg-card: rgba(255, 255, 255, 0.75);
  /* Frosted Structural Containers */
  --text-main: #0F172A;
  /* Primary Text Layer - High contrast deep slate */
  --text-muted: #64748B;
  /* Muted Secondary Labels - Slate grey */

  /* Ambient Lighting Accents */
  --ambient-shadow: rgba(15, 23, 42, 0.04);
  --ambient-hover: rgba(15, 23, 42, 0.05);
  --grid-color: rgba(15, 23, 42, 0.03);
  --border-color: rgba(15, 23, 42, 0.07);

  /* Pipeline Highlight Adaptation: Vibrant modern light mode accents */
  --receipts-accent: #E11D48;
  /* Rose crimson */
  --income-accent: #0D9488;
  /* Mint emerald */
  --mileage-accent: #2563EB;
  /* Ocean blue */
  --triage-accent: #7C3AED;
  /* Royal violet */

  /* Overwrite HSL Accent values inside light mode so legacy inline styles map cleanly */
  --accent-pink: #E11D48;
  --accent-mint: #0D9488;
  --accent-teal: #2563EB;
  --accent-red: #EF4444;
}

/* Base Optimization for mobile PWA */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

body {
  background-color: var(--bg-color);
  color: var(--text-main);
  font-family: var(--font-sans);
  line-height: 1.5;
  overflow: hidden;
  /* Lock scroll strictly to sub-containers to enable virtualization */
  position: relative;
  width: 100vw;
  height: 100vh;
  -webkit-font-smoothing: antialiased;
  touch-action: manipulation;
  /* Disable double-tap zoom */
}

/* Background grid fallback */
body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-image: linear-gradient(var(--grid-color, rgba(255, 255, 255, 0.015)) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-color, rgba(255, 255, 255, 0.015)) 1px, transparent 1px);
  background-size: 40px 40px;
  z-index: 0;
  pointer-events: none;
}

/* Canvas layers */
#node-canvas-bg,
#node-canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}

#node-canvas-bg {
  z-index: 0;
  filter: blur(4px);
  opacity: 0.25;
}

#node-canvas {
  z-index: 1;
  opacity: 0.4;
}

/* Horizontal Viewport Transform Engine (The Wrapper) */
.viewport-wrapper {
  display: flex;
  width: 200vw;
  height: 100vh;
  will-change: transform;
  /* Hardware accelerated transform with elastic snap profile */
  transform: translate3d(calc(var(--view-offset) * -1vw), 0, 0);
  transition: transform 0.35s cubic-bezier(0.25, 1, 0.5, 1);
  position: relative;
  z-index: 10;
}

/* Pane definitions */
.pane-view {
  width: 100vw;
  height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
  padding-bottom: 90px;
  /* Safe padding for bottom navigation tab bar */
  -webkit-overflow-scrolling: touch;
  /* Elastic momentum scroll on iOS */
  position: relative;
}

.pane-container {
  max-width: 1450px;
  margin: 0 auto;
  padding: 0 20px 30px 20px;
  /* 0px top padding to lock header flush to viewport edge */
}

/* Sidebar / Pane headers */
.pane-header {
  margin-bottom: 25px;
}

.pane-title {
  font-size: 1.8rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  display: flex;
  align-items: center;
  gap: 10px;
}

.pane-title i {
  width: 24px;
  height: 24px;
}

.pane-subtitle {
  font-size: 0.95rem;
  color: var(--text-muted);
  margin-top: 4px;
}

/* Bottom Navigation Tab Bar (Ensures standard mobile switching) */
.bottom-nav-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100vw;
  height: 80px;
  /* Scaled up from 75px to 80px (~7% larger) for fat fingers */
  background: rgba(11, 17, 32, 0.85);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  display: flex;
  justify-content: center;
  /* Centered layout with generous physical spacing */
  gap: 72px;
  /* Generous gap to completely eliminate fat-finger overlap. Came down from 85px when the second
     tab became "Jobs Center": at 75px wide the label filled 72 of them, which fits on this phone
     and wraps on one with larger text set. The targets grew instead and the gap paid for it, so
     two 88px targets are still 72px apart. */
  align-items: center;
  z-index: 100;
  padding: 0 20px;
}

.nav-tab-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex: none;
  /* Changed from 1 to protect against overlap in the center */
  min-width: 88px;
  width: auto;
  padding: 0 8px;
  /* A FLOOR ON THE TOUCH TARGET, NOT A CEILING ON THE LABEL. A fixed 88px held "Jobs Center" on
     this phone and hit the wall exactly at the first larger text setting, where it would have
     wrapped to two lines and pushed the bar out of shape. The target keeps its 88px minimum for
     fat fingers and the box grows with the words instead; the gap has the room. */
  height: 100%;
  transition: var(--transition-fast);
  position: relative;
  font-family: var(--font-sans);
}

.nav-tab-btn span {
  font-size: 0.75rem;
  font-weight: 550;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* Active navigation state */
.nav-tab-btn.active {
  color: var(--text-main);
}

/* Premium Dynamic Navigation Orb Container */
.nav-btn-orb {
  width: 38.5px;
  /* Scaled up by 5% from 36.5px to 38.5px */
  height: 38.5px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--transition-smooth);
  margin-bottom: 2px;
}

.nav-btn-orb i,
.nav-btn-orb svg {
  width: 22px !important;
  /* Scaled up by ~7% from 20.5px to 22px */
  height: 22px !important;
  transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275), color 0.3s ease;
  color: var(--text-muted);
  display: block;
}

/* Inactive button hover effects */
.nav-tab-btn:not(.active):hover .nav-btn-orb i,
.nav-tab-btn:not(.active):hover .nav-btn-orb svg {
  color: var(--text-main);
  transform: translateY(-1px);
}

/* Active State: Workbook (Mint/Teal Orb) */
.nav-tab-btn.active#tab-btn-center .nav-btn-orb {
  width: 57px;
  /* Scaled up by ~5% from 54px to 57px */
  height: 57px;
  background: radial-gradient(circle at 30% 30%, var(--accent-teal), #0f766e);
  border-color: var(--accent-teal);
  box-shadow: 0 0 15px rgba(0, 255, 255, 0.4), 0 4px 15px rgba(0, 0, 0, 0.5);
  margin-top: -28px;
  /* Slightly adjusted for taller bar */
}

.nav-tab-btn.active#tab-btn-center .nav-btn-orb i,
.nav-tab-btn.active#tab-btn-center .nav-btn-orb svg {
  color: #0b1120 !important;
  transform: scale(1.1);
}

/* Active State: Settings (Compliance-Blue Orb) */
.nav-tab-btn.active#tab-btn-left .nav-btn-orb {
  width: 57px;
  /* Scaled up by ~5% from 54px to 57px */
  height: 57px;
  background: radial-gradient(circle at 30% 30%, #2F80ED, #1d4ed8);
  border-color: #2F80ED;
  box-shadow: 0 0 15px rgba(47, 128, 237, 0.4), 0 4px 15px rgba(0, 0, 0, 0.5);
  margin-top: -28px;
  /* Slightly adjusted for taller bar */
}

.nav-tab-btn.active#tab-btn-left .nav-btn-orb i,
.nav-tab-btn.active#tab-btn-left .nav-btn-orb svg {
  color: #0b1120 !important;
  transform: scale(1.1);
}

/* Premium Solid/Opaque Cards */
.glass-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color, #334155);
  border-radius: 12px;
  padding: 20px;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: 0 10px 30px -10px var(--ambient-shadow);
  position: relative;
  z-index: 2;
  overflow: hidden;
}

.sticky-header-deck {
  position: sticky;
  top: 0;
  background: var(--bg-color) !important;
  z-index: 10000;
  padding-top: 30px;
  /* Stationary header top breathing room */
  margin-top: 0;
}

/* Ingestion Deck Center Pane styling */
.app-navbar {
  display: flex;
  justify-content: center;
  /* Centered brand logo */
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  padding-bottom: 15px;
  margin-bottom: 25px;
  position: relative;
}

.theme-switch-btn {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%) translateY(-7.5px);
  /* Subtract 7.5px to align with bottom padding shift */
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 6px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--transition-smooth);
}

.theme-switch-btn:hover {
  color: var(--text-main);
  background: var(--ambient-hover);
}

.theme-switch-btn i,
.theme-switch-btn svg {
  width: 18px;
  height: 18px;
}

.status-indicator {
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.04);
  padding: 4px 10px;
  border-radius: 20px;
}

.status-text {
  font-size: 0.65rem;
  font-weight: 600;
  font-family: var(--font-mono);
  color: var(--text-muted);
  letter-spacing: 0.05em;
}

/* Brand Block and Landing Intro Animations */
.brand-block img {
  visibility: hidden;
  /* Start hidden to allow dynamic clone intro animation */
}

/* Relocated Center Content Fade-in container */
#pane-center-content {
  will-change: opacity;
}

#pane-center-content .intro-fade-element {
  opacity: 0;
  transition: opacity 0.4s ease-out;
  will-change: opacity;
}

#pane-center-content.intro-visible .intro-fade-element {
  opacity: 1;
}

#ledger-sections-container {
  margin-top: 24px;
  padding-bottom: 120px;
  /* Safe padding for bottom navigation */
}

#ledger-sections-container::-webkit-scrollbar {
  width: 6px;
}

#ledger-sections-container::-webkit-scrollbar-track {
  background: transparent;
}

#ledger-sections-container::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

#ledger-sections-container::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.2);
}

/* Floating Collapsible Sidebar Dock */
.sidebar-dock {
  position: fixed;
  right: 0;
  top: 0;
  bottom: 0;
  /* Protrudes over bottom section to maximize vertical space since bottom buttons are blurred anyway */
  width: 110px;
  /* Wider menubar! */
  background: rgba(10, 17, 30, 0.65);
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  border-left: 1px solid rgba(255, 255, 255, 0.05);
  box-shadow: -10px 0 35px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Center the icons stack vertically! */
  padding: 15px 0;
  z-index: 990;

  /* Initial off-screen closed state */
  transform: translateX(110px);
  /* Shifted to 110px to match width */
  opacity: 1;
  /* Keep visible so the toggle handle sticks out! */
  will-change: transform;
}

/* Apple spring-in bounce animation */
.sidebar-dock.spring-in {
  animation: spring-in 0.45s cubic-bezier(0.25, 1, 0.5, 1) forwards;
}

/* Anticipatory wind-up and shoot-off close animation */
.sidebar-dock.windup-out {
  animation: windup-out 0.5s cubic-bezier(0.25, 1, 0.5, 1) forwards;
}

/* Sidebar Open State (for manual toggle) */
.sidebar-dock.open {
  transform: translateX(0) !important;
  opacity: 1 !important;
}

/* Settings View lock - completely restrict access,
hide handle,
and force offscreen */
.sidebar-dock.settings-active {
  transform: translateX(110px) !important;
  pointer-events: none !important;
}

.sidebar-dock.settings-active .sidebar-toggle-handle {
  opacity: 0 !important;
  pointer-events: none !important;
}

/* Spring-in bounce keyframes */
@keyframes spring-in {
  0% {
    transform: translateX(110px);
  }

  60% {
    transform: translateX(-12px);
    /* Springs past 0 to the left! */
  }

  80% {
    transform: translateX(3px);
    /* Soft rebound right */
  }

  100% {
    transform: translateX(0);
  }
}

/* Anticipatory windup-out keyframes */
@keyframes windup-out {
  0% {
    transform: translateX(0);
  }

  30% {
    transform: translateX(-15px);
    /* Winding up slightly to the left! */
  }

  100% {
    transform: translateX(110px);
    /* Shooting rapidly offscreen right */
  }
}

/* Floating Swipe Hint Indicator */
.sidebar-swipe-hint {
  position: fixed;
  right: 0px;
  /* Shifted right by 10px (flush with screen edge) */
  bottom: calc(50% + 70px);
  /* Shifted up by 20px */
  z-index: 980;
  background: rgba(10, 17, 30, 0.85);
  backdrop-filter: blur(15px);
  -webkit-backdrop-filter: blur(15px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 20px;
  padding: 6px 12px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.35);
  pointer-events: none;
  opacity: 0;
  transform: scale(0);
  transform-origin: right bottom;
  /* Expand gracefully from above the pull-tab */
  transition: opacity 0.3s cubic-bezier(0.25, 1, 0.5, 1), transform 0.3s cubic-bezier(0.25, 1, 0.5, 1);
}

/* Custom pop-in bounce animation */
.sidebar-swipe-hint.hint-pop {
  animation: hint-lifecycle 2.0s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

.sidebar-swipe-hint.hint-hidden {
  opacity: 0 !important;
  transform: scale(0) !important;
  pointer-events: none;
}

.sidebar-swipe-hint .hint-chevron {
  width: 12px;
  height: 12px;
  stroke: var(--accent-mint);
  animation: hint-arrow-pulse 1.25s infinite ease-in-out;
}

@keyframes hint-lifecycle {
  0% {
    opacity: 0;
    transform: scale(0);
  }

  15% {
    opacity: 1;
    transform: scale(2.0);
    /* Zooms up to 2x size over 0.3s */
  }

  25% {
    opacity: 1;
    transform: scale(1.0);
    /* Settles to normal size over 0.2s */
  }

  75% {
    opacity: 1;
    transform: scale(1.0);
    /* Stays at full size for 1.0 seconds */
  }

  100% {
    opacity: 0;
    transform: scale(0);
    /* Zooms out to disappear over 0.5 seconds */
  }
}

@keyframes hint-arrow-pulse {

  0%,
  100% {
    transform: translateX(0);
    opacity: 0.6;
  }

  50% {
    transform: translateX(-3px);
    opacity: 1;
  }
}

/* Slim Vertical Pull-Tab Handle */
.sidebar-toggle-handle {
  position: absolute;
  left: -22px;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 80px;
  background: rgba(10, 17, 30, 0.65);
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-right: none;
  border-radius: 8px 0 0 8px;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: -5px 0 15px rgba(0, 0, 0, 0.3);
  outline: none;

  /* Start hidden at page load, show on first slide-in */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease-in-out, color 0.3s ease, background 0.3s ease, box-shadow 0.3s ease;
}

/* Make toggle handle visible once sidebar is active */
.sidebar-dock.handle-active .sidebar-toggle-handle {
  opacity: 1;
  pointer-events: auto;
}

.sidebar-toggle-handle:hover {
  color: var(--text-main);
  background: rgba(15, 25, 45, 0.85);
  box-shadow: -5px 0 20px rgba(0, 0, 0, 0.4);
}

.sidebar-toggle-handle i {
  width: 14px;
  height: 14px;
  transition: transform 0.4s ease;
}

.sidebar-items-column {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
  /* Space items out elegantly to fit 95% of vertical space */
  width: 100%;
  height: 95%;
  /* occupy exactly 95% of vertical viewport height */
  overflow: hidden;
  /* Prevent overflow scrolls */
}

.sidebar-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
  position: relative;
  text-align: center;
}

.sidebar-icon-wrapper {
  width: 48px !important;
  /* Force a luxurious large 48px icon wrapper size on all standard viewports */
  height: 48px !important;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent-color);
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.sidebar-icon-wrapper i,
.sidebar-icon-wrapper svg {
  width: 100% !important;
  height: 100% !important;
  max-width: 100% !important;
  max-height: 100% !important;
  filter: drop-shadow(0 2px 8px var(--glow-shadow, rgba(255, 255, 255, 0.05)));
  transition: transform 0.3s ease;
}

.sidebar-label {
  font-size: 0.74rem;
  /* Scaled up text label to beautifully align with larger 48px icons */
  font-weight: 600;
  color: var(--text-muted);
  margin-top: 5px;
  transition: color 0.2s ease;
  letter-spacing: 0.01em;
}

/* Only scale down on extremely short screens to prevent vertical overflow */
@media (max-height: 480px) {
  .sidebar-icon-wrapper {
    width: 32px !important;
    height: 32px !important;
  }

  .sidebar-label {
    display: none;
    /* Hide label entirely on extremely short screens to conserve vertical height */
  }
}

/* Hover,
Active,
and Focus States on Sidebar Item */
.sidebar-item:hover .sidebar-icon-wrapper {
  transform: scale(1.15);
  /* Sleek micro-zoom directly on the transparent icon */
}

.sidebar-item:hover .sidebar-label {
  color: var(--text-main);
}

.sidebar-item:active .sidebar-icon-wrapper {
  transform: scale(0.92);
}




/* THREE SELECTORS WERE EATEN BY THEIR OWN COMMENTS, and one of them cost the phone every
   ingestion panel. Some pass over this file truncated a comment at its first comma and took
   the selector on the next line with it, three times: here, at `.ingest-card:hover` below,
   and at `.deck-layout` inside the desktop media query. The first two only commented out
   dead rules -- nothing in the app carries these classes any more. The third deleted the
   opening brace of a rule INSIDE `@media (min-width: 900px)`, so the closing brace that
   followed closed the MEDIA QUERY instead, and every desktop rule after it -- including
   `.workspace-overlay { top: 50%; left: 50% }` -- applied at every width. On a phone that
   put the panel's top left corner in the middle of the screen with nothing to pull it back,
   which is what Steve photographed on 2026-09-05. Restored from the first commit.
   Symmetrical Ingestion tactile grid (2x4 on mobile, 4x2 on desktop) */
.ingest-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 15px;
  margin-bottom: 20px;
}

/* Subtle, premium outline and shadow matching the website's tech stack item */
.ingest-card:hover,
.ingest-card:focus {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--glow-border, rgba(255, 255, 255, 0.08));
  box-shadow: 0 8px 24px var(--glow-shadow, rgba(255, 255, 255, 0.03));
  transform: translateY(-1.5px);
}

/* Blur background when workspace overlay is active */
body:has(#workspace-overlay.active) #viewport-wrapper {
  filter: blur(10px) brightness(0.7);
  transform: translate3d(calc(var(--view-offset) * -1vw), 0, 0) scale(0.97);
  pointer-events: none;
}

#viewport-wrapper {
  transition: filter 0.4s cubic-bezier(0.25, 1, 0.5, 1), transform 0.4s cubic-bezier(0.25, 1, 0.5, 1);
}

/* ==================== THE CENTERS ==================== */
/*
 * The five full-screen sheets: Spending,
Earning,
Jobs,
the Audit Report and the Evidence Packet.
 * They are created by their own engines and share this one class,
because the colour used to be
 * five identical copies of a string and changing it meant editing five files.
 *
 * WHY IT IS NOT SIMPLY OPAQUE. A sheet that covers the app completely reads as a new page,
and
 * these are not a new page: they are a layer over the books you were just looking at,
and the
 * hint of it underneath is what says so. Steve,
2026-08-29: the layer behind "needs to be BARELY
 * visible",
which is a hint rather than nothing and rather than the readable list it was.
 *
 * TWO THINGS DO THE WORK,
and the second is the one that was missing. The veil was already at 97%
 * on its own,
which sounds like plenty and is not: white text on a dark page still comes through
 * three per cent of the way,
and against a near-black sheet that is enough to read a word list by.
 * The blur is what makes the difference,
because it destroys the SHAPE of the letters rather than
 * their contrast,
and shapes are what reading needs. The dimming underneath it means the brightest
 * thing behind arrives no brighter than the sheet itself.
 *
 * The workspace overlay above this does the same job with the same two tools,
but it hangs them on
 * #viewport-wrapper because it is a floating card with the page visible around its edges. These
 * cover everything,
so the filter can live on the sheet.
 */
/*
 * THE VEIL IS A LAYER OF ITS OWN,
and that is not tidiness.
 *
 * Putting `backdrop-filter` on the sheet itself makes the sheet the containing block for every
 * `position: fixed` thing inside it. The To Top button is one,
and it stopped being locked to the
 * window: it was measured 1,
418 pixels up the page,
which on a forty job list means it is
 * somewhere nobody will ever scroll to. Caught by check_job_charts.mjs on the first run after the
 * change,
which is exactly what that check is for.
 *
 * So the filter lives on a fixed pseudo-element behind the content instead. It covers the viewport,
* takes no pointer,
and being a child of the sheet rather than the sheet means nothing inside is
 * measured against it.
 */
.center-overlay{ background: transparent; }
.center-overlay::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: rgba(7, 10, 16, 0.955);
  backdrop-filter: blur(14px) brightness(0.42) saturate(0.55);
  -webkit-backdrop-filter: blur(14px) brightness(0.42) saturate(0.55);
}

/* A browser without backdrop-filter would otherwise be left with only the veil, which is the
   readable version this was written to fix. It gets an opaque sheet instead: losing the hint is
   the lesser fault. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .center-overlay::before{ background: rgba(7, 10, 16, 1); }
}

:root[data-theme="light"] .center-overlay::before {
  background: rgba(241, 245, 249, 0.955);
  backdrop-filter: blur(14px) brightness(1.45) saturate(0.55);
  -webkit-backdrop-filter: blur(14px) brightness(1.45) saturate(0.55);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root[data-theme="light"] .center-overlay::before{ background: rgba(241, 245, 249, 1); }
}

/* ==================== PREMIUM WORKSPACE OVERLAY PANEL ==================== */
.workspace-overlay {
  position: fixed;
  /* Locked relative to the viewport, stationary */
  top: 60px;
  /* Locked below the status bar / navbar area */
  left: 3%;
  width: 94%;
  /* Wider profile on mobile screen sizes */
  bottom: 12px;
  /* stretched right to the bottom of the screen */
  height: auto;
  max-height: calc(100vh - 85px);
  /* Height locked to viewport dimensions */
  transform: scale(0.05);
  /* Tiny closed state default */
  transform-origin: center center;
  overflow: hidden;
  /* Prevent horizontal stretching/overflow */
  background: rgba(11, 17, 32, 0.9);
  backdrop-filter: blur(25px);
  -webkit-backdrop-filter: blur(25px);
  border: 2px solid rgba(255, 255, 255, 0.08);
  border-top: 4px solid var(--panel-accent, var(--accent-pink));
  border-radius: 14px;
  z-index: 1000;
  /* Stays on top of everything, including bottom nav and sidebar */
  padding: 1.5rem 1.2rem 1.2rem 1.2rem;
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  /* Smooth back-out elastic transition mimicking OS X Genie bounce! */
  transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.4s ease, visibility 0.4s;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.75),
    inset 0 0 40px rgba(255, 255, 255, 0.03),
    0 0 50px var(--panel-accent-glow, rgba(255, 255, 255, 0.15));
}

.workspace-overlay.active {
  transform: scale(1);
  opacity: 1;
  visibility: visible;
}

/* Colored Top Accent Bar */
.overlay-color-bar {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background-color: var(--panel-accent, var(--accent-pink));
  box-shadow: 0 2px 10px var(--panel-accent, var(--accent-pink));
  display: none;
  /* Handled directly by overlay border-top! */
}

.overlay-glow-radial {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  height: 100%;
  background: radial-gradient(circle at top center, var(--panel-accent-glow, rgba(255, 46, 147, 0.12)) 0%, transparent 80%);
  pointer-events: none;
  z-index: 0;
}

.overlay-close-btn {
  position: absolute;
  top: 15px;
  right: 15px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.05);
  color: var(--text-main);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: var(--transition-smooth);
  z-index: 10;
}

.overlay-close-btn:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: var(--panel-accent, var(--accent-pink));
  transform: rotate(90deg);
}

.overlay-close-btn i {
  width: 16px;
  height: 16px;
}

.overlay-content {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  /* Allow scrolling when contents exceed panel max-height */
  overflow-x: hidden;
  scrollbar-width: none;
  /* Hide default Firefox scrollbar */
}

.overlay-content::-webkit-scrollbar {
  display: none;
  /* Hide default webkit scrollbars for premium look */
}

/* Stretch wizard containers and their glass-form-cards to the bottom */
#receipt-wizard-container,
#invoice-wizard-container,
#donation-wizard-container,
#w9-wizard-container,
#coi-wizard-container,
#utility-wizard-container,
#mileage-wizard-container {
  display: flex;
  flex-direction: column;
  flex: 1;
}

#receipt-wizard-container .glass-form-card,
#invoice-wizard-container .glass-form-card,
#donation-wizard-container .glass-form-card,
#w9-wizard-container .glass-form-card,
#coi-wizard-container .glass-form-card,
#utility-wizard-container .glass-form-card,
#mileage-wizard-container .glass-form-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

/* Custom Scrollbar for floating panel */
.overlay-content::-webkit-scrollbar {
  width: 6px;
}

.overlay-content::-webkit-scrollbar-track {
  background: transparent;
}

.overlay-content::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.overlay-content::-webkit-scrollbar-thumb:hover {
  background: var(--panel-accent, rgba(255, 255, 255, 0.2));
}


.overlay-header {
  margin-top: 10px;
  margin-bottom: 25px;
  text-align: center;
}

.overlay-title {
  font-size: 1.8rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.overlay-subtitle {
  font-size: 0.9rem;
  color: var(--text-muted);
  margin-top: 2px;
}

.overlay-layout-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  flex: 1;
}

/* Ingest Drop zone styles */
.drop-zone {
  border: 2px dashed rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  background: rgba(15, 23, 42, 0.4);
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  transition: var(--transition-smooth);
  position: relative;
  min-height: 220px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.drop-zone-idle {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  width: 100% !important;
  gap: 8px;
}

.drop-zone.dragover {
  border-color: var(--panel-accent, var(--accent-pink));
  background: rgba(15, 23, 42, 0.6);
  box-shadow: 0 0 20px var(--panel-accent-glow, rgba(255, 46, 147, 0.12));
}

.drop-icon {
  width: 48px;
  height: 48px;
  color: var(--panel-accent, var(--accent-pink));
  opacity: 0.7;
  margin-bottom: 15px;
  transition: transform 0.3s ease;
}

.drop-zone:hover .drop-icon {
  transform: translateY(-4px) scale(1.05);
  opacity: 1;
}

.drop-text-primary {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-main);
  margin-bottom: 4px;
}

.settings-bulk-dropzone {
  border-color: rgba(224, 122, 95, 0.3) !important;
}

.settings-bulk-dropzone:hover {
  border-color: #e07a5f !important;
  background: rgba(224, 122, 95, 0.05) !important;
}

.settings-bulk-dropzone.dragover {
  border-color: #e07a5f !important;
  background: rgba(224, 122, 95, 0.15) !important;
  box-shadow: 0 0 20px rgba(224, 122, 95, 0.25) !important;
}

.drop-text-secondary {
  font-size: 0.75rem;
  color: var(--text-muted);
}

/* Spinner OCR loading animations */
.ocr-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid rgba(255, 255, 255, 0.05);
  border-top-color: var(--panel-accent, var(--accent-pink));
  border-radius: 50%;
  animation: spinner-ring 0.8s linear infinite;
  margin: 0 auto 15px auto;
  box-shadow: 0 0 10px var(--panel-accent-glow, rgba(255, 46, 147, 0.15));
}

.loading-text-primary {
  font-size: 0.95rem;
  font-weight: 600;
  font-family: var(--font-mono);
  color: var(--text-main);
  margin-bottom: 4px;
}

.loading-text-secondary {
  font-size: 0.75rem;
  color: var(--panel-accent, var(--accent-pink));
  letter-spacing: 0.05em;
  font-weight: 500;
}

/* Form input elements */
.glass-form-card {
  background: rgba(15, 23, 42, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  padding: 20px;
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.form-title {
  font-size: 1.1rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-main);
  margin-bottom: 6px;
}

.form-title i {
  width: 18px;
  height: 18px;
  color: var(--panel-accent, var(--accent-pink));
}

.form-instructions {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-bottom: 20px;
  line-height: 1.4;
}

.input-group {
  display: flex;
  flex-direction: column;
  margin-bottom: 12px;
  text-align: left;
}

.input-group label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 5px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.glass-input {
  background: rgba(11, 17, 32, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 6px;
  padding: 10px 12px;
  font-size: 0.9rem;
  color: var(--text-main);
  outline: none;
  font-family: var(--font-sans);
  transition: var(--transition-fast);
  width: 100%;
}

/* THE HINT MUST NOT LOOK LIKE AN ANSWER. Steve, 2026-08-29, about the My Business card: *"the
   default text (the text that goes away when the user starts entering in their information) is
   too prominent, it looks almost like the real entered text. It needs to be much more dim."*

   There was no rule for this at all, so every placeholder in the app was Chrome's default
   #757575 sitting under real text that is pure white. On a card whose whole job is to show what
   is filled in and what is not, a hint that reads as content is worse than cosmetic: "e.g. Paul
   Marek" looks like an owner name until you go to save it.

   opacity: 1 is not redundant. Firefox applies its own opacity to placeholders on top of the
   colour, so a colour set alone comes out dimmer there than anywhere else. */
.glass-input::placeholder,
.glass-input::-webkit-input-placeholder {
  color: rgba(226, 232, 240, 0.3);
  opacity: 1;
}

.glass-input:focus {
  border-color: var(--panel-accent, var(--accent-pink));
  background: rgba(11, 17, 32, 0.8);
  box-shadow: 0 0 10px var(--panel-accent-glow, rgba(255, 46, 147, 0.1));
}

.glass-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.glass-input-mono {
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}

/* Button UI systems */
.cta-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  font-size: 0.85rem;
  font-weight: 600;
  border-radius: 6px;
  cursor: pointer;
  transition: var(--transition-smooth);
  font-family: var(--font-sans);
  border: none;
  outline: none;
}

.cta-button i {
  width: 15px;
  height: 15px;
}

.primary-btn {
  background-color: var(--panel-accent, var(--accent-teal));
  color: #0b1120;
  box-shadow: 0 4px 15px var(--panel-accent-glow, rgba(0, 255, 255, 0.2));
}

.primary-btn:hover {
  filter: brightness(1.1);
  box-shadow: 0 4px 20px var(--panel-accent-glow, rgba(0, 255, 255, 0.3));
}

.primary-btn:active {
  transform: scale(0.97);
}

/*
 * A BUTTON THAT WILL NOT WORK MUST LOOK LIKE ONE.
 *
 * Steve,
2026-08-19,
on the Confirm Removal button: "if I type 4 characters,
the delete button is
 * dead,
doesn't work,
but there's no indicator of why." It was disabled,
correctly,
and looked
 * exactly the same as a working one because its colours were written inline on the element,
where
 * no stylesheet rule could reach them.
 *
 * `!important` here on purpose. Anything inline loses to it,
so a button that is disabled reads as
 * disabled no matter what colours the markup around it sets.
 */
/* The removal button's red. It was written inline on the element,
which is exactly what stopped
   the disabled rule below from ever showing. */
.danger-btn {
  background: rgba(225, 29, 72, 0.8);
  border-color: #be123c;
  color: #fff;
}

.cta-button:disabled,
.cta-button[disabled] {
  opacity: 0.4 !important;
  filter: grayscale(1) !important;
  cursor: not-allowed !important;
  box-shadow: none !important;
}

.cta-button:disabled:hover,
.cta-button[disabled]:hover {
  filter: grayscale(1) !important;
  transform: none;
}

.secondary-btn {
  background-color: rgba(255, 255, 255, 0.03);
  color: var(--text-main);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.secondary-btn:hover {
  background-color: rgba(255, 255, 255, 0.07);
  border-color: var(--panel-accent, var(--accent-pink));
}

.glass-btn {
  background-color: transparent;
  color: var(--text-muted);
  border: 1px solid rgba(255, 255, 255, 0.05);
}

.glass-btn:hover {
  background-color: rgba(255, 255, 255, 0.02);
  color: var(--text-main);
}

.form-actions {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 10px;
}

.ledger-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
  font-size: 0.85rem;
}

.ledger-table th {
  background: rgba(15, 23, 42, 0.3);
  color: var(--text-muted);
  font-weight: 600;
  padding: 14px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-family: var(--font-sans);
  text-transform: uppercase;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
}

.ledger-table td {
  padding: 14px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.03);
  color: var(--text-main);
  font-family: var(--font-sans);
  font-weight: 600 !important;
}

.ledger-table tbody tr {
  transition: var(--transition-fast);
}

.ledger-table tbody tr:hover {
  background-color: rgba(255, 255, 255, 0.015);
}

.ledger-table tbody tr:nth-child(even) {
  background-color: rgba(255, 255, 255, 0.005);
}

.text-right {
  text-align: right;
}

.text-mono {
  font-family: var(--font-mono) !important;
  letter-spacing: -0.01em;
}

/* Modal Dialog Popups */
.modal-dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(11, 17, 32, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.modal-dialog {
  max-width: 440px;
  width: 100%;
}

.modal-text {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-top: 6px;
  margin-bottom: 20px;
  line-height: 1.4;
}

.export-options {
  background: rgba(11, 17, 32, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 8px;
  padding: 15px;
}

.export-opt-label {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-size: 0.85rem;
}

.export-opt-label input {
  accent-color: var(--accent-teal);
}

.workflow-line-svg.active {
  opacity: 1;
}

#workflow-bezier-path {
  fill: none;
  stroke: var(--panel-accent, var(--accent-pink));
  stroke-width: 2.2;
  stroke-dasharray: 6 4;
  animation: line-dash-flow 15s linear infinite;
  filter: drop-shadow(0 0 4px var(--panel-accent, var(--accent-pink)));
}

/* Settings view Specifics */
.grid-two-col {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

.stat-row {
  display: flex;
  justify-content: space-between;
  font-size: 0.8rem;
  margin-bottom: 6px;
}

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

.stat-value {
  font-weight: 550;
}

.progress-bar-container {
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, 0.04);
  border-radius: 10px;
  overflow: hidden;
  margin-top: 10px;
}

.progress-bar {
  height: 100%;
  background: linear-gradient(to right, var(--accent-indigo), var(--accent-teal));
  border-radius: 10px;
}

/* Color styles */
.accent-indigo {
  color: var(--accent-indigo);
}

.text-green {
  color: var(--accent-mint);
}

.text-mono {
  font-family: var(--font-mono);
}

/* General keyframe animations */
@keyframes pulse-ring {
  0% {
    box-shadow: 0 0 0 0 rgba(0, 229, 255, 0.7);
  }

  70% {
    box-shadow: 0 0 0 8px rgba(0, 229, 255, 0);
  }

  100% {
    box-shadow: 0 0 0 0 rgba(0, 229, 255, 0);
  }
}

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

@keyframes line-dash-flow {
  to {
    stroke-dashoffset: -100px;
  }
}

/* ==================== RESPONSIVE LAYOUT SCALING (TABLET & DESKTOP) ==================== */
@media (min-width: 600px) {

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

@media (min-width: 900px) {
  body {
    background-size: 50px 50px;
  }

  /* Centered layout by default (strictly app-driven, no marketing copy) */
  .deck-layout {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 70vh;
    transition: var(--transition-smooth);
    position: relative;
    width: 100%;
    max-width: 980px;
    /* Slightly wider than the 920px grid to form a perfect outer frame! */
    margin: 0 auto;
    padding: 30px 24px;
    /* More generous framing padding */
  }

  /* Centered overlay floating card on desktop/laptop */
  .workspace-overlay {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0.05);
    /* Centered but tiny initially */
    transform-origin: center center;
    width: 90%;
    max-width: 460px;
    /* Restored back to the original width */
    height: auto;
    min-height: 690px;
    /* Increased height by 70px to completely clear the vertical space */
    max-height: 95vh;
    margin: 0;
  }

  .workspace-overlay.active {
    transform: translate(-50%, -50%) scale(1);
    overflow: hidden !important;
  }

  /* Form and actions scrollable layout in compact overlay */
  .overlay-layout-split {
    grid-template-columns: 1fr !important;
    gap: 20px;
  }

  .drop-zone {
    min-height: 155px;
    /* Compact drop zone */
    padding: 20px;
  }

  .glass-form-card {
    padding: 15px;
  }

  .pane-container {
    padding: 0 30px 50px 30px;
  }

  .sticky-header-deck {
    padding-top: 50px;
  }

  .bottom-nav-bar {
    width: 390px;
    /* Scaled up from 360px to 390px to accommodate larger icons and padding */
    left: 50%;
    transform: translateX(-50%);
    border-radius: 40px;
    bottom: 20px;
    height: 70px;
    /* Scaled up from 65px to 70px (~8% larger) */
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.6);
    display: flex;
    justify-content: center;
    gap: 75px;
    /* Generous physical button gap */
    padding: 0;
  }

  .nav-tab-btn.active .nav-btn-orb {
    margin-top: -24px;
    /* Adjusted for 70px height bar */
  }
}

/* ==================== MOBILE PORTRAIT FINE-TUNING (Width < 900px) ==================== */
@media (max-width: 899px) {
  .pane-container {
    padding: 0 12px 20px 12px !important;
    /* Slim side padding to let cards grow physically wider and larger by another ~2.5% */
  }

  .sticky-header-deck {
    padding-top: 20px;
    margin-left: -12px !important;
    margin-right: -12px !important;
    padding-left: 12px !important;
    padding-right: 12px !important;
    width: 100vw !important;
    background-color: var(--bg-color) !important;
    background-image:
      linear-gradient(var(--grid-color, rgba(255, 255, 255, 0.015)) 1px, transparent 1px),
      linear-gradient(90deg, var(--grid-color, rgba(255, 255, 255, 0.015)) 1px, transparent 1px) !important;
    background-size: 40px 40px, 40px 40px !important;
    background-attachment: fixed !important;
  }

  .workspace-overlay {
    top: 30px !important;
    /* Brought top up to the top of "Senes" word */
    left: 2% !important;
    /* A little bit wider (was left: 3%) */
    width: 96% !important;
    /* A little bit wider (was width: 94%) */
    bottom: 40px !important;
    /* set exactly to 40px as requested */
    height: auto !important;
    max-height: calc(100vh - 75px) !important;
    padding: 1.2rem 1rem 1rem 1rem !important;
    /* adjusted padding to prevent cutoff */
  }

  /* WHAT THE PHONE HAD BEEN RENDERING BY ACCIDENT, kept on purpose. These five rules lived in the
     `@media (min-width: 900px)` block above, and until 2026-09-05 that block was leaking at every
     width because a comment had eaten a selector's opening brace. So the phone has been drawing
     the floating pill nav and the compact panel furniture all along, and Steve has never asked for
     either to change. Repairing the media query would have taken them away with the bug, so they
     are stated here, for the screen they are actually right for: a phone has less room than a
     desktop, not more. The nav width is the one thing that is not a copy -- it was a flat 390px,
     which is exactly the width of the phone it was measured on and wider than the screen on a
     smaller one. */
  .bottom-nav-bar {
    width: min(390px, calc(100vw - 24px));
    left: 50%;
    transform: translateX(-50%);
    border-radius: 40px;
    bottom: 20px;
    height: 70px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.6);
    display: flex;
    justify-content: center;
    gap: 75px;
    padding: 0;
  }

  .nav-tab-btn.active .nav-btn-orb {
    margin-top: -24px;
    /* Adjusted for the 70px pill above, not the 80px full-width bar in the base rule. */
  }

  .drop-zone {
    min-height: 155px;
    padding: 20px;
  }

  .glass-form-card {
    padding: 15px;
  }

  /* ==================== PORTRAIT MOBILE DYNAMIC TABLE SCALING & COLUMN LOOKUPS ==================== */
  #ledger-sections-container td,
  #ledger-sections-container th {
    font-size: 11px !important;
    padding: 6px 8px !important;
  }

  /* Clients Table Mobile Columns */
  #clients-table>thead>tr>th:nth-child(3),
#clients-table tr.main-row td:nth-child(3) {
    display: none !important;
  }

  /* Receipts (Expense) Table Mobile Columns */
  #expense_ledger-table>thead>tr>th:nth-child(1),
#expense_ledger-table tr.main-row td:nth-child(1),
#expense_ledger-table>thead>tr>th:nth-child(6),
#expense_ledger-table tr.main-row td:nth-child(6),
#expense_ledger-table>thead>tr>th:nth-child(7),
#expense_ledger-table tr.main-row td:nth-child(7),
#expense_ledger-table>thead>tr>th:nth-child(8),
#expense_ledger-table tr.main-row td:nth-child(8),
#expense_ledger-table>thead>tr>th:nth-child(9),
#expense_ledger-table tr.main-row td:nth-child(9),
#expense_ledger-table>thead>tr>th:nth-child(10),
#expense_ledger-table tr.main-row td:nth-child(10) {
    display: none !important;
  }

  @media (orientation: landscape) {

    #expense_ledger-table>thead>tr>th:nth-child(6),
#expense_ledger-table tr.main-row td:nth-child(6) {
      display: table-cell !important;
    }

    .sticky-header-deck {
      position: static !important;
    }

    .bottom-nav-bar {
      display: none !important;
    }

    .pane-view {
      padding-bottom: 20px !important;
    }

    #ledger-sections-container {
      padding-bottom: 20px !important;
    }
  }

  /* Invoices (Income) Table Mobile Columns */
  #income_ledger-table>thead>tr>th:nth-child(1),
#income_ledger-table tr.main-row td:nth-child(1),
#income_ledger-table>thead>tr>th:nth-child(2),
#income_ledger-table tr.main-row td:nth-child(2),
#income_ledger-table>thead>tr>th:nth-child(6),
#income_ledger-table tr.main-row td:nth-child(6),
#income_ledger-table>thead>tr>th:nth-child(7),
#income_ledger-table tr.main-row td:nth-child(7),
#income_ledger-table>thead>tr>th:nth-child(8),
#income_ledger-table tr.main-row td:nth-child(8) {
    display: none !important;
  }

  /* Donations Table Mobile Columns */
  #donation_ledger-table>thead>tr>th:nth-child(1),
#donation_ledger-table tr.main-row td:nth-child(1),
#donation_ledger-table>thead>tr>th:nth-child(2),
#donation_ledger-table tr.main-row td:nth-child(2),
#donation_ledger-table>thead>tr>th:nth-child(6),
#donation_ledger-table tr.main-row td:nth-child(6),
#donation_ledger-table>thead>tr>th:nth-child(7),
#donation_ledger-table tr.main-row td:nth-child(7),
#donation_ledger-table>thead>tr>th:nth-child(8),
#donation_ledger-table tr.main-row td:nth-child(8) {
    display: none !important;
  }

  /* Utilities Table Mobile Columns */
  #utility_ledger-table>thead>tr>th:nth-child(4),
#utility_ledger-table tr.main-row td:nth-child(4) {
    display: none !important;
  }

  /* Vendor W9s Table Mobile Columns */
  #vendor_ledger-table>thead>tr>th:nth-child(5),
#vendor_ledger-table tr.main-row td:nth-child(5),
#vendor_ledger-table>thead>tr>th:nth-child(6),
#vendor_ledger-table tr.main-row td:nth-child(6) {
    display: none !important;
  }

  /* Compliance Table Mobile Columns
   *
   * COLUMN 1 KEEPS ITS PLACE ON A PHONE, BECAUSE THE EXPAND ARROW LIVES IN IT.
   *
   * It used to be hidden outright, alongside column 2, to fit the table on a narrow screen. That
   * was correct when the arrow was welded to the Certificate Holder column. The columns were
   * reordered on 2026-09-02 so the OTHER party leads, and the arrow was moved to whichever column
   * is leftmost so a future reorder could not strand it again -- which put it in column 1, the one
   * this rule was hiding. Measured in WebKit at 390x844: the arrow's box was ZERO BY ZERO at the
   * top left corner, because the cell containing it was display:none. There was nothing on the row
   * to tap, and a tap aimed at the arrow landed at 0,0 on the header deck instead.
   *
   * So the cell stays, and only its TEXT goes: font-size 0 collapses the party name and the header
   * label, while the chevron is an svg sized in pixels and is unaffected. The column is left about
   * as wide as the arrow. What a person sees on a phone is unchanged apart from the arrow coming
   * back -- the name in column 1 was already hidden and still is.
   */
  #compliance_ledger-table>thead>tr>th:nth-child(2),
#compliance_ledger-table>tbody>tr.main-row>td:nth-child(2) {
    display: none !important;
  }

  #compliance_ledger-table>thead>tr>th:nth-child(1),
#compliance_ledger-table>tbody>tr.main-row>td:nth-child(1) {
    font-size: 0 !important;
    width: 1.6rem !important;
    min-width: 1.6rem !important;
    padding-left: 0.3rem !important;
    padding-right: 0 !important;
  }

  #compliance_ledger-table>tbody>tr.main-row>td:nth-child(1) .coi-accordion-icon {
    margin-right: 0 !important;
  }
}

/* ==================== DYNAMIC DATABASE LEDGER & SPREADSHEET WORKBOOK STYLES ==================== */
.mono {
  font-family: 'Roboto Mono', monospace !important;
}

.primary-identifier {
  color: #FFFFFF !important;
  font-weight: 600 !important;
}

.secondary-metadata {
  color: #94A3B8 !important;
  font-weight: 600 !important;
}

.tabular-numeric {
  font-family: var(--font-sans) !important;
  font-variant-numeric: tabular-nums !important;
  font-weight: 600 !important;
  letter-spacing: -0.02em !important;
}

.sortable-header {
  cursor: pointer;
  user-select: none;
  transition: color 0.2s ease;
}

.sortable-header:hover {
  color: #FACC15 !important;
}

#ledger-sections-container th {
  text-align: left;
  background: rgba(15, 23, 42, 0.8);
  padding: 10px;
  color: #888;
  text-transform: uppercase;
  font-size: 10px;
  letter-spacing: 0.05em;
}

#ledger-sections-container td {
  padding: 8px 10px;
  border-bottom: 1px solid #1e293b;
  color: #cbd5e1;
  font-size: 13px;
  font-weight: 600 !important;
}

#ledger-sections-container tr.main-row {
  transition: background 0.15s ease;
}

#ledger-sections-container tr.main-row:hover {
  background: rgba(255, 255, 255, 0.05);
}

.grid-section {
  background: rgba(10, 17, 30, 0.65);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 12px;
  padding: 10px 15px;
  /* Tighter padding to reduce empty space above/below */
  margin-top: 16px;
  /* Slightly reduced margin-top */
  border: 1px solid rgba(255, 255, 255, 0.05);
  box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.35);
  overflow-x: auto;
}

/* Narrow the Client ID column */
table#clients-table th:first-child,
table#clients-table td:first-child {
  width: 70px !important;
  max-width: 70px !important;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#ledger-sections-container h2 {
  color: var(--accent-mint);
}

#ledger-sections-container h4 {
  color: #6ee7b7 !important;
  /* Soft premium emerald-mint green */
  opacity: 0.85;
  letter-spacing: 0.05em;
}

#ledger-sections-container button[id^="btn-sec-"] {
  color: var(--accent-mint) !important;
}

img.preview-doc {
  transition: transform 0.2s ease, border-color 0.2s ease;
  background-color: white !important;
}

img.preview-doc:hover {
  transform: scale(1.03);
  border-color: var(--accent-mint) !important;
}

#modal-img {
  background-color: white !important;
}

/* ==================== PORTRAIT MOBILE SPECIFIC BREAKOUT SUBTABLE SCALING ==================== */
@media (max-width: 899px) and (orientation: portrait) {

  /* Hide the 3rd column (Tax / TAX) in nested line-item breakout tables for Receipts and Invoices */
  tr[id^="child-expense_ledger-"] table th:nth-child(3),
  tr[id^="child-expense_ledger-"] table td:nth-child(3),
  tr[id^="child-income_ledger-"] table th:nth-child(3),
  tr[id^="child-income_ledger-"] table td:nth-child(3) {
    display: none !important;
  }
}

/* Dynamic slide-in animation for email input field */
#main-email-input.visible {
  width: 140px !important;
  /* Sleek compact width on mobile screens to prevent wrapping */
  opacity: 1 !important;
  padding-left: 8px !important;
  padding-right: 8px !important;
  border-width: 1px !important;
  margin-right: 8px !important;
  /* Elegant margin spacer only when email input is visible */
  pointer-events: auto !important;
}

@media (min-width: 640px) {
  #main-email-input.visible {
    width: 190px !important;
    /* Full width on larger screens */
  }
}

/* Remove mobile tap highlight and outline halos */
.cursor-pointer,
button,
[onclick] {
  -webkit-tap-highlight-color: transparent !important;
  outline: none !important;
}

/* Mobile-safe non-sticky hover background for folder headers */
@media (hover: hover) {
}


/* Smoked Glass Sidebar backdrop for blur and dim background effect */
.sidebar-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(3, 4, 6, 0.4);
  /* Dim */
  backdrop-filter: blur(8px);
  /* Blur */
  -webkit-backdrop-filter: blur(8px);
  z-index: 985;
  /* Behind sidebar (990) but in front of content and bottom nav */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s ease;
}

.sidebar-backdrop.active {
  opacity: 1;
  pointer-events: auto;
}

/* Premium dark-mode styling for calendar pickers */
input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(1) opacity(0.6);
  cursor: pointer;
  transition: opacity 0.2s ease;
}

input[type="date"]::-webkit-calendar-picker-indicator:hover {
  filter: invert(1) opacity(0.9);
}

/* Center select option dropdown text */
#master-client-select {
  text-align-last: center;
  text-align: center;
}

#master-client-select option {
  text-align: left;
}

/* UI Warning State: Continuous Red Warning Pulse Animation */
@keyframes warning-row-pulse {
  0% {
    background-color: rgba(136, 19, 55, 0.45);
    /* dark matte red */
  }

  50% {
    background-color: rgba(220, 38, 38, 0.7);
    /* brighter warning red */
  }

  100% {
    background-color: rgba(136, 19, 55, 0.45);
  }
}

.warning-pulse-row {
  animation: warning-row-pulse 2s infinite ease-in-out !important;
}

/* The open/closed chevron on a Compliance row. Right when the row is closed, down when it is open.
 * It sits beside the text of the leftmost cell rather than wrapping it, so the cell can still be
 * long-pressed to edit; see coiChevronHtml in ledger.js for why that matters. */
.coi-accordion-icon {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  margin-right: 0.45rem;
  transition: transform 160ms ease;
}

@media (prefers-reduced-motion: reduce) {
  .coi-accordion-icon {
    transition: none;
  }
}

/* ==================== A RECORD THE BOOKKEEPER DECLINED ====================
 *
 * Steve,
2026-08-23. She says once that a purchase is not a business expense,
and BOTH people see
 * the same decision. Nothing is deleted: he really did spend the money,
and it is his record of
 * his own spending.
 *
 * DELIBERATELY NOT RED. Red in this app is reserved for a record that would file WRONGLY if it
 * were committed. A declined record is not broken and nothing is going wrong — a decision has
 * been made about it. Slate,
struck through,
and quiet. If everything is red,
red says nothing.
 */
.record-declined > td {
  opacity: 0.55;
  text-decoration: line-through;
  text-decoration-color: rgba(148, 163, 184, 0.7);
  text-decoration-thickness: 1px;
}
/* The strike belongs to the money and the name,
not to the control you press to undo it. */
.record-declined > td .decline-pill,
.record-declined > td button {
  text-decoration: none;
  opacity: 1;
}

.decline-banner {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  margin-bottom: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 11px;
  line-height: 1.45;
  color: #cbd5e1;
  background: rgba(100, 116, 139, 0.12);
  border: 1px solid rgba(148, 163, 184, 0.32);
}
.decline-banner strong{ color: #e2e8f0; }
.decline-banner .decline-why {
  display: block;
  margin-top: 3px;
  font-style: italic;
  color: #94a3b8;
  /* Her words, and they can be any length. Wrapping beats truncating: the whole point is that he
     can read what she actually said. */
  overflow-wrap: anywhere;
}
.decline-banner button {
  margin-left: auto;
  flex: 0 0 auto;
  padding: 3px 9px;
  border-radius: 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #cbd5e1;
  background: rgba(15, 23, 42, 0.6);
  border: 1px solid rgba(148, 163, 184, 0.4);
  cursor: pointer;
}
.decline-banner button:hover{ color: #fff; border-color: rgba(203, 213, 225, 0.75); }

/* AN APPROVED RECORD SAYS SO IN THE APP'S OWN GREEN. Same shape as the declined banner,
   because it is the same kind of statement; a different color,
   because it is the opposite answer and she should be able to tell them apart across a room. */
.decline-banner--approved {
  color: #a7f3d0;
  background: rgba(16, 185, 129, 0.10);
  border-color: rgba(16, 185, 129, 0.34);
}
.decline-banner--approved strong{ color: #d1fae5; }

/* THE TWO ANSWERS,
side by side,
on a record he sent that nobody has decided about yet.
   They were one small gray box until 2026-09-07 and did not look like the app's own work.
   Approve carries the green this app already uses for money coming in,
Decline the rose it
   already uses for taking something away, so neither needs reading to be recognised. */
.decline-offer {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-bottom: 10px;
}
.decline-offer button {
  padding: 5px 14px;
  border-radius: 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: transparent;
  cursor: pointer;
  transition: color 0.18s ease, background-color 0.18s ease, border-color 0.18s ease;
}
.decline-offer button[data-decide="approve"] {
  color: #10b981;
  border: 1px solid rgba(16, 185, 129, 0.45);
}
.decline-offer button[data-decide="approve"]:hover {
  color: #0f172a;
  background: #10b981;
  border-color: #10b981;
}
.decline-offer button[data-decide="decline"] {
  color: #fb7185;
  border: 1px solid rgba(244, 63, 94, 0.4);
}
.decline-offer button[data-decide="decline"]:hover {
  color: #fff;
  background: #f43f5e;
  border-color: #f43f5e;
}
.decline-offer button:disabled{ opacity: 0.5; cursor: default; }

/* THE WAY BACK,
at the foot of the panel opposite Remove Record. It is quiet on purpose:
   it undoes a decision rather than making one,
and it must not compete with the two above
   or with the removal it sits beside. */
.decision-undo button {
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #94a3b8;
  background: transparent;
  border: 1px solid rgba(148, 163, 184, 0.3);
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.decision-undo button:hover{ color: #e2e8f0; border-color: rgba(203, 213, 225, 0.6); }
.decision-undo button:disabled{ opacity: 0.5; cursor: default; }

/* ==================== HIGH-TECH HUD BOOT-UP LIGHTS SEQUENCING ==================== */

/* 0. Grid Section Wrapper Styles */
.grid-section {
  background: #0d111c;
  border: 1px solid rgba(255, 255, 255, 0.04);
  box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.35);
  border-top: 1.5px solid var(--theme-color) !important;
  transition: border-top-color 0.4s ease, background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

/* 1. Lights Off (Dim/Grayscale Inactive State) */
.grid-section.lights-off {
  border-top-color: #162138 !important;
}

.grid-section.lights-off .header-icon-wrapper {
  background-color: rgba(255, 255, 255, 0.02) !important;
  box-shadow: none !important;
  transition: background-color 0.4s ease, box-shadow 0.4s ease;
}

.grid-section.lights-off .header-icon {
  color: #162138 !important;
  /* Extremely dark blue-slate */
  opacity: 0.25 !important;
  filter: grayscale(100%) drop-shadow(0 0 0 transparent) !important;
  transition: color 0.4s ease, opacity 0.4s ease, filter 0.4s ease;
}

.grid-section.lights-off .header-title {
  color: #162138 !important;
  /* Extremely dark blue-slate */
  opacity: 0.25 !important;
  text-shadow: none !important;
  transition: color 0.4s ease, opacity 0.4s ease, text-shadow 0.4s ease;
}

.grid-section.lights-off [id^="badge-"] {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
  transition: opacity 0.4s ease, visibility 0.4s ease;
}

/* 2. Lights On (Booting / Surge / Flicker Animations) */
.grid-section.lights-on {
  border-top-color: var(--theme-color) !important;
  animation: neon-flicker-border 0.45s ease-in-out forwards;
}

.grid-section.lights-on .header-icon-wrapper {
  background-color: var(--theme-bg) !important;
  box-shadow: 0 0 15px var(--theme-color-glow) !important;
  transition: background-color 0.4s ease, box-shadow 0.4s ease;
}

.grid-section.lights-on .header-icon {
  color: var(--theme-color) !important;
  opacity: 1 !important;
  filter: grayscale(0%) drop-shadow(0 0 6px var(--theme-color-glow)) !important;
  animation: neon-flicker-icon 0.45s ease-in-out forwards;
}

.grid-section.lights-on .header-title {
  color: var(--accent-mint) !important;
  opacity: 1 !important;
  text-shadow: 0 0 10px rgba(16, 185, 129, 0.25) !important;
  animation: neon-flicker-text 0.45s ease-in-out forwards;
}

.grid-section.lights-on [id^="badge-"] {
  visibility: visible !important;
  pointer-events: auto !important;
  opacity: 1 !important;
  filter: grayscale(0%) !important;
  animation: neon-flicker-badge 0.45s ease-in-out forwards;
}

/* 3. Cybernetic Neon Flicker Keyframes */
@keyframes neon-flicker-border {
  0% {
    border-top-color: #162138 !important;
  }

  15% {
    border-top-color: var(--theme-color) !important;
  }

  30% {
    border-top-color: #162138 !important;
  }

  45% {
    border-top-color: var(--theme-color) !important;
  }

  65% {
    border-top-color: #162138 !important;
  }

  100% {
    border-top-color: var(--theme-color) !important;
  }
}

@keyframes neon-flicker-icon {
  0% {
    color: #162138 !important;
    opacity: 0.25;
    filter: grayscale(100%) drop-shadow(0 0 0 transparent);
  }

  15% {
    color: var(--theme-color) !important;
    opacity: 0.9;
    filter: grayscale(0%) drop-shadow(0 0 10px var(--theme-color-glow));
  }

  30% {
    color: #162138 !important;
    opacity: 0.25;
    filter: grayscale(100%) drop-shadow(0 0 0 transparent);
  }

  45% {
    color: var(--theme-color) !important;
    opacity: 1;
    filter: grayscale(0%) drop-shadow(0 0 14px var(--theme-color-glow));
  }

  65% {
    color: #162138 !important;
    opacity: 0.55;
    filter: grayscale(50%) drop-shadow(0 0 2px var(--theme-color-glow));
  }

  100% {
    color: var(--theme-color) !important;
    opacity: 1;
    filter: grayscale(0%) drop-shadow(0 0 8px var(--theme-color-glow));
  }
}

@keyframes neon-flicker-text {
  0% {
    color: #162138 !important;
    opacity: 0.25;
    text-shadow: none;
  }

  20% {
    color: var(--accent-mint) !important;
    opacity: 0.9;
    text-shadow: 0 0 10px rgba(16, 185, 129, 0.4);
  }

  35% {
    color: #162138 !important;
    opacity: 0.25;
    text-shadow: none;
  }

  50% {
    color: var(--accent-mint) !important;
    opacity: 1;
    text-shadow: 0 0 14px rgba(16, 185, 129, 0.6);
  }

  65% {
    color: #162138 !important;
    opacity: 0.55;
    text-shadow: none;
  }

  100% {
    color: var(--accent-mint) !important;
    opacity: 1;
    text-shadow: 0 0 6px rgba(16, 185, 129, 0.2);
  }
}

@keyframes neon-flicker-badge {
  0% {
    opacity: 0.15;
    filter: grayscale(100%);
  }

  15% {
    opacity: 0.9;
    filter: grayscale(0%);
  }

  30% {
    opacity: 0.15;
    filter: grayscale(100%);
  }

  45% {
    opacity: 1;
    filter: grayscale(0%);
  }

  60% {
    opacity: 0.5;
    filter: grayscale(50%);
  }

  100% {
    opacity: 1;
    filter: grayscale(0%);
  }
}




/* ==================== BESPOKE RECEIPT INGESTION WIZARD SYSTEM ==================== */

.receipts-wizard-active .overlay-layout-split {
  display: flex !important;
  flex-direction: column !important;
  max-width: 620px !important;
  margin: 0 auto !important;
  width: 100% !important;
  padding-bottom: 30px;
}

/* Background OCR Processing Pulse bar */
.ocr-pulse-banner {
  background: rgba(255, 42, 95, 0.06);
  border: 1px solid rgba(255, 42, 95, 0.15);
  border-radius: 8px;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-bottom: 20px;
  animation: banner-pulse 2s ease-in-out infinite alternate;
}

.ocr-pulse-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(255, 42, 95, 0.2);
  border-top-color: #FF2A5F;
  border-radius: 50%;
  animation: spinner-ring 0.8s linear infinite;
  flex-shrink: 0;
}

.ocr-pulse-text {
  font-size: 0.78rem;
  color: #ff5e9c;
  font-weight: 550;
  letter-spacing: 0.01em;
}

@keyframes banner-pulse {
  0% {
    box-shadow: 0 0 5px rgba(255, 42, 95, 0.05);
    background: rgba(255, 42, 95, 0.04);
  }

  100% {
    box-shadow: 0 0 15px rgba(255, 42, 95, 0.15);
    background: rgba(255, 42, 95, 0.08);
  }
}

.client-selection-card.selected {
  background: rgba(255, 42, 95, 0.05);
  border-color: #FF2A5F;
  box-shadow: 0 0 18px rgba(255, 42, 95, 0.2);
}

.client-selection-card.selected::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background-color: #FF2A5F;
}

/* Pin Client switch block */
.pin-client-block {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: rgba(15, 23, 42, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.03);
  border-radius: 10px;
  padding: 12px 16px;
  margin-top: 15px;
  margin-bottom: 5px;
  text-align: left;
}

.pin-label-group {
  display: flex;
  align-items: center;
  gap: 10px;
}

.pin-icon-wrap {
  width: 32px;
  height: 32px;
  background: rgba(255, 42, 95, 0.04);
  border: 1px solid rgba(255, 42, 95, 0.08);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #FF2A5F;
  flex-shrink: 0;
}

.pin-icon-wrap i {
  width: 14px;
  height: 14px;
}

.pin-text-group {
  display: flex;
  flex-direction: column;
}

.pin-title-text {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-main);
}

.pin-desc-text {
  font-size: 0.68rem;
  color: var(--text-muted);
}

/* Sleek Toggle Switch slider */
.custom-switch {
  position: relative;
  display: inline-block;
  width: 42px;
  height: 22px;
  flex-shrink: 0;
}

.custom-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.custom-slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.08);
  transition: .3s;
  border-radius: 34px;
  border: 1px solid rgba(255, 255, 255, 0.04);
}

.custom-slider:before {
  position: absolute;
  content: "";
  height: 14px;
  width: 14px;
  left: 3px;
  bottom: 3px;
  background-color: var(--text-muted);
  transition: .3s;
  border-radius: 50%;
}

.custom-switch input:checked+.custom-slider {
  background-color: rgba(255, 42, 95, 0.15);
  border-color: rgba(255, 42, 95, 0.4);
}

.custom-switch input:checked+.custom-slider:before {
  transform: translateX(20px);
  background-color: #FF2A5F;
  box-shadow: 0 0 8px rgba(255, 42, 95, 0.5);
}

/* Custom Ingesting checklist progress */
.ingesting-checklist {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  max-width: 360px;
  margin: 25px auto 10px auto;
  text-align: left;
  background: rgba(15, 23, 42, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.02);
  padding: 18px;
  border-radius: 12px;
}

.checklist-title {
  font-size: 0.65rem;
  font-weight: 750;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  margin-bottom: 6px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  padding-bottom: 6px;
}

.checklist-item {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 0.78rem;
  color: var(--text-muted);
  transition: all 0.3s ease;
}

.checklist-item.active {
  color: #ff5e9c;
  font-weight: 550;
}

.checklist-item.completed {
  color: var(--accent-mint);
}

.checklist-icon {
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.checklist-icon i,
.checklist-icon svg {
  width: 100%;
  height: 100%;
}

.checklist-icon .active-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #FF2A5F;
  box-shadow: 0 0 8px #FF2A5F;
  animation: pulse-dot 1s infinite alternate;
}

@keyframes pulse-dot {
  0% {
    transform: scale(0.8);
    opacity: 0.6;
  }

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

/* Premium Verify Checkbox System */
/* The "proceed anyway" question. Appended to <body>,
so it works over any screen,
and above the
   workspace overlay rather than behind it. Amber on the affirmative button,
never the app's red:
   red is reserved for genuine exposure,
and this is a choice being offered,
not an alarm. The
   safe button is the plain one AND the focused one,
so pressing Return cannot force anything. */
.ask-proceed-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(2, 6, 23, 0.72);
  backdrop-filter: blur(3px);
}
.ask-proceed-box {
  width: 100%;
  max-width: 420px;
  padding: 20px;
  border-radius: 12px;
  background: #0f172a;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 24px 48px -12px rgba(0, 0, 0, 0.7);
}
.ask-proceed-title {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.4;
  color: #e2e8f0;
}
.ask-proceed-consequence {
  margin: 0 0 18px;
  font-size: 12px;
  line-height: 1.55;
  color: #94a3b8;
}
.ask-proceed-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}
.ask-proceed-actions button {
  padding: 8px 14px;
  border-radius: 7px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.10);
  background: rgba(148, 163, 184, 0.10);
  color: #cbd5e1;
}
.ask-proceed-actions button:hover{ background: rgba(148, 163, 184, 0.18); }
.ask-proceed-go {
  border-color: rgba(251, 191, 36, 0.55) !important;
  background: rgba(251, 191, 36, 0.14) !important;
  color: #fde68a !important;
}
.ask-proceed-go:hover{ background: rgba(251, 191, 36, 0.22) !important; }

/* The second affirmative,
for the dialogs that have one. It is the riskier of the two answers,
so
   it is the quiet one: no fill,
no glow,
sitting last. Not red. Red is reserved across this whole
   app for genuine exposure,
and choosing to re-send something deliberately is not exposure,
it is
   a decision somebody is entitled to make once they have read what it does. */
.ask-proceed-alt {
  border-color: rgba(148, 163, 184, 0.35) !important;
  background: transparent !important;
  color: #94a3b8 !important;
}
.ask-proceed-alt:hover {
  background: rgba(148, 163, 184, 0.12) !important;
  color: #cbd5e1 !important;
}

/* "You may already have this one." Amber,
not red. Red is reserved across this whole app for
   genuine exposure,
and a receipt that MIGHT be a second photograph is not exposure,
it is a
   question worth a second look. Sits directly above the verify checkbox,
because that is where
   the person is at the moment they decide. */
.dup-warning:empty{ display: none; }
.dup-warning {
  margin: 12px 0 0;
  padding: 9px 11px;
  border-radius: 7px;
  font-size: 11px;
  line-height: 1.5;
  color: #fde68a;
  background: rgba(251, 191, 36, 0.10);
  border-left: 2px solid rgba(251, 191, 36, 0.55);
}

.premium-verify-block {
  background: rgba(15, 23, 42, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 10px;
  padding: 14px 18px;
  margin-top: 20px;
  margin-bottom: 15px;
  text-align: left;
  transition: border-color 0.3s ease;
}

.premium-verify-block:hover {
  border-color: rgba(255, 42, 95, 0.2);
}

.premium-checkbox-label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
  font-size: 0.8rem;
  color: var(--text-muted);
  line-height: 1.4;
  user-select: none;
}

.premium-checkbox-label input {
  opacity: 0;
  position: absolute;
  width: 0;
  height: 0;
}

.checkbox-custom-orb {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border: 2px solid rgba(255, 255, 255, 0.2);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.25s cubic-bezier(0.25, 0.8, 0.25, 1);
  margin-top: 1px;
}

.premium-checkbox-label:hover .checkbox-custom-orb {
  border-color: #FF2A5F;
  background: rgba(255, 42, 95, 0.05);
}

.premium-checkbox-label input:checked+.checkbox-custom-orb {
  background-color: #FF2A5F;
  border-color: #FF2A5F;
  box-shadow: 0 0 10px rgba(255, 42, 95, 0.35);
}

.checkbox-custom-orb i,
.checkbox-custom-orb svg {
  color: #0b1120;
  width: 14px;
  height: 14px;
  stroke-width: 3.5px;
  display: none;
}

.premium-checkbox-label input:checked+.checkbox-custom-orb i,
.premium-checkbox-label input:checked+.checkbox-custom-orb svg {
  display: block;
}

.premium-checkbox-label input:checked~.checkbox-text-msg {
  color: var(--text-main);
}

/* "Optional" sits under the Project / Job field rather than in its label,
because the label was
   long enough to wrap and a wrapped label pushes its own input down past the one beside it.
   Set to sit QUIETLY. The first version was uppercase and letter-spaced,
which is how every
   label in this app is styled,
so it read as a second heading and pulled the eye harder than the
   field it belongs to.

   It lived inside the donation block and was deleted with it on 2026-08-11,
which left the word
   at browser default size and weight,
shouting. Kept here on its own now,
where nothing it is
   unrelated to can take it out again. */
.field-note {
  margin: 7px 0 0;
  font-size: 10.5px;
  font-weight: 500;
  line-height: 1.45;
  color: #64748b;
}

/* Mapped Line Items list styles */
.mapped-lines-box {
  margin-top: 15px;
  background: rgba(15, 23, 42, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.03);
  border-radius: 10px;
  padding: 15px;
}

.mapped-lines-title {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--text-muted);
  letter-spacing: 0.05em;
  margin-bottom: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.mapped-lines-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.line-item-row {
  display: flex;
  gap: 10px;
  align-items: center;
  background: rgba(11, 17, 32, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.04);
  padding: 8px 12px;
  border-radius: 6px;
}

.line-item-account-input {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  color: inherit;
  background: transparent;
  border: none;
  outline: none;
  flex: 0 0 50px;
  width: 50px;
  text-align: center;
  padding: 2px;
}

.line-item-account-input:focus {
  background: rgba(15, 23, 42, 0.5);
  box-shadow: 0 0 0 1px currentColor;
  border-radius: 4px;
}

.line-item-account {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  color: #FF2A5F;
}

.line-item-desc {
  font-size: 0.78rem;
  color: var(--text-main);
  background: transparent;
  border: none;
  outline: none;
  padding: 2px 4px;
  flex: 1;
  flex-grow: 1;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.line-item-desc:focus {
  background: rgba(15, 23, 42, 0.5);
  box-shadow: 0 0 0 1px rgba(255, 42, 95, 0.2);
  border-radius: 4px;
}

.line-item-amount {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-main);
  text-align: right;
  background: transparent;
  border: none;
  outline: none;
  padding: 2px 4px;
  flex: 0 0 120px;
  width: 120px;
  min-width: 120px;
}

.line-item-amount:focus {
  background: rgba(15, 23, 42, 0.5);
  box-shadow: 0 0 0 1px rgba(255, 42, 95, 0.2);
  border-radius: 4px;
}

/* Math Discrepancy warning banner */
.math-discrepancy-banner {
  background: rgba(239, 68, 68, 0.06);
  border: 1px solid rgba(239, 68, 68, 0.15);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 0.75rem;
  color: #f87171;
  font-weight: 550;
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.math-discrepancy-banner i,
.math-discrepancy-banner svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* Success Card check circle */
.success-card-circle {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  background: rgba(16, 185, 129, 0.08);
  border: 2px solid var(--accent-mint);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent-mint);
  box-shadow: 0 0 20px rgba(16, 185, 129, 0.2);
  margin: 15px auto 20px auto;
  animation: success-pulse 1.8s ease-in-out infinite alternate;
}

.success-card-circle i,
.success-card-circle svg {
  width: 32px;
  height: 32px;
  stroke-width: 2.5px;
}

/* ==================== BESPOKE INVOICE INGESTION WIZARD SYSTEM ==================== */

.invoices-wizard-active .overlay-layout-split {
  display: flex !important;
  flex-direction: column !important;
  max-width: 620px !important;
  margin: 0 auto !important;
  width: 100% !important;
  padding-bottom: 30px;
}

/* Background OCR Processing Pulse bar */
.invoice-pulse-banner {
  background: rgba(16, 185, 129, 0.06);
  border: 1px solid rgba(16, 185, 129, 0.15);
  border-radius: 8px;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-bottom: 20px;
  animation: invoice-banner-pulse 2s ease-in-out infinite alternate;
}

.invoice-pulse-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(16, 185, 129, 0.2);
  border-top-color: #10B981;
  border-radius: 50%;
  animation: spinner-ring 0.8s linear infinite;
  flex-shrink: 0;
}

.invoice-pulse-text {
  font-size: 0.78rem;
  color: #34d399;
  font-weight: 550;
  letter-spacing: 0.01em;
}

@keyframes invoice-banner-pulse {
  0% {
    box-shadow: 0 0 5px rgba(16, 185, 129, 0.05);
    background: rgba(16, 185, 129, 0.04);
  }

  100% {
    box-shadow: 0 0 15px rgba(16, 185, 129, 0.15);
    background: rgba(16, 185, 129, 0.08);
  }
}

/* Client Selection Card for Invoices */
.invoice-client-card.selected {
  background: rgba(16, 185, 129, 0.05);
  border-color: #10B981;
  box-shadow: 0 0 18px rgba(16, 185, 129, 0.2);
}

.invoice-client-card.selected::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background-color: #10B981;
}

/* Toggle Switch slider for Invoices */
.invoice-switch input:checked+.custom-slider {
  background-color: rgba(16, 185, 129, 0.15);
  border-color: rgba(16, 185, 129, 0.4);
}

.invoice-switch input:checked+.custom-slider:before {
  transform: translateX(20px);
  background-color: #10B981;
  box-shadow: 0 0 8px rgba(16, 185, 129, 0.5);
}

.invoice-active-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #10B981;
  box-shadow: 0 0 8px #10B981;
  animation: pulse-dot 1s infinite alternate;
}

/* Premium Verify Checkbox System for Invoices */
.invoice-verify-block:hover {
  border-color: rgba(16, 185, 129, 0.2);
}

.invoice-checkbox-label:hover .checkbox-custom-orb {
  border-color: #10B981;
  background: rgba(16, 185, 129, 0.05);
}

.invoice-checkbox-label input:checked+.checkbox-custom-orb {
  background-color: #10B981;
  border-color: #10B981;
  box-shadow: 0 0 10px rgba(16, 185, 129, 0.4);
}

/* ==================== BESPOKE DONATION INGESTION WIZARD SYSTEM ==================== */

.donations-wizard-active .overlay-layout-split {
  display: flex !important;
  flex-direction: column !important;
  max-width: 620px !important;
  margin: 0 auto !important;
  width: 100% !important;
  padding-bottom: 30px;
}

/* Background OCR Processing Pulse bar */
.donation-pulse-banner {
  background: rgba(168, 85, 247, 0.06);
  border: 1px solid rgba(168, 85, 247, 0.15);
  border-radius: 8px;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-bottom: 20px;
  animation: donation-banner-pulse 2s ease-in-out infinite alternate;
}

.donation-pulse-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(168, 85, 247, 0.2);
  border-top-color: #A855F7;
  border-radius: 50%;
  animation: spinner-ring 0.8s linear infinite;
  flex-shrink: 0;
}

.donation-pulse-text {
  font-size: 0.78rem;
  color: #c084fc;
  font-weight: 550;
  letter-spacing: 0.01em;
}

@keyframes donation-banner-pulse {
  0% {
    box-shadow: 0 0 5px rgba(168, 85, 247, 0.05);
    background: rgba(168, 85, 247, 0.04);
  }

  100% {
    box-shadow: 0 0 15px rgba(168, 85, 247, 0.15);
    background: rgba(168, 85, 247, 0.08);
  }
}

/* Client Selection Card for Donations */
.donation-client-card.selected {
  background: rgba(168, 85, 247, 0.05);
  border-color: #A855F7;
  box-shadow: 0 0 18px rgba(168, 85, 247, 0.2);
}

.donation-client-card.selected::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background-color: #A855F7;
}

/* Toggle Switch slider for Donations */
.donation-switch input:checked+.custom-slider {
  background-color: rgba(168, 85, 247, 0.15);
  border-color: rgba(168, 85, 247, 0.4);
}

.donation-switch input:checked+.custom-slider:before {
  transform: translateX(20px);
  background-color: #A855F7;
  box-shadow: 0 0 8px rgba(168, 85, 247, 0.5);
}

.donation-active-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #A855F7;
  box-shadow: 0 0 8px #A855F7;
  animation: pulse-dot 1s infinite alternate;
}

/* Premium Verify Checkbox System for Donations */
.donation-verify-block:hover {
  border-color: rgba(168, 85, 247, 0.2);
}

.donation-checkbox-label:hover .checkbox-custom-orb {
  border-color: #A855F7;
  background: rgba(168, 85, 247, 0.05);
}

.donation-checkbox-label input:checked+.checkbox-custom-orb {
  background-color: #A855F7;
  border-color: #A855F7;
  box-shadow: 0 0 10px rgba(168, 85, 247, 0.4);
}

/* ==================== BESPOKE W-9 ONBOARDING WIZARD SYSTEM ==================== */

.w9s-wizard-active .overlay-layout-split {
  display: flex !important;
  flex-direction: column !important;
  max-width: 620px !important;
  margin: 0 auto !important;
  width: 100% !important;
  padding-bottom: 30px;
}

/* Background OCR Processing Pulse bar */
.w9-pulse-banner {
  background: rgba(247, 223, 30, 0.06);
  border: 1px solid rgba(247, 223, 30, 0.15);
  border-radius: 8px;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-bottom: 20px;
  animation: w9-banner-pulse 2s ease-in-out infinite alternate;
}

.w9-pulse-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(247, 223, 30, 0.2);
  border-top-color: #F7DF1E;
  border-radius: 50%;
  animation: spinner-ring 0.8s linear infinite;
  flex-shrink: 0;
}

.w9-pulse-text {
  font-size: 0.78rem;
  color: #fef08a;
  font-weight: 550;
  letter-spacing: 0.01em;
}

@keyframes w9-banner-pulse {
  0% {
    box-shadow: 0 0 5px rgba(247, 223, 30, 0.05);
    background: rgba(247, 223, 30, 0.04);
  }

  100% {
    box-shadow: 0 0 15px rgba(247, 223, 30, 0.15);
    background: rgba(247, 223, 30, 0.08);
  }
}

/* Client Selection Card for W9 */
.w9-client-card.selected {
  background: rgba(247, 223, 30, 0.05);
  border-color: #F7DF1E;
  box-shadow: 0 0 18px rgba(247, 223, 30, 0.2);
}

.w9-client-card.selected::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background-color: #F7DF1E;
}

/* Toggle Switch slider for W9 */
.w9-switch input:checked+.custom-slider {
  background-color: rgba(247, 223, 30, 0.15);
  border-color: rgba(247, 223, 30, 0.4);
}

.w9-switch input:checked+.custom-slider:before {
  transform: translateX(20px);
  background-color: #F7DF1E;
  box-shadow: 0 0 8px rgba(247, 223, 30, 0.5);
}

.w9-active-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #F7DF1E;
  box-shadow: 0 0 8px #F7DF1E;
  animation: pulse-dot 1s infinite alternate;
}

/* Premium Verify Checkbox System for W9 */
.w9-verify-block:hover {
  border-color: rgba(247, 223, 30, 0.2);
}

.w9-checkbox-label:hover .checkbox-custom-orb {
  border-color: #F7DF1E;
  background: rgba(247, 223, 30, 0.05);
}

.w9-checkbox-label input:checked+.checkbox-custom-orb {
  background-color: #F7DF1E;
  border-color: #F7DF1E;
  box-shadow: 0 0 10px rgba(247, 223, 30, 0.4);
}

/* ==================== BESPOKE COI COMPLIANCE WIZARD SYSTEM ==================== */

.cois-wizard-active .overlay-layout-split {
  display: flex !important;
  flex-direction: column !important;
  max-width: 620px !important;
  margin: 0 auto !important;
  width: 100% !important;
  padding-bottom: 30px;
}

/* Background OCR Processing Pulse bar */
.coi-pulse-banner {
  background: rgba(47, 128, 237, 0.06);
  border: 1px solid rgba(47, 128, 237, 0.15);
  border-radius: 8px;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-bottom: 20px;
  animation: coi-banner-pulse 2s ease-in-out infinite alternate;
}

.coi-pulse-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(47, 128, 237, 0.2);
  border-top-color: #2F80ED;
  border-radius: 50%;
  animation: spinner-ring 0.8s linear infinite;
  flex-shrink: 0;
}

.coi-pulse-text {
  font-size: 0.78rem;
  color: #79a6fe;
  font-weight: 550;
  letter-spacing: 0.01em;
}

@keyframes coi-banner-pulse {
  0% {
    box-shadow: 0 0 5px rgba(47, 128, 237, 0.05);
    background: rgba(47, 128, 237, 0.04);
  }

  100% {
    box-shadow: 0 0 15px rgba(47, 128, 237, 0.15);
    background: rgba(47, 128, 237, 0.08);
  }
}

/* Client Selection Card for COI */
.coi-client-card.selected {
  background: rgba(47, 128, 237, 0.05);
  border-color: #2F80ED;
  box-shadow: 0 0 18px rgba(47, 128, 237, 0.2);
}

.coi-client-card.selected::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background-color: #2F80ED;
}

/* Toggle Switch slider for COI */
.coi-switch input:checked+.custom-slider {
  background-color: rgba(47, 128, 237, 0.15);
  border-color: rgba(47, 128, 237, 0.4);
}

.coi-switch input:checked+.custom-slider:before {
  transform: translateX(20px);
  background-color: #2F80ED;
  box-shadow: 0 0 8px rgba(47, 128, 237, 0.5);
}

.coi-active-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #2F80ED;
  box-shadow: 0 0 8px #2F80ED;
  animation: pulse-dot 1s infinite alternate;
}

/* Premium Verify Checkbox System for COI */
.coi-verify-block:hover {
  border-color: rgba(47, 128, 237, 0.2);
}

.coi-checkbox-label:hover .checkbox-custom-orb {
  border-color: #2F80ED;
  background: rgba(47, 128, 237, 0.05);
}

.coi-checkbox-label input:checked+.checkbox-custom-orb {
  background-color: #2F80ED;
  border-color: #2F80ED;
  box-shadow: 0 0 10px rgba(47, 128, 237, 0.4);
}

/* ==================== BESPOKE UTILITIES INGESTION WIZARD SYSTEM ==================== */

.utilities-wizard-active .overlay-layout-split {
  display: flex !important;
  flex-direction: column !important;
  max-width: 620px !important;
  margin: 0 auto !important;
  width: 100% !important;
  padding-bottom: 30px;
}

/* Background OCR Processing Pulse bar */
.utility-pulse-banner {
  background: rgba(249, 115, 22, 0.06);
  border: 1px solid rgba(249, 115, 22, 0.15);
  border-radius: 8px;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-bottom: 20px;
  animation: utility-banner-pulse 2s ease-in-out infinite alternate;
}

.utility-pulse-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(249, 115, 22, 0.2);
  border-top-color: #F97316;
  border-radius: 50%;
  animation: spinner-ring 0.8s linear infinite;
  flex-shrink: 0;
}

.utility-pulse-text {
  font-size: 0.78rem;
  color: #fdba74;
  font-weight: 550;
  letter-spacing: 0.01em;
}

@keyframes utility-banner-pulse {
  0% {
    box-shadow: 0 0 5px rgba(249, 115, 22, 0.05);
    background: rgba(249, 115, 22, 0.04);
  }

  100% {
    box-shadow: 0 0 15px rgba(249, 115, 22, 0.15);
    background: rgba(249, 115, 22, 0.08);
  }
}

/* Client Selection Card for Utility */
.utility-client-card.selected {
  background: rgba(249, 115, 22, 0.05);
  border-color: #F97316;
  box-shadow: 0 0 18px rgba(249, 115, 22, 0.2);
}

.utility-client-card.selected::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background-color: #F97316;
}

/* Toggle Switch slider for Utility */
.utility-switch input:checked+.custom-slider {
  background-color: rgba(249, 115, 22, 0.15);
  border-color: rgba(249, 115, 22, 0.4);
}

.utility-switch input:checked+.custom-slider:before {
  transform: translateX(20px);
  background-color: #F97316;
  box-shadow: 0 0 8px rgba(249, 115, 22, 0.5);
}

.utility-active-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #F97316;
  box-shadow: 0 0 8px #F97316;
  animation: pulse-dot 1s infinite alternate;
}

/* Premium Verify Checkbox System for Utility */
.utility-verify-block:hover {
  border-color: rgba(249, 115, 22, 0.2);
}

.utility-checkbox-label:hover .checkbox-custom-orb {
  border-color: #F97316;
  background: rgba(249, 115, 22, 0.05);
}

.utility-checkbox-label input:checked+.checkbox-custom-orb {
  background-color: #F97316;
  border-color: #F97316;
  box-shadow: 0 0 10px rgba(249, 115, 22, 0.4);
}

/* ==================== BESPOKE MILEAGE INGESTION WIZARD SYSTEM ==================== */

.mileage-wizard-active .overlay-layout-split {
  display: flex !important;
  flex-direction: column !important;
  max-width: 620px !important;
  margin: 0 auto !important;
  width: 100% !important;
  padding-bottom: 30px;
}

@keyframes mileage-banner-pulse {
  0% {
    box-shadow: 0 0 5px rgba(0, 245, 212, 0.05);
    background: rgba(0, 245, 212, 0.04);
  }

  100% {
    box-shadow: 0 0 15px rgba(0, 245, 212, 0.15);
    background: rgba(0, 245, 212, 0.08);
  }
}

/* Client Selection Card for Mileage */
.mileage-client-card.selected {
  background: rgba(0, 245, 212, 0.05);
  border-color: #00F5D4;
  box-shadow: 0 0 18px rgba(0, 245, 212, 0.2);
}

.mileage-client-card.selected::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background-color: #00F5D4;
}

/* Toggle Switch slider for Mileage */
.mileage-switch input:checked+.custom-slider {
  background-color: rgba(0, 245, 212, 0.15);
  border-color: rgba(0, 245, 212, 0.4);
}

.mileage-switch input:checked+.custom-slider:before {
  transform: translateX(20px);
  background-color: #00F5D4;
  box-shadow: 0 0 8px rgba(0, 245, 212, 0.5);
}

/* Premium Verify Checkbox System for Mileage */
.mileage-verify-block:hover {
  border-color: rgba(0, 245, 212, 0.2);
}

.mileage-checkbox-label:hover .checkbox-custom-orb {
  border-color: #00F5D4;
  background: rgba(0, 245, 212, 0.05);
}

.mileage-checkbox-label input:checked+.checkbox-custom-orb {
  background-color: #00F5D4;
  border-color: #00F5D4;
  box-shadow: 0 0 10px rgba(0, 245, 212, 0.4);
}

/* Landscape-Only Table Inline Editing Visual Cues */
@media (orientation: landscape) {
  td.editable-cell {
    -webkit-touch-callout: none !important;
    -webkit-user-select: none !important;
    user-select: none !important;
  }

  td.editable-cell[contenteditable="true"] {
    -webkit-user-select: text !important;
    user-select: text !important;
    cursor: text;
    transition: background-color 0.2s ease, border-bottom 0.2s ease;
    outline: none !important;
  }

  td.editable-cell[contenteditable="true"]:hover {
    background-color: rgba(255, 255, 255, 0.04) !important;
  }

  td.editable-cell[contenteditable="true"]:focus {
    background-color: rgba(255, 255, 255, 0.08) !important;
    border-bottom: 2px solid var(--accent-mint, #10b981) !important;
  }
}

/* Suggestions for a cell you are editing in place. Fixed rather than absolute: these cells sit
   inside panes that scroll and clip,
and an absolutely positioned list gets cut off by the first
   ancestor with overflow hidden. */
.cell-suggest {
  position: fixed;
  z-index: 10050;
  max-height: 200px;
  overflow-y: auto;
  background: rgba(15, 23, 42, 0.96);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.6);
}

.cell-suggest-item {
  padding: 7px 12px;
  font-size: 12px;
  color: #cbd5e1;
  cursor: pointer;
  white-space: nowrap;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

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

/* A question,
not an option. Amber so it does not read as one more name in the list. */
.cell-suggest-ask {
  padding: 7px 12px;
  font-size: 12px;
  font-weight: 700;
  color: #fde68a;
  background: rgba(251, 191, 36, 0.1);
  border-bottom: 1px solid rgba(251, 191, 36, 0.35);
  cursor: pointer;
  white-space: nowrap;
}

.cell-suggest-ask:hover {
  background: rgba(251, 191, 36, 0.2);
}

.cell-suggest-item:hover,
.cell-suggest-item.is-active {
  background: rgba(56, 189, 248, 0.16);
  color: #e2e8f0;
}

/* Empty fields in a record's detail panel.
   Hidden by default because a wall of blank rows is noise — but a hidden field is also an
   uneditable one,
so `.show-empty-fields` on the panel brings them all back. A CLASS rather than
   an inline style on purpose: an inline display:none cannot be overridden by a stylesheet,
and
   the toggle would have nothing to fight with. */
.detail-row-empty {
  display: none;
}

.show-empty-fields .detail-row-empty {
  display: table-row;
}

/* Deliberately quiet. It is a way back to something,
not a thing to do.

   THE MARGINS BELONG TO A GROUPING ARGUMENT,
not to taste. This pill controls the details table
   ABOVE it,
and it used to sit 13px from that table and 32px from the Line Items heading below --
   nearer to the thing it has nothing to do with. Steve,
2026-08-26,
seeing the effect rather than
   the cause: "The space between Details and Line items appears larger because it's measured from
   the button. Can we,
instead,
raise the Line Items higher,
so that the space between the tables
   looks even?"

   So it hugs its own table,
and the negative bottom margin cancels the extra 16px the next section
   carries,
bringing that section up. Negative here rather than removed there because the pill is
   the thing that is sometimes absent: a record with no empty fields has no pill,
and the section
   below must keep its normal spacing. The two gaps cannot be made identical -- the pill occupies
   23px that the other gap does not -- and tools/check_party_contacts.mjs asserts exactly that
   weaker,
true thing: the difference is no more than the pill's own height. */
.empty-fields-toggle {
  display: block;
  margin: 2px 0 -16px auto;
  padding: 3px 9px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #64748b;
  background: rgba(148, 163, 184, 0.06);
  border: 1px solid rgba(148, 163, 184, 0.2);
  border-radius: 6px;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

/* On the phone the details table is the LEFT column of a two column row,
so the control that
   reveals more of its fields belongs directly under that column. Floated right it sits under the
   photograph instead,
pointing at nothing. The desktop panel is a single full width column,
where
   right aligned reads correctly,
so it keeps the default above. */
.empty-fields-toggle--left {
  margin-left: 0;
  margin-right: auto;
  /* And room underneath. On the phone the next thing is the Line Items heading, and with no
     bottom margin the two read as one block. 16px matches the gap between the other sections.
     This overrides the desktop's negative bottom margin above, which exists to solve a spacing
     problem the phone's single column layout does not have. */
  margin-bottom: 16px;
}

/* THE NOTES BOX — the one long-form field in a record's details.
   Steve,
2026-08-16: "in case the user requires any details that aren't provided for with the
   standard ingestion fields ... make it a multi line text box so a user can click into it if they
   need."

   pre-wrap is the whole feature: without it every line break a person typed collapses into a
   space the next time the panel is drawn,
so the box would accept a second line and lose it.
   min-height gives an empty one something to aim at,
since a value-less cell is otherwise nought
   pixels tall,
which is what made the hidden empty fields unclickable in the first place. */
.detail-notes-cell {
  white-space: pre-wrap;
  word-break: break-word;
  min-height: 2.75em;
  line-height: 1.45;
  vertical-align: top;
}

.detail-notes-cell:focus {
  outline: 1px solid rgba(59, 130, 246, 0.7);
  outline-offset: -1px;
  background: rgba(15, 19, 28, 0.85);
}

.empty-fields-toggle:hover {
  color: #cbd5e1;
  border-color: rgba(148, 163, 184, 0.45);
}

/* Rapid Green Flash Keyframes & Class */
@keyframes rapid-green-flash {

  0%,
  100% {
    background-color: transparent;
  }

  50% {
    background-color: rgba(16, 185, 129, 0.35);
  }
}

.rapid-flash-success {
  animation: rapid-green-flash 0.2s ease-in-out infinite;
}

/* Rapid Red Flash Keyframes & Class (Alarm-shade of Red) */
@keyframes rapid-red-flash {

  0%,
  100% {
    background-color: transparent;
  }

  50% {
    background-color: rgba(239, 68, 68, 0.45);
  }
}

.rapid-flash-failure {
  animation: rapid-red-flash 0.2s ease-in-out infinite;
}

/* ==================== COMMON LOCATIONS SYSTEM STYLES ==================== */
.common-loc-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
  min-height: 20px;
  justify-content: flex-end;
  /* Align to the right */
}

.loc-pill-btn {
  background: rgba(0, 245, 212, 0.05);
  border: 1px solid rgba(0, 245, 212, 0.15);
  color: #00F5D4;
  border-radius: 12px;
  padding: 4px 10px;
  font-size: 0.72rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  user-select: none;
}

.loc-pill-btn:hover {
  background: rgba(0, 245, 212, 0.15);
  border-color: rgba(0, 245, 212, 0.35);
  transform: translateY(-1px);
}

.loc-pill-btn:active {
  transform: translateY(0) scale(0.95);
}

.loc-pill-btn.active {
  background: rgba(0, 245, 212, 0.22) !important;
  border-color: #00F5D4 !important;
  color: white !important;
  box-shadow: 0 0 10px rgba(0, 245, 212, 0.3);
}

/* Multi-destination wizard stops */
.dest-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.dest-input-wrap {
  flex: 1;
  min-width: 0;
}

.btn-dest-action {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: white;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-top: auto;
  /* aligns nicely with the bottom-aligned input */
  margin-bottom: 2px;
}

.btn-dest-action:hover {
  background: rgba(0, 245, 212, 0.1);
  border-color: #00F5D4;
  color: #00F5D4;
}

.btn-dest-action.btn-dest-remove:hover {
  background: rgba(255, 42, 95, 0.1);
  border-color: #ff2a5f;
  color: #ff2a5f;
}

.settings-loc-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-main);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.settings-loc-delete {
  background: transparent;
  border: none;
  color: #ef4444;
  opacity: 0.7;
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.settings-loc-delete:hover {
  opacity: 1;
  background: rgba(239, 68, 68, 0.1);
  transform: scale(1.1);
}

/* Auto-detect Location Suggestion Banner */
.suggest-location-banner {
  background: rgba(0, 245, 212, 0.03);
  border: 1px dashed rgba(0, 245, 212, 0.2);
  border-radius: 8px;
  padding: 15px;
  margin: 15px 0;
  text-align: left;
  animation: fadeIn 0.3s ease-out;
}

.suggest-banner-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.82rem;
  font-weight: 600;
  color: #00F5D4;
  margin-bottom: 4px;
}

.suggest-banner-desc {
  font-size: 0.72rem;
  color: var(--text-muted);
  line-height: 1.3;
  margin-bottom: 10px;
}

.suggest-banner-inputs {
  display: flex;
  gap: 8px;
  align-items: center;
}

.suggest-banner-inputs .glass-input {
  padding: 6px 10px;
  font-size: 0.8rem;
}

/* ==========================================================================
   Nordic Fog & Aurora Glass Light Mode Theme Overrides
   ========================================================================== */
:root[data-theme="light"] {
  --border-glass: rgba(15, 23, 42, 0.08);
  --bg-input: rgba(255, 255, 255, 0.85);
}

:root[data-theme="light"] body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-image:
    radial-gradient(circle at 20% 35%, rgba(99, 102, 241, 0.15) 0%, transparent 50%),
    radial-gradient(circle at 80% 80%, rgba(13, 148, 136, 0.12) 0%, transparent 50%),
    radial-gradient(circle at 50% 40%, rgba(225, 29, 72, 0.08) 0%, transparent 60%),
    radial-gradient(circle at 85% 35%, rgba(56, 189, 248, 0.15) 0%, transparent 45%),
    linear-gradient(var(--grid-color) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
  background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%, 40px 40px, 40px 40px;
  z-index: 0;
  pointer-events: none;
  opacity: 1;
}

/* Light mode specific scrollbars */
:root[data-theme="light"] #ledger-sections-container::-webkit-scrollbar-thumb {
  background: rgba(15, 23, 42, 0.1);
}

:root[data-theme="light"] #ledger-sections-container::-webkit-scrollbar-thumb:hover {
  background: rgba(15, 23, 42, 0.2);
}

/* Sticky Header Deck adaptation: Frosted glass on desktop, solid background on mobile to prevent text leakage */
@media (min-width: 900px) {
  :root[data-theme="light"] .sticky-header-deck {
    background: rgba(255, 255, 255, 0.25) !important;
    backdrop-filter: blur(20px) saturate(150%) !important;
    -webkit-backdrop-filter: blur(20px) saturate(150%) !important;
    border: none !important;
    box-shadow: none !important;
  }
}

@media (max-width: 899px) {
  :root[data-theme="light"] .sticky-header-deck {
    margin-left: -12px !important;
    margin-right: -12px !important;
    padding-left: 12px !important;
    padding-right: 12px !important;
    width: 100vw !important;
    background-color: var(--bg-color) !important;
    background-image:
      radial-gradient(circle at 20% 35%, rgba(99, 102, 241, 0.15) 0%, transparent 50%),
      radial-gradient(circle at 80% 80%, rgba(13, 148, 136, 0.12) 0%, transparent 50%),
      radial-gradient(circle at 50% 40%, rgba(225, 29, 72, 0.08) 0%, transparent 60%),
      radial-gradient(circle at 85% 35%, rgba(56, 189, 248, 0.15) 0%, transparent 45%),
      linear-gradient(var(--grid-color) 1px, transparent 1px),
      linear-gradient(90deg, var(--grid-color) 1px, transparent 1px) !important;
    background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%, 40px 40px, 40px 40px !important;
    background-attachment: fixed !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border: none !important;
    box-shadow: none !important;
  }
}

/* Client Select & Date Pill inputs */
:root[data-theme="light"] #master-client-select {
  background-color: #ffffff;
  color: #0f172a;
  border-color: rgba(15, 23, 42, 0.12);
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.03);
}

:root[data-theme="light"] #date-range-btn {
  background-color: #ffffff;
  color: #0f172a;
  border-color: rgba(15, 23, 42, 0.12);
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.03);
}

/* Date range modal popover */
:root[data-theme="light"] #date-range-modal,
:root[data-theme="light"] #global-date-range-modal {
  background-color: #ffffff;
  border-color: rgba(15, 23, 42, 0.15);
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.08);
}

:root[data-theme="light"] #date-range-modal h3,
:root[data-theme="light"] #global-date-range-modal h3 {
  color: #0f172a;
}

:root[data-theme="light"] #date-range-modal input[type="date"],
:root[data-theme="light"] #global-date-range-modal input[type="date"] {
  background-color: #f8fafc;
  color: #0f172a;
  border-color: rgba(15, 23, 42, 0.1);
}

/* App Navbar borders */
:root[data-theme="light"] .app-navbar {
  border-bottom-color: rgba(15, 23, 42, 0.06);
}

/* Glass Inputs in Settings Forms */
:root[data-theme="light"] .glass-input {
  background: #ffffff;
  border-color: rgba(15, 23, 42, 0.12);
  color: #0f172a;
}

/* Same decision on white, where #94a3b8 was reading as a filled-in field for the same reason. */
:root[data-theme="light"] .glass-input::placeholder,
:root[data-theme="light"] .glass-input::-webkit-input-placeholder {
  color: rgba(15, 23, 42, 0.3);
  opacity: 1;
}

:root[data-theme="light"] .glass-input:focus {
  border-color: var(--accent-mint);
  box-shadow: 0 0 8px rgba(13, 148, 136, 0.15);
}

/* Dropdown settings background adjustments */
:root[data-theme="light"] #settings-startup-range {
  background: #ffffff !important;
  color: #0f172a !important;
  border-color: rgba(15, 23, 42, 0.12) !important;
}

:root[data-theme="light"] #settings-startup-range option {
  background: #ffffff !important;
  color: #0f172a !important;
}

/* Bottom Nav bar */
:root[data-theme="light"] .bottom-nav-bar {
  background: rgba(241, 245, 249, 0.85);
  border-top-color: rgba(15, 23, 42, 0.08);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
}

:root[data-theme="light"] .nav-tab-btn {
  color: #64748b;
}

:root[data-theme="light"] .nav-tab-btn.active {
  color: #0f172a;
}

/* Active buttons in navigation */
:root[data-theme="light"] .nav-tab-btn:not(.active):hover .nav-btn-orb i,
:root[data-theme="light"] .nav-tab-btn:not(.active):hover .nav-btn-orb svg {
  color: #0f172a;
}

/* active settings button blue orb */
:root[data-theme="light"] .nav-tab-btn.active#tab-btn-left .nav-btn-orb {
  background: radial-gradient(circle at 30% 30%, #3B82F6, #1D4ED8);
  border-color: #3B82F6;
  box-shadow: 0 0 15px rgba(59, 130, 246, 0.4), 0 4px 15px rgba(0, 0, 0, 0.08);
}

/* active workbook button mint orb */
:root[data-theme="light"] .nav-tab-btn.active#tab-btn-center .nav-btn-orb {
  background: radial-gradient(circle at 30% 30%, #10B981, #059669);
  border-color: #10B981;
  box-shadow: 0 0 15px rgba(16, 185, 129, 0.4), 0 4px 15px rgba(0, 0, 0, 0.08);
}

/* Floating Sidebar Ingestion Deck menu */
:root[data-theme="light"] .sidebar-dock {
  background: rgba(241, 245, 249, 0.85);
  border-left-color: rgba(15, 23, 42, 0.08);
  box-shadow: -10px 0 35px rgba(15, 23, 42, 0.05);
  backdrop-filter: blur(25px);
  -webkit-backdrop-filter: blur(25px);
}

:root[data-theme="light"] .sidebar-toggle-handle {
  background: rgba(241, 245, 249, 0.85);
  border-color: rgba(15, 23, 42, 0.08);
  border-right: none;
}

:root[data-theme="light"] .sidebar-toggle-handle:hover {
  background: #ffffff;
}

/* Glass structural cards */
:root[data-theme="light"] .glass-card {
  background: rgba(255, 255, 255, 0.75) !important;
  border-color: rgba(15, 23, 42, 0.07) !important;
  box-shadow: 0 10px 30px -10px rgba(15, 23, 42, 0.04) !important;
  backdrop-filter: blur(25px) !important;
  -webkit-backdrop-filter: blur(25px) !important;
}

/* Workspace modal overlay styling */
:root[data-theme="light"] .workspace-overlay {
  background-color: #f1f5f9 !important;
}

:root[data-theme="light"] .overlay-header {
  border-bottom-color: rgba(15, 23, 42, 0.08);
}

:root[data-theme="light"] .overlay-close-btn {
  background-color: #ffffff;
  color: #0f172a;
  border-color: rgba(15, 23, 42, 0.12);
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.03);
}

:root[data-theme="light"] .overlay-close-btn:hover {
  background-color: #f8fafc;
}

:root[data-theme="light"] .grid-row {
  border-bottom-color: rgba(15, 23, 42, 0.05);
}

:root[data-theme="light"] .grid-row:hover {
  background: rgba(15, 23, 42, 0.02);
}

:root[data-theme="light"] .grid-row.selected {
  background: rgba(15, 23, 42, 0.04);
}

/* Modals */
:root[data-theme="light"] .modal-dialog-overlay {
  background: rgba(241, 245, 249, 0.8) !important;
  backdrop-filter: blur(12px);
}

:root[data-theme="light"] .modal-dialog {
  background: #ffffff;
  border-color: rgba(15, 23, 42, 0.1);
  box-shadow: 0 20px 50px rgba(15, 23, 42, 0.08);
}

:root[data-theme="light"] .modal-dialog h3 {
  color: #0f172a;
}

:root[data-theme="light"] .modal-text {
  color: #64748b;
}

:root[data-theme="light"] .export-opt-label {
  border-color: rgba(15, 23, 42, 0.08);
  color: #0f172a;
}

:root[data-theme="light"] .export-opt-label input[type="radio"]:checked+span {
  color: #0d9488;
}

/* Interactive elements default text colors in light mode */
:root[data-theme="light"] button.glass-btn {
  color: #0f172a;
  border-color: rgba(15, 23, 42, 0.12);
  background: #ffffff;
}

:root[data-theme="light"] button.glass-btn:hover {
  background: rgba(15, 23, 42, 0.03);
}

/* General form elements text inputs */
:root[data-theme="light"] input[type="text"],
:root[data-theme="light"] input[type="email"],
:root[data-theme="light"] input[type="number"],
:root[data-theme="light"] select {
  color: #0f172a;
}

/* Override tailwind background styles for specific light theme containers */
:root[data-theme="light"] .bg-\[\#0f131c\] {
  background-color: rgba(255, 255, 255, 0.8) !important;
}

:root[data-theme="light"] .border-\[\#2d3748\] {
  border-color: rgba(15, 23, 42, 0.08) !important;
}

:root[data-theme="light"] .border-\[\#162138\] {
  border-color: rgba(15, 23, 42, 0.06) !important;
}

:root[data-theme="light"] .text-white {
  color: #0f172a !important;
}

:root[data-theme="light"] .text-\[\#94a3b8\] {
  color: #64748b !important;
}

:root[data-theme="light"] .bg-\[\#162138\] {
  background-color: rgba(255, 255, 255, 0.7) !important;
}

:root[data-theme="light"] .border-\[\#334155\] {
  border-color: rgba(15, 23, 42, 0.08) !important;
}

:root[data-theme="light"] .bg-slate-800 {
  background-color: rgba(15, 23, 42, 0.03) !important;
  color: #0f172a !important;
}

:root[data-theme="light"] .bg-slate-800:hover {
  background-color: rgba(15, 23, 42, 0.06) !important;
}

:root[data-theme="light"] .text-\[\#cbd5e1\] {
  color: #0f172a !important;
}

:root[data-theme="light"] .bg-\[\#0f172a\] {
  background-color: rgba(255, 255, 255, 0.85) !important;
}

/* Premium Light-mode Data Pills (Badges) with high-contrast pastel backgrounds and colored borders */
:root[data-theme="light"] .bg-\[\#881337\] {
  background-color: #FEE2E2 !important;
  color: #991B1B !important;
  border-color: rgba(239, 68, 68, 0.25) !important;
}

:root[data-theme="light"] .bg-\[\#064e3b\] {
  background-color: #D1FAE5 !important;
  color: #065F46 !important;
  border-color: rgba(16, 185, 129, 0.25) !important;
}

:root[data-theme="light"] .bg-\[\#1e293b\] {
  background-color: #F1F5F9 !important;
  color: #334155 !important;
  border-color: rgba(148, 163, 184, 0.25) !important;
}

:root[data-theme="light"] .bg-\[\#7c2d12\] {
  background-color: #FFEDD5 !important;
  color: #9A3412 !important;
  border-color: rgba(249, 115, 22, 0.25) !important;
}

:root[data-theme="light"] .bg-\[\#0f766e\] {
  background-color: #CCFBF1 !important;
  color: #0F766E !important;
  border-color: rgba(20, 184, 166, 0.25) !important;
}

:root[data-theme="light"] .bg-\[\#f59e0b\] {
  background-color: #FEF3C7 !important;
  color: #92400E !important;
  border-color: rgba(245, 158, 11, 0.25) !important;
}

/* Also style the export email input in light mode */
:root[data-theme="light"] #main-email-input {
  background-color: #ffffff !important;
  color: #0f172a !important;
  border: 1px solid rgba(15, 23, 42, 0.15) !important;
}


/* Brand logo color adjustment in light mode (invert logo white to black) */
:root[data-theme="light"] .brand-block img,
:root[data-theme="light"] .intro-logo-clone {
  filter: invert(1) brightness(0.15);
}

:root[data-theme="light"] .ledger-table {
  background: transparent !important;
  color: #0f172a !important;
}

:root[data-theme="light"] .ledger-table th {
  background: rgba(226, 232, 240, 0.8) !important;
  color: #0f172a !important;
  border-bottom: 2px solid rgba(15, 23, 42, 0.08) !important;
}

:root[data-theme="light"] .ledger-table td {
  color: #0f172a !important;
  border-bottom: 1px solid rgba(15, 23, 42, 0.05) !important;
}

:root[data-theme="light"] .ledger-table tbody tr:hover {
  background-color: rgba(15, 23, 42, 0.02) !important;
}

:root[data-theme="light"] .ledger-table tbody tr:nth-child(even) {
  background-color: rgba(15, 23, 42, 0.01) !important;
}

/* Explicit high-specificity overrides for elements inside the ledger container */
:root[data-theme="light"] #ledger-sections-container td {
  color: #0f172a !important;
  border-bottom-color: rgba(15, 23, 42, 0.05) !important;
}

:root[data-theme="light"] #ledger-sections-container th {
  color: #0f172a !important;
  background: rgba(226, 232, 240, 0.8) !important;
}

:root[data-theme="light"] #ledger-sections-container tr.main-row:hover {
  background: rgba(15, 23, 42, 0.02) !important;
}

/* Override utility color classes in sub-tables / child details */
:root[data-theme="light"] .text-slate-300 {
  color: #0f172a !important;
}

:root[data-theme="light"] .text-slate-400 {
  color: #64748b !important;
}

:root[data-theme="light"] .text-slate-200 {
  color: #0f172a !important;
}

:root[data-theme="light"] .text-slate-500 {
  color: #64748b !important;
}

/* Border and background overrides for sub-tables */
:root[data-theme="light"] .border-slate-800,
:root[data-theme="light"] .border-slate-800\/60,
:root[data-theme="light"] .border-slate-800\/50,
:root[data-theme="light"] .border-slate-700\/50 {
  border-color: rgba(15, 23, 42, 0.08) !important;
}

:root[data-theme="light"] .bg-slate-950\/60,
:root[data-theme="light"] .bg-slate-950\/70,
:root[data-theme="light"] .bg-slate-950\/20,
:root[data-theme="light"] .bg-slate-900\/20,
:root[data-theme="light"] .bg-slate-900\/30,
:root[data-theme="light"] .bg-slate-900\/40,
:root[data-theme="light"] .bg-slate-900\/10,
:root[data-theme="light"] .bg-slate-800\/80 {
  background-color: rgba(15, 23, 42, 0.02) !important;
  color: #0f172a !important;
}

/* Table detail expanded child rows */
:root[data-theme="light"] .child-row {
  background-color: rgba(15, 23, 42, 0.01) !important;
}

:root[data-theme="light"] .child-row h4 {
  color: #0f172a !important;
}

:root[data-theme="light"] .child-row td {
  border-left-width: 4px;
}

:root[data-theme="light"] .child-row .ledger-table th {
  background: rgba(226, 232, 240, 0.9) !important;
  color: #0f172a !important;
}

:root[data-theme="light"] .child-row .bg-slate-900\/40 {
  background-color: rgba(255, 255, 255, 0.8) !important;
  border-color: rgba(15, 23, 42, 0.08) !important;
}

/* Override the inline background style of grid-section cards in light mode */
:root[data-theme="light"] .grid-section {
  background: rgba(255, 255, 255, 0.75) !important;
  border-left: 1px solid rgba(15, 23, 42, 0.08) !important;
  border-right: 1px solid rgba(15, 23, 42, 0.08) !important;
  border-bottom: 1px solid rgba(15, 23, 42, 0.08) !important;
  box-shadow: 0 8px 32px 0 rgba(15, 23, 42, 0.04) !important;
  backdrop-filter: blur(25px);
  -webkit-backdrop-filter: blur(25px);
}

:root[data-theme="light"] .grid-section.lights-on {
  border-top: 4px solid var(--theme-color) !important;
}

:root[data-theme="light"] .grid-section.lights-off {
  border-top: 4px solid rgba(15, 23, 42, 0.08) !important;
}

/* Ensure section titles do not use neon text-shadow / blur filter in light mode */
:root[data-theme="light"] .grid-section.lights-on .header-title {
  text-shadow: none !important;
  color: #0f172a !important;
}

:root[data-theme="light"] .grid-section.lights-off .header-title {
  color: #64748b !important;
  opacity: 0.6 !important;
}

:root[data-theme="light"] .grid-section.lights-off .header-icon {
  color: #64748b !important;
  opacity: 0.6 !important;
  filter: grayscale(100%) !important;
}

/* Local search input override inside cards */
:root[data-theme="light"] [id$="-local-search"] {
  background-color: #ffffff !important;
  color: #0f172a !important;
  border-color: rgba(15, 23, 42, 0.12) !important;
  box-shadow: inset 0 2px 4px rgba(15, 23, 42, 0.02) !important;
}

:root[data-theme="light"] [id$="-local-search"]::placeholder {
  color: #94a3b8 !important;
}

:root[data-theme="light"] [id$="-local-search"]+span i,
:root[data-theme="light"] [id$="-local-search"]+span svg {
  color: #64748b !important;
}

/* Pagination row separators and labels */
:root[data-theme="light"] .grid-section div.border-b.border-slate-800\/50 {
  border-bottom-color: rgba(15, 23, 42, 0.08) !important;
}

:root[data-theme="light"] [id^="page-info-"] {
  color: #64748b !important;
}

/* Prev/Next buttons styling overrides */
:root[data-theme="light"] .grid-section button[onclick^="changePage"] {
  background-color: rgba(15, 23, 42, 0.03) !important;
  color: #0f172a !important;
  border-color: rgba(15, 23, 42, 0.08) !important;
}

:root[data-theme="light"] .grid-section button[onclick^="changePage"]:hover {
  background-color: rgba(15, 23, 42, 0.06) !important;
}

:root[data-theme="light"] .grid-section .bg-slate-950\/40 {
  background-color: #ffffff !important;
  border-color: rgba(15, 23, 42, 0.08) !important;
}

/* View limit dropdown styling overrides inside cards */
:root[data-theme="light"] .grid-section select[onchange^="updateLimit"] {
  background-color: #ffffff !important;
  color: #0f172a !important;
  border-color: rgba(15, 23, 42, 0.12) !important;
}

/* Sortable table header text adjustment in light mode (make it readable charcoal) */
:root[data-theme="light"] .sortable-header {
  color: #64748b !important;
  border-bottom-color: rgba(15, 23, 42, 0.08) !important;
}

:root[data-theme="light"] .ledger-table th.sortable-header {
  color: #64748b !important;
}

/* Light mode expanded table detail heading contrast fix */
:root[data-theme="light"] #ledger-sections-container h4 {
  color: #0f172a !important;
}

/* Light mode sidebar icon shading accessibility adjustments */
:root[data-theme="light"] #btn-w9s {
  --accent-color: #B59A00 !important;
  /* Darker golden amber for light mode readability */
}

:root[data-theme="light"] #btn-mileage {
  --accent-color: #008B7A !important;
  /* Darker teal/cyan for light mode visibility */
}

/* Light mode card container (Ingestion,
Settings,
etc.) overrides */
:root[data-theme="light"] .glass-form-card {
  background: rgba(255, 255, 255, 0.75) !important;
  border-color: rgba(15, 23, 42, 0.08) !important;
  box-shadow: 0 8px 32px 0 rgba(15, 23, 42, 0.04) !important;
  backdrop-filter: blur(25px);
  -webkit-backdrop-filter: blur(25px);
}

/* Ingestion Drop Zone override in light mode */
:root[data-theme="light"] .drop-zone {
  background: #ffffff !important;
  border-color: rgba(15, 23, 42, 0.12) !important;
}

:root[data-theme="light"] .drop-zone.dragover {
  background: rgba(15, 23, 42, 0.04) !important;
}

/* Settings Form Select inputs background and text overrides in light mode */
:root[data-theme="light"] select,
:root[data-theme="light"] select.glass-input,
:root[data-theme="light"] .glass-form-card select {
  background-color: #ffffff !important;
  color: #0f172a !important;
  border-color: rgba(15, 23, 42, 0.12) !important;
}

:root[data-theme="light"] select option,
:root[data-theme="light"] select.glass-input option,
:root[data-theme="light"] .glass-form-card select option {
  background-color: #ffffff !important;
  color: #0f172a !important;
}

/* Hide background particle animation in light mode to keep background clean */
:root[data-theme="light"] #node-canvas-bg,
:root[data-theme="light"] #node-canvas {
  display: none !important;
}

/* Save Preferences button text color override in light mode */
:root[data-theme="light"] #btn-save-prefs {
  color: #ffffff !important;
}

/* Light theme overrides for dynamic ingestion sub-containers */
:root[data-theme="light"] .pin-client-block {
  background: #ffffff !important;
  border-color: rgba(15, 23, 42, 0.12) !important;
}

:root[data-theme="light"] .ingesting-checklist {
  background: #ffffff !important;
  border-color: rgba(15, 23, 42, 0.12) !important;
}

:root[data-theme="light"] .checklist-title {
  border-bottom-color: rgba(15, 23, 42, 0.08) !important;
}

:root[data-theme="light"] .line-item-row {
  background: #ffffff !important;
  border-color: rgba(15, 23, 42, 0.12) !important;
}

/* Light mode overrides for mapped lines box and premium verify block in Ingestion */
:root[data-theme="light"] .mapped-lines-box,
:root[data-theme="light"] .premium-verify-block {
  background: rgba(15, 23, 42, 0.03) !important;
  border-color: rgba(15, 23, 42, 0.1) !important;
}

:root[data-theme="light"] .premium-verify-block:hover {
  border-color: rgba(225, 29, 72, 0.3) !important;
}

/* Light mode override for discrepancy error banners */
:root[data-theme="light"] .math-discrepancy-banner {
  color: #e11d48 !important;
  background: rgba(225, 29, 72, 0.04) !important;
  border-color: rgba(225, 29, 72, 0.15) !important;
}

/* Accessibility icon color overrides for light mode */
:root[data-theme="light"] #btn-receipts {
  --accent-color: #E11D48 !important;
}

:root[data-theme="light"] #btn-invoices {
  --accent-color: #0D9488 !important;
}

:root[data-theme="light"] #btn-donations {
  --accent-color: #7C3AED !important;
}

:root[data-theme="light"] #btn-w9s {
  --accent-color: #A16207 !important;
}

:root[data-theme="light"] #btn-cois {
  --accent-color: #2563EB !important;
}

:root[data-theme="light"] #btn-utilities {
  --accent-color: #EA580C !important;
}

:root[data-theme="light"] #btn-mileage {
  --accent-color: #0F766E !important;
}

:root[data-theme="light"] #btn-triage {
  --accent-color: #EF4444 !important;
}

/* Light theme overrides for mobile badges */
:root[data-theme="light"] [id^="badge-"] {
  background-color: #ffffff !important;
  font-weight: 700 !important;
}

:root[data-theme="light"] #badge-expense_ledger {
  background-color: #ffe4e6 !important;
  color: #b91c1c !important;
  border: 1.5px solid #fca5a5 !important;
}

:root[data-theme="light"] #badge-income_ledger {
  background-color: #d1fae5 !important;
  color: #047857 !important;
  border: 1.5px solid #6ee7b7 !important;
}

:root[data-theme="light"] #badge-donation_ledger {
  background-color: #f3e8ff !important;
  color: #7e22ce !important;
  border: 1.5px solid #d8b4fe !important;
}

:root[data-theme="light"] #badge-utility_ledger {
  background-color: #ffedd5 !important;
  color: #c2410c !important;
  border: 1.5px solid #fdba74 !important;
}

:root[data-theme="light"] #badge-mileage_ledger {
  background-color: #ccfbf1 !important;
  color: #0f766e !important;
  border: 1.5px solid #5eead4 !important;
}

:root[data-theme="light"] #badge-vendor_ledger {
  background-color: #fef9c3 !important;
  color: #a16207 !important;
  border: 1.5px solid #fde047 !important;
}

:root[data-theme="light"] #badge-compliance_ledger {
  background-color: #dbeafe !important;
  color: #1d4ed8 !important;
  border: 1.5px solid #93c5fd !important;
}


/* ==================== TRIAGE ROOM WORKSPACE CUSTOM SYSTEM ==================== */

.workspace-overlay.triage-wizard-active {
  background: rgba(48, 4, 15, 0.95) !important;
  border-top-color: #EF4444 !important;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.9),
    inset 0 0 40px rgba(239, 68, 68, 0.05),
    0 0 50px rgba(239, 68, 68, 0.2) !important;
  transition: all 0.4s ease;
}

.workspace-overlay.triage-wizard-active.triage-wizard-staging-active {
  background: rgba(4, 15, 48, 0.95) !important;
  border-top-color: #2A66F7 !important;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.9),
    inset 0 0 40px rgba(42, 102, 247, 0.05),
    0 0 50px rgba(42, 102, 247, 0.2) !important;
}

.triage-wizard-active .overlay-layout-split {
  display: none !important;
}

.triage-tabs-container {
  display: flex;
  gap: 15px;
  border-bottom: 2px solid rgba(255, 255, 255, 0.05);
  margin-bottom: 20px;
  justify-content: center;
}

.triage-tab-btn {
  background: transparent;
  border: none;
  color: #94A3B8;
  padding: 12px 24px;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
  transition: all 0.3s ease;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.triage-tab-btn:hover {
  color: #f8fafc;
}

.triage-tab-btn.active {
  color: #EF4444;
  border-bottom-color: #EF4444;
  text-shadow: 0 0 8px rgba(239, 68, 68, 0.5);
}

.triage-wizard-staging-active .triage-tab-btn.active {
  color: #60A5FA !important;
  border-bottom-color: #3B82F6 !important;
  text-shadow: 0 0 8px rgba(96, 165, 250, 0.6) !important;
}

@media (max-width: 900px) {

  .triage-left-panel,
.triage-right-panel {
    max-height: none !important;
  }
}

.triage-left-panel {
  flex: 1.2;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 15px;
  overflow: hidden;
  max-height: calc(100vh - 280px);
  position: relative;
  min-height: 300px;
}

.triage-left-panel img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}

.triage-right-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 15px;
  max-height: calc(100vh - 280px);
  overflow-y: auto;
  padding-right: 5px;
}

.triage-right-panel::-webkit-scrollbar {
  width: 6px;
}

.triage-right-panel::-webkit-scrollbar-track {
  background: transparent;
}

.triage-right-panel::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 10px;
}

.neon-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  z-index: 50 !important;
  background: #EF4444;
  color: white;
  font-size: 10px;
  font-weight: 800;
  border-radius: 10px;
  padding: 2px 6px;
  line-height: 1;
  box-shadow: 0 0 10px #EF4444, 0 0 20px #EF4444;
  border: 1px solid rgba(255, 255, 255, 0.3);
  animation: neon-badge-pulse 2s infinite alternate;
}

.neon-badge-blue {
  position: absolute;
  top: -5px;
  left: -5px;
  z-index: 50 !important;
  background: #2A66F7;
  color: white;
  font-size: 10px;
  font-weight: 800;
  border-radius: 10px;
  padding: 2px 6px;
  line-height: 1;
  box-shadow: 0 0 10px #2A66F7, 0 0 20px #2A66F7;
  border: 1px solid rgba(255, 255, 255, 0.3);
  animation: neon-badge-pulse-blue 2s infinite alternate;
}

/* Saves this device is still holding because the server has not confirmed them yet.
 *
 * Third corner of the same icon,
deliberately: red (top right) is "something went wrong and needs
 * you",
blue (top left) is "something is staged",
and yellow (bottom right) is "something has not
 * landed yet". Same language,
same place,
so there is one spot to look rather than three.
 *
 * Yellow rather than amber-on-white: this is not an error. Nothing is lost and nobody needs to act
 * — the app is retrying by itself. It exists so that "it didn't save" is visible rather than
 * something the user has to remember from a dialog they dismissed.
 *
 * Dark text,
unlike the red and blue badges,
because white on #F7DF1E is unreadable. */
.neon-badge-yellow {
  position: absolute;
  bottom: -5px;
  right: -5px;
  z-index: 50 !important;
  background: #F7DF1E;
  color: #1A1A1A;
  font-size: 10px;
  font-weight: 800;
  border-radius: 10px;
  padding: 2px 6px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 0 10px #F7DF1E, 0 0 20px #F7DF1E;
  border: 1px solid rgba(255, 255, 255, 0.3);
  animation: neon-badge-pulse-yellow 2s infinite alternate;
}

@keyframes neon-badge-pulse-yellow {
  0% {
    box-shadow: 0 0 6px #F7DF1E, 0 0 12px #F7DF1E;
    transform: scale(1);
  }

  100% {
    box-shadow: 0 0 12px #F7DF1E, 0 0 24px #F7DF1E;
    transform: scale(1.08);
  }
}

/* A tap target you can actually hit.
 *
 * The badge itself is about 20x14px. Apple and Google both put the minimum at around 44px,
so a
 * thumb aimed at it lands on the icon behind roughly as often as not — which is why tapping it
 * felt like it randomly either did nothing or opened the Triage room.
 *
 * An invisible ::before extends the hittable area without changing how it looks. Only on coarse
 * pointers: on a desktop a mouse is precise,
and silently swallowing clicks 14px away from a
 * visible control would be its own surprise. */
.neon-badge-yellow::before {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 999px;
}

@media (hover: none) and (pointer: coarse) {
  .neon-badge-yellow::before {
    inset: -14px;
  }
}

/* Acknowledge the tap.
 *
 * A retry that succeeds makes the badge vanish; one that fails leaves it sitting there unchanged.
 * Either way,
tapping produced no visible response,
which teaches people the control is dead —
 * the same quiet untrustworthiness as a save that fails silently,
just smaller.
 *
 * So it grows and spins while it tries,
then either disappears because everything landed,
or
 * shrinks back to the number because it did not. The pulse is switched off first: it animates
 * transform too,
and would fight the scale. */
.neon-badge-yellow.is-retrying {
  animation: none;
  transform: scale(2);
  transition: transform 160ms ease-out;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 14px;
  min-height: 11px;
  box-shadow: 0 0 14px #F7DF1E, 0 0 28px #F7DF1E;
}

.neon-badge-yellow .badge-spinner {
  display: inline-block;
  width: 8px;
  height: 8px;
  border: 2px solid rgba(26, 26, 26, 0.3);
  border-top-color: #1A1A1A;
  border-radius: 50%;
  animation: badge-spin 0.6s linear infinite;
}

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

@keyframes neon-badge-pulse {
  0% {
    box-shadow: 0 0 6px #EF4444, 0 0 12px #EF4444;
    transform: scale(1);
  }

  100% {
    box-shadow: 0 0 12px #EF4444, 0 0 24px #EF4444;
    transform: scale(1.08);
  }
}

@keyframes neon-badge-pulse-blue {
  0% {
    box-shadow: 0 0 6px #2A66F7, 0 0 12px #2A66F7;
    transform: scale(1);
  }

  100% {
    box-shadow: 0 0 12px #2A66F7, 0 0 24px #2A66F7;
    transform: scale(1.08);
  }
}

.triage-queue-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

.triage-queue-item {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  padding: 12px 15px;
  cursor: pointer;
  transition: all 0.25s ease;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.triage-queue-item:hover,
.triage-queue-item.active {
  background: rgba(239, 68, 68, 0.08);
  border-color: rgba(239, 68, 68, 0.3);
  transform: translateY(-1px);
}

.triage-queue-item.staged-item:hover {
  background: rgba(59, 130, 246, 0.08) !important;
  border-color: rgba(59, 130, 246, 0.3) !important;
}

.triage-queue-item.active {
  box-shadow: 0 0 12px rgba(239, 68, 68, 0.1);
}

.triage-field-group {
  margin-bottom: 12px;
}

.triage-field-group label {
  display: block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  color: #94A3B8;
  margin-bottom: 4px;
  letter-spacing: 0.05em;
}

.triage-field-group input {
  width: 100%;
  background: rgba(15, 23, 42, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  padding: 8px 12px;
  color: white;
  font-family: inherit;
  font-size: 0.85rem;
  transition: all 0.3s ease;
}

.triage-field-group input:focus {
  border-color: #EF4444;
  outline: none;
  background: rgba(15, 23, 42, 0.8);
}

#pwa-titlebar {
  display: none;
}

/* ==================== CONTRACTOR DATA INTAKE WORKBENCH OVERLAY ==================== */
#intake-workbench-overlay {
  box-sizing: border-box;
}

@media (min-width: 1024px) {
  #intake-workbench-overlay {
    width: 95vw !important;
    max-width: 1600px !important;
    min-height: 85vh !important;
    height: auto !important;
    max-height: 95vh !important;
    top: 50% !important;
    left: 50% !important;
    margin: 0 !important;
  }

  /* Side-by-side flex orientation: 60% Left queue,
40% Right validation HUD */
  #intake-workbench-overlay .overlay-content>.flex {
    display: flex !important;
    flex-direction: row !important;
    gap: 1.5rem !important;
  }

  #intake-workbench-overlay .overlay-content>.flex>div:first-child {
    width: 60% !important;
    flex: 0 0 60% !important;
  }

  #intake-workbench-overlay .overlay-content>.flex>div:last-child {
    width: 40% !important;
    flex: 0 0 40% !important;
  }
}

@media (max-width: 1023px) {
  #intake-workbench-overlay {
    width: 94% !important;
    left: 3% !important;
    top: 60px !important;
    bottom: 12px !important;
    height: auto !important;
    max-height: calc(100vh - 85px) !important;
  }

  /* Vertical stacking for responsive viewports below 1024px */
  #intake-workbench-overlay .overlay-content>.flex {
    display: flex !important;
    flex-direction: column !important;
    gap: 1rem !important;
    overflow-y: auto !important;
  }

  #intake-workbench-overlay .overlay-content>.flex>div:first-child,
#intake-workbench-overlay .overlay-content>.flex>div:last-child {
    width: 100% !important;
    flex: none !important;
  }
}

/* Tabular Scannability & Non-Clipping Optimizations */
#intake-workbench-overlay table {
  width: 100%;
  border-collapse: collapse;
  table-layout: auto !important;
  /* Native expanding boundaries */
}

#intake-workbench-overlay th,
#intake-workbench-overlay td {
  padding: 0.75rem !important;
  vertical-align: middle;
  white-space: nowrap;
  /* Prevent vertical stacking of key columns */
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Enforce explicit widths on specific fields to prevent word stacking and truncation */
#intake-workbench-overlay th:nth-child(2),
#intake-workbench-overlay td:nth-child(2) {
  /* Vendor / Payee */
  min-width: 180px !important;
  max-width: 300px !important;
  white-space: normal !important;
  word-break: break-word !important;
}

#intake-workbench-overlay th:nth-child(3),
#intake-workbench-overlay td:nth-child(3) {
  /* Suggested Category */
  min-width: 180px !important;
  max-width: 250px !important;
  white-space: normal !important;
  word-break: break-word !important;
}

/* Dynamic Accent Colors for Workspace Overlay based on active doc type */
.workspace-overlay.receipts-wizard-active {
  --panel-accent: #FF2A5F;
  --panel-accent-glow: rgba(255, 42, 95, 0.25);
}
.workspace-overlay.invoices-wizard-active {
  --panel-accent: #10B981;
  --panel-accent-glow: rgba(16, 185, 129, 0.25);
}
.workspace-overlay.donations-wizard-active {
  --panel-accent: #A855F7;
  --panel-accent-glow: rgba(168, 85, 247, 0.25);
}
.workspace-overlay.w9s-wizard-active {
  --panel-accent: #F7DF1E;
  --panel-accent-glow: rgba(247, 223, 30, 0.25);
}
.workspace-overlay.cois-wizard-active {
  --panel-accent: #2F80ED;
  --panel-accent-glow: rgba(47, 128, 237, 0.25);
}
.workspace-overlay.utilities-wizard-active {
  --panel-accent: #F97316;
  --panel-accent-glow: rgba(249, 115, 22, 0.25);
}
.workspace-overlay.quotes-wizard-active {
  --panel-accent: #A855F7;
  --panel-accent-glow: rgba(168, 85, 247, 0.25);
}
.workspace-overlay.mileage-wizard-active {
  --panel-accent: #00F5D4;
  --panel-accent-glow: rgba(0, 245, 212, 0.25);
}

/* Enforce multiline rendering and wrapping on physical address cells */
td[data-col="physical_address"] {
  white-space: pre-wrap !important;
  word-break: break-word !important;
}

/* ==================== EXPORT CENTER STYLING ==================== */
/* Anchor the Export Center to the top of the viewport instead of centring it.
   The shared overlay centres vertically,
which is fine for a fixed-size dialog but not
   here: every tab holds a different number of rows,
so switching from Receipts (27) to
   Donations (3) shortened the dialog and re-centred it,
and the whole panel lurched up the
   screen mid-task. Anchored,
the header,
filters,
ledger tabs and destination buttons stay
   exactly where they were and only the bottom edge moves.

   Scoped to this dialog by id — the overlay class is shared,
and every other modal in the
   app is short enough that centring is right for it.

   overflow-y matters as much as the anchoring: once the top is pinned,
content taller than
   the viewport would run off the bottom with no way to reach it. The dialog carries no
   max-height,
so the overlay has to do the scrolling. */
#export-center-modal {
  align-items: flex-start;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Flex containers that scroll drop their end padding in several engines,
so the breathing
   room at the bottom has to come from the dialog rather than the overlay's padding. */
#export-center-modal .export-center-dialog {
  margin-bottom: 20px;
}

.export-center-dialog {
  max-width: 1040px !important;
  width: 95vw !important;
  padding: 24px;
  background: #0A090E radial-gradient(circle at top center, rgba(99, 102, 241, 0.28) 0%, transparent 65%) !important;
  border-top: 4px solid #6366F1 !important;
  border-left: 1px solid rgba(99, 102, 241, 0.4) !important;
  border-right: 1px solid rgba(99, 102, 241, 0.4) !important;
  border-bottom: 1px solid rgba(99, 102, 241, 0.4) !important;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.95), 0 0 45px rgba(99, 102, 241, 0.35) !important;
  border-radius: 16px;
}



.export-center-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-b: 1px solid rgba(255, 255, 255, 0.1);
  padding-bottom: 12px;
}

.export-center-close-btn {
  background: transparent;
  border: none;
  color: #94a3b8;
  font-size: 1.8rem;
  cursor: pointer;
  line-height: 1;
  transition: color 0.2s;
}
.export-center-close-btn:hover {
  color: #f43f5e;
}

/* Breathing room on both sides of the control row,
so the selection breakdown reads as its
   own band rather than as part of the sync notice above it or the ledger tabs below. The
   emphasis comes from the separation rather than from making the pill louder. */
.ec-control-row {
  padding-top: 20px;
}
.export-center-tabs {
  padding-top: 20px;
}

/* Global selection controls. Deliberately small and quiet — they sit beside the history
   filter rather than near the destination buttons,
so "clear everything" is never adjacent
   to "send everything". */
.ec-global-select {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  flex-shrink: 0;
}
.ec-global-btn-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ec-global-select-label {
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #64748b;
}
.ec-global-btn {
  padding: 3px 9px;
  border-radius: 6px;
  font-size: 0.66rem;
  font-weight: 700;
  cursor: pointer;
  color: #cbd5e1;
  background: rgba(51, 65, 85, 0.55);
  border: 1px solid rgba(100, 116, 139, 0.45);
  transition: all 0.15s ease;
}
.ec-global-btn:hover {
  background: rgba(71, 85, 105, 0.8);
  color: #f1f5f9;
}
.ec-global-btn-clear:hover {
  background: rgba(159, 18, 57, 0.45);
  border-color: rgba(251, 113, 133, 0.5);
  color: #fecdd3;
}

/* Selection breakdown — sits directly above the destination buttons and names every
   ledger the export would touch. Quiet by default; the only loud element is the count of
   what is selected but NOT visible on the current tab,
because that is the part that
   silently sent 46 records to QuickBooks from a tab showing one selected row. */
/* Shares the control row with the global select buttons. It takes the middle of the row and
   nothing else moves when it appears or disappears — the row's height comes from the
   buttons,
so the table below never reflows. Its previous home above the destination
   buttons pushed the whole grid down each time it rendered. */
.ec-selection-breakdown {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  flex: 1;
  gap: 8px;
  min-width: 0;
  padding: 5px 14px;
  border-radius: 999px;
  border: 1px solid rgba(99, 102, 241, 0.28);
  background: rgba(49, 46, 129, 0.22);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: #a5b4fc;
}

/* Attention without permanent visual weight. A louder resting style would compete with the
   destination buttons all the time; a brief pulse fires only when the numbers actually
   change, which is the moment the figure needs to be read. Retriggered from JS by removing
   and re-adding the class, and only when the rendered content differs — otherwise every
   unrelated re-render would flash it and it would become wallpaper. */
@keyframes ecBreakdownPulse {
  0% {
    border-color: rgba(129, 140, 248, 0.9);
    background: rgba(99, 102, 241, 0.42);
    box-shadow: 0 0 0 0 rgba(99, 102, 241, 0.5);
  }
  55% {
    border-color: rgba(129, 140, 248, 0.65);
    background: rgba(99, 102, 241, 0.26);
    box-shadow: 0 0 0 7px rgba(99, 102, 241, 0);
  }
  100% {
    border-color: rgba(99, 102, 241, 0.28);
    background: rgba(49, 46, 129, 0.22);
    box-shadow: 0 0 0 0 rgba(99, 102, 241, 0);
  }
}
.ec-selection-breakdown.ec-bd-pulse {
  animation: ecBreakdownPulse 0.75s ease-out;
}
/* Motion is the whole mechanism here, so when it is unwelcome the resting state has to
   carry the emphasis on its own rather than simply going quiet. */
@media (prefers-reduced-motion: reduce) {
  .ec-selection-breakdown.ec-bd-pulse {
    animation: none;
  }
  .ec-selection-breakdown {
    border-color: rgba(129, 140, 248, 0.55);
    background: rgba(99, 102, 241, 0.2);
  }
}
/* `hidden` is a display:none utility from the page's CSS framework,
and letting it apply
   here would defeat the point: the middle of the row would collapse,
the buttons and the
   history pill would slide toward each other,
and hiding the breakdown would cause the very
   shift it was moved here to avoid. Keep the box in flow and hide only its contents. */
.ec-selection-breakdown.hidden {
  display: flex;
  visibility: hidden;
}
/* Lifted off the slate greys these used before — on the indigo panel they read as disabled
   text,
which is the opposite of the intent. */
.ec-bd-label {
  text-transform: uppercase;
  font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  color: #818cf8;
}
.ec-bd-item {
  color: #e0e7ff;
}
.ec-bd-item strong {
  color: #ffffff;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* The ledger you are looking at,
so the eye can separate "this tab" from "everything else". */
.ec-bd-item.ec-bd-here strong,
.ec-bd-item.ec-bd-here {
  color: #7dd3fc;
}
.ec-bd-sep {
  color: rgba(129, 140, 248, 0.5);
}
.ec-bd-warn {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(217, 119, 6, 0.16);
  border: 1px solid rgba(251, 191, 36, 0.42);
  color: #fcd34d;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* These are short phrases that name one figure. Letting them break mid-phrase turns "113 not on
   this tab" into a five line tower,
and the row wraps BETWEEN items anyway,
which is the break
   that keeps them readable. */
.ec-bd-item,
.ec-bd-warn {
  white-space: nowrap;
}

/* THE EXPORT CENTER ON A PHONE, LAID OUT RATHER THAN PATCHED
   ==========================================================
   Three rounds got here. The control row was one horizontal flex line with no width rule at
   all, so at 390px the will-send strip was 30px wide and 490px tall and two controls ended past
   the right edge. Fixing that left the rest, and Steve, 2026-08-22: "this just does not look
   'neat' or organized at all. This all really just needs to be ripped out and redesigned."

   It read as random because nothing shared an alignment. Every group centred itself
   independently and then wrapped, so the client and the start date sat on one line with the end
   date centred beneath them, two accounting packages sat on one line with the third centred
   beneath, and seven ledger tabs wrapped at whatever width each one happened to be. Centring is
   what produces a ragged edge once things wrap: each line centres on its own contents.

   So below 768px this panel has ONE column, one left edge and one right edge, and every group
   is a grid that fills it:

     - the three filters are label-left, control-right, so the labels align and the controls
       share a right edge;
     - the accounting packages are equal tiles two to a row, and an odd one out spans the row
       rather than leaving a hole;
     - the ledger tabs are the same, so no tab is wider than another and none is off-screen;
     - the will-send figures stop being a pill. A capsule is a shape for a few words on one
       line, and this is five figures and a warning. It is a panel with one row per ledger and
       the numbers in a column, which is the same thing the list below it does.

   Nothing here changes the desktop: it is all inside the query. Where !important appears it is
   overriding a utility class written on the element itself, which a stylesheet cannot outrank
   by specificity alone. */
@media (max-width: 767px) {

  /* ---- header ------------------------------------------------------------------------
     A two-ended row: the title on one end,
the running total and the close on the other. At
     390px the total is a sentence rather than a chip,
and it took enough of the row that the
     title broke to one word per line. Each gets the full width; the close is lifted out of the
     flow so it stays in the corner a thumb reaches for rather than being pushed below the
     title by the wrap. */
  /* Everything else on this panel is centred,
so the one thing that was not read as a mistake.
     No padding is reserved for the close button: it is out of the flow,
so reserving room for it
     would shift the true centre left by half of whatever was reserved,
which is the sort of
     nearly-centred that looks worse than not trying. The close sits on its own line's worth of
     height at the top right,
and the title and subtitle clear it. Measured,
not assumed. */
  .export-center-header {
    position: relative;
    flex-wrap: wrap;
    row-gap: 10px;
    text-align: center;
  }
  /* Held back from both edges by the width of the close button,
so the subtitle wraps before it
     reaches it rather than running underneath. Equal on both sides,
so the centre stays the
     panel's centre: taking the room off one side only would centre the text on a box that is not
     the panel and it would sit slightly left of everything below it. */
  .export-center-title-group {
    flex: 1 0 100%;
    min-width: 0;
    margin-left: auto;
    margin-right: auto;
  }
  .export-center-title-group h3 {
    justify-content: center;
  }
  /* Only the subtitle needs holding back,
and measuring said so: the title's text ends at 317
     and the close button starts at 326,
but the subtitle ran to 330 while the button,
being 35px
     tall,
reaches down into its line. Held off both sides equally so the centre stays the panel's
     centre; taking the room off the right only would leave it sitting slightly left of
     everything below it,
which is the near-miss that looks worse than not centring at all. */
  .export-center-subtitle {
    max-width: calc(100% - 56px);
    /* !important because the element carries Tailwind's m-0, one class against this one class,
       and the tie goes to whichever comes later in the file. Without it the block kept its zero
       margins, sat hard left inside a full-width parent, and both its lines centred on 167
       against the panel's 195: text that is centred within a box that is not. */
    margin-left: auto !important;
    margin-right: auto !important;
  }
  .export-center-header > div:last-child {
    flex: 1 0 100%;
  }
  .export-center-metrics {
    flex: 1 1 auto;
    text-align: center;
  }
  .export-center-close-btn {
    position: absolute;
    top: 0;
    right: 0;
  }
  /* At the desktop size the name breaks after "Cloud" and drops "Sync" onto a line of its own,
with the icon stranded beside the first half. One step down fits it on one line inside the
     245px the close button leaves. */
  .export-center-title-group h3 {
    font-size: 1rem;
    line-height: 1.25;
  }
  .export-center-title-group h3 svg {
    flex-shrink: 0;
  }

  /* ---- filters and destinations ------------------------------------------------------ */
  .export-center-bar {
    padding: 12px !important;
    gap: 14px !important;
    margin-bottom: 16px !important;
  }
  .export-center-inputs {
    display: grid !important;
    grid-template-columns: 1fr;
    gap: 8px !important;
  }
  /* Label left,
control right,
on one line each. The label column is fixed so the three
     controls start at the same x and end at the same x,
which is the whole difference between
     this and three centred stacks. */
  .export-center-inputs > .input-field-group {
    display: grid !important;
    grid-template-columns: 98px minmax(0, 1fr);
    align-items: center;
    gap: 10px !important;
    width: 100%;
  }
  .export-center-inputs > .input-field-group > label {
    text-align: left;
    line-height: 1.2;
  }
  /* CENTRING A NATIVE CONTROL IS NOT text-align,
AND WEBKIT PROVED IT
     ----------------------------------------------------------------
     text-align: center was set on all three and computed as `center` on all three,
and Steve's
     phone still showed the client name hard left. Chrome agreed with the stylesheet,
so reading
     it proved nothing; a WebKit build reproduced his screen exactly. WebKit draws a <select>'s
     value and a date field's value through shadow content that plain text-align does not reach.

     A <select> answers to text-align-last. It does NOT need appearance: none,
and must not have
     it: that was tried and it removes the chevron,
so the control stops looking like a menu.

     A date field answers only through its shadow pseudo-elements,
and the two engines do not
     agree on which one exists: desktop WebKit draws ::-webkit-datetime-edit,
iOS draws
     ::-webkit-date-and-time-value. They are written as SEPARATE rules on purpose. One selector
     list holding both would be discarded whole by any engine that does not know one of them,
which is how a fix silently applies nowhere.

     And the first attempt at this was written `#start,
#end::-webkit-...`,
which attaches the
     pseudo-element to the LAST item only. The end date centred,
the start date did not,
and the
     screenshot said so. Each item carries its own.

     The alignment is verified in WebKit. The OTHER half of the report,
the date fields hanging
     past the right edge of the dropdown above them,
is not fixed by anything in this rule. The
     appearance: none below is what did that; the note there says so. */
  .export-center-inputs > .input-field-group > select,
.export-center-inputs > .input-field-group > input {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;
    text-align: center !important;
  }
  #export-center-client-select {
    text-align-last: center;
  }
  /* THE RIGHT EDGE,
ATTEMPT TWO. Still hanging over after min-width: 0 and max-width: 100%,
which is the fix for a grid item whose automatic minimum is its content. So that was not
     the mechanism. On iOS a date field is laid out from its own intrinsic size and simply does
     not honour a width while it keeps its native appearance; appearance: none is the documented
     lever and the one deliberately skipped last time,
because it was tried on the SELECT,
where
     it deletes the chevron. A date field has no chevron to lose: the whole field is the target
     and iOS still opens its picker. Verified in WebKit that the value stays visible and centred.

     CONFIRMED ON THE DEVICE,
2026-08-22: Steve reported the edges flush after this shipped,
and
     it took two attempts to get here,
the first one naming the wrong mechanism. Recorded because
     nothing in this repo can re-check it: neither engine on this machine reproduces the
     overhang,
both laying all three controls out at exactly 166..332. If these four declarations
     are ever deleted as redundant,
the only thing that will notice is his screen. */
  #export-center-start-date,
#export-center-end-date {
    -webkit-appearance: none;
    appearance: none;
    display: block;
  }
  #export-center-start-date::-webkit-datetime-edit,
  #export-center-end-date::-webkit-datetime-edit {
    text-align: center;
    width: 100%;
    margin: 0;
  }
  /* margin: 0 as well as width. iOS gives this shadow value a default margin,
and a margin on
     the thing inside the field is width the field asks for on top of whatever it was given. */
  #export-center-start-date::-webkit-date-and-time-value,
#export-center-end-date::-webkit-date-and-time-value {
    text-align: center;
    width: 100%;
    margin: 0;
  }

  .export-center-actions {
    display: grid !important;
    grid-template-columns: 1fr;
    gap: 10px !important;
    margin-top: 14px !important;
    /* The element carries Tailwind's items-center, which on a grid centres every item in its row
       instead of filling it. The ZIP button is 18px taller than the others because it carries an
       icon, so beside FreshBooks it sat 9px proud at both ends. Equal width was never going to
       read as equal while one of them was visibly bigger. */
    align-items: stretch !important;
  }
  /* "Download ZIP Archive" is too long to sit on one line in half the width,
and shortening it
     would be renaming a control nobody asked to rename. So the rows match the tallest instead and
     all four buttons come out the same size,
which reads as a set rather than as one row of small
     buttons above one row of large ones.

     Bookkeeper only,
and a screenshot is what said so. Contractor Edition has one column,
so
     equal rows there stretched the ZIP button to the height of the platform picker above it and
     it became the biggest thing on the panel. Equal rows are only worth having when there is
     something beside them to be equal to. */
  body:not(.contractor-edition) .export-center-actions {
    grid-auto-rows: 1fr;
  }

  /* FOUR DESTINATIONS,
TWO BY TWO,
AND NONE OF THEM FAVOURED
     -------------------------------------------------------
     FreshBooks and Download ZIP were each a row to themselves,
because the three accounting
     buttons live in one box and the ZIP button in another beside it: an odd count in the first
     box left FreshBooks spanning,
and the ZIP button was always full width. Steve,
2026-08-22:
     "kinda looks like we're giving preference to Freshbooks (which I certainly am not!!!!!!)".
     Size is emphasis whether or not anyone meant it.

     display: contents dissolves the inner box so all four sit in one grid. The ZIP button keeps
     its own wrapper,
because a popover is positioned against it.

     TWO GUARDS,
and they are not belt and braces,
they are the same fault twice in one night.
     refreshCeControl() writes `display: none` INLINE on this element for Contractor Edition,
and
     `display: contents !important` outranks an inline style: that is exactly how a stop sign,
an
     empty dropdown and a Connect button landed on a bookkeeper's screen a few hours ago. So the
     rule asks the body which edition it is AND refuses to fire on an element that has been told
     to be none. Either would do; both mean neither has to be right on its own. */
  body:not(.contractor-edition) .export-center-actions {
    /* minmax(0, 1fr), not 1fr. A bare `1fr` is `minmax(auto, 1fr)`, so a column whose content
       will not shrink pushes it wider and squeezes the other one: with FreshBooks shipped the
       row became QuickBooks 124px beside Xero 153px, because "Manage connections" sits in the
       second column and sets its floor. Which is the same fault Steve named on 2026-08-22 --
       "kinda looks like we're giving preference to Freshbooks (which I certainly am not!!!!!!)"
       -- arriving again by a different route the moment a fifth destination appeared. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  body:not(.contractor-edition) #bk-platform-buttons:not([style*="none"]) {
    display: contents !important;
  }
  /* Contractor Edition's picker is a row of three parts and takes the width. */
  #ce-platform-control {
    grid-column: 1 / -1;
  }
  /* NOT display:grid on this one. Contractor Edition's picker is hidden by an inline
     style="display: none" that Bookkeeper Edition never removes,
and `display: grid !important`
     outranks an inline style: it put a stop sign,
an empty dropdown and a Connect button on a
     bookkeeper's screen. Size its children instead and leave its display alone. */
  #ce-platform-control {
    width: 100%;
    gap: 8px !important;
  }
  #ce-platform-control > select,
#ce-platform-control > .cloud-sync-btn {
    flex: 1 1 auto;
  }
  .export-center-actions .cloud-sync-btn {
    width: 100%;
    justify-content: center;
  }
  /* The ZIP button lives in its own positioned wrapper because a popover hangs off it. As a flex
     box the button inside stretches to whatever height the row takes,
so it lines up with
     FreshBooks beside it instead of sitting 9px proud of it. */
  .export-center-actions > .relative.inline-block {
    display: flex;
    width: 100%;
  }
  .export-center-actions > .relative.inline-block > .cloud-sync-btn {
    width: 100%;
  }
  #zip-export-popover {
    width: 100%;
    left: 0;
    right: 0;
  }

  /* ---- the two notices --------------------------------------------------------------- */
  /* The sync notice is the longest text on the screen and it is reference material,
not
     something to act on. It keeps every word and stops competing for the eye. */
  #export-center-compliance-banner {
    font-size: 0.68rem;
    line-height: 1.45;
    align-items: flex-start !important;
  }
  #export-center-compliance-banner > div {
    align-items: flex-start !important;
  }

  /* The categorise banner puts its sentence and its button on one line,
and the button carries
     whitespace-nowrap,
so the button kept its width and the sentence was squeezed into a
     column. The button goes underneath and spans the banner,
which also makes it a target a
     thumb can hit. The frame is written from JS on every render,
so these hang off the id,
which that rewrite cannot remove. */
  #export-center-classify-banner {
    flex-wrap: wrap;
    row-gap: 10px;
  }
  #export-center-classify-banner > div:first-child {
    flex: 1 0 100%;
    min-width: 0;
  }
  #export-center-classify-action {
    flex: 1 0 100%;
  }
  #export-center-classify-action button {
    width: 100%;
  }

  /* ---- the selection row ------------------------------------------------------------- */
  .ec-control-row {
    flex-wrap: wrap;
    row-gap: 10px;
  }
  .ec-global-select{ order: 1; }
  /* Which platform "already sent" is measured against comes second now,
and the all/unsent
     toggle third and centred. The two cannot share a line at this width and it is not close:
     the global select needs 135px and the platform select alone is about 180px,
of 284px of
     usable row. So the scope takes a whole line rather than being left to wrap,
which also
     guarantees the toggle starts a line of its own -- and only then do the auto margins on it
     have free space to centre into. */
  .ec-scope {
    order: 2;
    flex: 1 0 100%;
    /* align-items is centre at every width now, so it is not repeated here. What this rule still
       does is give the block a line of its own: the select alone is about 180px of 284px usable. */
  }
  /* THE TOGGLE MOVED INSIDE .ec-scope on 2026-09-05, so the order and auto margins that used to
     place it here have nothing to act on. It is the select it has to share a line with, and at
     this width the two do not fit: the platform select alone is about 180px of 284px usable. So
     the row wraps and centres rather than being squeezed, and the two stay the same height as
     each other whichever line they land on. */
  .ec-scope-row {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 6px;
  }

  /* ---- what will be sent ------------------------------------------------------------- */
  /* Not a pill. A capsule holds a few words on one line; this is five figures and a warning,
and forcing them into one made it read as barely fitting. One row per ledger,
the counts
     in their own column,
the off-tab warning as a footer,
which is the shape of the record
     list further down the same screen. */
  .ec-selection-breakdown {
    order: 4;
    /* flex-basis 100% is what puts it on a line of its own. Without it, `display: block` still
       leaves it a flex ITEM of the control row, and it sized itself to its content and sat on
       top of the history filter. */
    flex: 1 0 100%;
    display: block !important;
    width: 100%;
    padding: 10px 12px;
    border-radius: 10px;
  }
  .ec-bd-label {
    display: block;
    margin-bottom: 6px;
  }
  .ec-bd-sep {
    display: none;
  }
  /* row-reverse puts the <strong> count,
which is written first,
on the right,
so the ledger
     names align down the left and the figures align down the right. */
  .ec-bd-item {
    display: flex;
    flex-direction: row-reverse;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    padding: 3px 0;
    border-top: 1px solid rgba(129, 140, 248, 0.16);
  }
  .ec-bd-warn {
    display: block;
    margin-top: 8px;
    text-align: center;
  }

  /* ---- the ledger tabs --------------------------------------------------------------- */
  /* Reaching a ledger must not require discovering that a strip scrolls. Steve,
2026-08-22:
     "Always a bad choice." Four of the seven were off the right-hand edge with nothing saying
     they existed,
so a person could export from one tab while six others were fully ticked,
which is the exact failure the will-send figures were added to prevent. Equal tiles rather
     than a wrap,
because a wrap of seven different widths is what read as random. */
  .export-center-tabs {
    display: grid !important;
    /* minmax(0, 1fr), not 1fr. A bare 1fr has an AUTO minimum, and .ec-tab-btn is nowrap, so
       each track was pinned to its widest label and the two came to 329px inside a 300px strip.
       Measured: 168px and 157px, unequal, with the right-hand column ending 29px past the edge.
       It only showed up when COIs became Compliance and made the left column the wider one. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    /* Tailwind's gap-1 is on the element and is 4px; this needs to be the known number the
       centring below is written against. */
    gap: 6px !important;
    overflow-x: visible;
  }
  /* Every tab gets the tile the active one already had. .ec-tab-btn carries a transparent 1px
     border at every size,
so turning it visible changes nothing about the geometry and the
     seven read as one set rather than one button and six labels. The per-ledger active colours
     are `[data-tab=...].active`,
which outranks this and still wins. */
  /* Tightened so the longest label,
"Compliance (3) ZIP" with its icon,
fits a 147px track
     rather than being clipped by it. */
  .export-center-tabs > .ec-tab-btn {
    width: 100%;
    justify-content: flex-start;
    text-align: left;
    font-size: 0.68rem;
    /* 6px, not 8px. At 8px the longest label needed 148px of a 145px box and was cut off, which
       overflow:hidden below would have hidden rather than shown. */
    padding: 7px 6px;
    overflow: hidden;
    border-color: rgba(100, 116, 139, 0.3);
    background: rgba(15, 23, 42, 0.5);
  }
  /* An odd one out is centred on its row WITHOUT being made wider. Spanning both columns and
     setting a width back to one column's worth does not work: a percentage width on a grid item
     resolves against its area,
and it measured 147px against the 139px of every other tab.
     Leaving it in column one and shifting it is exact instead. Half a column plus half a gap
     lands its centre on the strip's centre,
and 50% here is 50% of the button,
which IS one
     column,
so the arithmetic holds whatever the strip is worth. */
  .export-center-tabs > .ec-tab-btn:last-child:nth-child(odd) {
    transform: translateX(calc(50% + 3px));
  }
}

.cloud-sync-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 8px;
  font-size: 0.75rem;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid transparent;
}
.cloud-sync-btn.btn-qbo {
  background: rgba(44, 160, 28, 0.2);
  color: #4ade80;
  border-color: rgba(74, 222, 128, 0.3);
}
.cloud-sync-btn.btn-qbo:hover {
  background: rgba(44, 160, 28, 0.4);
}
.cloud-sync-btn:has(.status-light-dot.disconnected.stop-sign) {
  background: rgba(153, 27, 27, 0.25) !important;
  color: #fca5a5 !important;
  border-color: rgba(239, 68, 68, 0.5) !important;
}
.cloud-sync-btn:has(.status-light-dot.disconnected.stop-sign):hover {
  background: rgba(153, 27, 27, 0.45) !important;
}

.cloud-sync-btn.btn-xero {
  background: rgba(19, 181, 234, 0.2);
  color: #38bdf8;
  border-color: rgba(56, 189, 248, 0.3);
}
.cloud-sync-btn.btn-xero:hover {
  background: rgba(19, 181, 234, 0.4);
}

.cloud-sync-btn.btn-wave {
  background: rgba(2, 132, 199, 0.2);
  color: #60a5fa;
  border-color: rgba(96, 165, 250, 0.3);
}
.cloud-sync-btn.btn-wave:hover {
  background: rgba(2, 132, 199, 0.4);
}

.cloud-sync-btn.btn-freshbooks {
  background: rgba(0, 117, 225, 0.2);
  color: #93c5fd;
  border-color: rgba(147, 197, 253, 0.3);
}
.cloud-sync-btn.btn-freshbooks:hover {
  background: rgba(0, 117, 225, 0.4);
}

.cloud-sync-btn.btn-archive {
  background: rgba(168, 85, 247, 0.2);
  color: #c084fc;
  border-color: rgba(192, 132, 252, 0.3);
}
.cloud-sync-btn.btn-archive:hover {
  background: rgba(168, 85, 247, 0.4);
}
.ec-btn-toggle.active {
  background: rgba(16, 185, 129, 0.2);
  color: #34d399;
  border-color: rgba(52, 211, 153, 0.4);
}

.ec-tab-btn {
  background: transparent;
  border: 1px solid transparent;
  color: #94a3b8;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.2s ease;
}
.ec-tab-btn:hover {
  background: rgba(255, 255, 255, 0.05);
  color: #f1f5f9;
}

/* Receipts - Rose #FF2A5F */
.ec-tab-btn[data-tab="expense_ledger"].active {
  background: rgba(255, 42, 95, 0.15);
  color: #ff2a5f;
  border: 1px solid rgba(255, 42, 95, 0.4);
  box-shadow: 0 0 12px rgba(255, 42, 95, 0.2);
}

/* Invoices - Mint Emerald #10B981 */
.ec-tab-btn[data-tab="income_ledger"].active {
  background: rgba(16, 185, 129, 0.15);
  color: #10b981;
  border: 1px solid rgba(16, 185, 129, 0.4);
  box-shadow: 0 0 12px rgba(16, 185, 129, 0.2);
}

/* Utilities - Vibrant Orange #F97316 */
.ec-tab-btn[data-tab="utility_ledger"].active {
  background: rgba(249, 115, 22, 0.15);
  color: #f97316;
  border: 1px solid rgba(249, 115, 22, 0.4);
  box-shadow: 0 0 12px rgba(249, 115, 22, 0.2);
}

/* Mileage - Electric Cyan #00F5D4 */
.ec-tab-btn[data-tab="mileage_ledger"].active {
  background: rgba(0, 245, 212, 0.15);
  color: #00f5d4;
  border: 1px solid rgba(0, 245, 212, 0.4);
  box-shadow: 0 0 12px rgba(0, 245, 212, 0.2);
}

/* W-9s - Amber Yellow #F7DF1E */
.ec-tab-btn[data-tab="vendor_ledger"].active {
  background: rgba(247, 223, 30, 0.15);
  color: #f7df1e;
  border: 1px solid rgba(247, 223, 30, 0.4);
  box-shadow: 0 0 12px rgba(247, 223, 30, 0.2);
}

/* Compliance COIs - Sapphire Blue #2F80ED */
.ec-tab-btn[data-tab="compliance_ledger"].active {
  background: rgba(47, 128, 237, 0.15);
  color: #2f80ed;
  border: 1px solid rgba(47, 128, 237, 0.4);
  box-shadow: 0 0 12px rgba(47, 128, 237, 0.2);
}

/* Quotes - Royal Purple #A855F7 */
.ec-tab-btn[data-tab="quotes_ledger"].active {
  background: rgba(168, 85, 247, 0.15);
  color: #a855f7;
  border: 1px solid rgba(168, 85, 247, 0.4);
  box-shadow: 0 0 12px rgba(168, 85, 247, 0.2);
}

.ec-data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
  margin-top: 10px;
  table-layout: fixed;
}
.ec-data-table th {
  background: rgba(15, 23, 42, 0.9);
  color: #94a3b8;
  padding: 8px 10px;
  text-align: left;
  font-weight: 700;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  position: sticky;
  top: 0;
  z-index: 5;
}
.ec-data-table td {
  padding: 6px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  color: #e2e8f0;
}
.ec-row:hover {
  background: rgba(255, 255, 255, 0.03);
}
.ec-row-warning {
  background: rgba(244, 63, 94, 0.1) !important;
}

/* NINE COLUMNS DO NOT FIT ON A PHONE, AND NEITHER DOES A CARD MADE OF ALL NINE
   -----------------------------------------------------------------------------
   The table is 743px of columns in a 300px container: the tick and the date were off to the
   left, the vendor could not be reached at all, and the description column, the only one with
   no fixed width, took what was left and set a product name one word to a line.

   The first answer here was a card carrying every cell. It measured well and it was still
   wrong, 2026-08-22: "This just ain't hitting it for me. It definitely looks like a
   'workaround'." The regular ledgers had already solved this and I did not go and look at how.
   They hide the surplus columns outright on a phone and let the row's own expander show the
   rest, so a list reads as a list. This does the same thing.

   Closed, a record is one line: when, who, how much. Open, the four that were hidden appear
   underneath it, above the breakdown the arrow already produced.

   Deliberately NOT a second renderer. renderGrid() still writes the same nine cells and this
   reshapes them, because the fault fixed a few hours earlier tonight was two renderers of one
   panel drifting apart until the phone's copy stopped working. A column added to the table
   appears here without anyone remembering to.

   The widths are !important because renderGrid writes them inline, per cell, and an inline
   width beats a stylesheet. Nothing else here needs it. */
@media (max-width: 767px) {
  .ec-data-table,
.ec-data-table > tbody {
    display: block;
    width: 100%;
    table-layout: auto;
  }
  /* The headings named columns that are no longer columns. */
  .ec-data-table > thead {
    display: none;
  }
  .ec-data-table > tbody > tr.ec-row {
    display: grid;
    /* The last two tracks are FIXED, not auto. Every record is its own grid, so an auto track is
       sized by that row alone and nothing lines up down the list: on Tax Docs the last column
       holds "1099-NEC" on one row and "W-9" on the next, and the date moved with it. Reported
       2026-08-22: "the date placement is extremely inconsistent and is determined by the tax
       doctype. This cannot be." Fixed tracks give every row the same column, which is what a
       column is. The name takes what is left, which is the one thing that should vary. */
    grid-template-columns: 20px 20px minmax(0, 1fr) 66px 68px;
    align-items: center;
    gap: 6px;
    padding: 9px 8px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 11px;
  }
  .ec-data-table > tbody > tr.ec-row > td {
    display: block;
    width: auto !important;
    max-width: none !important;
    min-width: 0;
    padding: 0;
    border: none;
  }
  /* Who,
when,
how much — the order the Receipts ledger already uses on this screen,
which is
     what was asked for. The name takes the flexible track because it is the one that varies and
     the one the eye scans for; the date and the amount are fixed-shape and take what they need. */
  /* TAX DOCS PUTS THE DATE AT THE EDGE. Asked for 2026-08-22: "swap the date and the tax doc
     type,
so the date is always at the edge and the tax doctype is the middle column." Every
     other ledger ends on a figure and this one has none,
so on this tab alone the two trade
     places. Mobile only: the desktop table has column HEADINGS,
and moving a cell out from under
     the word Date is a different and worse thing than moving it in a list that has none.
     The hook is the table's own data-tab,
so the rule cannot fire on the wrong ledger. */
  .ec-data-table[data-tab="vendor_ledger"] > tbody > tr.ec-row > .ec-cell-amount {
    grid-column: 4;
    text-align: left !important;
  }
  .ec-data-table[data-tab="vendor_ledger"] > tbody > tr.ec-row > .ec-cell-date {
    grid-column: 5;
    text-align: right;
  }
  .ec-cell-expand{ grid-column: 1; grid-row: 1; }
  .ec-cell-tick{ grid-column: 2; grid-row: 1; }
  .ec-cell-name{ grid-column: 3; grid-row: 1; }
  .ec-cell-date{ grid-column: 4; grid-row: 1; }
  .ec-cell-amount{ grid-column: 5; grid-row: 1; }

  /* Everything else is behind the arrow. The four rules that put them back have to carry the
     SAME path as the rule that hides them: a bare `.ec-row-expanded > .ec-cell-details` loses
     to `.ec-data-table > tbody > tr.ec-row > .ec-cell-details` on specificity,
and the arrow
     then opens a breakdown while the four cells it is meant to reveal stay hidden. That is how
     this was written the first time,
and the browser caught it rather than a reading. */
  .ec-data-table > tbody > tr.ec-row > .ec-cell-docnum,
.ec-data-table > tbody > tr.ec-row > .ec-cell-details,
.ec-data-table > tbody > tr.ec-row > .ec-cell-shield,
.ec-data-table > tbody > tr.ec-row > .ec-cell-doc {
    display: none;
  }
  .ec-data-table > tbody > tr.ec-row.ec-row-expanded > .ec-cell-details {
    display: block;
    grid-column: 3 / -1;
    grid-row: 2;
    white-space: normal !important;
    padding-top: 4px !important;
  }
  .ec-data-table > tbody > tr.ec-row.ec-row-expanded > .ec-cell-docnum {
    display: block;
    grid-column: 3;
    grid-row: 3;
    text-align: left;
  }
  .ec-data-table > tbody > tr.ec-row.ec-row-expanded > .ec-cell-shield {
    display: block;
    grid-column: 4;
    grid-row: 3;
    text-align: left !important;
  }
  .ec-data-table > tbody > tr.ec-row.ec-row-expanded > .ec-cell-doc {
    display: block;
    grid-column: 5;
    grid-row: 3;
    text-align: right !important;
  }

  /* An input with no width attribute is about 177px wide,
and in an `auto` grid track that
     becomes the column: measured at 153px,
which left the vendor 2px and drew the row as a date
     and a price with a gap between them.

     The path has to be this long. `.ec-cell-amount .ec-inline-input` is two classes,
and so is
     `.ec-inline-input[readonly]` further down this file,
so the tie goes to whichever comes
     last and that is not this one. Being inside a media query does not add specificity. */
  /* The two ledgers that put text in this column rather than a figure render it a size larger
     than the row,
and "3 policies" then needed 72px of a 68px track and wrapped,
taking the
     whole record to two lines. It matches the row now. */
  .ec-data-table > tbody > tr.ec-row > .ec-cell-amount > span {
    font-size: 11px;
    white-space: nowrap;
  }
  .ec-data-table > tbody > tr.ec-row > .ec-cell-amount .ec-inline-input {
    width: 9ch;
    padding: 0;
    font-size: 11px;
    text-align: right;
  }
  .ec-data-table > tbody > tr.ec-row > .ec-cell-name .ec-inline-input {
    padding: 0;
    font-size: 11px;
    text-overflow: ellipsis;
  }
  .ec-cell-date {
    white-space: nowrap;
    color: #94a3b8;
  }

  /* The breakdown the arrow opens still contains real tables — line items,
coverages,
trip
     legs — and those are genuinely tabular. They keep their shape and scroll inside the row
     rather than widening it. */
  .ec-data-table > tbody > tr.ec-child-row {
    display: block;
  }
  .ec-data-table > tbody > tr.ec-child-row > td {
    display: block;
    width: auto !important;
    padding: 0;
    overflow-x: auto;
  }
}

.ec-inline-input[readonly] {
  width: 100%;
  box-sizing: border-box;
  background: transparent !important;
  border: 1px solid transparent !important;
  outline: none !important;
  cursor: pointer !important;
  color: inherit;
  box-shadow: none !important;
  padding: 2px 4px;
}
.ec-inline-input[readonly]:hover,
.ec-inline-input[readonly]:focus {
  background: transparent !important;
  border: 1px solid transparent !important;
  outline: none !important;
  cursor: pointer !important;
  box-shadow: none !important;
}

.ec-inline-input:not([readonly]) {
  background: #0f172a !important;
  border: 1px solid #6366f1 !important;
  outline: none !important;
  cursor: text !important;
  color: #ffffff !important;
  padding: 2px 6px;
  border-radius: 4px;
  box-shadow: 0 0 8px rgba(99, 102, 241, 0.4) !important;
}

/* Which platform "already sent" is measured against,
with its count stacked underneath
   rather than sitting beside it. Side by side the two ate enough width to wrap the
   selection breakdown onto a second line; stacked they fit inside the height the
   Select all / Clear all block already sets,
so the control row does not grow. */
/* THE HEADING GOES ABOVE ITS CONTROLS, the same way "All ledgers" does at the other end of this
   row. It used to sit beside the select reading "Already in", which was wrong twice over: it named
   where records ARE, when what this actually decides is which platform the whole Status column is
   measured against, and a label inside the row made it impossible for the select and the button
   next to it to line up. Steve, 2026-09-05: "it is uneven with the 'All Records' directly next to
   it, and that looks sloppy."
   CENTRED OVER ITS CONTROLS, not right aligned. This was flex-end for a day, which kept the block
   hanging off the right of the control row where it has always sat but pushed the heading over the
   All Records button rather than over the pair. Steve: "the 'Status by Platform' looks cockeyed. It
   needs to be centered over those items, not right aligned." The block still sits at the right end
   of the row, because the row's own layout puts it there; align-items decides only where the
   heading and the count sit ACROSS it. */
.ec-scope {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  line-height: 1.1;
}
/* Brighter than the muted grey it replaced, because it names the thing that changes the meaning of
   every row below it. Slate-300 rather than an accent: this is a heading, not a warning, and the
   colours that carry meaning in this table are already spoken for. */
.ec-scope-label {
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #cbd5e1;
}
.ec-scope-row {
  display: flex;
  align-items: stretch;
  gap: 6px;
  font-size: 0.69rem;
  font-weight: 500;
  color: #64748b;
}
/* THE SELECT AND THE TOGGLE ARE ONE HEIGHT, and it is set here rather than left to whichever
   padding each happened to carry. They were 3px/6px against 4px/10px with different radii and
   different font sizes, which is exactly what "uneven" looks like. align-items: stretch above
   makes them share a line; this makes them share a size. */
.ec-scope-select,
.ec-scope-row .ec-unsent-toggle {
  height: 26px;
  box-sizing: border-box;
  font-size: 0.69rem;
}
.ec-scope-select {
  background: #1e293b;
  border: 1px solid #334155;
  color: #e2e8f0;
  padding: 0 6px;
  border-radius: 6px;
}
.ec-scope-select:focus {
  outline: none;
  border-color: #10b981;
}
.ec-scope-count {
  font-size: 0.63rem;
  font-weight: 500;
  color: #64748b;
  white-space: nowrap;
}

/* nowrap on all four of these,
not two. ec-pending-pill and ec-sent-pill got it when their
   wording grew long enough to break; the other two were only ever safe because a desktop column
   is 90px wide and "Clean" is short. In a phone card the column is whatever is left over,
and
   "Clean" broke away from its tick and sat on its own line under it. */
/* ALL FOUR ARE BUTTONS NOW, 2026-09-05, and each one has to LOOK like something you can press.
   The reason a record carries its status was already written and lived in a `title`, which a
   mouse finds by accident and a phone never finds at all. Steve, on sixty rows each reading
   Warning: "there is NOTHING that indicates what each warning means." The pointer cursor and the
   hover lift are the part that says the answer is one press away. `cursor: help` was already on
   two of them and, tellingly, not on the warning -- the one he asked about. */
.ec-warning-pill, .ec-ok-pill, .ec-pending-pill, .ec-sent-pill {
  font-family: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  /* A real target rather than a five pixel word, for the same reason the connection light was
     given one: this is pressed with a thumb as often as with a mouse. */
  min-height: 24px;
  line-height: 1.25;
}
.ec-warning-pill:hover, .ec-ok-pill:hover, .ec-pending-pill:hover, .ec-sent-pill:hover {
  filter: brightness(1.25);
}
.ec-warning-pill:focus-visible, .ec-ok-pill:focus-visible,
.ec-pending-pill:focus-visible, .ec-sent-pill:focus-visible {
  outline: 2px solid #38bdf8;
  outline-offset: 1px;
}
.ec-warning-pill {
  display: inline-block;
  white-space: nowrap;
  background: rgba(244, 63, 94, 0.2);
  color: #f43f5e;
  border: 1px solid rgba(244, 63, 94, 0.4);
  font-size: 0.7rem;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 600;
}
.ec-ok-pill {
  display: inline-block;
  white-space: nowrap;
  color: #34d399;
  font-size: 0.7rem;
  font-weight: 600;
  background: transparent;
  border: 1px solid transparent;
  padding: 2px 6px;
  border-radius: 4px;
}
.ec-ok-pill:hover {
  border-color: rgba(52, 211, 153, 0.4);
}

/* Sent to a DIFFERENT platform,
but not to the one in scope — so it is still waiting to go.
   Two earlier attempts at this were wrong. "Clean,
in QuickBooks Online" while the scope was
   Xero said the opposite of what it meant,
because the eye takes the platform name as where
   the record IS going. Naming both platforms then wrapped onto a second line,
which grew
   every row and made the whole table jump on switching scope. So: ONE word,
no wrap,
the
   same footprint as Sent,
and the detail lives in the tooltip where it costs no height. */
.ec-pending-pill {
  display: inline-block;
  white-space: nowrap;
  background: rgba(56, 189, 248, 0.15);
  color: #38bdf8;
  border: 1px solid rgba(56, 189, 248, 0.35);
  font-size: 0.7rem;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 600;
  /* pointer, not help: it is a button now. Declared here as well as in the shared rule above
     because this one comes later and would otherwise win. */
  cursor: pointer;
}

/* Record already delivered to the platform in scope. This carries the strongest warning in
   the column,
ahead of a preflight fault: a miscategorised record can be fixed in the books,
but a second send is a duplicate transaction the user has to go and unpick by hand. It
   used to wear the calm blue now given to Unsent,
which read as reassurance. */
.ec-sent-pill {
  display: inline-block;
  white-space: nowrap;
  background: rgba(249, 115, 22, 0.18);
  color: #fb923c;
  border: 1px solid rgba(249, 115, 22, 0.45);
  font-size: 0.7rem;
  padding: 2px 6px;
  border-radius: 4px;
  font-weight: 600;
  cursor: pointer;
  animation: ec-sent-pulse 1.9s ease-in-out infinite;
}

/* The first version breathed only the border and a faint halo, on the theory that 152 of
   these on screen at once would strobe. It went the other way: at 1px and 0.3 alpha it was
   invisible unless you zoomed in and stared. Fill, text and glow all move now, and the
   badge swings from orange to full red at the peak — still short of .warning-pulse-row,
   which drives an entire row's background, but present enough to be seen in passing. */
@keyframes ec-sent-pulse {
  0%, 100% {
    background: rgba(249, 115, 22, 0.18);
    border-color: rgba(249, 115, 22, 0.5);
    color: #fb923c;
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
  }
  50% {
    background: rgba(239, 68, 68, 0.42);
    border-color: rgba(248, 113, 113, 1);
    color: #fecaca;
    box-shadow: 0 0 10px 2px rgba(239, 68, 68, 0.55);
  }
}

/* Motion here is decoration, not information — the word and the colour already say it. */
@media (prefers-reduced-motion: reduce) {
  .ec-sent-pill{ animation: none; }
}

/* "All Records" / "Unsent Only" export-history filter toggle */
.ec-unsent-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(15, 23, 42, 0.9);
  border: 1px solid rgba(71, 85, 105, 0.6);
  color: #94a3b8;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  cursor: pointer;
  transition: all 0.15s ease;
}
.ec-unsent-toggle:hover {
  border-color: rgba(56, 189, 248, 0.5);
  color: #e2e8f0;
}
.ec-unsent-toggle .ec-unsent-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #475569;
  transition: all 0.15s ease;
}
.ec-unsent-toggle.active {
  background: rgba(56, 189, 248, 0.15);
  border-color: rgba(56, 189, 248, 0.55);
  color: #38bdf8;
}
.ec-unsent-toggle.active .ec-unsent-dot {
  background: #38bdf8;
  box-shadow: 0 0 6px rgba(56, 189, 248, 0.9);
}

/* The status explainer. Sits above the Export Center, which is itself a .modal-dialog-overlay, so
   it needs a z-index of its own: two elements at 200 leaves the winner to document order, and this
   one is added to the page before the Export Center is. */
.ec-explain-overlay {
  z-index: 320;
  align-items: center;
}
.ec-explain-dialog {
  max-width: 460px;
  width: min(460px, calc(100vw - 40px));
  padding: 18px 20px 16px;
  border-radius: 16px;
  background: rgba(15, 23, 42, 0.97);
  border: 1px solid rgba(99, 102, 241, 0.35);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  color: #e2e8f0;
}
.ec-explain-head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.3;
  margin-bottom: 10px;
}
.ec-explain-icon { font-size: 1.05rem; line-height: 1.3; }
.ec-explain-headline { flex: 1; }
.ec-explain-dismiss {
  background: none;
  border: 0;
  color: #64748b;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}
.ec-explain-dismiss:hover { color: #e2e8f0; }
.ec-explain-body {
  font-size: 0.82rem;
  line-height: 1.55;
  color: #cbd5e1;
}
/* The second sentence of every one of these says what happens next, and it is the half people
   skip. Given its own weight rather than left as more of the same paragraph. */
.ec-explain-body .ec-explain-note { margin: 0 0 8px; }
.ec-explain-body .ec-explain-dim { display: block; margin-top: 6px; color: #94a3b8; }
.ec-explain-ok {
  margin-top: 14px;
  width: 100%;
  padding: 9px 12px;
  border-radius: 10px;
  border: 1px solid rgba(99, 102, 241, 0.45);
  background: rgba(99, 102, 241, 0.18);
  color: #c7d2fe;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
}
.ec-explain-ok:hover { background: rgba(99, 102, 241, 0.3); color: #fff; }
/* Warning wears its own edge, because it is the only one of the four that asks for something to
   be done rather than describing where a record has been. */
.ec-explain-overlay[data-kind="warning"] .ec-explain-dialog {
  border-color: rgba(244, 63, 94, 0.45);
}

.ec-expand-btn {
  background: rgba(99, 102, 241, 0.15);
  border: 1px solid rgba(99, 102, 241, 0.3);
  color: #818cf8;
  cursor: pointer;
  padding: 1px 5px;
  font-size: 0.7rem;
  border-radius: 4px;
  transition: all 0.15s ease;
}
.ec-expand-btn:hover {
  background: rgba(99, 102, 241, 0.35);
  color: #ffffff;
}

.ec-doc-btn {
  background: rgba(59, 130, 246, 0.2);
  color: #60a5fa;
  border: 1px solid rgba(96, 165, 250, 0.3);
  font-size: 0.7rem;
  padding: 2px 6px;
  border-radius: 4px;
  cursor: pointer;
}
.ec-doc-btn:hover {
  background: rgba(59, 130, 246, 0.4);
}

#execute-export-main {
  background-color: #6366f1 !important;
  color: #ffffff !important;
  box-shadow: 0 4px 14px rgba(99, 102, 241, 0.4) !important;
}
#execute-export-main:hover {
  background-color: #4f46e5 !important;
}

.ec-empty-state {
  text-align: center;
  padding: 40px 20px;
  color: #64748b;
  font-style: italic;
  font-size: 0.85rem;
}

/* OAuth Status Badge Indicators */
.status-light-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-right: 6px;
  vertical-align: middle;
  transition: all 0.2s ease;
  /* The light is itself a control: it opens the connection manager, so re-authorising
     no longer requires the connection to be broken first. */
  cursor: pointer;
}
.status-light-dot:hover {
  transform: scale(1.25);
}
.status-light-dot:focus-visible {
  outline: 2px solid #38bdf8;
  outline-offset: 2px;
}

.status-light-dot.connected {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 8px rgba(34, 197, 94, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.4);
}

/* Third state: the platform could not be reached,
so the connection is neither proven
   live nor proven dead. Green would be a lie; red would wrongly demand a reconnect.
   Amber + slow pulse reads as "checking / unknown" rather than "go" or "stop". */
.status-light-dot.unverified {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #f59e0b;
  box-shadow: 0 0 8px rgba(245, 158, 11, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.4);
  animation: ec-unverified-pulse 1.8s ease-in-out infinite;
}

@keyframes ec-unverified-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

/* Fourth state,
added 2026-08-13: the connection is fine,
or irrelevant,
because Sync cannot
   export to this platform yet. Not green,
because nothing can be sent. Not red,
because there is
   nothing for the user to fix and a stop sign would send them round a pointless re-authorisation.
   A steady grey ring reads as "present but inactive",
which is exactly the situation.

   This exists because `.status-light-dot.disconnected` on its own had NO size rule at all: only
   `.disconnected.stop-sign` was styled,
so the light the not-implemented branch asked for rendered
   at zero by zero and the FreshBooks button simply had nothing beside it. A missing light next to
   two working ones does not read as "not supported yet",
it reads as broken. */
.status-light-dot.not-supported {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(148, 163, 184, 0.25);
  border: 1px solid rgba(148, 163, 184, 0.7);
  box-shadow: none;
}

/* Any `disconnected` light that reaches the page without the stop sign still gets a size,
so a
   state nobody anticipated shows something rather than nothing. */
.status-light-dot.disconnected {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(148, 163, 184, 0.25);
  border: 1px solid rgba(148, 163, 184, 0.7);
}

.status-light-dot.disconnected.stop-sign {
  width: 16px;
  height: 16px;
  background: linear-gradient(135deg, #ef4444 0%, #b91c1c 100%);
  clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
  animation: stopSignPulse 1.8s infinite ease-in-out;
}

.status-light-dot.disconnected.stop-sign::after {
  content: 'STOP';
  font-size: 5.5px;
  font-weight: 900;
  color: #ffffff;
  letter-spacing: 0.2px;
  font-family: system-ui, -apple-system, sans-serif;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  text-align: center;
}

@keyframes stopSignPulse {
  0% {
    transform: scale(1);
    filter: drop-shadow(0 0 2px rgba(239, 68, 68, 0.6));
  }
  50% {
    transform: scale(1.18);
    filter: drop-shadow(0 0 8px rgba(239, 68, 68, 0.9));
  }
  100% {
    transform: scale(1);
    filter: drop-shadow(0 0 2px rgba(239, 68, 68, 0.6));
  }
}

/* ── Export result panel ─────────────────────────────────────────────────────────────
   Replaces the browser alert() that used to report export outcomes. A modal forces the
   user to read and dismiss before they can look at anything else,
and truncates when the
   content is long. Results belong in the page. */
.ec-result {
  border-radius: 10px;
  border: 1px solid rgba(71, 85, 105, 0.6);
  background: rgba(15, 23, 42, 0.92);
  padding: 10px 12px;
  font-size: 0.72rem;
  line-height: 1.5;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.ec-result.hidden{ display: none; }

.ec-result-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  letter-spacing: 0.01em;
}
.ec-result-icon{ font-size: 0.85rem; line-height: 1; }
.ec-result-headline{ flex: 1; }

.ec-result-dismiss {
  background: none;
  border: 0;
  color: #64748b;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
  transition: color 0.15s ease;
}
.ec-result-dismiss:hover{ color: #e2e8f0; }

.ec-result-body{ margin-top: 7px; }
.ec-result-note{ margin: 0 0 7px 0; }
.ec-result-note:last-child{ margin-bottom: 0; }
.ec-result-dim{ color: #94a3b8; font-style: italic; }

/* A control offered INSIDE an export result,
which today is only "send the ones that fit" when
   Xero has refused a whole selection for want of its daily allowance. It has to look like
   something to press: the first version of it inherited nothing and rendered as plain text with a
   pointer cursor,
which is a control that does not look like one. */
.ec-btn-inline {
  display: inline-block;
  padding: 5px 11px;
  margin-right: 6px;
  border-radius: 7px;
  border: 1px solid rgba(56, 189, 248, 0.45);
  background: rgba(56, 189, 248, 0.12);
  color: #7dd3fc;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.ec-btn-inline:hover:not(:disabled) {
  background: rgba(56, 189, 248, 0.2);
  border-color: rgba(56, 189, 248, 0.7);
}
.ec-btn-inline:focus-visible{ outline: 2px solid #38bdf8; outline-offset: 2px; }
.ec-btn-inline:disabled{ opacity: 0.5; cursor: default; }
/* THE LINE OF ARCHIVES. It borrows .ec-result's shell so it sits in the panel like everything
   else, and adds only what a list of waiting things needs. Its own colour is deliberately calm:
   waiting is not a warning, and an amber box would have people pressing Export again. */
.ec-queue .ec-result-head,
.ec-queue .ec-result-icon{ color: #7dd3fc; }
.ec-queue-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  border-top: 1px solid rgba(71, 85, 105, 0.35);
}
.ec-queue-row:first-child{ border-top: 0; }
.ec-queue-what{ flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.ec-queue-where{ color: #94a3b8; white-space: nowrap; }
.ec-queue-now{ color: #34d399; white-space: nowrap; font-weight: 700; }
.ec-queue-stop {
  background: none;
  border: 1px solid rgba(244, 63, 94, 0.45);
  color: #fb7185;
  border-radius: 6px;
  padding: 2px 9px;
  font-size: 0.7rem;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.ec-queue-stop:hover:not(:disabled){ background: rgba(244, 63, 94, 0.15); border-color: #fb7185; }
.ec-queue-stop:disabled{ opacity: 0.45; cursor: default; }

/* A PACK THAT DIED. Until 2026-09-03 its line simply left the screen and somebody went on waiting
   for a file that was never coming. The reason sits on its own line below the row because it is a
   sentence rather than a status, and wrapping it into the row would push the button off a phone. */
.ec-queue-row-failed{ flex-wrap: wrap; }
.ec-queue-failed{ color: #fbbf24; white-space: nowrap; font-weight: 700; }
.ec-queue-why{
  flex-basis: 100%;
  color: #cbd5e1;
  font-size: 0.7rem;
  line-height: 1.35;
  padding-bottom: 2px;
}

.ec-result-ok    .ec-result-head,
.ec-result-ok    .ec-result-icon{ color: #34d399; }
.ec-result-info  .ec-result-head,
.ec-result-info  .ec-result-icon{ color: #38bdf8; }
.ec-result-warn  .ec-result-head,
.ec-result-warn  .ec-result-icon{ color: #f59e0b; }
.ec-result-error .ec-result-head,
.ec-result-error .ec-result-icon{ color: #f43f5e; }

.ec-result-body strong{ color: #e2e8f0; }


/* Export button while a run is in flight. The connection is verified with a live call to
   the platform (~1s) before the export starts; without a visible busy state the button
   looks unresponsive and users click again,
which duplicated an entire set of books. */
.cloud-sync-btn.ec-btn-busy,
.cloud-sync-btn:disabled {
  opacity: 0.55;
  cursor: progress;
  pointer-events: none;
  filter: saturate(0.6);
}


/* =============================================================================================
 * THE BOOKKEEPER LINK PANEL
 *
 * A connection is a relationship between two accounts,
so the panel has to answer three
 * questions at a glance: who,
how much has moved,
and how do I stop it. Everything below serves
 * that and nothing else — the code itself is the only thing given any size,
because it is the
 * one piece of it a person has to read out loud over a phone.
 * ============================================================================================= */

.bk-link-list{ margin: 8px 0 4px; }

/* WHAT THE ROWS ABOVE THE FORM ARE. They used to float directly above "Send my paperwork to a
   bookkeeper" with nothing naming them, so the panel read as one long thing with two date pickers
   in it. Steve, 2026-08-30: "it's a little confusing... I guarantee someone is gonna be confused
   by [it] - cause people are like that & truth be told, it sorta got me as well." */
.bk-link-list-head {
  margin: 14px 0 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #94a3b8;
}

/* REMOVE, ON A FINISHED ROW ONLY. Deliberately not .bk-link-danger: nothing is destroyed and
   nothing about the connection changes, so it must not wear the colour that Disconnect wears.
   Red is reserved. */
.bk-link-remove {
  flex: 0 0 auto;
  padding: 5px 9px;
  font-size: 11px;
  font-weight: 600;
  border-radius: 6px;
  cursor: pointer;
  color: #94a3b8;
  background: rgba(148, 163, 184, 0.08);
  border: 1px solid rgba(148, 163, 184, 0.22);
}
.bk-link-remove:hover{ background: rgba(148, 163, 184, 0.18); color: #e2e8f0; }
.bk-link-remove:disabled{ opacity: 0.4; cursor: default; }

/* The folded send form, when there is already an invitation out or a connection live. It is one
   line of text and the sentence explaining what opening it would do, so it cannot be mistaken for
   a control belonging to the connection above it. */
.bk-link-block-quiet { border-top-style: dashed; }

.bk-link-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  margin-bottom: 8px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(15, 23, 42, 0.55);
  font-size: 12px;
  color: #e2e8f0;
}
.bk-link-row[data-status="active"]{ border-color: rgba(0, 245, 212, 0.30); }
.bk-link-row[data-status="invited"]{ border-color: rgba(245, 158, 11, 0.35); }
/* A finished connection is history,
not a problem. Red is reserved for things that need doing. */
.bk-link-row[data-status="revoked"]{ opacity: 0.7; }

/* An active connection carries a second line of controls,
so it stacks rather than sitting on
   one row like the pending and finished ones. */
.bk-link-row-stack{ flex-direction: column; align-items: stretch; }
.bk-link-row-main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* WHAT IS ON OFFER, on the card where she decides. She was being asked to accept a connection
   without being told how much of his history came with it, which is the one fact that decides
   whether the answer is useful to her. */
.bk-link-offered { margin-top: 8px; color: #cbd5e1; }
.bk-link-offered strong { color: #e2e8f0; }

/* WHAT HE HAS TO FINISH BEFORE HE CAN CONNECT. It replaces the buttons rather than sitting
   beside them: a message next to a live Send button is a message that gets pressed past. Amber
   and not red -- nothing is broken and nothing has failed, there is simply a step first. Red in
   this app is reserved for somebody needing help. */
.bk-link-profile-gap {
  margin-top: 12px;
  padding: 11px 12px;
  border: 1px solid rgba(245, 158, 11, 0.35);
  border-left: 3px solid rgba(245, 158, 11, 0.75);
  border-radius: 6px;
  background: rgba(245, 158, 11, 0.07);
  font-size: 11px;
  color: #cbd5e1;
}
.bk-link-profile-gap strong{ display: block; color: #fbbf24; margin-bottom: 4px; font-size: 12px; }
.bk-link-profile-gap span{ display: block; line-height: 1.45; }

/* HOW FAR BACK HE IS SHARING. Sits above the two consent switches, because it is the wider
   question: those decide which KINDS of document go, this decides how much of his history does.

   The sentence and the selector are separate on purpose. The sentence states the stored date and
   is always true; the selector is a list of changes and never claims to be showing the current
   one. A select whose value is not among its options silently displays the first option instead,
   and "the last 90 days" resolves to a different day tomorrow than it did today, so a selector
   that tried to show the setting would start lying within a day of being used. */
.bk-link-range {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}
.bk-link-range-now{ font-size: 11px; color: #cbd5e1; flex: 1 1 190px; min-width: 0; }
.bk-link-range-now strong{ color: #e2e8f0; }
.bk-link-range-pick {
  flex: 0 1 auto;
  width: auto;
  max-width: 100%;
  /* NO font-size OVERRIDE, AND THAT IS THE WHOLE NOTE. The first version set 11px to match the
     small print beside it, and in WebKit that made the control 19px tall against 22px for every
     other select in the app: Safari draws a native select from its FONT and ignores author
     padding and min-height entirely, so the usual levers do nothing. Chrome laid the same rule
     out at 30px and would never have shown it.

     appearance: none is the documented lever and it is deliberately not used. It was tried on a
     select in this stylesheet before and it deletes the chevron, so the control stops looking
     like a menu; the note above #export-center-start-date records that.

     So this inherits .glass-input's size and is exactly as big as the "Which business" and "File
     it under" selectors he already uses. WHAT IS NOT PROVED: whether 22px is comfortable on a
     real iPhone. Playwright's WebKit on this Mac is not iOS Safari and does not size controls
     like it, so the absolute number here means nothing about his phone. The relative one does,
     and that is what test_sharing_range_control.mjs asserts. */
  min-height: 0;
}
/* What the BOOKKEEPER sees in its place: the range, and who to ask about it. */
.bk-link-range-note{ margin-top: 8px; }

/* The W-9 switch. Deliberately plain: a control that gives away somebody's tax number should
   look like a decision,
not like a preference. */
.bk-link-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  font-size: 11px;
  color: #cbd5e1;
  cursor: pointer;
}
.bk-link-toggle input{ accent-color: #00F5D4; cursor: pointer; }
.bk-link-toggle + .bk-link-toggle{ margin-top: 4px; padding-top: 0; border-top: none; }
/* What the BOOKKEEPER sees in place of the switches: the state,
and who to ask. */
.bk-link-consent-note{ margin-top: 8px; }
.bk-link-consent-note + .bk-link-consent-note{ margin-top: 2px; }
.bk-link-toggle em{ color: #94a3b8; font-style: normal; }

.bk-link-sub {
  margin-top: 3px;
  font-size: 11px;
  color: #94a3b8;
  line-height: 1.45;
}
.bk-link-sub em{ color: #cbd5e1; font-style: normal; }

.bk-link-danger {
  flex: 0 0 auto;
  padding: 6px 10px;
  font-size: 11px;
  font-weight: 600;
  border-radius: 6px;
  cursor: pointer;
  color: #f87171;
  background: rgba(239, 68, 68, 0.10);
  border: 1px solid rgba(239, 68, 68, 0.25);
}
.bk-link-danger:hover{ background: rgba(239, 68, 68, 0.18); }

.bk-link-block {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}
.bk-link-block h4 {
  margin: 0 0 4px;
  font-size: 12px;
  font-weight: 700;
  color: #f1f5f9;
  letter-spacing: 0.02em;
}
.bk-link-help {
  margin: 0 0 10px;
  font-size: 11px;
  line-height: 1.5;
  color: #94a3b8;
}

/* Item 22: "4 records have changed since you sent them". Amber,
not red: red is reserved for
   real exposure and a record you changed after sending it is worth knowing,
not an emergency. */
/* ITEMS 17 AND 21,
2026-08-21. The address box's answer,
and an invitation that names her.
   Deliberately quiet: this is somebody's name being confirmed,
not an alert. Green for a hit and
   grey for a miss,
because "no account there yet" is a perfectly good outcome he can act on and
   colouring it as a failure would tell him to stop. */
.bk-link-found {
  margin: 8px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid rgba(148, 163, 184, 0.25);
  background: rgba(148, 163, 184, 0.06);
  line-height: 1.45;
}
.bk-link-found[data-found="yes"] {
  border-color: rgba(52, 211, 153, 0.35);
  background: rgba(52, 211, 153, 0.08);
  color: #d1fae5;
}
.bk-link-found strong{ color: #ffffff; }

/* One invitation,
with everything she needs to answer it on the same card. Teal,
the colour
   reserved for invitations across the whole app since v10.036 — not red,
which is kept for
   exposure,
and not amber,
which is "should know". */
.bk-link-invite-card {
  margin: 10px 0;
  padding: 12px;
  border-radius: 10px;
  border: 1px solid rgba(45, 212, 191, 0.45);
  background: rgba(45, 212, 191, 0.07);
}
.bk-link-invite-who {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 6px;
}
.bk-link-invite-who strong{ color: #99f6e4; font-size: 0.95rem; }
.bk-link-invite-who span{ color: #94a3b8; font-size: 0.78rem; word-break: break-all; }
/* ITEM 31. The one thing on this card she has to read,
so it sits between the card and the
   button rather than under it as small print. */
.bk-link-ack {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  background: rgba(148, 163, 184, 0.07);
  border: 1px solid rgba(148, 163, 184, 0.22);
  color: #cbd5e1;
  font-size: 0.78rem;
  line-height: 1.45;
  cursor: pointer;
}
.bk-link-ack input{ margin-top: 3px; flex: 0 0 auto; }

.bk-link-invite-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
  flex-wrap: wrap;
}
.bk-link-invite-actions .cta-button{ flex: 1 1 auto; }

.bk-link-changed {
  margin-bottom: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid rgba(217, 165, 69, 0.35);
  background: rgba(217, 165, 69, 0.08);
  font-size: 12px;
  line-height: 1.5;
}
.bk-link-changed strong {
  display: block;
  color: #f1f5f9;
  font-weight: 700;
  margin-bottom: 3px;
}
.bk-link-changed span {
  color: #94a3b8;
}

/* Item 13: a contractor has one business,
so the panel STATES which one is being connected
   instead of asking a question with a single answer. Brighter than the surrounding help text
   because it is a fact about what is about to happen,
not an aside. */
.bk-link-which {
  color: #cbd5e1;
}
.bk-link-which strong {
  color: #f1f5f9;
  font-weight: 700;
}

/* Item 12: each edition sees its own half of the wire. The other half is folded away rather than
   removed,
because window.appEdition can be briefly absent and a bookkeeper who cannot find the
   accept panel has no way to discover why. Kept visually quiet so it reads as an escape hatch and
   not as a second,
equal choice. */
.bk-link-other {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid rgba(148, 163, 184, 0.18);
}
.bk-link-textlink {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 11px;
  color: #94a3b8;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.bk-link-textlink:hover {
  color: #cbd5e1;
}
.bk-link-textlink:focus-visible {
  outline: 2px solid rgba(0, 245, 212, 0.6);
  outline-offset: 3px;
  border-radius: 2px;
}
.bk-link-other > div[hidden] {
  display: none;
}
.bk-link-other > div:not([hidden]) {
  margin-top: 12px;
}

/* The code is the whole point of the contractor's half of this panel: it is read aloud,
so it
   is set large {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding: 12px;
  border-radius: 8px;
  border: 1px solid rgba(0, 245, 212, 0.35);
  background: rgba(0, 245, 212, 0.06);
}

.bk-link-msg {
  margin: 10px 0 2px;
  padding: 9px 11px;
  border-radius: 8px;
  font-size: 11.5px;
  line-height: 1.5;
}
.bk-link-msg[data-kind="ok"] {
  color: #6ee7b7;
  background: rgba(16, 185, 129, 0.10);
  border: 1px solid rgba(16, 185, 129, 0.28);
}
.bk-link-msg[data-kind="error"] {
  color: #fca5a5;
  background: rgba(239, 68, 68, 0.10);
  border: 1px solid rgba(239, 68, 68, 0.28);
}
/* Added 2026-08-24 with "ending the relationship also ends the connection". Half of that job
   can succeed while the other half cannot reach the accounting platform,
and neither green nor
   red is honest about it: the relationship really did end,
and a key really is still live. It
   needs its own colour,
and it must not be red -- red is reserved for an exposure,
and this
   tells somebody exactly what is left to do. */
.bk-link-msg[data-kind="warn"] {
  color: #fcd34d;
  background: rgba(245, 158, 11, 0.10);
  border: 1px solid rgba(245, 158, 11, 0.32);
}


/* =============================================================================================
 * THE GIVING QUESTION,
on the receipt review form.
 *
 * A quiet control that becomes a prompt only when the vendor reads like an organisation rather
 * than a shop. It must never look like an alarm: nothing is wrong,
there is simply a fact worth
 * establishing while the person still remembers the answer.
 * ============================================================================================= */

/* The prompt sits BENEATH the control,
not beside the label. Next to the label it wrapped to
   four lines and shouldered its neighbour out of alignment,
which is what Steve saw on screen:
   two fields side by side,
one of them three times the height of the other. */



/* Copies taken of a contractor's records,
on the connect screen. Added 2026-08-21.
   Sits inside .bk-link-row-stack under the consent switches,
so it reads as part of the
   connection rather than as a separate feature. */
.bk-link-exports {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(148, 163, 184, 0.18);
}
.bk-link-exports-head {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #94a3b8;
  margin-bottom: 6px;
}
.bk-link-exports-list {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.bk-link-exports-list li {
  padding: 6px 8px;
  border-radius: 6px;
  background: rgba(15, 19, 28, 0.6);
  border: 1px solid rgba(148, 163, 184, 0.14);
}
.bk-link-exports-list strong{ display: block; font-size: 0.8rem; color: #e2e8f0; }
.bk-link-exports-note{ font-style: italic; opacity: 0.85; }

.bk-link-collections {
  list-style: none;
  margin: 6px 0 0;
  padding: 0 0 0 10px;
  border-left: 2px solid rgba(148, 163, 184, 0.22);
  font-size: 0.72rem;
  color: #94a3b8;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bk-link-collections em{ opacity: 0.75; }

/* ── Connection Center ────────────────────────────────────────────────────────────────────
   Added 2026-08-24. Every class below is used by src/engines/connectionCenter.js,
and the
   button rules exist because a <button> with no rule renders as plain text with a pointer
   cursor -- which is exactly how .ec-btn-inline shipped invisible on 2026-08-23 and was only
   caught by loading the real stylesheet into the test harness.

   THE OVERLAY KEEPS .modal-dialog-overlay AS WELL AS .cc-overlay. desktop.js clears the
   inspection pane on any click outside the content grid and exempts that class by name; a
   dialog opened from a client's row without it would close the row behind it. */
.cc-launch{ margin-top: 12px; }

.cc-open-btn {
  display: inline-block;
  padding: 7px 14px;
  border-radius: 8px;
  border: 1px solid rgba(56, 189, 248, 0.45);
  background: rgba(56, 189, 248, 0.12);
  color: #7dd3fc;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.cc-open-btn:hover{ background: rgba(56, 189, 248, 0.2); border-color: rgba(56, 189, 248, 0.75); }
.cc-open-btn:focus-visible{ outline: 2px solid #38bdf8; outline-offset: 2px; }

.cc-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  background: rgba(2, 6, 23, 0.78);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.cc-dialog {
  width: 100%;
  max-width: 520px;
  max-height: 86vh;
  overflow-y: auto;
  border-radius: 14px;
  border: 1px solid rgba(51, 65, 85, 0.9);
  background: #0b1220;
  padding: 18px 20px 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.cc-head{ display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.cc-head h3{ margin: 0; font-size: 0.95rem; font-weight: 800; color: #e2e8f0; letter-spacing: 0.02em; }
.cc-sub{ margin: 2px 0 0; font-size: 0.78rem; color: #94a3b8; }
.cc-close {
  border: 0; background: transparent; color: #94a3b8;
  font-size: 1.4rem; line-height: 1; cursor: pointer; padding: 0 4px;
}
.cc-close:hover{ color: #e2e8f0; }
.cc-close:focus-visible{ outline: 2px solid #38bdf8; outline-offset: 2px; }

.cc-rows{ margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.cc-row {
  border: 1px solid rgba(51, 65, 85, 0.8);
  border-radius: 10px;
  background: rgba(15, 23, 42, 0.6);
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "main act" "sub act";
  gap: 2px 12px;
  align-items: center;
}
.cc-row-main{ grid-area: main; display: flex; align-items: center; gap: 8px; }
.cc-row-sub{ grid-area: sub; font-size: 0.74rem; color: #cbd5e1; }
.cc-row-act{ grid-area: act; }
.cc-plat{ font-size: 0.84rem; font-weight: 700; color: #e2e8f0; }
.cc-state{ font-size: 0.74rem; color: #94a3b8; }
.cc-dim{ color: #64748b; font-style: italic; }

/* Semantic,
and separate from the accent. Amber is "not answered",
never "broken" --
   unverified is not disconnected,
and colouring it red would send somebody to reconnect a
   connection that is working. */
.cc-dot{ width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.cc-on{ background: #22c55e; box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18); }
.cc-off{ background: #64748b; }
.cc-unknown{ background: #f59e0b; box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.16); }

.cc-btn {
  padding: 6px 12px;
  border-radius: 7px;
  border: 1px solid rgba(56, 189, 248, 0.45);
  background: rgba(56, 189, 248, 0.12);
  color: #7dd3fc;
  font-size: 0.76rem;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.cc-btn:hover{ background: rgba(56, 189, 248, 0.2); border-color: rgba(56, 189, 248, 0.75); }
.cc-btn:focus-visible{ outline: 2px solid #38bdf8; outline-offset: 2px; }
/* Ending a connection is not the same kind of act as starting one,
and the button should not
   look like it is. Not the red reserved for an exposure -- this is deliberate,
not wrong. */
.cc-btn-cut {
  border-color: rgba(248, 113, 113, 0.45);
  background: rgba(248, 113, 113, 0.1);
  color: #fca5a5;
}
.cc-btn-cut:hover{ background: rgba(248, 113, 113, 0.18); border-color: rgba(248, 113, 113, 0.7); }
.cc-btn-cut:focus-visible{ outline: 2px solid #f87171; }

.cc-note{ margin: 12px 0 0; font-size: 0.76rem; color: #94a3b8; }
.cc-warn{ color: #fcd34d; }
.cc-foot{ margin: 14px 0 0; font-size: 0.72rem; color: #64748b; line-height: 1.5; }

@media (max-width: 480px) {
  .cc-row{ grid-template-columns: 1fr; grid-template-areas: "main" "sub" "act"; gap: 6px; }
  .cc-row-act{ justify-self: stretch; }
  .cc-btn{ width: 100%; }
}

/* Waiting for the other window. Added 2026-08-24 after Steve refused the "Check again" button:
   "that shouldn't be there. It needs to be automatic." What replaces it must still SAY that
   something is happening -- a control that has silently gone away reads as one that ignored you. */
.cc-waiting {
  display: inline-block;
  padding: 6px 12px;
  font-size: 0.74rem;
  font-weight: 700;
  color: #fcd34d;
  white-space: nowrap;
}

/* "Manage connections" — the advertised way into connection management,
added 2026-08-24 after
   Steve pointed out that the only route was clicking a 5px status light nothing pointed at,
and
   that in Bookkeeper Edition that dot sits INSIDE the platform button so a near miss ran an
   export instead.

   DELIBERATELY QUIETER THAN THE PLATFORM BUTTONS. It sits in the same row as QuickBooks,
Xero and
   FreshBooks and must not compete with them: those are the thing you came to press,
this is the
   thing you press occasionally. Legible,
obviously a control,
and second in the visual order. */
.ec-manage-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 9px;
  border: 1px solid rgba(100, 116, 139, 0.55);
  background: rgba(30, 41, 59, 0.7);
  color: #cbd5e1;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.ec-manage-btn:hover {
  background: rgba(51, 65, 85, 0.85);
  border-color: rgba(148, 163, 184, 0.75);
  color: #f1f5f9;
}
.ec-manage-btn:focus-visible{ outline: 2px solid #38bdf8; outline-offset: 2px; }

/* The light is an indicator now. It kept its click as a shortcut for anybody who already knows,
but it must not LOOK like the way in,
or the same mistake is being made in CSS instead of HTML. */
.status-light-dot{ cursor: default; }

/* "Exports go here" — Contractor Edition only. It answers a question Steve asked out loud: a
   panel listing three platforms reads as an invitation to connect all three,
when the design is
   that a business keeps one set of books and the others merely stay connected. Quiet,
because it
   is a label rather than a state: the light already carries the state. */
.cc-tag {
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #7dd3fc;
  background: rgba(56, 189, 248, 0.12);
  border: 1px solid rgba(56, 189, 248, 0.35);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
}

/* A line inside an opened record that is one of the lines a wedge was made of.
   The mark is a bar down the left edge plus a wash,
NOT a background colour on its own: the
   sub-table rows already sit on a translucent slate and a second flat fill just looks like a
   different striping. It uses the accent of whichever screen sent you here,
set as a custom
   property on the ledger card,
so the highlight is the same colour as the thing you pressed. */
tr.line-matched > td {
  background: var(--matched-wash, rgba(56, 189, 248, 0.10));
}
tr.line-matched > td:first-child {
  box-shadow: inset 3px 0 0 var(--matched-edge, #38bdf8);
  font-weight: 600;
}

/* =================================================================================
 * THE CATEGORIZE SCAN'S "THERE IS MORE COMING" INDICATOR
 *
 * Steve, 2026-09-01: *"When you're at the bottom of the list and waiting on the next batch to
 * load, the only way to know the next batch has loaded is when the number x of y line items will
 * be saved changes, which if you're not watching, you might not see."*
 *
 * The header already said "180 of 542 loaded, still working through the rest", and it was correct
 * and useless: by the time you are answering the last row on screen it has scrolled a thousand
 * pixels out of sight. The state a person needs at the bottom of a list is not a running total,
 * it is whether pressing down will do anything.
 *
 * Two indicators, and they must never both be looking at you:
 *   - the PILL floats over the bottom of the scroll area and appears only when there is list
 *     below the fold. It is a chevron, and pressing it goes down.
 *   - the END MARKER sits at the very bottom of the list itself, and only matters once you are
 *     there: three animated dots while a batch is still coming, and a plain sentence when there
 *     is nothing left to come.
 * ================================================================================= */

#classify-scroll-hint {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: #0f172a;
  background: #fbbf24;
  border: 1px solid rgba(255, 255, 255, 0.35);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
  cursor: pointer;
  /* It sits over rows that can be answered, so it must not swallow a press meant for one of
     them anywhere except on the pill itself. */
  pointer-events: auto;
  animation: classify-hint-in 180ms ease-out;
}

#classify-scroll-hint:hover { background: #fcd34d; }

#classify-scroll-hint .chev {
  display: inline-block;
  animation: classify-chev-nudge 1.4s ease-in-out infinite;
}

@keyframes classify-hint-in {
  from { opacity: 0; transform: translateX(-50%) translateY(6px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

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

/* THREE DOTS, and they have to be moving. A static row of dots is indistinguishable from a list
   that has quietly stopped, which is the exact confusion this whole thing exists to end. */
.classify-dots {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  vertical-align: middle;
}

.classify-dots i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #fbbf24;
  display: inline-block;
  animation: classify-dot 1.05s ease-in-out infinite;
}

.classify-dots i:nth-child(2) { animation-delay: 0.15s; }
.classify-dots i:nth-child(3) { animation-delay: 0.30s; }

@keyframes classify-dot {
  0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
  40%           { opacity: 1;    transform: translateY(-3px); }
}

/* Somebody who has asked for less movement gets less of it, and still gets the information:
   the dots stay lit rather than still, so "waiting" and "finished" remain different. */
@media (prefers-reduced-motion: reduce) {
  #classify-scroll-hint,
  #classify-scroll-hint .chev,
  .classify-dots i { animation: none; }
  .classify-dots i { opacity: 0.85; }
}

#classify-end {
  padding: 10px 2px 4px;
  font-size: 11px;
  color: #94a3b8;
  display: flex;
  align-items: center;
  gap: 8px;
}
