@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');

/* ── Field label wrapping — app-wide, zero HTML changes needed ───────────
   Every form field's <label> in this app is short text (often icon + a few
   words) sitting in a narrow grid column, so it wraps often. Default text
   wrapping is greedy — it fills the first line completely, however little
   is left over lands alone on a second line (e.g. "Fuel / Other Charges
   Collected" then a lone orphaned "(₹)"), which reads as broken next to a
   sibling label in the same row that didn't wrap at all, throwing the
   input boxes below out of alignment. text-wrap:balance instead distributes
   a wrapped label's characters evenly across its lines, so it never
   produces that single-orphaned-word look. Supported in all evergreen
   browsers (Chrome/Edge 114+, Firefox 121+, Safari 17.5+); unsupported
   browsers just keep the previous default wrapping — never worse than
   before. Scoped to <label> only (not headings/paragraphs) since that's
   exactly where this app's short-text-in-a-narrow-column pattern lives. */
label {
  text-wrap: balance;
}

/* ── Expense description quick-pick chips ─────────────────────────────────
   Shared by the 3 parallel transaction forms (New Transaction drawer, Edit
   Transaction modal, Vehicle-detail Add Transaction) — lets the admin tap a
   common expense category (Fuel/Washing/Service/...) instead of typing free
   text every time. "Others" stays available for anything uncategorized. */
/* Composes the .pill-badge shape/glow recipe (custom.css, Unified Button
   System section) via --pill-accent: amber, this chip's own accent color,
   same as the app's other quick-pick/status chips — was its own small
   rounded-rectangle shape before, now the same pill shape as every other
   chip in the app. */
.desc-chip {
  --pill-accent: #f59e0b;
  min-height: 18px;
  padding: 0.2rem 0.6rem;
  font-size: 0.6875rem;
  line-height: 1.4;
}
.desc-chip.desc-chip-active {
  color: #fcd34d;
}

/* ── App-wide hover/focus tooltip — one canonical style used everywhere,
   matching the dark rounded popup Chart.js already renders for the
   Monthly Overview chart's hover tooltip (dark box, white text, small
   pointer caret). Pure CSS, drop-in replacement for a plain `title`
   attribute: add `data-tooltip="Label text"` to any element (icon-only
   buttons benefit most, since they have no visible label of their own).
   Deliberately NOT applied to native form controls (<select>/<input>) —
   pseudo-elements don't render reliably there across browsers, so those
   keep their native title. Fleet Booking Calendar keeps its own existing
   custom tooltip (calShowBookingTooltip) and isn't touched by this.

   Scoped to (hover: hover) and (pointer: fine) — i.e. a real mouse, not a
   touchscreen. Two independent reasons:
    1. A CSS :hover tooltip is a poor fit for touch anyway — there's no
       reliable hover gesture, so it either never appears or gets "stuck"
       open after a tap with no obvious way to dismiss it.
    2. Even fully invisible (opacity:0, not currently hovered), an
       absolutely-positioned ::after with white-space:nowrap and
       left:50%/translateX(-50%) still occupies layout space that can
       extend past the true viewport edge for any tooltip sitting near a
       screen edge (header icons, this KPI row's own toggle button, etc).
       html having overflow-x:hidden stops that from becoming a visible
       scrollbar, but on mobile browsers it can still silently widen the
       page's effective layout viewport to fit that off-screen content —
       shrinking everything else (100%-width sections, [data-modal-page]'s
       max-width:639px mobile-fullscreen breakpoint) to fit inside a
       viewport wider than the actual screen. That's what was producing
       the reported dead space / non-full-screen modals on mobile — this
       media query removes the pseudo-elements from the layout tree
       entirely on touch devices, not just visually hides them. */
@media (hover: hover) and (pointer: fine) {
  [data-tooltip] {
    position: relative;
  }
  [data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    padding: 0.375rem 0.625rem;
    border-radius: 6px;
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
    opacity: 0;
    pointer-events: none;
    transition: opacity 150ms ease, transform 150ms ease;
    z-index: 9999;
  }
  /* Caret — built with the standard 3-border CSS-triangle trick (explicit
     width/height:0, only the "pointing" side's border gets a width; the
     other side is omitted entirely rather than set to transparent). The
     earlier version used the 4-side `border: Npx solid transparent` shorthand
     for all variants, which makes an hourglass-shaped border box whose
     colored half sits UNDER the tooltip's own text box — ::after (painted
     after ::before, per spec, regardless of source order) then drew right
     over it, hiding the arrow completely. Explicit width/height:0 avoids
     that entirely: the triangle's own box is exactly the caret's visible
     size, positioned to sit *in the gap* between the element and the text
     box, never underneath it. */
  [data-tooltip]::before {
    content: '';
    position: absolute;
    bottom: calc(100% + 2px);
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid rgba(0, 0, 0, 0.85);
    opacity: 0;
    pointer-events: none;
    transition: opacity 150ms ease;
    z-index: 9999;
  }
  [data-tooltip]:hover::after,
  [data-tooltip]:focus-visible::after {
    opacity: 1;
    transition-delay: 300ms;
    transform: translateX(-50%) translateY(0);
  }
  [data-tooltip]:hover::before,
  [data-tooltip]:focus-visible::before {
    opacity: 1;
    transition-delay: 300ms;
  }
  /* Flip below the element when it's near the top of the viewport (header
     icons) — opt in per-element with data-tooltip-pos="bottom". */
  [data-tooltip-pos="bottom"]::after {
    bottom: auto;
    top: calc(100% + 8px);
    transform: translateX(-50%) translateY(-4px);
  }
  [data-tooltip-pos="bottom"]:hover::after,
  [data-tooltip-pos="bottom"]:focus-visible::after {
    transform: translateX(-50%) translateY(0);
  }
  [data-tooltip-pos="bottom"]::before {
    bottom: auto;
    top: calc(100% + 2px);
    border-top: none;
    border-bottom: 5px solid rgba(0, 0, 0, 0.85);
  }
  /* Flip to the right of the element — used by the collapsed nav rail, whose
     icons sit flush against the left edge of the screen. */
  [data-tooltip-pos="right"]::after {
    bottom: auto;
    top: 50%;
    left: calc(100% + 10px);
    transform: translateY(-50%) translateX(-4px);
  }
  [data-tooltip-pos="right"]:hover::after,
  [data-tooltip-pos="right"]:focus-visible::after {
    transform: translateY(-50%) translateX(0);
  }
  [data-tooltip-pos="right"]::before {
    bottom: auto;
    top: 50%;
    left: calc(100% + 2px);
    transform: translateY(-50%);
    border-left: none;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    border-right: 5px solid rgba(0, 0, 0, 0.85);
  }
}

/* ── Description-cell tooltip (hover + tap), driven by js/utils/desc-tooltip.js ──
   Table Description/Details columns opt into this via a second attribute,
   [data-tooltip-tap], alongside the usual [data-tooltip] (kept separate so
   icon-only Edit/Delete/status buttons that carry [data-tooltip] purely as
   an accessible hover label keep performing their real tap action instead
   of being hijacked into popping up their own label as a "description").

   [data-tooltip-tap] elements are shown ONLY via this JS-positioned,
   position:fixed singleton — the pure-CSS [data-tooltip]::after popup above
   is explicitly suppressed for them (see the media-query rule right below).
   Reason: several of these tables sit inside a `.table-scroll-wrapper` with
   `overflow: auto` (needed for horizontal scroll + a sticky header) —
   that ancestor clips the CSS ::after popup whenever it renders above a row
   sitting near the top of the wrapper's current scroll position, which is
   exactly where a Description-column tooltip needs to appear, so it was
   silently invisible despite `opacity: 1`. A position:fixed popup appended
   to <body> isn't inside that overflow box, so it can't be clipped by it.
   Icon-only buttons ([data-tooltip] without the -tap attribute) aren't
   affected by that bug in practice (short single-line labels, not sitting
   right under a sticky header) so they're left on the simpler CSS-only path. */
@media (hover: hover) and (pointer: fine) {
  [data-tooltip][data-tooltip-tap]::after,
  [data-tooltip][data-tooltip-tap]::before {
    display: none;
  }
}
/* Same card look as the Fleet Calendar booking hover tooltip (#fcBookingTooltip
   above) — dark gradient, soft border, deep shadow, backdrop blur, and a
   diamond arrow pointing at whichever cell triggered it, flipping above/below
   depending on available space (js/utils/desc-tooltip.js's _positionPopup(),
   ported from fleet-calendar.js's _positionBookingTooltip()).

   Two open modes share this one popup:
   - Hover (desktop, real mouse): non-interactive, just like the Fleet
     Calendar tooltip — appears on mouseover, disappears on mouseout, no
     close button needed since moving the mouse away already closes it.
   - Tap (touch): needs an explicit dismissal since there's no hover-out
     gesture, so this mode alone adds .desc-tap-interactive, which is what
     turns on pointer-events (so the button is clickable) and reveals the
     close (×) button. */
#descTapTooltip {
  position: fixed;
  z-index: 10000;
  max-width: min(80vw, 300px);
  background: linear-gradient(180deg, rgba(30,41,59,0.98), rgba(15,23,42,0.98));
  border: 1px solid rgba(100,116,139,0.5);
  border-radius: 14px;
  box-shadow: 0 20px 40px -8px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.03);
  backdrop-filter: blur(10px);
  color: #fff;
  padding: 0.75rem 0.875rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  opacity: 0;
  transform: translateY(4px) scale(0.97);
  transition: opacity 150ms ease, transform 150ms ease;
  pointer-events: none;
}
#descTapTooltip.desc-tap-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}
#descTapTooltip.desc-tap-interactive.desc-tap-visible {
  pointer-events: auto;
}
#descTapTooltip.desc-tap-interactive {
  padding-right: 1.75rem;
}
#descTapTooltip::before {
  content: '';
  position: absolute;
  left: var(--desc-tt-arrow-left, 20px);
  width: 10px;
  height: 10px;
  background: #1e293b;
  border-left: 1px solid rgba(100,116,139,0.5);
  border-top: 1px solid rgba(100,116,139,0.5);
}
#descTapTooltip[data-arrow="bottom"]::before {
  bottom: -6px;
  transform: rotate(225deg);
}
#descTapTooltip[data-arrow="top"]::before {
  top: -6px;
  transform: rotate(45deg);
}
#descTapTooltip .desc-tap-close {
  display: none;
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  width: 1.25rem;
  height: 1.25rem;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.7rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
#descTapTooltip.desc-tap-interactive .desc-tap-close {
  display: flex;
}
#descTapTooltip .desc-tap-close:hover,
#descTapTooltip .desc-tap-close:active {
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
}
/* Marks the currently tap-opened trigger so re-tapping it toggles the
   popup closed instead of just re-opening the same content in place.
   Interactive (tap) mode only — a hover-opened popup never needs this,
   moving the mouse away already closes it. */
[data-tooltip-tap].desc-tap-active {
  outline: 1px dashed rgba(34, 211, 238, 0.5);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Modal header "expand to full screen" buttons ([data-expand-btn]) sit right
   next to the close (×) button with the same w-8 h-8 flex-centered box, but
   fa-expand's glyph isn't drawn symmetrically within its own em-box the way
   fa-times/fa-compress are — it visually reads as sitting high/off-center
   even though the button itself is centered correctly. Nudge the icon only. */
[data-expand-btn] i.fa-expand,
[data-expand-btn] i.fa-compress {
  transform: translateY(1px);
}

/* ── Homepage hero: full-bleed background photo behind a transparent-to-solid
   header (see js/utils/header-scroll.js). The url() below is only the
   pre-JS/offline fallback (public/images/hero-bg.jpg) — admins set the live
   image from Admin Panel → Branding, which is stored in RTDB and applied at
   runtime as an inline style on #homeHero (see brand-assets-service.js,
   [data-brand-hero]). ──────────────────*/
.hero-section {
  background-image: url('/images/hero-bg.jpg');
  background-size: cover;
  background-position: center;
  background-color: #0f172a; /* shows through while the photo loads / if it's missing */
  min-height: 520px;
  /* Break out of <main>'s side padding to bleed edge-to-edge regardless of
     its responsive px-3..px-16 scale — safe because html has
     overflow-x: hidden (see below), so 100vw can't cause a horizontal
     scrollbar. */
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
}
@media (min-width: 640px) {
  .hero-section { min-height: 640px; }
}
.hero-overlay {
  background-image: linear-gradient(to bottom, rgba(2,6,23,.35), rgba(2,6,23,.55) 55%, rgba(2,6,23,.88));
}
/* .hero-badge's actual rule now lives with the rest of the Badge/chip
   tier, further down this file ("Badge/chip: non-interactive trust
   indicators & status labels") — kept as one definition shared with the
   formal .badge class instead of duplicated here. */

/* ── Modal-as-Page: full-screen native screen on mobile ──────────────────*/
@media (max-width: 639px) {
  [data-modal-page] {
    background-color: transparent !important;
    padding: 0 !important;
    align-items: flex-start !important;
    justify-content: flex-start !important;
  }
  [data-modal-page] > [data-modal-inner] {
    width: 100vw !important;
    max-width: 100vw !important;
    height: 100dvh !important;
    max-height: 100dvh !important;
    border-radius: 0 !important;
    margin: 0 !important;
    overflow-y: auto;
  }
  /* Slide-in from right on open */
  [data-modal-page]:not(.hidden) > [data-modal-inner] {
    animation: mobilePageSlideIn 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
  }
}
@keyframes mobilePageSlideIn {
  from { transform: translateX(100%); }
  to   { transform: translateX(0); }
}

/* ── Right-side slide-over drawer (desktop) ───────────────────────────────
   Pairs with [data-modal-page] above: mobile (<640px) already gets the
   full-screen slide-in-from-right treatment for free from that rule. This
   block only adds the desktop (>=640px) right-side panel behavior for any
   modal that also carries [data-drawer] alongside [data-modal-page]. ────*/

/* Drawers are a docked side panel, not a floating centered card — the
   universal animated glow-border (see [data-modal-inner] further below) reads
   as a stray pulsating outline on a flush-edge panel, so drawers opt out of
   it at every breakpoint (including the mobile full-screen state). */
[data-drawer] > [data-modal-inner] {
  animation: none;
  box-shadow: -8px 0 32px rgba(0, 0, 0, 0.4);
}

@media (min-width: 640px) {
  [data-drawer] {
    align-items: stretch !important;
    justify-content: flex-end !important;
    padding: 0 !important;
  }
  [data-drawer] > [data-modal-inner] {
    max-width: 32rem;
    width: 100%;
    height: 100%;
    max-height: 100%;
    border-radius: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  }
  [data-drawer]:not(.hidden) > [data-modal-inner] {
    transform: translateX(0);
  }
}

.drawer-footer {
  position: sticky;
  bottom: 0;
  background: #1e293b;
  border-top: 1px solid rgba(51, 65, 85, 0.6);
  flex-shrink: 0;
}

/* ── Bottom-sheet modal safe-area (iPhone home bar) ─────────────────────────*/
@media (max-width: 639px) {
  [data-modal-inner] {
    padding-bottom: max(0px, env(safe-area-inset-bottom));
  }
}

/* ── Fleet Category Placeholder Cards ───────────────── */
@keyframes fleetBorderSpin {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
.fleet-cat-wrap {
  padding: 1.5px;
  border-radius: 1rem;
  background-size: 300% 300%;
  animation: fleetBorderSpin 5s ease infinite;
}
.fleet-cat-wrap-a {
  background-image: linear-gradient(135deg, #06b6d4, #3b82f6, #8b5cf6, #06b6d4);
  box-shadow: 0 8px 40px rgba(6,182,212,0.22);
}
.fleet-cat-wrap-b {
  background-image: linear-gradient(135deg, #6366f1, #3b82f6, #06b6d4, #6366f1);
  box-shadow: 0 8px 40px rgba(99,102,241,0.22);
}
.fleet-cat-wrap-c {
  background-image: linear-gradient(135deg, #a855f7, #ec4899, #7e22ce, #a855f7);
  box-shadow: 0 8px 40px rgba(168,85,247,0.22);
}
.fleet-cat-inner {
  border-radius: calc(1rem - 1.5px);
  position: relative;
  overflow: hidden;
  padding: 1.5rem;
  min-height: clamp(130px, 25vw, 168px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.fleet-cat-inner-a { background: linear-gradient(135deg, #082f49 0%, #0c6b8a 45%, #1e40af 100%); }
.fleet-cat-inner-b { background: linear-gradient(135deg, #1e1b4b 0%, #3730a3 45%, #0369a1 100%); }
.fleet-cat-inner-c { background: linear-gradient(135deg, #2e1065 0%, #6b21a8 45%, #9f1239 100%); }
.fleet-cat-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(40px);
  pointer-events: none;
}
.fleet-cat-ghost {
  position: absolute;
  top: -10px;
  right: -6px;
  font-size: 6rem;
  font-weight: 900;
  line-height: 1;
  letter-spacing: -3px;
  color: rgba(255,255,255,0.06);
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
}

/* ── Auth Modal ─────────────────────────────────────── */
/* ── Universal Modal Glow Border ─────────────────────── */
@keyframes modalBorderGlow {
  0%   { box-shadow: 0 0 0 1.5px rgba(6,182,212,0.75),  0 0 28px rgba(6,182,212,0.30),  0 24px 64px rgba(0,0,0,0.55); }
  25%  { box-shadow: 0 0 0 1.5px rgba(99,102,241,0.75), 0 0 28px rgba(99,102,241,0.30), 0 24px 64px rgba(0,0,0,0.55); }
  50%  { box-shadow: 0 0 0 1.5px rgba(168,85,247,0.75), 0 0 28px rgba(168,85,247,0.30), 0 24px 64px rgba(0,0,0,0.55); }
  75%  { box-shadow: 0 0 0 1.5px rgba(236,72,153,0.75), 0 0 28px rgba(236,72,153,0.30), 0 24px 64px rgba(0,0,0,0.55); }
  100% { box-shadow: 0 0 0 1.5px rgba(6,182,212,0.75),  0 0 28px rgba(6,182,212,0.30),  0 24px 64px rgba(0,0,0,0.55); }
}
[data-modal-inner] {
  animation: modalBorderGlow 5s ease-in-out infinite;
}
/* Every modal in this app goes edge-to-edge (full-bleed bottom sheet,
   flush against the screen's left/right edges) on mobile — the exact
   same condition [data-drawer] already opts out of this glow for below
   (see that rule's own comment: "reads as a stray pulsating outline on
   a flush-edge panel"), just true for every modal here, not only
   drawers. box-shadow draws OUTSIDE an element's own border; with the
   panel already touching the screen edges there's no room for the ring
   to visually wrap around it, so instead of an even glowing border it
   shows up as a bright, color-cycling line sitting a few px above/
   around the header — reported repeatedly as looking offset/broken on
   a Samsung Galaxy S23. Swapped for a plain static shadow below 640px —
   same depth cue, no animation, no color to look "offset" from
   anything. */
@media (max-width: 639.98px) {
  [data-modal-inner] {
    animation: none;
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.4);
  }
}

@keyframes authBorderSpin {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
.auth-modal-border {
  background: linear-gradient(135deg, #06b6d4, #3b82f6, #a855f7, #ec4899, #06b6d4);
  background-size: 300% 300%;
  animation: authBorderSpin 5s ease infinite;
  border-radius: 1rem;
  padding: 1px;
  box-shadow: 0 0 0 0 transparent, 0 0 28px rgba(6,182,212,0.30), 0 24px 64px rgba(0,0,0,0.55);
  animation: authBorderSpin 5s ease infinite, modalBorderGlow 5s ease-in-out infinite;
}
.auth-card {
  background: #1e293b;
  border-radius: calc(1rem - 1px);
  background-image: radial-gradient(rgba(148,163,184,0.05) 1px, transparent 1px);
  background-size: 20px 20px;
}
/* Below sm (640px), authModal's root is now .rp-modal, which lays this out
   as a full-bleed bottom sheet — flatten the bottom corners to match every
   other bottom-sheet modal in the app instead of a floating rounded card. */
@media (max-width: 639.98px) {
  .auth-modal-border { border-radius: 1rem 1rem 0 0; }
  .auth-card { border-radius: calc(1rem - 1px) calc(1rem - 1px) 0 0; }
}
.auth-heading-row {
  margin-bottom: 28px;
}
.auth-heading-row--compact {
  margin-bottom: 24px;
}
/* Login/Signup/phone-step heading block (logo + "Welcome to EliteSteer",
   etc.) — the 28px/24px gap below it reads fine on a tall desktop card,
   but on a phone it pushed the first input field nearly a quarter of the
   screen down before any content. Tighten just the gap and the card's own
   padding on mobile; desktop keeps the original, more generous spacing. */
@media (max-width: 639.98px) {
  .auth-modal-body.p-6 {
    padding: 1rem 1.25rem 1.5rem;
  }
  .auth-heading-row,
  .auth-heading-row--compact {
    margin-bottom: 16px;
  }
}
.auth-input-login {
  transition: border-color 0.2s, box-shadow 0.2s;
}
.auth-input-login:focus {
  border-color: #06b6d4 !important;
  box-shadow: 0 0 0 3px rgba(6,182,212,0.15);
  outline: none;
}
.auth-input-signup {
  transition: border-color 0.2s, box-shadow 0.2s;
}
.auth-input-signup:focus {
  border-color: #a855f7 !important;
  box-shadow: 0 0 0 3px rgba(168,85,247,0.15);
  outline: none;
}
.auth-tab-strip {
  border-bottom: 1px solid rgba(51,65,85,0.6);
  padding: 8px 10px 0;
  gap: 4px;
}
.auth-tab-btn {
  position: relative;
  transition: color 0.2s;
  padding-bottom: 10px;
  border-radius: 0;
  color: #94a3b8;
}
.auth-tab-btn:hover {
  color: #e2e8f0;
}
/* glowing bottom border on active tab */
.auth-tab-btn.auth-tab-active {
  color: transparent;
  background: linear-gradient(90deg, #06b6d4, #3b82f6, #a855f7);
  -webkit-background-clip: text;
  background-clip: text;
}
.auth-tab-btn.auth-tab-active::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 10%;
  width: 80%;
  height: 2px;
  border-radius: 2px 2px 0 0;
  background: linear-gradient(90deg, #06b6d4, #3b82f6, #a855f7);
  box-shadow: 0 0 8px rgba(6,182,212,0.6), 0 0 16px rgba(59,130,246,0.3);
}
/* ─────────────────────────────────────────────────── */

:root {
  --primary-color: #4f46e5;
  --primary-dark: #312e81;
  --success-color: #059669;
  --danger-color: #dc2626;
  --warning-color: #f59e0b;
  --gray-light: #f8fafc;
  --gray-border: #e5e7eb;
  --cyan-primary: #06b6d4;
  --cyan-light: #22d3ee;
  --slate-900: #0f172a;
  --slate-800: #1e293b;
  --slate-700: #334155;
}

/* overflow-x is handled on <html> instead (below) — setting it here too
   makes body's own overflow-y auto-compute to a non-'visible' value,
   which turns body into an unintended scroll container. position:sticky
   elements inside it then measure their sticky offset against body's own
   box instead of the real viewport, so they can appear to stop sticking /
   get hidden partway through a scroll. */
body {
  font-family: 'Inter', sans-serif;
  background-color: var(--slate-900);
  color: #ffffff;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* ── Standardized form field ───────────────────────────────────────────────
   One height/border/background/radius/placeholder recipe for every text-
   like input, date/time picker, and dropdown in the app, reading from the
   same design-tokens.css this file's button tiers use — so a field and a
   button sitting in the same row (e.g. the hero search's date/time inputs
   next to "Search Fleet") share one visual system instead of two, and
   both meet the 44px touch-target minimum via the same --control-height
   token .btn-primary/.btn-secondary/.btn-destructive use at 640px+.

   Height/padding/radius/transition are enforced directly (a plain
   tag+attribute selector, same as before) — these were the actually
   inconsistent properties worth standardizing outright. Background/
   border/text-color are instead set via :where(...), which has ZERO
   specificity: it supplies the shared default (--field-bg/--field-border/
   --field-text) for any field that doesn't set its own, but a field that
   DOES carry its own Tailwind class (bg-slate-800, bg-slate-900/70 on
   .dt-compact, bg-slate-600 inside a lighter modal, ...) keeps winning
   exactly as before — those exist for real contrast reasons against
   different modal/card backgrounds across the app, and a blanket
   override here would have flattened that on hundreds of fields sight
   unseen instead of by deliberate choice. */
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="password"],
input[type="date"],
input[type="datetime-local"],
select,
textarea {
  width: 100%;
  min-height: var(--field-height);
  padding: 0.625rem var(--field-padding-x);
  font-size: var(--field-font-size);
  line-height: 1.5;
  border-radius: var(--field-radius);
  transition: border-color var(--control-transition-duration) var(--control-transition-easing),
    box-shadow var(--control-transition-duration) var(--control-transition-easing);
}
:where(
  input[type="text"],
  input[type="email"],
  input[type="tel"],
  input[type="number"],
  input[type="password"],
  input[type="date"],
  input[type="datetime-local"],
  select,
  textarea
) {
  background-color: var(--field-bg);
  border: 1px solid var(--field-border);
  color: var(--field-text);
}
input[type="text"]::placeholder,
input[type="email"]::placeholder,
input[type="tel"]::placeholder,
input[type="number"]::placeholder,
input[type="password"]::placeholder,
textarea::placeholder {
  color: var(--field-placeholder);
}

@media (min-width: 640px) {
  input[type="text"],
  input[type="email"],
  input[type="tel"],
  input[type="number"],
  input[type="password"],
  input[type="date"],
  input[type="datetime-local"],
  select,
  textarea {
    font-size: 1rem;
  }
}

/* Fuel Level (select) + Range km (input) pairs: the input/select width:100%
   rule above is a compound selector (tag+attribute), which outranks the
   Tailwind .flex-1 / .w-32 utility classes on these two elements regardless
   of source order. Without this, the select collapses to near-zero width
   inside any narrower container (e.g. a 2-col grid) because the range
   input's "100%" wins the flex-basis fight and eats all the row's space. */
#tripStartFuelLevel, #editStartFuelLevel, #completeEndFuelLevel {
  width: auto;
  flex: 1 1 0%;
}
#tripStartFuelRange, #editStartFuelRange, #completeEndFuelRange {
  width: 8rem;
  flex: none;
}

/* Compact pickup/return date+time pickers (hero search, sticky edit-search
   bar, booking Step 1, My Bookings reschedule) live in a narrow
   grid-cols-[1.3fr_1fr] pair, each meant to be tight (Tailwind's px-2
   py-2.5 on the element) — but the input/select rule above (padding:
   0.75rem 1rem) is a compound tag+attribute selector that outranks a plain
   utility class, same trap as the fuel-level fields above, so it silently
   won regardless of the intended px-2/py-2.5. select{} further down also
   reserves 2.75rem of right padding for a dropdown arrow these compact
   selects never draw. On screens ≤640px the input/date/select font-size is
   additionally forced to 16px !important (prevents iOS auto-zoom on
   focus) with no matching padding reduction — between the oversized
   padding and the larger mobile font, there was routinely no room left in
   the column to render the date/time value at all. */
input[type="date"].dt-compact,
select.dt-compact {
  padding: 0.5rem 0.5rem;
  /* The shared input[type="date"]/select rule above this comment block
     sets min-height:var(--field-height) (44px) as a floor — padding
     alone can't shrink these below that, so a reduced padding here would
     otherwise silently have no visual effect. More specific already (two
     classes vs. one attribute selector), so this wins without !important.
     Uses --control-height-sm (the SAME token .btn-primary/.btn-secondary
     use below 640px) rather than its own hardcoded pixel value, so a
     compact date field sitting next to a button in the same row — the
     hero/booking search's Pickup/Return + Search Fleet row — lines up
     with it exactly at every breakpoint instead of needing to be
     pixel-matched by hand. */
  min-height: var(--control-height-sm);
  /* Same pill shape as .btn-primary/.btn-secondary/.btn-destructive
     (--control-radius-pill), not the field system's default
     --control-radius-rect — these compact pickers sit right next to those
     buttons (hero search, sticky booking-header popup) and read as part of
     the same control row, so they're deliberately matched to the button
     shape rather than the plain-field one. */
  border-radius: var(--control-radius-pill);
}
@media (min-width: 640px) {
  input[type="date"].dt-compact,
  select.dt-compact {
    min-height: var(--control-height);
  }
}

@media (max-width: 640px) {
  input[type="date"].dt-compact,
  select.dt-compact {
    padding: 0.625rem 0.25rem;
  }

  /* "dd-mm-yyyy" (10 characters) needs more room than a time slot like
     "10:00 AM" (8 characters) — the 1.3fr/1fr split (Tailwind's
     grid-cols-[1.3fr_1fr] utility class on the wrapper) still wasn't wide
     enough for the date column once the calendar icon and the forced 16px
     mobile font-size (anti-iOS-zoom) are both accounted for on a narrow
     phone, so the value had no room left and didn't render at all. Plain
     CSS override (not a new Tailwind arbitrary-value class like
     grid-cols-[1.6fr_1fr]) because that combination isn't already used
     elsewhere in the compiled, pre-built tailwind.css and would silently
     have no effect without a rebuild — same trap as the .dt-compact
     padding fix above. custom.css loads after tailwind.css, so this wins
     by source order even though both are single-class selectors. */
  .dt-grid {
    grid-template-columns: 1.6fr 1fr;
  }
}

/* #stickyDateEditPanel (the pencil-icon popup next to the date range in the
   booking header) is narrow by design regardless of viewport — capped at
   max-width:420px and then split into two flex-1 Pickup/Return columns, so
   each date+time pair only ever gets ~190px even on a wide desktop screen.
   The max-width:640px rules above only fire on an actually-narrow
   viewport, so on desktop this popup kept the wider padding/1.3fr ratio
   and "dd-mm-yyyy" still had no room — unconditional here since this
   container's narrowness isn't tied to viewport width at all. */
#stickyDateEditPanel .dt-grid {
  grid-template-columns: 1.7fr 1fr;
}
#stickyDateEditPanel input[type="date"].dt-compact,
#stickyDateEditPanel select.dt-compact {
  padding: 0.625rem 0.1875rem;
}
/* Above 640px, index.html's own sm:flex-row switches Pickup/Return from
   stacked to side-by-side inside this same 420px-capped popup — the inline
   Tailwind w-[min(90vw,420px)] utility on this element only ever supplies
   the 90vw part (this is a pre-built/purged tailwind.css with no build
   step, so an arbitrary-value class works only if that exact class string
   already exists somewhere in the compiled output; it does here, but
   420px was never enough once split into two side-by-side columns). Below
   640px the 90vw term already dominates that min() on every real phone
   width, so widening the fixed cap here doesn't affect the stacked mobile
   layout at all — measured (getBoundingClientRect) at 640-1024px: the time
   <select> collapsed to 25-50px there before this change, nowhere near
   enough for "10:00 AM", which is the truncation the pencil-icon popup
   screenshot showed. */
@media (min-width: 640px) {
  #stickyDateEditPanel {
    width: min(94vw, 500px) !important;
  }
  #stickyDateEditPanel > div.flex {
    gap: 0.5rem;
  }
  /* 1.7fr:1fr was tuned for the stacked mobile layout, where each column
     gets the full popup width and the date side's calendar-icon clearance
     is the binding constraint. Side-by-side, both columns share one much
     narrower row, and the time column was the one actually starving —
     re-measured after this change: no truncation 640-1024px, was
     collapsing to 25-50px before. */
  #stickyDateEditPanel .dt-grid {
    grid-template-columns: 1.15fr 1fr;
    gap: 0.375rem;
  }
}
/* The generic input rule bumps font-size to 1rem (16px) from 640px up —
   fine for most fields, but "dd-mm-yyyy" at 16px still didn't fit even
   after the ratio/padding fixes above: scrollWidth==clientWidth checks
   out because a native date input clips its internal day/month/year
   segments within the given box rather than reporting real DOM overflow,
   so that check passed while the value was still visibly cut off. 16px is
   only a hard requirement on mobile (prevents iOS auto-zoom on focus,
   enforced separately with !important at max-width:640px, which still
   wins over this on phones); desktop has no such constraint, so this
   popup's inputs can just run smaller here. */
#stickyDateEditPanel input[type="date"].dt-compact,
#stickyDateEditPanel select.dt-compact {
  font-size: 0.8125rem;
}

/* The native calendar icon is invisible-but-still-clickable on every date
   input — date-placeholder.js draws its own themed .rp-date-icon glyph on
   top instead (see responsive-primitives.css). Earlier versions of this
   fix tried recoloring the native icon directly (filter:invert(1),
   color-scheme:dark) — both real fixes on Chromium/WebKit desktop, but
   fragile: color-scheme:dark on the whole input once suppressed the
   "dd-mm-yyyy" placeholder digits' own color on Android Chrome specifically
   (field rendered fully blank, not just the icon), and neither approach
   does anything at all in Firefox, which has no styling hook for this
   glyph and paints its own unstyleable icon regardless — reported showing
   up black in multiple places despite the invert rule, since that rule can
   only ever affect Chromium/WebKit. A real DOM icon element behaves
   identically everywhere, same reasoning as the "dd-mm-yyyy"/value overlay
   already replacing native text rendering for the same cross-browser
   reasons. opacity (not display:none) keeps the tap target intact — the
   date input still opens its picker when tapped/clicked there. */
input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 0;
  cursor: pointer;
}

select {
  appearance: none;
  -webkit-appearance: none;
  background-image: none;
  padding-right: 2.75rem;
  color: #ffffff;
  color-scheme: dark;
}

select option {
  background-color: #1e293b;
  color: #ffffff;
  padding: 0.5rem;
}

/* Compact by default on every screen size — mouse/trackpad users on
   desktop and laptop don't need a 44-48px touch target, and the previous
   sizing here made every plain button in the app noticeably bigger/more
   padded than it needed to be. Touch accessibility isn't dropped, just
   moved to where it actually matters: the (pointer: coarse) rule below
   restores a real 44px minimum on touch devices specifically (phones,
   tablets), the same pattern already used for .btn-close/.btn-icon-danger
   and the dot/icon touch targets elsewhere in this file — so mouse users
   get the smaller, tighter button and touch users still get an
   accessible tap target, instead of one size compromising for both. */
button,
.btn {
  min-height: 36px;
  padding: 0.5rem 1rem;
  font-size: 0.8125rem;
  font-weight: 600;
  border-radius: 0.75rem;
  transition: all 0.2s ease;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  white-space: nowrap;
}

@media (min-width: 640px) {
  button,
  .btn {
    min-height: 40px;
    padding: 0.5625rem 1.25rem;
    font-size: 0.875rem;
  }
}

@media (pointer: coarse) {
  button,
  .btn {
    min-height: 44px;
  }
}

/* Header icon buttons (notification bell / account avatar / quick-access
   menu) are plain circular icon buttons, not labeled CTAs — the global
   button padding/min-height above (tuned for text buttons like "Search
   Fleet") was inflating their footprint well past their actual 36px
   (w-9 h-9) visual circle, which is what made the gaps between them look
   oversized. ID selectors here outrank the plain "button" element selector
   and the media query above, at every screen size, without touching any
   other button in the app. */
#notificationBell,
#userIconBtn,
#headerMenuBtn {
  min-height: 0;
  padding: 0;
}

label {
  display: inline-block;
  margin-bottom: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: #ffffff;
}

label.flex {
  display: flex;
  align-items: center;
  margin-bottom: 0.75rem;
}

label.flex i {
  flex-shrink: 0;
}

.relative > input {
  padding-left: 2.75rem;
}

.relative > select {
  padding-left: 2.75rem;
}

.relative > i.fa-location-dot,
.relative > i.fa-location-crosshairs,
.relative > i.fa-clock,
.relative > i.fa-chevron-down,
.relative > i.absolute {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
}

.relative > i.fa-location-dot,
.relative > i.fa-location-crosshairs,
.relative > i.fa-clock {
  left: 1rem;
}

.relative > i.fa-chevron-down {
  right: 1rem;
}

.relative > input[type="datetime-local"],
.relative > select {
  min-height: 48px;
  display: flex;
  align-items: center;
}

@media (min-width: 640px) {
  .relative > input[type="datetime-local"],
  .relative > select {
    min-height: 52px;
  }
}

#bookingPage {
  min-height: 100vh;
  padding-top: 0;
}

#bookingCheckoutStep label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: #ffffff;
}

@media (min-width: 640px) {
  #bookingCheckoutStep label {
    font-size: 0.9375rem;
  }
}

#bookingCheckoutStep input,
#bookingCheckoutStep select {
  min-height: 48px;
  padding: 0.875rem 1rem;
  padding-left: 2.75rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  border-radius: 0.75rem;
  transition: all 0.2s ease;
}

@media (min-width: 640px) {
  #bookingCheckoutStep input,
  #bookingCheckoutStep select {
    min-height: 52px;
    padding: 1rem 1rem;
    padding-left: 2.75rem;
    font-size: 1rem;
  }
}

#bookingCheckoutStep select {
  padding-right: 2.75rem !important;
}

#vehicleCardsContainer {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

@media (min-width: 768px) {
  #vehicleCardsContainer {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1280px) {
  #vehicleCardsContainer {
    grid-template-columns: repeat(2, 1fr);
    gap: 2rem;
  }
}

@media (max-width: 1023px) {
  #bookingVehicleStep .lg\\:w-80 {
    width: 100%;
    margin-bottom: 1.5rem;
  }
  
  #bookingVehicleStep .lg\\:sticky {
    position: static;
  }
}

#checkoutForm .grid {
  gap: 1rem;
}

@media (min-width: 768px) {
  #checkoutForm .grid {
    gap: 1.5rem;
  }
}

.lg\\:sticky {
  position: -webkit-sticky;
  position: sticky;
}

@media (min-width: 1024px) {
  .lg\\:sticky {
    top: 6rem;
  }
}

/* top offset comes from the element's own top-14/sm:top-16 Tailwind classes
   (matching the app's fixed header height, 56px/64px) — previously forced
   to top:0 here, which only worked because the app header was made
   position:relative on this page (below), letting the two swap places
   instead of stacking. Removed that override (below) so the real fixed
   header and this page's own sub-header both stay visible on scroll,
   consistent with every other page. */
#bookingPage .sticky {
  margin-top: 0;
}

#bookingPage > div.sticky:first-child {
  z-index: 50;
}

/* The persistent app header (with its Quick Access dropdown, notification
   panel, etc.) must always stack above any in-page sticky sub-header —
   otherwise on the booking page the sticky title/progress-bar strip above
   (z-index 50) sits on top of the header's own dropdown menus, since those
   are trapped inside #siteHeader's stacking context (previously z-40). */
#siteHeader {
  z-index: 60;
}

header.sticky {
  z-index: 60 !important;
}

body:has(#termsModal:not(.hidden)) #bookingPage > div.sticky,
body:has(#privacyModal:not(.hidden)) #bookingPage > div.sticky,
body:has(#rentalModal:not(.hidden)) #bookingPage > div.sticky,
body:has(#footerPrivacyModal:not(.hidden)) #bookingPage > div.sticky,
body:has(#footerTermsModal:not(.hidden)) #bookingPage > div.sticky,
body:has(#footerCookieModal:not(.hidden)) #bookingPage > div.sticky {
  z-index: 10 !important;
}

#bookingPage > div.sticky.z-50 {
  z-index: 50;
}

body:has(#termsModal:not(.hidden)) #bookingPage > div.sticky.z-50,
body:has(#privacyModal:not(.hidden)) #bookingPage > div.sticky.z-50,
body:has(#rentalModal:not(.hidden)) #bookingPage > div.sticky.z-50,
body:has(#footerPrivacyModal:not(.hidden)) #bookingPage > div.sticky.z-50,
body:has(#footerTermsModal:not(.hidden)) #bookingPage > div.sticky.z-50,
body:has(#footerCookieModal:not(.hidden)) #bookingPage > div.sticky.z-50 {
  z-index: 10 !important;
}

#bookingSearchStep,
#bookingVehicleStep,
#bookingAddonsStep,
#bookingCheckoutStep {
  margin-top: 0;
}

#bookingPage > div.sticky {
  width: 100%;
  left: 0;
  right: 0;
}

#postTripFeedbackModal {
  z-index: 9999 !important;
}

/* .dashboard-tab's own look now lives entirely in dashboard-rail.css — the
   5 dashboard section buttons moved from a horizontal pill bar into the
   nav rail, see index.html's #dashboardRail. */

.vehicle-sub-tab {
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: #94a3b8;
  background: transparent;
  white-space: nowrap;
  transition: all 0.2s ease;
  cursor: pointer;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
}

@media (min-width: 640px) {
  .vehicle-sub-tab {
    padding: 0.625rem 1.25rem;
    font-size: 0.875rem;
  }
}

.vehicle-sub-tab:hover {
  color: #e2e8f0;
  background: rgba(51, 65, 85, 0.5);
}

.vehicle-sub-tab.active {
  color: #ffffff;
  background: rgba(34, 211, 238, 0.12);
  box-shadow: 0 0 0 1px rgba(34, 211, 238, 0.25) inset;
}

.tab-content {
  animation: tabFadeIn 0.3s ease-out;
}

.vtab-content {
  animation: tabFadeIn 0.3s ease-out;
}

@keyframes tabFadeIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.no-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

.no-scrollbar::-webkit-scrollbar {
  display: none;
}

.accordion-chevron {
  transition: transform 0.3s ease;
}

.accordion-chevron.rotate-180 {
  transform: rotate(180deg);
}

.partner-accordion-item {
  transition: border-color 0.2s ease;
}

.partner-accordion-item:hover {
  border-color: rgba(34, 211, 238, 0.3);
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.7;
  }
}

@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10px);
  }
}

/* (old duplicate loader rules removed — see ELITE STEER LOADER section below) */

html {
  scroll-behavior: smooth;
}

*:focus-visible {
  outline: 2px solid var(--cyan-primary);
  outline-offset: 2px;
}

table {
  width: 100%;
  min-width: 640px;
}

@media (max-width: 768px) {
  table {
    font-size: 0.875rem;
  }
  
  table th,
  table td {
    padding: 0.75rem 0.5rem;
  }
}

@media print {
  body {
    background: white;
    color: black;
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
  }
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

@media (prefers-contrast: high) {
  button,
  .btn {
    border: 2px solid currentColor;
  }
  
  input,
  select,
  textarea {
    border: 2px solid currentColor;
  }
}

@media (max-width: 640px) {
  input[type="text"],
  input[type="email"],
  input[type="tel"],
  input[type="number"],
  input[type="password"],
  input[type="date"],
  input[type="datetime-local"],
  select,
  textarea {
    font-size: 16px !important;
  }
  
  .booking-step > .search-container button.w-full,
  #homeTransactionView form button[type="submit"] {
    width: 100%;
  }
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: var(--slate-800);
}

::-webkit-scrollbar-thumb {
  background: var(--slate-700);
  border-radius: 5px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--cyan-primary);
}

* {
  scrollbar-width: thin;
  scrollbar-color: var(--slate-700) var(--slate-800);
}

#termsModal [style*="overflow-y"]::-webkit-scrollbar-thumb {
  background: rgb(6 182 212);
}

#termsModal [style*="overflow-y"]::-webkit-scrollbar-thumb:hover {
  background: rgb(8 145 178);
}

#privacyModal [style*="overflow-y"]::-webkit-scrollbar-thumb {
  background: rgb(168 85 247);
}

#privacyModal [style*="overflow-y"]::-webkit-scrollbar-thumb:hover {
  background: rgb(147 51 234);
}

#rentalModal [style*="overflow-y"]::-webkit-scrollbar-thumb {
  background: rgb(16 185 129);
}

#rentalModal [style*="overflow-y"]::-webkit-scrollbar-thumb:hover {
  background: rgb(5 150 105);
}

#termsModal [style*="overflow-y"]::-webkit-scrollbar-track,
#privacyModal [style*="overflow-y"]::-webkit-scrollbar-track,
#rentalModal [style*="overflow-y"]::-webkit-scrollbar-track {
  background: rgb(30 41 59);
  border-radius: 0;
}

#termsModal [style*="overflow-y"]::-webkit-scrollbar,
#privacyModal [style*="overflow-y"]::-webkit-scrollbar,
#rentalModal [style*="overflow-y"]::-webkit-scrollbar {
  width: 8px;
}

.status-dot {
  height: 8px;
  width: 8px;
  border-radius: 50%;
  display: inline-block;
}

input, select {
  transition: border-color 0.2s, box-shadow 0.2s;
}

/* Was an indigo glow (rgba(79,70,229,...)) unrelated to the app's own
   cyan brand accent used everywhere else (button hover/focus glows, link
   hover states, focus-visible outlines) — same --field-border-focus/
   --field-glow-focus tokens the field system above already defines, so a
   focused field now reads as the same accent-color system as the
   buttons, not a second, disconnected color. */
input:focus, select:focus {
  outline: none;
  border-color: var(--field-border-focus);
  box-shadow: 0 0 0 3px var(--field-glow-focus);
}

button {
  font-family: 'Inter', sans-serif;
  cursor: pointer;
  transition: all 0.2s;
}

table {
  border-collapse: collapse;
}

tr {
  transition: background-color 0.2s;
}

#guideModal {
  animation: fadeIn 0.3s ease;
}

@media (max-width: 768px) {
  .glass-card {
    padding: 16px;
  }
}

.animated-toast {
  opacity: 0;
  transform: translateX(400px);
  pointer-events: auto;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.animated-toast.show {
  opacity: 1;
  transform: translateX(0);
}

@media (max-width: 640px) {
  #notificationContainer {
    left: 16px !important;
    right: 16px !important;
    bottom: 16px !important;
    max-width: none !important;
  }

  .animated-toast {
    transform: translateY(200px);
  }

  .animated-toast.show {
    transform: translateY(0);
  }
}

/* Responsive Utilities */
@media (max-width: 640px) {
  body {
    font-size: 14px;
  }
  
  /* Reduce padding on small screens */
  .overflow-x-auto {
    margin-left: -0.75rem;
    margin-right: -0.75rem;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }
}

/* Ensure tables don't overflow */
table {
  min-width: 100%;
}

table th,
table td {
  white-space: nowrap;
}

/* Responsive text truncation */
.line-clamp-1 {
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  line-clamp: 1;
  -webkit-box-orient: vertical;
}

/* Ensure flex items don't shrink beyond readable size */
.flex > * {
  min-width: 0;
}

/* Responsive header */
@media (max-width: 640px) {
  header {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
  }
}

/* Pagination Controls */
#partnersPaginationContainer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1rem 0;
  margin-top: 1rem;
  border-top: 1px solid rgba(51, 65, 85, 0.5);
}

#partnersPaginationContainer button {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0.875rem;
  font-size: 0.875rem;
  font-weight: 600;
  border-radius: 0.5rem;
  transition: all 0.2s ease;
}

#partnersPaginationContainer button:not(:disabled):hover {
  background-color: rgba(71, 85, 105, 0.8);
  color: #e2e8f0;
}

#partnersPaginationContainer button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

#partnersPaginationInfo {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  padding: 0 1rem;
  min-width: 180px;
  text-align: center;
}

/* Mobile responsive pagination */
@media (max-width: 640px) {
  #partnersPaginationContainer {
    gap: 0.5rem;
    padding: 0.75rem 0;
    margin-top: 0.75rem;
  }

  #partnersPaginationContainer button {
    padding: 0.5rem 0.75rem;
    font-size: 0.75rem;
  }

  #partnersPaginationInfo {
    min-width: 150px;
    padding: 0 0.5rem;
    font-size: 0.75rem;
  }

  #partnersPaginationContainer button span {
    display: none;
  }
}

/* Button and Input Alignment */
input[type="month"] {
  height: 2.5rem;
  vertical-align: middle;
}

/* Align Add Member button with filter */
@media (min-width: 640px) {
  .flex.gap-3.sm\:items-end {
    align-items: flex-end;
  }
}

/* ============================================
   ELITE STEER LOADER — CINEMATIC SPEEDOMETER
   ============================================ */

/* Overlay */
.loader-overlay {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.4s ease, visibility 0.4s ease;
}

.loader-overlay.visible {
  opacity: 1;
  visibility: visible;
}

.loader-overlay.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* Cinematic dark backdrop — deep cockpit black */
.loader-background {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 70% 55% at 50% 45%,
      rgba(6, 20, 45, 0.97) 0%,
      rgba(2, 6, 16, 0.99) 100%);
  backdrop-filter: blur(6px);
}

/* Subtle ambient light bloom behind the gauge */
.loader-background::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -58%);
  width: 480px; height: 360px;
  background: radial-gradient(ellipse at center,
      rgba(6, 182, 212, 0.10) 0%,
      rgba(14, 165, 233, 0.04) 40%,
      transparent 70%);
  pointer-events: none;
}

/* Main container */
.loader-container {
  position: relative;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.75rem;
}

/* ── Speedometer wrapper ──────────────────────── */
.speedo-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* SVG entrance */
.speedo-svg {
  display: block;
  animation: speedoFadeIn 0.6s ease-out both;
  filter: drop-shadow(0 0 28px rgba(6, 182, 212, 0.22))
          drop-shadow(0 8px 40px rgba(0, 0, 0, 0.7));
}

@keyframes speedoFadeIn {
  from { opacity: 0; transform: scale(0.88); }
  to   { opacity: 1; transform: scale(1); }
}

/* Speed arc dash animation (draw-in on appear) */
.speedo-arc {
  animation: arcReveal 1s ease-out 0.3s both, arcBreath 3s ease-in-out 1.3s infinite;
}

@keyframes arcReveal {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes arcBreath {
  0%, 100% { opacity: 0.6; }
  50%       { opacity: 1;   }
}

/* Tick marks pulse */
.speedo-ticks {
  animation: tickPulse 2.5s ease-in-out infinite;
}

@keyframes tickPulse {
  0%, 100% { opacity: 0.75; }
  50%       { opacity: 1;    filter: drop-shadow(0 0 3px rgba(34,211,238,0.8)); }
}

/* ── Needle sweep ──────────────────────────────── */
/* Needle starts at -110deg (pointing at "0") then sweeps +160deg to ~160 and back */
.speedo-needle-group {
  transform-origin: 100px 100px;
  animation: needleSweep 3s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

@keyframes needleSweep {
  0%    { transform: rotate(225deg); }   /* 0 km/h  — lower-left  */
  38%   { transform: rotate(405deg); }   /* ~100 km/h — 12 o'clock */
  44%   { transform: rotate(416deg); }   /* spring overshoot       */
  54%   { transform: rotate(405deg); }   /* settle                 */
  65%   { transform: rotate(405deg); }   /* hold                   */
  100%  { transform: rotate(225deg); }   /* return to 0            */
}

/* Needle tip neon flicker */
.needle-body {
  animation: needleFlicker 3s ease-in-out infinite;
}

@keyframes needleFlicker {
  0%, 38%, 65%, 100% { opacity: 1;    }
  50%                 { opacity: 0.91; }
}

/* Pivot centre glow */
.pivot-glow {
  animation: pivotPulse 1.8s ease-in-out infinite;
}

@keyframes pivotPulse {
  0%, 100% { opacity: 0.65; }
  50%       { opacity: 1;    filter: drop-shadow(0 0 4px #22d3ee); }
}

/* ── Bokeh / lens flare circles ──────────────── */
/* Bokeh / lens-flare spots */
.bokeh {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  background: rgba(34, 211, 238, 0.10);
  border: 1px solid rgba(34, 211, 238, 0.24);
}

.bokeh-1 { width: 15px; height: 15px; top: 6px;     left: 14px;  animation: bokehFloat 4.2s ease-in-out infinite 0.0s; }
.bokeh-2 { width:  9px; height:  9px; top: 30px;    right: 10px; animation: bokehFloat 3.6s ease-in-out infinite 0.8s; }
.bokeh-3 { width: 11px; height: 11px; bottom: 20px; left:   6px; animation: bokehFloat 5.0s ease-in-out infinite 1.4s; }
.bokeh-4 { width:  7px; height:  7px; bottom: 12px; right: 16px; animation: bokehFloat 3.3s ease-in-out infinite 0.3s; }

@keyframes bokehFloat {
  0%, 100% { opacity: 0.18; transform: translateY(0px)   scale(1);    }
  50%       { opacity: 0.46; transform: translateY(-7px) scale(1.22); }
}

/* ── Text ──────────────────────────────────────── */
/* Text */
.loader-text-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  animation: loaderFadeUp 0.8s ease-out 0.3s both;
}

@keyframes loaderFadeUp {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0);   }
}

.loader-text {
  font-size: 1.1rem;
  font-weight: 700;
  background: linear-gradient(120deg, #22d3ee 0%, #38bdf8 55%, #818cf8 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  margin: 0;
  letter-spacing: 0.04em;
  animation: loaderTextBreath 2.8s ease-in-out infinite;
}

@keyframes loaderTextBreath {
  0%, 100% { opacity: 0.80; }
  50%       { opacity: 1;   }
}

.loader-message {
  font-size: 0.82rem;
  color: rgba(148, 163, 184, 0.70);
  margin: 0;
  font-weight: 400;
  min-height: 1.2em;
}

/* ── Mobile ──────────────────────────────────── */
/* Mobile */
@media (max-width: 640px) {
  .speedo-svg      { width: 80px; height: 80px; }
  .loader-text     { font-size: 0.92rem; }
  .loader-message  { font-size: 0.75rem; }
  .bokeh-2, .bokeh-4 { display: none; }
  .bokeh-1         { width: 11px; height: 11px; }
  .bokeh-3         { width:  8px; height:  8px; }
  .loader-container { gap: 1.1rem; }
}

/* Large / TV */
@media (min-width: 1536px) {
  .speedo-svg      { width: 130px; height: 130px; }
  .loader-text     { font-size: 1.35rem; }
  .loader-message  { font-size: 0.95rem; }
}

/* ============================================
   RESPONSIVE DESIGN FIXES
   ============================================ */

/* Disable hover scale transforms on touch/small devices to prevent overlap */
@media (max-width: 768px) {
  .hover\:scale-105:hover {
    transform: none !important;
  }
  .hover\:-translate-y-1:hover {
    transform: none !important;
  }
}

/* Transaction tables - compact styling on mobile (all columns visible with horizontal scroll) */
@media (max-width: 640px) {
  #activityLog table th,
  #activityLog table td {
    padding: 0.375rem 0.5rem;
    font-size: 0.7rem;
    white-space: nowrap;
  }

  #vehicleHistoryTable th,
  #vehicleHistoryTable td {
    padding: 0.375rem 0.5rem;
    font-size: 0.7rem;
    white-space: nowrap;
  }
}

/* Partner cards sharing badges - wrap on very small screens */
@media (max-width: 380px) {
  #partnersList .flex.gap-4 {
    flex-wrap: wrap;
    gap: 0.25rem;
  }
}

/* Ensure modals don't overflow on small screens */
@media (max-width: 640px) {
  /* Modal internal padding reduction */
  #addPartnerModal .p-8,
  #editPartnerModal .p-8,
  #addCarModal .p-8,
  #editCarModal .p-8,
  #transactionDetailsModal .p-8,
  #trackingDetailsModal .p-8 {
    padding: 1rem;
  }
  
  /* Modal header text sizing */
  #addPartnerModal h2,
  #editPartnerModal h2,
  #addCarModal h2,
  #editCarModal h2,
  #transactionDetailsModal h2,
  #trackingDetailsModal h2,
  #confirmModal h3 {
    font-size: 1.25rem;
  }
}

/* Vehicle detail sticky header - proper spacing */
@media (max-width: 640px) {
  #vehicleDetailView > .sticky {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }
}

/* Landing page stats - prevent text overflow */
@media (max-width: 380px) {
  /* Make stat numbers smaller on very tiny screens */
  .text-5xl {
    font-size: 2.25rem;
  }
}

/* ============================================
   UX IMPROVEMENTS
   ============================================ */

/* #5 - Mobile table scroll indicator */
.table-scroll-wrapper {
  position: relative;
}

.table-scroll-wrapper::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 24px;
  background: linear-gradient(to left, rgba(15, 23, 42, 0.9), transparent);
  pointer-events: none;
  opacity: 1;
  transition: opacity 0.3s;
  z-index: 1;
}

.table-scroll-wrapper.scrolled-end::after {
  opacity: 0;
}


.scroll-hint {
  display: none;
  text-align: center;
  padding: 4px 0;
  font-size: 0.7rem;
  color: #94a3b8;
  animation: scrollHintPulse 2s ease-in-out infinite;
}

@media (max-width: 640px) {
  .scroll-hint {
    display: block;
  }
}

@keyframes scrollHintPulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}

/* #7 - Skeleton loading screens */
.skeleton {
  background: linear-gradient(90deg, rgba(51, 65, 85, 0.5) 25%, rgba(71, 85, 105, 0.5) 50%, rgba(51, 65, 85, 0.5) 75%);
  background-size: 200% 100%;
  animation: skeletonShimmer 1.5s ease-in-out infinite;
  border-radius: 0.5rem;
}

@keyframes skeletonShimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Brochure Viewer Modal Scrollbar */
.brochure-scroll-area {
  scrollbar-width: thin;
  scrollbar-color: #0891b2 #1e293b;
}

.brochure-scroll-area::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

.brochure-scroll-area::-webkit-scrollbar-track {
  background: #1e293b;
  border-radius: 6px;
}

.brochure-scroll-area::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, #0891b2 0%, #06b6d4 100%);
  border-radius: 6px;
  border: 2px solid #1e293b;
}

.brochure-scroll-area::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, #06b6d4 0%, #22d3ee 100%);
}

.brochure-scroll-area::-webkit-scrollbar-corner {
  background: #1e293b;
}

.skeleton-card {
  height: 12rem;
  border: 1px solid rgba(51, 65, 85, 0.5);
}

/* #4 - Undo toast */
.undo-toast {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  background: #1e293b;
  border: 1px solid #475569;
  border-radius: 0.5rem;
  color: #e2e8f0;
  font-size: 0.875rem;
  box-shadow: 0 10px 25px rgba(0,0,0,0.3);
}

.undo-toast button {
  background: #2563eb;
  color: white;
  border: none;
  padding: 0.25rem 0.75rem;
  border-radius: 0.375rem;
  font-weight: 600;
  font-size: 0.8rem;
  cursor: pointer;
  white-space: nowrap;
}

.undo-toast button:hover {
  background: #1d4ed8;
}

/* #11 - Tooltip for sharing type */
.info-tooltip {
  position: relative;
  display: inline-flex;
  cursor: help;
}

.info-tooltip .tooltip-text {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  bottom: 125%;
  left: 50%;
  transform: translateX(-50%);
  background: #1e293b;
  color: #cbd5e1;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  font-size: 0.7rem;
  white-space: nowrap;
  border: 1px solid #475569;
  z-index: 50;
  transition: opacity 0.2s, visibility 0.2s;
  pointer-events: none;
  max-width: 250px;
  white-space: normal;
  text-align: center;
  line-height: 1.4;
}

.info-tooltip:hover .tooltip-text {
  visibility: visible;
  opacity: 1;
}

/* #12 - Active nav section highlight */
.nav-section-active {
  border-left: 3px solid #22d3ee;
  background: rgba(34, 211, 238, 0.05);
}

/* #15 - Welcome banner */
.welcome-banner {
  animation: slideDown 0.5s ease-out;
}

/* #16 - Print-friendly CSS */
@media print {
  body {
    background: white !important;
    color: black !important;
    font-size: 12pt;
  }

  header, footer, #notificationContainer, #notificationPanel,
  #notificationBell, #userMenu, #userIconBtn, #adminHeaderButton,
  #connDot, #eliteSteerLoader, .collapse-toggle, button,
  #ctaSection, #landingPage {
    display: none !important;
  }

  #dashboardView, #vehicleDetailView, #homeTransactionView, #activityLog {
    display: block !important;
  }

  .bg-slate-800, .bg-slate-700, .bg-slate-900 {
    background: white !important;
    border-color: #ddd !important;
    color: black !important;
  }

  .text-white, .text-slate-300, .text-slate-400, .text-emerald-400,
  .text-rose-400, .text-cyan-400, .text-blue-400, .text-amber-400,
  .text-purple-400 {
    color: black !important;
  }

  table { border-collapse: collapse; width: 100%; }
  th, td { border: 1px solid #ccc; padding: 6px 10px; }
  th { background: #f0f0f0 !important; }
}

/* ============= PREMIUM BOOKING PLATFORM STYLES ============= */

/* Vehicle card hover effects */
#bookingVehicleList > div {
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

#bookingVehicleList > div:hover {
  transform: translateY(-8px);
}

/* Image zoom on hover */
#bookingVehicleList img {
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Input focus effects - desktop only */
@media (min-width: 768px) {
  #bookingPage input:focus,
  #bookingPage textarea:focus {
    transform: scale(1.01);
  }
}

/* Error state pulse */
.border-red-500 {
  animation: errorPulse 0.5s ease-in-out;
}

/* ============================================
   COMPREHENSIVE RESPONSIVE DESIGN ENHANCEMENTS
   Mobile → Tablet → Laptop → Desktop → TV/4K
   ============================================ */

/* --- Global: cap max content width for ultra-wide / TV screens --- */
main {
  max-width: 1920px;
  margin-left: auto;
  margin-right: auto;
}

/* --- Global: ensure all images scale properly on all devices --- */
img {
  max-width: 100%;
}

/* --- Responsive chart height (dashboard overview) --- */
.chart-responsive {
  height: 250px;
}

@media (min-width: 1024px) {
  .chart-responsive {
    height: 310px;
  }
}

@media (min-width: 1280px) {
  .chart-responsive {
    height: 370px;
  }
}

@media (min-width: 1536px) {
  .chart-responsive {
    height: 440px;
  }
}

/* --- Dashboard stat values: scale up on large / TV screens --- */
@media (min-width: 1280px) {
  #totalIncome, #totalExpense, #totalAllowance, #netProfit, #carCount {
    font-size: 1.5rem; /* text-2xl */
  }
}

@media (min-width: 1536px) {
  #totalIncome, #totalExpense, #totalAllowance, #netProfit, #carCount {
    font-size: 1.75rem; /* text-[1.75rem] */
  }
}

/* --- Loader: scale up for large / TV screens --- */
@media (min-width: 1536px) {
  .speedo-svg {
    width: 320px;
    height: 320px;
  }
  .loader-text {
    font-size: 1.5rem;
  }
  .loader-message {
    font-size: 1.1rem;
  }
}

/* --- Touch devices: ensure minimum 44px touch target on interactive header elements --- */
@media (hover: none) and (pointer: coarse) {
  header button {
    min-width: 44px;
    min-height: 44px;
  }
  .dashboard-tab {
    min-height: 44px;
  }
  .vehicle-sub-tab {
    min-height: 44px;
  }
}

/* Very-small-screen modal max-height override this used to need (for
   crmAddCustomerModal, crmEditCustomerModal, adminAddUserModal, then
   crmWADispatchModal) is gone — every one of those is on .rp-modal now
   (responsive-primitives.css), which gives every converted modal the same
   max-height/scroll handling consistently without a per-modal override. */

/* --- Vehicle detail sub-tabs: icon-only on phones (≤480px) — .dashboard-tab
   is excluded on purpose: the dashboard rail's mobile drawer state always
   shows full labels (see dashboard-rail.css), it's never icon-only. --- */
@media (max-width: 480px) {
  .vehicle-sub-tab span {
    display: none;
  }
  .vehicle-sub-tab {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }
}

/* --- Public fleet and booking vehicle images: consistent height --- */
#publicFleetGrid img {
  width: 100%;
  height: 13rem;
  object-fit: cover;
}

@media (min-width: 1280px) {
  #publicFleetGrid img {
    height: 15rem;
  }
}

@media (min-width: 1536px) {
  #publicFleetGrid img {
    height: 17rem;
  }
}


/* --- App-wide edge gutter, one scale for every page ---
   #mainContent wraps every top-level view (home, booking, car detail, my
   bookings, dashboard alike) and is the SINGLE place edge padding is
   defined for the whole app — replaces its own Tailwind px-3 through
   2xl:px-16 (12-64px) with a smaller, constant scale. Individual pages
   that used to layer their OWN px-3/xl:px-8-style wrapper padding on top
   of this (booking's 4 steps, My Bookings, car detail's .cd-body) have
   that inner padding zeroed elsewhere (booking-redesign.css, car-
   detail.css, and below) so every page gets this one gutter exactly
   once, not stacked — previously booking had been fixed to go edge-to-
   edge on its own while every other page kept the old wide margin,
   which read as inconsistent between pages; this is the fix for that. */
#mainContent {
  padding-left: 0.625rem;
  padding-right: 0.625rem;
}
@media (min-width: 640px) {
  #mainContent {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }
}
@media (min-width: 1024px) {
  #mainContent {
    padding-left: 1rem;
    padding-right: 1rem;
  }
}
@media (min-width: 1280px) {
  #mainContent {
    padding-left: 1.25rem;
    padding-right: 1.25rem;
  }
}
@media (min-width: 1536px) {
  #mainContent {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
}
/* My Bookings: sticky header row + main content wrapper both carried
   their own px-3 through xl:px-8 / px-4 sm:px-8 on top of #mainContent's
   padding above — zeroed so this page gets the same single gutter as
   everything else instead of a wider, doubled-up margin. */
#myBookingsPage > .sticky > .w-full,
#myBookingsPage > .max-w-4xl {
  padding-left: 0;
  padding-right: 0;
}

/* --- Vehicle sub-tabs: scale up on large screens --- */
@media (min-width: 1280px) {
  .vehicle-sub-tab {
    padding: 0.625rem 1.25rem;
    font-size: 0.875rem;
  }
}

/* --- Progress steps in booking flow: scale on large screens --- */
@media (min-width: 1280px) {
  .progress-step {
    width: 3rem;
    height: 3rem;
    font-size: 1rem;
  }
  .progress-line {
    width: 3rem;
  }
}

/* --- Booking search heading: scale on xl+ --- */
@media (min-width: 1280px) {
  #bookingSearchStep h2 {
    font-size: 2.75rem;
  }
}

@media (min-width: 1536px) {
  #bookingSearchStep h2 {
    font-size: 3.25rem;
  }
}

/* --- Partner cards: better spacing on large screens --- */
@media (min-width: 1280px) {
  #partnersList .space-y-2 > div {
    padding: 1rem 1.25rem;
  }
}

/* --- Table: more padding on xl screens for better readability --- */
@media (min-width: 1280px) {
  table th,
  table td {
    padding: 0.625rem 0.875rem;
  }
}

/* --- Footer: ensure links are readable on all sizes --- */
footer a {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}

/* --- Footer social links: 44px minimum touch target on touch devices --- */
@media (hover: none) and (pointer: coarse) {
  footer a.rounded-full {
    min-width: 44px;
    min-height: 44px;
  }
}

/* --- Landing 'By The Numbers' stat values: scale on xl+ screens --- */
@media (min-width: 1280px) {
  #landingByTheNumbers .font-black.mb-3 {
    font-size: 3.75rem; /* text-6xl */
  }
}

@media (min-width: 1536px) {
  #landingByTheNumbers .font-black.mb-3 {
    font-size: 4.5rem; /* text-7xl */
  }
}

/* --- Booking confirmation / success cards: responsive --- */
@media (max-width: 640px) {
  #bookingSuccessStep .text-6xl {
    font-size: 3rem;
  }
}

/* --- Fix: promotional campaign panel on very narrow mobile --- */
@media (max-width: 360px) {
  #adminPanelCustomers .grid-cols-2 {
    grid-template-columns: 1fr;
  }
}

@keyframes errorPulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
  }
  50% {
    box-shadow: 0 0 0 8px rgba(239, 68, 68, 0);
  }
}

/* Price breakdown entrance */
#pricingBreakdown:not(.hidden) {
  animation: priceSlideDown 0.4s ease-out;
}

@keyframes priceSlideDown {
  from {
    opacity: 0;
    max-height: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    max-height: 500px;
    transform: translateY(0);
  }
}

/* Filter button active state */
.filter-btn.active {
  box-shadow: 0 0 20px rgba(6, 182, 212, 0.4);
}

/* Mobile responsive adjustments */
@media (max-width: 768px) {
  #bookingVehicleList > div:hover {
    transform: translateY(-4px);
  }
}

/* ============= END PREMIUM BOOKING STYLES ============= */

/* ============= MOBILE RESPONSIVE ENHANCEMENTS ============= */

/* Ensure no horizontal overflow */
html {
  overflow-x: hidden;
}

/* Mobile: reduce hero heading sizes */
@media (max-width: 640px) {
  #landingPage h2.text-3xl {
    font-size: 1.5rem;
  }
  
  #landingPage .text-2xl {
    font-size: 1.25rem;
  }
  
  /* Reduce feature card icon sizes */
  #landingPage .w-16.h-16 {
    width: 3rem;
    height: 3rem;
  }
  
  /* Booking success modal */
  #bookingSuccessModal .p-8 {
    padding: 1.25rem;
  }
  
  #bookingSuccessModal .w-24.h-24 {
    width: 4rem;
    height: 4rem;
  }
  
  #bookingSuccessModal .text-6xl {
    font-size: 2.5rem;
  }

  /* Footer legal modals padding */
  #footerPrivacyModal .p-6,
  #footerTermsModal .p-6,
  #footerCookieModal .p-6 {
    padding: 1rem;
  }

  /* Tracking details modal */
  #trackingDetailsModal .p-6 {
    padding: 1rem;
  }
  
  /* Vehicle detail header buttons */
  #vehicleDetailView .w-7.h-7 {
    width: 2rem;
    height: 2rem;
  }
  
  /* Dashboard stat cards - text wrapping */
  #dashboardView .text-lg {
    font-size: 1rem;
  }
  
  /* Table scroll hint visibility */
  .scroll-hint {
    display: flex;
  }
  
  /* Booking search heading */
  #bookingSearchStep h2 {
    font-size: 1.5rem;
  }
}

/* Very small screens (< 380px) */
@media (max-width: 380px) {
  /* Further reduce padding */
  #landingPage section {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }
  
  /* Reduce booking form padding */
  #bookingSearchForm {
    padding: 1rem;
  }
  
  /* Stack booking stats vertically */
  #bookingSearchForm .flex.items-center.justify-center {
    flex-direction: column;
    gap: 0.5rem;
  }
  
  /* Hide stat dividers on very small screens */
  #bookingSearchForm .h-4.w-px {
    display: none;
  }
}

/* ============= END MOBILE RESPONSIVE ENHANCEMENTS ============= */

/* ============= ICON BUTTON CENTERING FIX ============= */
/*
  Font Awesome glyphs can have unequal left/right bearings causing them
  to appear off-center inside flex buttons. margin-right compensates for
  this rendering offset. :only-child ensures export/label buttons
  (where <i> has a <span> sibling) are NOT affected.
*/
button > .fas:only-child,
button > .far:only-child,
button > .fab:only-child,
button > .fal:only-child,
button > .fat:only-child,
button > .fad:only-child {
  line-height: 1;
  margin-right: 10px;
}
/* ============= END ICON BUTTON CENTERING FIX ============= */

/* ============= ICON-ONLY SQUARE BUTTON CENTERING (overrides above) =====
   Measured with Playwright: the margin-right:10px above is only correct for
   buttons where it doubles as icon-to-label spacing (e.g. "Search Fleet",
   "Save Changes" — icon + visible text, both centered together via
   justify-center). On a button whose *entire* content is one icon (close ×,
   expand/collapse, lightbox prev/next/manage — no label to space away from),
   that same margin drags the icon ~5px off the button's true center because
   justify-content:center centers the icon's margin box, not its glyph.
   Opt in per-button with class="icon-btn-center" rather than flipping the
   rule above, since dozens of icon+label CTA buttons still need it. ==== */
.icon-btn-center > .fas:only-child,
.icon-btn-center > .far:only-child,
.icon-btn-center > .fab:only-child,
.icon-btn-center > .fal:only-child,
.icon-btn-center > .fat:only-child,
.icon-btn-center > .fad:only-child {
  margin-right: 0;
}
/* ============= END ICON-ONLY SQUARE BUTTON CENTERING ============= */

/* ============= FLEET CALENDAR ============= */

/* ---- Vehicle colour palette (used by both monthly + gantt) ---- */
/* Solid fills (not the translucent .pill-badge glass look) on purpose —
   these are scanned at a glance across a dense calendar grid, where a
   solid, high-contrast status color reads faster than a soft translucent
   tint would. Each still gets a matching accent glow (below, .fc-pill)
   for the same "glowing" language as the rest of the button system,
   layered on top instead of replacing the fill. */
.vc-cyan    { background-color: #0e7490; border-left: 3px solid #22d3ee; }
.vc-emerald { background-color: #065f46; border-left: 3px solid #34d399; }
.vc-done    { background-color: #374151; border-left: 3px solid #6b7280; opacity: 0.75; }
.vc-violet  { background-color: #4c1d95; border-left: 3px solid #a78bfa; }
.vc-amber   { background-color: #92400e; border-left: 3px solid #fbbf24; }
.vc-rose    { background-color: #9f1239; border-left: 3px solid #fb7185; }
.vc-blue    { background-color: #1e3a5f; border-left: 3px solid #60a5fa; }
.vc-orange  { background-color: #7c2d12; border-left: 3px solid #fb923c; }
.vc-teal    { background-color: #134e4a; border-left: 3px solid #2dd4bf; }
/* Vehicle pause/maintenance blocks — deliberately NOT one of the 4 booking-
   status colors above (cyan/emerald/violet/done): a diagonal hatch reads as
   "unavailable" at a glance and can never be mistaken for a real booking,
   confirmed vs requested vs completed, no matter how briefly glanced at. */
.vc-paused {
  background-color: #44403c;
  background-image: repeating-linear-gradient(45deg, rgba(248,113,113,0.18) 0, rgba(248,113,113,0.18) 4px, transparent 4px, transparent 9px);
  border-left: 3px solid #f87171;
}

/* ---- Monthly Calendar ---- */
.fc-monthly {
  user-select: none;
}

.fc-day-headers {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  margin-bottom: 2px;
}

.fc-day-header {
  text-align: center;
  font-size: 11px;
  font-weight: 700;
  color: #94a3b8;
  padding: 6px 4px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.fc-day-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.fc-day-cell {
  min-height: 80px;
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 8px;
  padding: 4px;
  cursor: pointer;
  transition: background 0.15s;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
}

.fc-day-cell:hover {
  background: #263346;
  border-color: #06b6d4;
}

.fc-day-empty {
  background: transparent;
  border-color: transparent;
  cursor: default;
}
.fc-day-empty:hover { background: transparent; border-color: transparent; }

.fc-today {
  background: #1e3a5f !important;
  border-color: #3b82f6 !important;
}

.fc-today-num {
  color: #60a5fa !important;
  background: #1e3a5f;
  border-radius: 50%;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.fc-weekend {
  background: #1a2235;
}

.fc-day-num {
  font-size: 11px;
  font-weight: 700;
  color: #94a3b8;
  line-height: 1;
  padding: 2px 3px;
  align-self: flex-end;
}

.fc-pills {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  overflow: hidden;
}

.fc-pill {
  font-size: 10px;
  font-weight: 600;
  color: #fff;
  padding: 2px 6px;
  border-radius: 9999px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: filter 0.15s, box-shadow 0.2s ease;
  max-width: 100%;
}

.fc-pill:hover { filter: brightness(1.2); }
/* Same glowing-accent language as .pill-badge/.btn-primary, keyed to each
   status's own vc-* color instead of switching to that class's translucent
   fill — see the note on .vc-cyan etc. above for why the fill itself stays
   solid. */
.fc-pill.vc-cyan    { box-shadow: 0 0 8px rgba(34, 211, 238, 0.45); }
.fc-pill.vc-emerald { box-shadow: 0 0 8px rgba(52, 211, 153, 0.45); }
.fc-pill.vc-violet  { box-shadow: 0 0 8px rgba(167, 139, 250, 0.45); }
.fc-pill.vc-done    { box-shadow: none; }
.fc-pill.vc-paused  { box-shadow: none; }

/* ---- Gantt / Fleet Timeline ---- */
.fc-gantt {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  isolation: isolate;
}

.gantt-header {
  display: grid;
  position: sticky;
  top: 0;
  z-index: 2;
  background: #1e293b;
  border-bottom: 2px solid #334155;
}

.gantt-day-header {
  font-size: 10px;
  font-weight: 700;
  color: #94a3b8;
  text-align: center;
  padding: 6px 2px;
  border-right: 1px solid #1e293b;
}

.gantt-weekend { background: #1a2235; color: #64748b; }
.gantt-today-header { background: #1e3a5f; color: #60a5fa; }

.gantt-label-cell {
  font-size: 11px;
  font-weight: 600;
  color: #e2e8f0;
  padding: 6px 8px;
  background: #1e293b;
  position: sticky;
  left: 0;
  z-index: 1;
  border-right: 2px solid #334155;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 140px;
  max-width: 140px;
  overflow: hidden;
}

.gantt-reg {
  font-size: 9px;
  color: #64748b;
  font-weight: 400;
}

.gantt-body {
  display: flex;
  flex-direction: column;
}

.gantt-row {
  display: grid;
  border-bottom: 1px solid #1e293b;
  min-height: 38px;
  align-items: stretch;
}

.gantt-row-alt { background: #1a2539; }

.gantt-cell {
  border-right: 1px solid #252f3f;
  cursor: pointer;
  transition: background 0.1s;
}

.gantt-cell:hover { background: #263346; }
.gantt-cell.gantt-weekend { background: #1a2235; }
.gantt-cell.gantt-today-col { background: #1e3a5f26; }

.gantt-block {
  display: flex;
  align-items: center;
  padding: 0 6px;
  border-radius: 9999px;
  margin: 3px 2px;
  cursor: pointer;
  transition: filter 0.15s, box-shadow 0.2s ease;
  min-height: 28px;
  overflow: hidden;
}

.gantt-block:hover { filter: brightness(1.15); }
.gantt-block.vc-cyan    { box-shadow: 0 0 8px rgba(34, 211, 238, 0.4); }
.gantt-block.vc-emerald { box-shadow: 0 0 8px rgba(52, 211, 153, 0.4); }
.gantt-block.vc-violet  { box-shadow: 0 0 8px rgba(167, 139, 250, 0.4); }
.gantt-block.vc-done    { box-shadow: none; }
.gantt-block.vc-paused  { box-shadow: none; }

.gantt-block-text {
  font-size: 11px;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Responsive ---- */
@media (max-width: 640px) {
  .fc-day-cell { min-height: 60px; }
  .fc-day-num  { font-size: 10px; }
  .fc-pill     { font-size: 9px; padding: 1px 3px; }
  .gantt-label-cell { min-width: 90px; max-width: 90px; font-size: 10px; }
  .gantt-day-header { font-size: 9px; padding: 4px 1px; }
}
/* A booking pill at the compact mobile size above is only ~11px tall —
   far below anything a finger can reliably hit, especially with several
   stacked in one day cell only 2px apart. Taps kept landing on the
   surrounding .fc-day-cell instead of the pill, which opens "Add Booking"
   for that date rather than the tapped booking's own detail view
   (reported: tapping a booking on the calendar wouldn't open it on
   mobile). Scoped to (pointer: coarse), same convention as the 44px
   icon-button rule above, so desktop's compact pills at a narrow window
   width are untouched — only real touch input gets the bigger target.
     Touch devices now default to List view instead of Calendar
   (fleet-calendar.js's initFleetCalendar), which sidesteps this
   altogether with full-width, single-tap rows — but an admin can still
   switch back to Calendar/Gantt manually, so both grid views keep their
   own touch-target hardening as a second layer rather than relying on
   the default alone. Bumped further (was 22px) after the same complaint
   recurred — still below the 44px ideal, but a day cell with several
   stacked bookings has limited real estate; .gantt-block, previously
   unstyled for coarse pointers at all, gets the same treatment here for
   the first time. */
@media (pointer: coarse) {
  .fc-day-cell { min-height: 72px; }
  .fc-pills { gap: 5px; }
  .fc-pill {
    font-size: 11px;
    padding: 6px 8px;
    min-height: 30px;
    display: flex;
    align-items: center;
  }
  .gantt-block {
    min-height: 34px;
    padding: 0 8px;
  }
}

/* Vehicle filter dropdown: the shared select{width:100%} rule from the
   "Standardized form field" system further up this file (a plain
   tag+attribute selector, so it outranks any Tailwind width class in the
   markup) made this stretch across the entire filters row, leaving no
   room for the status chips beside it and pushing them onto their own
   line even on a wide laptop screen — reported as wasted width. Capped
   here to a sane dropdown width so the row has room for both on the same
   line; the max-width:540px rule below further relaxes this back to
   flexible on very small screens where a fixed width costs too much of
   the row. */
#calVehicleFilter {
  width: auto;
  min-width: 160px;
  max-width: 220px;
}

/* ============= END FLEET CALENDAR ============= */

/* ============================================================
   COMPREHENSIVE RESPONSIVE ENHANCEMENTS
   Covers: fleet calendar, booking controls, toll form,
           TV/large screens, and edge-case mobile fixes.
   ============================================================ */

/* ---- 1. Monthly fleet calendar: allow horizontal scroll on small screens ---- */
/* The gantt view has its own overflow-x:auto via .fc-gantt, but the monthly
   view's 7-column grid would compress cells to ~45px on a 320px screen.
   Setting a min-width on .fc-monthly makes cells stay readable and the
   container scrolls instead of squashing. */
#fleetCalendarContainer {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.fc-monthly {
  min-width: 420px; /* 7 cols × 60px min each */
}

/* ---- 2. Fleet calendar booking controls: compact on small screens ---- */
/* On ≤ 540px: hide legend text labels (keep coloured dots) to save space.
   On ≤ 360px: show only the icon inside the view-toggle button. */
@media (max-width: 540px) {
  /* Legend badge text (e.g. "Confirmed", "Active", "Completed") */
  #tabBookings .ml-auto .text-xs.font-medium.text-slate-300 {
    display: none;
  }
  /* Keep the coloured dot still visible */
  #tabBookings .ml-auto span[style] {
    flex-shrink: 0;
  }
  /* Vehicle filter: full width below controls row */
  #calVehicleFilter {
    flex: 1 1 120px;
    min-width: 0;
  }
}

@media (max-width: 360px) {
  /* View toggle button: icon only */
  #calViewToggleBtn {
    padding-left: 0.625rem;
    padding-right: 0.625rem;
    gap: 0;
  }
  #calViewToggleBtn .fas + * {
    display: none;
  }
}

/* ---- 3. Toll / washing / fuel charges: single column on very small screens ---- */
/* This 3-column grid inside the transaction form becomes too tight at ≤ 400px. */
@media (max-width: 400px) {
  #tollWashingChargesRow .grid {
    grid-template-columns: 1fr !important;
  }
}

/* ---- 4. Very large / TV screen max-width cap ---- */
/* Without a cap the dashboard stretches to fill 3840 px+ on 4K TVs.
   Centring with a 2400 px cap keeps things readable. */
@media (min-width: 2560px) {
  main {
    max-width: 2400px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ---- 5. KPI stat cards: smaller text on very tiny phones (< 360px) ---- */
@media (max-width: 359px) {
  #totalIncome,
  #totalExpense,
  #totalAllowance,
  #netProfit,
  #carCount {
    font-size: 0.875rem; /* 14px */
  }
  /* KPI card label text */
  #dashboardView .grid > div > p:first-child {
    font-size: 0.5625rem; /* 9px */
  }
}

/* ---- 6. Transaction history table: match header sticky bg to row bg ---- */
/* The tbody rows use bg #1e293b (slate-800), but the sticky <th> uses #0f172a.
   Normalise so the sticky shadow looks consistent. */
#activityLog table th:last-child {
  background: #0f172a;
}

/* ---- 7. Fleet vehicle cards: consistent minimum touch target on phones ---- */
@media (hover: none) and (pointer: coarse) {
  #carsList .cursor-pointer {
    min-height: 44px;
  }
}

/* ---- 8. Modal inner padding on phones < 380px ---- */
/* Many (legacy) modals put their p-4 sm:p-8 padding directly on
   [data-modal-inner] itself. On very small phones this reduces that
   horizontal padding so content doesn't feel cramped.
   :not(.rp-modal__panel) excludes the newer responsive-primitives.css
   modal system (Privacy Policy/Terms/Cookie and ~7 others) — those
   panels carry NO padding of their own by design (.rp-modal__header/
   __body/__footer each manage their own instead), so this rule was
   forcing padding onto a box that should have none, insetting the
   header from the panel's actual rounded edges below 380px — a plain
   dark sliver of the panel's own background showed on each side, most
   visible at the top corners where the header's gradient background
   (e.g. the legal modals' cyan-to-blue header) no longer reached the
   panel's own border-radius at all. */
@media (max-width: 379px) {
  [data-modal-inner]:not(.rp-modal__panel) {
    padding-left: 0.75rem !important;
    padding-right: 0.75rem !important;
  }
}

/* ---- 9. Booking checkout sticky summary: prevent overlap with content ---- */
/* On ≤ 1023px the sticky summary becomes static (handled elsewhere),
   but on very large screens ensure it doesn't grow beyond viewport. */
@media (min-width: 1024px) {
  #bookingCheckoutStep .lg\:sticky {
    max-height: calc(100vh - 8rem);
    overflow-y: auto;
  }
}

/* ---- 10. Landing page hero text: scale up on 4K screens ---- */
@media (min-width: 2560px) {
  #landingPage .text-4xl { font-size: 3.5rem; }
  #landingPage .text-5xl { font-size: 4.5rem; }
  #landingPage .text-6xl { font-size: 5.5rem; }
  #landingPage .text-7xl { font-size: 6.5rem; }
}

/* ---- 11. Booking flow progress bar: full width on mobile ---- */
@media (max-width: 480px) {
  #bookingPage .progress-line {
    display: none;
  }
}

/* ---- 13. Notification panel: never wider than the viewport ---- */
#notificationPanel {
  max-width: calc(100vw - 1.5rem);
}

/* ---- 14. Auth modal responsive sizing ----
   Was a "full-screen on very small phones" rule with its own <400px margin
   + full-corner-radius override; superseded now that #authModal's root is
   .rp-modal (responsive-primitives.css), which already gives it the same
   full-bleed bottom-sheet treatment as every other modal below 640px (see
   the .auth-modal-border/.auth-card corner-radius override further up this
   file) — this old ID-specificity rule was winning over that at <400px and
   producing a floating rounded card instead of a flush bottom sheet. */

/* ---- 15. Public fleet vehicle image height on very small screens ---- */
@media (max-width: 375px) {
  #publicFleetGrid img {
    height: 10rem;
  }
  .vehicle-card img {
    height: 9rem;
  }
}

/* ============================================================
   END COMPREHENSIVE RESPONSIVE ENHANCEMENTS
   ============================================================ */

/* ── Fleet Calendar: booking hover tooltip ──────────────────────────────── */
#fcBookingTooltip {
  position: fixed;
  z-index: 10000;
  width: 250px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(30,41,59,0.98), rgba(15,23,42,0.98));
  border: 1px solid rgba(100,116,139,0.5);
  border-radius: 14px;
  box-shadow: 0 20px 40px -8px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.03);
  padding: 12px 14px;
  opacity: 0;
  transform: translateY(4px) scale(0.97);
  transition: opacity 0.15s ease, transform 0.15s ease;
  backdrop-filter: blur(10px);
}
#fcBookingTooltip.hidden { display: none; }
#fcBookingTooltip.fc-tt-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}
#fcBookingTooltip::before {
  content: '';
  position: absolute;
  left: var(--fc-tt-arrow-left, 20px);
  width: 10px;
  height: 10px;
  background: #1e293b;
  border-left: 1px solid rgba(100,116,139,0.5);
  border-top: 1px solid rgba(100,116,139,0.5);
}
#fcBookingTooltip[data-arrow="bottom"]::before {
  bottom: -6px;
  transform: rotate(225deg);
}
#fcBookingTooltip[data-arrow="top"]::before {
  top: -6px;
  transform: rotate(45deg);
}
.fc-tt-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-bottom: 9px;
  padding-bottom: 9px;
  border-bottom: 1px solid rgba(100,116,139,0.25);
}
.fc-tt-source {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.fc-tt-src-cyan   { background: rgba(8,145,178,0.18);   color: #22d3ee; border: 1px solid rgba(34,211,238,0.35); }
.fc-tt-src-purple { background: rgba(147,51,234,0.18);  color: #c084fc; border: 1px solid rgba(192,132,252,0.35); }
.fc-tt-src-blue   { background: rgba(37,99,235,0.18);   color: #60a5fa; border: 1px solid rgba(96,165,250,0.35); }
.fc-tt-src-slate  { background: rgba(71,85,105,0.25);   color: #cbd5e1; border: 1px solid rgba(203,213,225,0.25); }
.fc-tt-status {
  font-size: 10px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  text-transform: capitalize;
  white-space: nowrap;
}
.fc-tt-st-purple  { background: rgba(147,51,234,0.18); color: #c084fc; }
.fc-tt-st-cyan    { background: rgba(8,145,178,0.18);  color: #22d3ee; }
.fc-tt-st-emerald { background: rgba(5,150,105,0.18);  color: #34d399; }
.fc-tt-st-slate   { background: rgba(71,85,105,0.25);  color: #cbd5e1; }
.fc-tt-st-rose    { background: rgba(225,29,72,0.18);  color: #fb7185; }
.fc-tt-vehicle {
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  margin-bottom: 5px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.fc-tt-vehicle i { color: #22d3ee; font-size: 11px; width: 12px; text-align: center; }
.fc-tt-customer {
  font-size: 12px;
  color: #cbd5e1;
  margin-bottom: 5px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.fc-tt-customer i { color: #a78bfa; font-size: 10px; width: 12px; text-align: center; }
.fc-tt-dates {
  font-size: 11px;
  color: #94a3b8;
  margin-bottom: 4px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.fc-tt-dates i { color: #fbbf24; font-size: 10px; width: 12px; text-align: center; }
.fc-tt-duration {
  font-size: 11px;
  color: #94a3b8;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 7px;
}
.fc-tt-duration i { color: #38bdf8; font-size: 10px; width: 12px; text-align: center; }
.fc-tt-amounts {
  background: rgba(15,23,42,0.55);
  border: 1px solid rgba(100,116,139,0.2);
  border-radius: 10px;
  padding: 8px 10px;
}
.fc-tt-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 11px;
  padding: 2px 0;
}
.fc-tt-row + .fc-tt-row { margin-top: 2px; padding-top: 4px; border-top: 1px dashed rgba(100,116,139,0.2); }
.fc-tt-row span:first-child { color: #94a3b8; }
.fc-tt-amt { color: #34d399; font-weight: 700; }
.fc-tt-pd  { color: #fb923c; font-weight: 700; }

/* ── Fleet Bookings: List/Table view ──────────────────────────────────── */
.fc-table { border-collapse: collapse; }
.fc-table thead th {
  text-align: left;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #64748b;
  font-weight: 700;
  padding: 10px 14px;
  background: #1a2539;
  border-bottom: 1px solid #334155;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}
.fc-table thead th:hover { color: #94a3b8; }
.fc-table thead th .fc-sort-icon { font-size: 9px; margin-left: 3px; opacity: 0.4; }
.fc-table thead th .fc-sort-icon.fc-sort-active { opacity: 1; color: #22d3ee; }
.fc-table tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid rgba(51,65,85,0.5);
  font-size: 13px;
  color: #e2e8f0;
  vertical-align: middle;
}
.fc-table tbody tr { cursor: pointer; transition: background 0.15s; }
.fc-table tbody tr:hover { background: rgba(51,65,85,0.35); }
.fc-table tbody tr:last-child td { border-bottom: none; }
/* Bare icon, no background box — same "no circle/rectangle behind the
   icon" treatment as .btn-close/.btn-icon-danger, color-only feedback. */
.fc-list-view-btn {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  color: #64748b; background: transparent;
  transition: color 0.15s ease;
}
.fc-table tbody tr:hover .fc-list-view-btn { color: #22d3ee; }
.fc-list-empty { text-align: center; padding: 48px 16px; color: #64748b; }

/* ── Booking Detail drawer: status stepper ───────────────────────────── */
.fc-stepper { display: flex; align-items: flex-start; margin-bottom: 1.25rem; }
.fc-stepper-step { display: flex; flex-direction: column; align-items: center; flex: 0 0 auto; width: 64px; }
.fc-stepper-dot {
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700;
  background: #1e293b; color: #64748b; border: 2px solid #334155;
  transition: all 0.2s;
}
.fc-stepper-label { font-size: 9.5px; color: #64748b; margin-top: 5px; text-align: center; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; }
.fc-stepper-line { flex: 1 1 auto; height: 2px; background: #334155; margin-top: 12px; }
.fc-stepper-line.fc-line-done { background: #0891b2; }
.fc-step-done .fc-stepper-dot { background: #0891b2; border-color: #0891b2; color: #fff; }
.fc-step-done .fc-stepper-label { color: #22d3ee; }
.fc-step-active .fc-stepper-dot { background: #0e7490; border-color: #22d3ee; color: #fff; box-shadow: 0 0 0 3px rgba(34,211,238,0.25); }
.fc-step-active .fc-stepper-label { color: #fff; }
@media (max-width: 640px) {
  .fc-stepper { margin-bottom: 0.75rem; }
  .fc-stepper-label { margin-top: 3px; }
  .fc-stepper-line { margin-top: 10px; }
}

/* Booking-detail status action buttons (Confirm/Reject/Mark Active/
   Complete/Edit/Cancel, fleet-calendar.js) intentionally keep their own
   status colors instead of .btn-primary/.btn-secondary/.btn-destructive —
   see the Unified Button System comment above — so they get the same
   glow-on-hover language added directly to their own colors here, scoped
   to their #bdActions container, rather than switching them to a
   different color scheme. Zero HTML/JS changes needed: these are already
   shared Tailwind utility classes. */
#bdActions button.bg-purple-700:hover { box-shadow: 0 0 16px rgba(168,85,247,0.45); }
#bdActions button.bg-red-700:hover { box-shadow: 0 0 16px rgba(239,68,68,0.45); }
#bdActions button.bg-emerald-700:hover,
#bdActions button.bg-emerald-600:hover { box-shadow: 0 0 16px rgba(16,185,129,0.45); }
#bdActions button.bg-cyan-600:hover { box-shadow: 0 0 16px rgba(6,182,212,0.45); }
#bdActions button.bg-slate-700:hover { box-shadow: 0 0 14px rgba(100,116,139,0.35); }
#bdActions a.bg-emerald-900\/50:hover,
#bdActions button.bg-emerald-900\/50:hover { box-shadow: 0 0 14px rgba(16,185,129,0.3); }

@media (max-width: 639px) {
  .fc-table thead th, .fc-table tbody td { padding: 8px 10px; font-size: 12px; }
}

/* ── Unified Button System ────────────────────────────────────────────────
   Reads its actual values from design-tokens.css (:root custom properties)
   — this file defines the SHAPES/STATES, the token file defines the
   COLORS/SIZES, so a future theme is a token-file edit, not a rule-by-rule
   rewrite here. Three tiers:

   .btn-primary     the one dominant action in a screen — Search Fleet,
                     Save, Confirm, Submit, Add Transaction/Vehicle/Booking.
                     Solid gradient fill, rounded rectangle.
   .btn-secondary   supporting actions — Sign In, View, Edit, Cancel, Back.
                     Dark outlined pill with icon + label (Create Account's
                     existing treatment, now the shared one).
   .badge           non-interactive trust indicators and status labels
                     ("Guaranteed Rides", booking status). Same pill/border
                     language as .btn-secondary, deliberately with NO
                     hover/focus/cursor styling — it isn't a control.
   .pill-badge      a close relative of .badge for controls that DO need
                     to be clickable (filter chips, the rating picker,
                     status pills that toggle) — same shape tokens, own
                     --pill-accent color, kept interactive.

   .btn-destructive (pre-dates the 3-tier spec above, kept alongside it)
                     dangerous actions — Delete, Remove, Reject.

   Every tier carries ONLY color/shape/motion, never a specific width or
   flex layout — a compact toolbar button and a full-width checkout CTA
   both still read as "the same button", sized for their own context via
   the ordinary Tailwind utilities already on the element (px-*, py-*,
   w-full, flex-1, gap-2, ...).

   Deliberately NOT applied to: the booking-detail status-action buttons in
   fleet-calendar.js (Confirm/Mark Active/Complete/Reject) — those reuse the
   purple/cyan/emerald/slate status colors on purpose, to visually match the
   Requested/Confirmed/Active/Completed stepper and legend chips elsewhere
   on that screen. Also not applied to third-party-branded buttons (Login
   with Google) or WhatsApp actions, which intentionally keep their own
   brand color so people still recognize them as what they are. ──────────*/
.btn-primary,
.btn-secondary,
.btn-destructive {
  min-height: var(--control-height-sm);
  padding: 0 var(--control-padding-x-sm);
  font-size: var(--control-font-size);
  font-weight: var(--control-font-weight);
  gap: var(--control-icon-gap);
  cursor: pointer;
  border: 1px solid transparent;
  /* border:1px solid transparent + a background-image gradient + a large
     border-radius (the pill shape below) is a known Chromium rendering
     bug: at the point of tightest curvature — the exact middle of a
     pill's rounded end — the gradient's default border-box clipping and
     the transparent border's own anti-aliasing don't quite agree, and a
     sliver of the WRONG part of the gradient leaks through (reported: a
     stray fleck of the gradient's start color showing up at the far end,
     where only the end color should be). padding-box clips the
     background to just inside the border instead, which is what
     actually fixes it — confirmed by reproducing the artifact and
     testing both padding-box and border:none, before picking whichever
     preserves the border's existing sizing/spacing. Harmless for
     .btn-secondary/.btn-destructive's solid-color fills, kept here so
     any future gradient tier doesn't reintroduce the same bug. */
  background-clip: padding-box;
  -webkit-background-clip: padding-box;
  transition: background 0.2s ease, background-image 0.2s ease, border-color 0.2s ease,
    color 0.2s ease, box-shadow var(--control-transition-duration) var(--control-transition-easing),
    transform var(--control-transition-duration) var(--control-transition-easing), filter 0.2s ease;
}
@media (min-width: 640px) {
  .btn-primary,
  .btn-secondary,
  .btn-destructive {
    min-height: var(--control-height);
    padding: 0 var(--control-padding-x);
  }
}
.btn-primary:disabled,
.btn-secondary:disabled,
.btn-destructive:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none !important;
}
.btn-primary:active:not(:disabled),
.btn-destructive:active:not(:disabled) {
  filter: brightness(0.92);
}
/* Shared loading state — toggle by adding this class (or [aria-busy="true"],
   which does the same thing) to any Primary/Secondary/Destructive button;
   dims it and blocks interaction the same way :disabled does, without
   actually setting the disabled attribute (so a screen reader still
   reports it as "busy" rather than unavailable). Purely a style hook —
   nothing in this pass wires it up to any button's own JS. */
.btn-primary.is-loading,
.btn-secondary.is-loading,
.btn-destructive.is-loading,
.btn-primary[aria-busy="true"],
.btn-secondary[aria-busy="true"],
.btn-destructive[aria-busy="true"] {
  opacity: 0.7;
  cursor: wait;
  pointer-events: none;
  transform: none !important;
}

.btn-primary {
  background-image: linear-gradient(to right, var(--btn-primary-grad-from), var(--btn-primary-grad-via), var(--btn-primary-grad-to));
  color: var(--btn-primary-text);
  border-radius: var(--control-radius-pill);
  box-shadow: 0 0 0 rgba(8, 145, 178, 0);
}
.btn-primary:hover:not(:disabled):not(.is-loading) {
  background-image: linear-gradient(to right, var(--btn-primary-grad-from-hover), var(--btn-primary-grad-via-hover), var(--btn-primary-grad-to-hover));
  box-shadow: 0 0 18px var(--btn-primary-glow), 0 0 34px var(--btn-primary-glow-2);
  transform: scale(var(--control-hover-scale));
}
.btn-primary:focus-visible {
  outline: var(--focus-ring-width) solid var(--accent);
  outline-offset: var(--focus-ring-offset);
  box-shadow: 0 0 18px var(--btn-primary-glow);
}
/* Optional slow, low-amplitude pulse — opt-in via .btn-pulse, reserved for
   one hero CTA per page (the homepage/booking-search "Search Fleet"
   button), never applied to every .btn-primary by default. */
@keyframes btn-pulse-glow {
  0%, 100% { box-shadow: 0 0 10px var(--btn-primary-glow); }
  50%      { box-shadow: 0 0 22px var(--btn-primary-glow), 0 0 8px var(--btn-primary-glow-2); }
}
.btn-primary.btn-pulse {
  animation: btn-pulse-glow 2.6s ease-in-out infinite;
}
.btn-primary.btn-pulse:hover:not(:disabled):not(.is-loading) {
  animation-play-state: paused;
}
@media (prefers-reduced-motion: reduce) {
  .btn-primary.btn-pulse { animation: none; }
}

.btn-secondary {
  background-color: var(--btn-secondary-bg);
  border-color: var(--btn-secondary-border);
  color: var(--btn-secondary-text);
  border-radius: var(--control-radius-pill);
  backdrop-filter: blur(6px);
}
.btn-secondary:hover:not(:disabled):not(.is-loading) {
  background-color: var(--btn-secondary-bg-hover);
  border-color: var(--btn-secondary-border-hover);
  box-shadow: 0 0 14px var(--btn-secondary-glow);
  transform: scale(var(--control-hover-scale));
}
.btn-secondary:focus-visible {
  outline: var(--focus-ring-width) solid var(--btn-secondary-border-hover);
  outline-offset: var(--focus-ring-offset);
  box-shadow: 0 0 14px var(--btn-secondary-glow);
}

.btn-destructive {
  background-color: var(--btn-destructive-bg);
  color: var(--btn-destructive-text);
  border-radius: var(--control-radius-pill);
}
.btn-destructive:hover:not(:disabled):not(.is-loading) {
  background-color: var(--btn-destructive-bg-hover);
  box-shadow: 0 0 18px var(--btn-destructive-glow);
}
.btn-destructive:focus-visible {
  outline: var(--focus-ring-width) solid var(--btn-destructive-bg);
  outline-offset: var(--focus-ring-offset);
  box-shadow: 0 0 18px var(--btn-destructive-glow);
}

/* ── Team Members: outstanding-settlement warning glyph ──────────────────
   Sits next to a partner's name on the COLLAPSED accordion row so an
   outstanding Owed To balance is visible without expanding the card.
   Amber to match this app's existing warning language (the settlement
   mismatch banner's text-amber-400/bg-amber-900), with the same
   pulsing-glow treatment as .btn-pulse (own keyframes since that one's
   glow color is the cyan/blue primary-button gradient, wrong hue here) —
   this needs to catch the eye on its own since, unlike a button, nothing
   else about it visually reads as "action needed" until you notice it.
   Tooltip behavior (hover on desktop, tap on mobile) is the existing
   [data-tooltip][data-tooltip-tap] system (desc-tooltip.js) — the same one
   table Description cells already use — not anything new. Split into a
   wrapper (.tm-owed-warning-btn, carries the tooltip attributes + click
   handling + flex sizing) and the glyph itself (.tm-owed-warning, just
   color/animation) — this app's [data-tooltip][data-tooltip-tap]::before
   suppression rule (desktop: hides the plain-CSS popup so only the JS tap-
   tooltip singleton shows) would otherwise blank the glyph too, since Font
   Awesome ALSO renders it via ::before on the same element. */
.tm-owed-warning-btn {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  flex-shrink: 0;
}
.tm-owed-warning {
  color: #f59e0b;
  font-size: 0.7rem;
  animation: tm-owed-pulse 2s ease-in-out infinite;
}
@keyframes tm-owed-pulse {
  0%, 100% { text-shadow: 0 0 3px rgba(245, 158, 11, 0.55); }
  50%      { text-shadow: 0 0 9px rgba(245, 158, 11, 0.9), 0 0 14px rgba(245, 158, 11, 0.45); }
}
@media (prefers-reduced-motion: reduce) {
  .tm-owed-warning { animation: none; text-shadow: 0 0 6px rgba(245, 158, 11, 0.7); }
}

/* ── Badge/chip: non-interactive trust indicators & status labels ────────
   Same pill shape/border language as .btn-secondary (both read from the
   same --btn-secondary-* tokens) but deliberately carries NO hover, focus,
   or cursor styling — a badge is a label, not a control. .hero-badge (the
   "Guaranteed Rides" row) is this tier's original, still-used name; .badge
   is the same recipe under the tier's formal name for use anywhere else a
   static label like this is needed (e.g. a booking status chip that isn't
   meant to be clicked). */
.hero-badge,
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--control-icon-gap);
  padding: 0.4rem 0.75rem;
  border-radius: var(--control-radius-pill);
  background: var(--btn-secondary-bg);
  border: 1px solid var(--btn-secondary-border);
  backdrop-filter: blur(6px);
  color: var(--btn-secondary-text);
  font-size: 0.75rem;
  font-weight: var(--control-font-weight);
}
@media (min-width: 640px) {
  .hero-badge,
  .badge { font-size: 0.8125rem; }
}

/* ── Pill/badge primitive (interactive) ───────────────────────────────────
   Same shape/motion recipe as .badge above, but for controls that DO need
   to be clickable — filter chips (.desc-chip), status pills (.fc-pill),
   the star/emoji rating picker (.emoji-btn), the recommend toggle
   (.rec-btn), review filter chips (.rv-filter-btn), the auth login/signup
   tab switch (.auth-tab-btn), and booking status badges (.booking-chip)
   all compose .pill-badge instead of each defining their own shape from
   scratch. Each control's own accent color layers on top via
   --pill-accent (falls back to the app's cyan brand color when a control
   doesn't set one) — color still carries meaning (status/rating/tab
   colors are unchanged), only the shape/border/blur/glow are shared. */
.pill-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  border-radius: var(--control-radius-pill);
  background: color-mix(in srgb, var(--pill-accent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--pill-accent) 38%, transparent);
  color: var(--pill-accent);
  font-weight: var(--control-font-weight);
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.25s ease,
    transform var(--control-transition-duration) var(--control-transition-easing);
}
.pill-badge:hover {
  background: color-mix(in srgb, var(--pill-accent) 22%, transparent);
  border-color: color-mix(in srgb, var(--pill-accent) 55%, transparent);
  box-shadow: 0 0 14px color-mix(in srgb, var(--pill-accent) 35%, transparent);
}
.pill-badge:focus-visible {
  outline: var(--focus-ring-width) solid var(--pill-accent);
  outline-offset: var(--focus-ring-offset);
}
.pill-badge.pill-badge-active {
  background: color-mix(in srgb, var(--pill-accent) 26%, transparent);
  border-color: var(--pill-accent);
  color: #fff;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pill-accent) 45%, transparent),
              0 0 16px color-mix(in srgb, var(--pill-accent) 40%, transparent);
}
.pill-badge:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
}

/* ── Pagination buttons — same shape/glow language as .pill-badge above,
   sized for a numbered "« 1 2 3 »" pager instead of a text chip. Every
   admin-facing paginated table (Transaction History, Vehicle Detail
   History, CRM Customers, Admin Users/Docs/Reviews) previously built its
   own copy of this exact button with plain bg-cyan-600/bg-slate-700
   Tailwind classes and no glow at all — this replaces all of those with
   one shared, on-theme control. --pill-accent defaults to the app's cyan
   brand color; a section can still override it inline the same way
   .select-pill/.pill-badge already do. */
.pg-btn {
  --pill-accent: #22d3ee;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* min-width is the effective width for anything up to 2 characters (a
     chevron icon, or page numbers 1-99): at this font-size/weight, 1-2
     digits plus this padding stay under 2rem, so min-width wins and the
     box is exactly 2rem square — a true circle, not the icons-are-round/
     2-digit-numbers-are-oval inconsistency this replaced. A 3+ digit page
     count is the one case content genuinely no longer fits at 2rem: its
     intrinsic content+padding width exceeds min-width, so THAT wins
     instead and the box widens into a pill while keeping the same
     border-radius: 9999px — no separate rule needed for that case. */
  min-width: 2rem;
  /* The global `button, .btn { min-height: 40px/44px }` touch-target rules
     (640px+ and pointer:coarse, further up this file) otherwise clamp this
     shorter than that regardless of the height:2rem below — same fix
     .ts-dot needed (trip-showcase.css) for the same reason. .pg-btn's own
     class selector outweighs that plain `button` element selector, so this
     wins without needing !important. */
  min-height: 2rem;
  height: 2rem;
  padding: 0 0.4rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 600;
  background: color-mix(in srgb, var(--pill-accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--pill-accent) 32%, transparent);
  color: #cbd5e1;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.25s ease, color 0.2s ease;
}
.pg-btn:hover:not(:disabled) {
  background: color-mix(in srgb, var(--pill-accent) 20%, transparent);
  border-color: color-mix(in srgb, var(--pill-accent) 55%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--pill-accent) 35%, transparent);
  color: #fff;
}
.pg-btn:focus-visible {
  outline: none;
  border-color: var(--pill-accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pill-accent) 50%, transparent);
}
.pg-btn.pg-btn-active {
  background: color-mix(in srgb, var(--pill-accent) 28%, transparent);
  border-color: var(--pill-accent);
  color: #fff;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pill-accent) 45%, transparent),
              0 0 14px color-mix(in srgb, var(--pill-accent) 45%, transparent);
}
.pg-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  box-shadow: none;
}
.pg-ellipsis {
  padding: 0 0.25rem;
  color: #64748b;
  font-size: 0.75rem;
  align-self: center;
}

/* ── Optional-field badge: small persistent-glow pill next to a field's
   label when, unlike its usual siblings, it isn't required — currently
   just the Vehicle field on the Add/Edit Transaction forms' Income type
   (income no longer forces a vehicle; see the Company Income removal).
   Composes the same color-mix background/border/glow recipe as
   .pill-badge/.select-pill above, but the glow is always on rather than
   hover-triggered, since this is a static label (not a control) — same
   non-interactive intent as .badge, just carrying a glow at rest the way
   .role-badge's status dots already do. */
.field-optional-badge {
  --pill-accent: #38bdf8;
  display: inline-flex;
  align-items: center;
  padding: 0.05rem 0.45rem;
  border-radius: 9999px;
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: color-mix(in srgb, var(--pill-accent) 14%, transparent);
  color: var(--pill-accent);
  border: 1px solid color-mix(in srgb, var(--pill-accent) 40%, transparent);
  box-shadow: 0 0 6px color-mix(in srgb, var(--pill-accent) 45%, transparent);
  vertical-align: middle;
}

/* ── Compact filter select (chart year range, transaction/partner/vehicle
   month filters) — pill shape + glow, matching .pill-badge's shape/glow
   language above instead of the plain rounded-rectangle look these small
   inline selects used before.
   Reported: the chart's year-range selects were clipping "2026" down to
   "202". Root cause — the shared "Standardized form field" select{...}
   rule further up this file (a plain tag selector, so it already
   outranks these selects' own compact Tailwind classes regardless of
   source order — same trap as the fuel-level/dt-compact fields) sets
   min-height:44px, and a separate mobile-only rule forces
   font-size:16px !important (deliberately, to stop iOS Safari
   auto-zooming the page on focus — not something to fight). Between an
   effectively-doubled font and a 44px-tall box, two of these side by
   side with an em-dash between them had nowhere near enough width left
   for a 4-digit year.
   This class doesn't touch font-size — same call custom.css's existing
   input[type="date"].dt-compact already makes for the identical
   conflict — and instead narrows the space AROUND the forced 16px font
   (min-height, padding), which is what actually makes room for it.
   --pill-accent lets each usage keep its section's existing color
   (cyan for the chart/vehicle filters, purple for financial
   summary/partner) via an inline style, same customization point
   .pill-badge itself uses. */
.select-pill {
  --pill-accent: #22d3ee;
  /* The shared field system (further up this file) also sets
     width:100% — harmless for a field alone on its own row, but these
     selects sit as flex children next to other things (an em-dash and
     a second select, or a button), and 100% fed into flex-basis:auto's
     sizing calculation squeezed each one down to an arbitrary share of
     the row instead of however wide its actual text needs — measured
     as little as ~21px of usable content width against text (e.g.
     "2024") that needs closer to 40px, which is what was actually
     clipping the year down to 2 digits even after the min-height/
     padding fix above. width:auto lets it size to its own content
     (the OS-rendered <option> text) the same as an ordinary unstyled
     select would; flex-shrink:0 stops it from being compressed back
     down if the row ever runs tight on space instead of wrapping. */
  width: auto;
  flex-shrink: 0;
  min-height: var(--control-height-sm);
  /* Trimmed further (was 0.75rem/1.5rem) — the Overview chart's two year
     selects plus the em-dash/divider/toggle-button needed to share one
     line with the card's own title on mobile without wrapping; every
     other px of horizontal padding directly widened that row past what
     fits. Can't shrink the FONT to claw back more (still 16px on mobile
     via the iOS-zoom-prevention rule these selects deliberately don't
     fight, see the comment above) — padding was the only lever left. */
  padding: 0.2rem 1.125rem 0.2rem 0.5rem;
  border-radius: 9999px;
  background: color-mix(in srgb, var(--pill-accent) 12%, #0f172a);
  border: 1px solid color-mix(in srgb, var(--pill-accent) 40%, transparent);
  color: #fff;
  cursor: pointer;
  transition: border-color 0.2s ease, box-shadow 0.25s ease;
}
.select-pill:hover {
  border-color: color-mix(in srgb, var(--pill-accent) 60%, transparent);
  box-shadow: 0 0 10px color-mix(in srgb, var(--pill-accent) 35%, transparent);
}
.select-pill:focus-visible {
  outline: none;
  border-color: var(--pill-accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pill-accent) 50%, transparent),
              0 0 14px color-mix(in srgb, var(--pill-accent) 45%, transparent);
}
@media (min-width: 640px) {
  .select-pill {
    min-height: var(--control-height);
    padding: 0.3rem 1.75rem 0.3rem 0.875rem;
  }
}

/* ── Unified close button ──────────────────────────────────────────────────
   Every "X" dismiss control in the app — modal/drawer headers, lightboxes,
   file-remove buttons, banner dismissals — used to be one of 7+ different
   ad-hoc icon-button treatments. Reported twice now: first that a circular
   background looked too heavy, then that ANY background box (rounded-
   rectangle included) still looked wrong — so this is bare icon only, no
   background, no border, no box-shadow at rest OR hover. Feedback is
   color-only (slate → rose on hover, same "this dismisses" cue as
   before), plus a focus-visible OUTLINE for keyboard users — a thin ring
   drawn outside the icon, not a filled box behind it, which is a
   different, standard accessibility affordance rather than the "box
   around the icon" look being removed here. */
.btn-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  background: transparent;
  border: none;
  color: #94a3b8;
  cursor: pointer;
  transition: color 0.2s ease;
}
.btn-close:hover {
  color: #fda4af;
}
.btn-close:focus-visible {
  outline: 2px solid #22d3ee;
  outline-offset: 2px;
  border-radius: var(--control-radius-rect);
}
@media (pointer: coarse) {
  .btn-close {
    width: 2.75rem;
    height: 2.75rem;
  }
}

/* ── Unified icon-only delete button ──────────────────────────────────────
   Same bare-icon treatment as .btn-close, but for an actual destructive
   trash/delete icon button (row-level delete on a list, remove-user,
   etc.) rather than a dismiss action — rose at rest instead of
   .btn-close's neutral slate, since here the color should say "delete"
   immediately, not just warm up as a hover hint. Distinct from
   .btn-destructive, which is for a full labeled delete button (icon +
   text); this is for the icon-only case those don't fit (a compact row
   action, a table cell). */
.btn-icon-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  background: transparent;
  border: none;
  color: #fb7185;
  cursor: pointer;
  transition: color 0.2s ease;
}
.btn-icon-danger:hover {
  color: #fecdd3;
}
.btn-icon-danger:focus-visible {
  outline: 2px solid #22d3ee;
  outline-offset: 2px;
  border-radius: var(--control-radius-rect);
}
@media (pointer: coarse) {
  .btn-icon-danger {
    width: 2.75rem;
    height: 2.75rem;
  }
}

/* ── Unified icon-only neutral/promote buttons ────────────────────────────
   Same bare-icon family as .btn-close/.btn-icon-danger, for row actions
   whose meaning is carried by the icon rather than the color being a
   universal "delete" cue — the admin-role toggle (User Roles list) uses
   these instead of a filled Make Admin/Remove Admin text button, so the
   row reads as a compact icon action like every other row control instead
   of a big solid rectangle. .btn-icon-neutral is the "promote" state
   (currently a plain user, click to make admin); .btn-icon-amber is the
   "demote" state (currently an admin — amber matches the Admin badge/
   crown color used everywhere else in the app, click to remove admin). */
.btn-icon-neutral {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  background: transparent;
  border: none;
  color: #94a3b8;
  cursor: pointer;
  transition: color 0.2s ease;
}
.btn-icon-neutral:hover {
  color: #cbd5e1;
}
.btn-icon-neutral:focus-visible {
  outline: 2px solid #22d3ee;
  outline-offset: 2px;
  border-radius: var(--control-radius-rect);
}
.btn-icon-neutral:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
@media (pointer: coarse) {
  .btn-icon-neutral {
    width: 2.75rem;
    height: 2.75rem;
  }
}

.btn-icon-amber {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  background: transparent;
  border: none;
  color: #fbbf24;
  cursor: pointer;
  transition: color 0.2s ease;
}
.btn-icon-amber:hover {
  color: #fde68a;
}
.btn-icon-amber:focus-visible {
  outline: 2px solid #22d3ee;
  outline-offset: 2px;
  border-radius: var(--control-radius-rect);
}
.btn-icon-amber:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
@media (pointer: coarse) {
  .btn-icon-amber {
    width: 2.75rem;
    height: 2.75rem;
  }
}

/* ── Compact role/status icon badges (User Roles list) ────────────────────
   Replaces the old "Admin"/"User"/"Active"/"Inactive" text pills that sat
   in their own row below the contact details — reported as wasting a full
   extra line per user card. Now a small icon-only dot sitting right next
   to the name; the label that used to be baked into the pill text is
   still there for anyone who needs it, via the existing [data-tooltip]
   hover affordance (see the [data-tooltip] rules above) instead of always
   being spelled out, which is what actually let the badge shrink down to
   icon size. Admin/Active get a glow (privileged/healthy state worth
   drawing the eye to); User/Inactive stay flat. */
.role-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 9999px;
  font-size: 0.6875rem;
  flex-shrink: 0;
}
.role-badge--admin {
  background: rgba(245, 158, 11, 0.18);
  color: #fbbf24;
  box-shadow: 0 0 8px rgba(245, 158, 11, 0.55);
}
.role-badge--user {
  background: rgba(59, 130, 246, 0.15);
  color: #60a5fa;
}
.role-badge--active {
  background: rgba(16, 185, 129, 0.18);
  color: #34d399;
  box-shadow: 0 0 8px rgba(16, 185, 129, 0.5);
}
.role-badge--inactive {
  background: rgba(100, 116, 139, 0.2);
  color: #94a3b8;
}

/* ── WhatsApp chat widget — pulsing FAB, panel open/close transition,
   trust-signal dot, and send-button glow. Drag position math, the
   above/below panel-flip math, the wa.me deep link, Enter-to-send, and
   click-outside-to-close all stay entirely in whatsapp-widget.js — this
   is purely the visual layer on top of the classes that JS toggles. */
@keyframes wa-fab-pulse {
  0%, 100% { filter: drop-shadow(0 2px 6px rgba(34, 197, 94, 0.45)) drop-shadow(0 0 10px rgba(34, 197, 94, 0.28)); }
  50%      { filter: drop-shadow(0 2px 8px rgba(34, 197, 94, 0.6)) drop-shadow(0 0 20px rgba(34, 197, 94, 0.55)); }
}
#whatsappWidgetButton {
  animation: wa-fab-pulse 2.6s ease-in-out infinite;
}
#whatsappWidgetButton:hover {
  animation-play-state: paused;
}
@media (prefers-reduced-motion: reduce) {
  #whatsappWidgetButton { animation: none; }
}

/* Scale+fade open/close, same recipe as .hp-dropdown's entrance
   (header-panels.css) — whatsapp-widget.js toggles .wa-panel-visible a
   frame after removing `hidden` (and removes it before re-adding
   `hidden` on close) so the transition actually plays instead of
   snapping instantly the way the old plain `hidden` toggle did. */
#whatsappWidgetPanel {
  transform: scale(0.95);
  opacity: 0;
  transition: transform 0.2s ease-out, opacity 0.2s ease-out;
  box-shadow:
    0 0 0 1px rgba(16, 185, 129, 0.2),
    0 0 24px rgba(16, 185, 129, 0.18),
    0 0 40px rgba(20, 184, 166, 0.16),
    0 20px 44px rgba(0, 0, 0, 0.55);
}
#whatsappWidgetPanel.wa-panel-visible {
  transform: scale(1);
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  #whatsappWidgetPanel {
    transition: opacity 0.15s ease-out;
    transform: none;
  }
}

/* Trust-signal status dot beneath the header */
@keyframes wa-status-pulse {
  0%, 100% { box-shadow: 0 0 0 rgba(52, 211, 153, 0.7); opacity: 1; }
  50%      { box-shadow: 0 0 6px rgba(52, 211, 153, 0.9); opacity: 0.7; }
}
.wa-status-dot {
  background: #34d399;
  animation: wa-status-pulse 2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .wa-status-dot { animation: none; }
}

/* Textarea: same focus-glow tokens every other field in the app uses
   (design-tokens.css), plus auto-grow room (whatsapp-widget.js sets an
   inline height on input, capped here) instead of a fixed 3 rows. */
#whatsappWidgetInput {
  min-height: 76px;
  max-height: 160px;
  overflow-y: auto;
}
#whatsappWidgetInput:focus {
  outline: none;
  border-color: var(--field-border-focus);
  box-shadow: 0 0 0 3px var(--field-glow-focus);
}

/* Send button: gradient fill is set via Tailwind classes in index.html;
   this adds the hover/focus glow and a cursor hint for the brief
   "Opening WhatsApp…" acknowledgment state (button disabled while it plays). */
#whatsappWidgetSend:hover:not(:disabled),
#whatsappWidgetSend:focus-visible {
  box-shadow: 0 0 16px rgba(16, 185, 129, 0.5), 0 0 30px rgba(20, 184, 166, 0.3);
}
#whatsappWidgetSend:disabled {
  opacity: 0.85;
  cursor: wait;
}
