/* ------------------------------------------------------------
   Theme tokens
   - Central place for colours, spacing, and typography.
   - Prefer reusing variables rather than hardcoding values.
------------------------------------------------------------- */
/* Note: tokens have been moved to /assets/css/tokens.css (single source of truth). */

/* ------------------------------------------------------------
   Base / Resets
------------------------------------------------------------- */
* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  color: var(--theme-body-text);
  background: var(--theme-body-bg);
}

a { color: inherit; }

/* ------------------------------------------------------------
   Accessibility
------------------------------------------------------------- */
a:focus-visible,
button:focus-visible {
  outline: 3px solid var(--theme-focus);
  outline-offset: 2px;
}

/* ------------------------------------------------------------
   App layout shell
------------------------------------------------------------- */
/* Layout wrapper (Pro Sidebar-like) */
.layout {
  width: 100%;
  min-height: 100vh;
  display: grid;
  position: relative;
}

/* Why: When the sidebar is fixed/sticky at 100vh, the main content should scroll internally.
   This prevents the page from extending past the sidebar height and leaving empty space under it. */
.layout.fixed-sidebar.fixed-header {
  height: 100vh;
  overflow: hidden;
}

.layout-main {
  min-width: 0;
  display: grid;
  grid-template-rows: 64px 1fr;
}

.layout.fixed-sidebar.fixed-header .layout-main {
  height: 100vh;
  overflow: hidden;
}

.layout.fixed-sidebar.fixed-header .layout-main > main.page {
  min-height: 0;
  overflow-y: auto;
}

/* ------------------------------------------------------------
   Buttons
------------------------------------------------------------- */
.btn svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
}

.muted { color: var(--theme-muted); }

.required-asterisk {
  /* Tokenised required marker colour (single source of truth). */
  color: var(--theme-required-asterisk);
  /* Visual spacing between the label text and the asterisk. */
  margin-left: 4px; 
  /* Emphasise the asterisk so it's clearly visible. */
  font-weight: 700; 
  /* Increase asterisk size relative to the label text. */
  font-size: 1.50em; 
  /* Required so the vertical offset below applies consistently. */
  display: inline-block;
  /* Enables fine-grained vertical adjustment without affecting surrounding layout. */
  position: relative; 
  /* Lower the asterisk slightly to align better with label baseline. */
  top: 6px; 
  /* Prevent extra vertical space; keeps the asterisk aligned with the label. */
  line-height: 1; 
}

.field-inline-error {
  margin-left: 8px;
  font-weight: 600;
  font-size: 0.75rem;
  color: var(--toast-error);
  display: none;
}

.field-inline-error.is-visible {
  display: inline;
}

.field-inline-error.is-flashing {
  /* Why: Keep attention on blocking validation (e.g., duplicate rego) until resolved. */
  animation: fieldInlineErrorPulse 1.1s ease-in-out infinite;
}

@keyframes fieldInlineErrorPulse {
  0% { opacity: 1; }
  50% { opacity: 0.35; }
  100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .field-inline-error.is-flashing {
    animation: none;
  }
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--theme-border);
  background: var(--theme-surface);
  color: var(--theme-body-text);
  text-decoration: none;
}

/* Navbar styles have been moved to /assets/css/navbar.css */

.btn:hover {
  background: var(--theme-border);
}

/* ------------------------------------------------------------
   Pills / Chips
------------------------------------------------------------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 999px;
  border: 1px solid var(--theme-border);
  background: var(--theme-surface);
  font-size: 13px;
  max-width: 100%;
}

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 360px;
}

/* ------------------------------------------------------------
   Page containers
------------------------------------------------------------- */
.page {
  padding: 18px;
  width: 100%;
  /* max-width: 1000px; */
  max-width: 95%;
  margin: 0 auto;
}

.page.page-wide {
  max-width: none;
}

.page-grid {
  display: grid;
  grid-template-columns: 1.25fr 0.75fr;
  gap: 18px;
}

/* Mobile: stack split layouts into a single column */
@media (max-width: 760px) {
  .page {
    padding: 12px;
  }

  .page-grid {
    grid-template-columns: 1fr;
  }
}

/* ------------------------------------------------------------
   Cards
------------------------------------------------------------- */
.card {
  padding: 18px;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: var(--radius-base);
}

h1 {
  margin: 0 0 8px;
  font-size: 22px;
  letter-spacing: -0.02em;
}

/* ------------------------------------------------------------
   Page-scoped typography overrides
   Why:
   - Bootstrap sets responsive heading sizes globally (e.g., h2 = 2rem on >=1200px).
   - For /general-settings we want a denser admin-style layout without changing other pages.
------------------------------------------------------------- */
.page-general-settings {
  /* Why CSS variables:
     - Allows quick per-page tuning without searching for multiple selectors.
     - Keeps the override scoped to this page only. */
  --general-settings-h2-font-size: 1.25rem;
}

.page-general-settings h2,
.page-general-settings .h2 {
  font-size: var(--general-settings-h2-font-size);
  line-height: 1.75;
}

/* ------------------------------------------------------------
   Auth pages
------------------------------------------------------------- */
.auth-shell {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 48px 18px;
  position: relative;
  overflow: hidden;
  background: var(--theme-body-bg);
}

.auth-shell::before {
  content: '';
  position: absolute;
  inset: -2px;
  filter: blur(18px);
  opacity: 0.9;
  pointer-events: none;
}

.auth-card {
  width: 100%;
  max-width: 460px;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
  border-radius: 18px;
  box-shadow: 0 18px 60px var(--theme-shadow);
  padding: 26px;
  position: relative;
  z-index: 1;
}

.auth-header h1 {
  margin: 18px 0 8px;
  font-size: 26px;
  letter-spacing: -0.02em;
}

.auth-header-centered {
  text-align: center;
}

.auth-hero-icon {
  display: flex;
  justify-content: center;
  margin-bottom: 8px;
}

.login-logo {
  display: flex;
  justify-content: center;
  margin-bottom: 8px;
}

.login-logo img {
  height: 96px;
  width: auto;
  display: block;
}

.auth-subtitle {
  margin-top: 0;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.brand-mark {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: linear-gradient(135deg, var(--theme-primary-btn-bg), var(--theme-primary-btn-hover-bg));
  box-shadow: 0 12px 40px var(--theme-shadow);
  position: relative;
}

.brand-mark::after {
  content: '';
  position: absolute;
  inset: 10px;
  border-radius: 10px;
  background: var(--theme-surface);
  border: 1px solid var(--theme-border);
}

.brand-name {
  font-weight: 700;
  letter-spacing: 0.02em;
}

.brand-subtitle {
  color: var(--theme-muted);
  font-size: 13px;
  margin-top: 2px;
}

.alert {
  margin-top: 14px;
  border: 1px solid var(--theme-border);
  background: var(--theme-border);
  color: var(--theme-body-text);
  padding: 12px 12px;
  border-radius: 12px;
  font-size: 14px;
}

.auth-form {
  margin-top: 18px;
  display: grid;
  gap: 14px;
}

.field {
  display: grid;
  gap: 8px;
}

.label {
  font-size: 13px;
  color: var(--theme-muted);
}

/* ------------------------------------------------------------
   Forms
------------------------------------------------------------- */
input[type="email"],
input[type="password"],
input[type="text"],
input[type="date"],
input[type="tel"],
input[type="number"],
select,
textarea,
.form-control {
  width: 100%;
  padding: 8px 10px; /* Why: reduce overall control height across all forms (denser layout, less scrolling). */
  border-radius: 0; /* Why: standardize on square corners for a more "corporate"/grid-aligned look. */
  border: 1px solid var(--theme-border);
  background: var(--theme-surface);
  color: var(--theme-body-text);
  outline: none;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}

input::placeholder {
  color: var(--theme-muted);
}

textarea::placeholder {
  color: var(--theme-muted);
}

input:focus {
  border-color: var(--theme-focus);
  box-shadow: 0 0 0 4px var(--theme-focus-ring);
}

select:focus,
textarea:focus,
.form-control:focus {
  border-color: var(--theme-focus);
  box-shadow: 0 0 0 4px var(--theme-focus-ring);
}

/* ------------------------------------------------------------
   Primary action button (forms)
------------------------------------------------------------- */
.btn-primary {
  margin-top: 4px;
  width: 100%;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid var(--theme-primary-btn-bg);
  color: var(--theme-primary-btn-text);
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--theme-primary-btn-bg);
  cursor: pointer;
  transition: transform 120ms ease, filter 120ms ease;
}

.btn-primary:hover {
  background: var(--theme-primary-btn-hover-bg);
  border-color: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
}

.btn-primary:active {
  transform: translateY(1px);
}

/* ------------------------------------------------------------
   Reports landing page
------------------------------------------------------------- */
.reports-btn {
  /* Why: Keep report buttons visually consistent with the global theme while allowing
     a single place to tweak radius/spacing specifically for /reports UI. */
  border-radius: 4px;
  width: 100%;
}

.meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  padding-top: 6px;
}

.auth-footer {
  z-index: 1;
  margin-top: 18px;
  font-size: 12px;
  text-align: center;
  color: var(--theme-muted);
}

@media (max-width: 420px) {
  .auth-card {
    padding: 20px;
  }
  .meta {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 980px) {
  .page-grid { grid-template-columns: 1fr; }
  .truncate { max-width: 240px; }
}

@media (max-width: 760px) {
  .layout { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------
   Modals (scoped)
   - Keep changes scoped to specific modals to avoid unintended UI impact.
------------------------------------------------------------- */
#bookingModal > .modal-dialog {
  /* modal width */
  width: 80vw;
  max-width: 80vw;
  min-width: 80vw;
  /* modal height */
  height: 80vh;
  min-height: 80vh;
  max-height: 80vh;
}

#invoiceModal > .modal-dialog {
  /* modal width
     Why: keep Invoice modal consistent with Booking modal sizing across the app. */
  width: 80vw;
  max-width: 80vw;
  min-width: 80vw;
  /* modal height
     Why: keep New/Update Invoice consistent with New/Update Booking. */
  height: 80vh;
  min-height: 80vh;
  max-height: 80vh;
}

 #paymentModal > .modal-dialog {
   /* modal width
      Why: keep Payment modal consistent with Booking/Invoice modal sizing across the app. */
   width: 80vw;
   max-width: 80vw;
   min-width: 80vw;
   /* modal height
      Why: keep Record Payment consistent with other primary modals. */
   height: 80vh;
   min-height: 80vh;
   max-height: 80vh;
 }

/* Booking modal: Quick Add Vehicle modal should be smaller than the main booking modal.
   Target: ~20% narrower and ~30% shorter than #bookingModal.
   Keep this scoped to avoid affecting other Bootstrap modals. */
#quickAddVehicleModal .modal-dialog {
  width: 864px;
  max-width: 95vw;
}

#quickAddClientModal .modal-dialog {
  width: 864px;
  max-width: 95vw;
}

#quickAddVehicleModal .modal-dialog,
#quickAddVehicleModal .modal-content {
  min-height: 32vh;
  max-height: 42vh;
}

#quickAddClientModal .modal-dialog,
#quickAddClientModal .modal-content {
  min-height: 32vh;
  max-height: 42vh;
}

/* Keep Quick Add Client modal the same visible height as Quick Add Vehicle.
   Why: client quick-add will be expanded with more fields; keeping a stable height avoids UI jumping. */
#quickAddClientModal .modal-dialog,
#quickAddClientModal .modal-content,
#quickAddClientModal .modal-dialog-scrollable .modal-content {
  height: 42vh;
}

#bookingModal > .modal-dialog,
#bookingModal > .modal-dialog > .modal-content {
  min-height: 80vh; /* Why: the tabbed modal needs a stable workspace height so content doesn't feel cramped (esp. on tall screens). */
  max-height: 80vh; /* Why: never exceed the viewport height; prevents the footer from falling below the fold. */
}

#bookingModal > .modal-dialog-scrollable > .modal-content {
  max-height: 80vh; /* Why: keep scrollable modal constrained to viewport height (Bootstrap's scrollable modal uses this as its container). */
}

#invoiceModal > .modal-dialog,
#invoiceModal > .modal-dialog > .modal-content {
  min-height: 80vh; /* Why: match Booking modal height so New/Update Invoice are consistent with New/Update Booking. */
  max-height: 80vh; /* Why: keep invoice modal within viewport like booking modal. */
}

#invoiceModal > .modal-dialog-scrollable > .modal-content {
  max-height: 80vh; /* Why: match booking modal scrollable container constraint. */
}

 #paymentModal > .modal-dialog,
 #paymentModal > .modal-dialog > .modal-content {
   min-height: 60vh; /* Why: match Booking/Invoice modal height for consistent modal UX. */
   max-height: 60vh; /* Why: keep payment modal within viewport like other modals. */
 }

 #paymentModal > .modal-dialog-scrollable > .modal-content {
   max-height: 60vh; /* Why: keep payment modal scrollable container consistent with other modals. */
 }

/* Vertically center Booking modal
   Why: When we fix the dialog height (80vh), Bootstrap's default top/bottom margins make the modal appear top-biased.
   We switch the modal container to flex so the dialog can be centered within the viewport. */
#bookingModal.modal.show {
  display: flex;
  align-items: center;
}

#bookingModal.modal.show > .modal-dialog {
  margin-top: 5%;
  margin-bottom: 10%;
}

#invoiceModal.modal.show {
  display: flex;
  align-items: center;
}

#invoiceModal.modal.show > .modal-dialog {
  margin-top: 5%;
  margin-bottom: 10%;
}

 #paymentModal.modal.show {
   display: flex;
   align-items: center;
 }

 #paymentModal.modal.show > .modal-dialog {
   margin-top: 10%;
   margin-bottom: 20%;
 }

#quickAddVehicleModal .modal-dialog-scrollable .modal-content {
  max-height: 42vh;
}

#quickAddClientModal .modal-dialog-scrollable .modal-content {
  max-height: 42vh;
}

/* Ensure Quick Add Vehicle modal behaves like the main booking modal:
   header/footer remain visible and only the body scrolls within the constrained height. */
#quickAddVehicleModal .modal-content {
  display: flex;
  flex-direction: column;
}

#quickAddClientModal .modal-content {
  display: flex;
  flex-direction: column;
}

#quickAddVehicleModal .modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  gap: 8px !important;
}

#quickAddClientModal .modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  gap: 8px !important;
}

/* Center Quick Add Vehicle modal within the Booking modal (not the full viewport).
   Why: quick-add is rendered inside booking_modal.php, and should feel like a nested dialog.
   Implementation: turn the nested .modal into an absolute overlay within #bookingModal and center its dialog. */
#bookingModal #quickAddVehicleModal {
  position: absolute;
  inset: 0;
  z-index: 1061; /* Above the booking modal content; below Bootstrap backdrops (typically 1050/1060+). */
}

#bookingModal #quickAddVehicleModal.show {
  display: flex !important;
  align-items: center;
  justify-content: center;
  padding: 12px;
  background: var(--theme-overlay-35);
}

#bookingModal #quickAddVehicleModal .modal-dialog {
  margin: 0;
}

#bookingModal #quickAddClientModal {
  position: absolute;
  inset: 0;
  z-index: 1061;
}

#bookingModal #quickAddClientModal.show {
  display: flex !important;
  align-items: center;
  justify-content: center;
  padding: 12px;
  background: var(--theme-overlay-35);
}

#bookingModal #quickAddClientModal .modal-dialog {
  margin: 0;
}

/* Google Places Autocomplete
   Why: Google appends `.pac-container` to <body>. In Bootstrap modals (and nested modals),
   the suggestions list can render behind the modal due to z-index stacking, making it look
   like autocomplete is not working. We force a high z-index so suggestions always appear
   above modal chrome/backdrops. */
.pac-container {
  z-index: 20000 !important;
}

/* Match Booking modal header/footer chrome for Quick Add Vehicle modal. */
#quickAddVehicleModal .modal-content,
#quickAddVehicleModal .modal-header,
#quickAddVehicleModal .modal-footer {
  border-radius: 0 !important;
}

#quickAddVehicleModal .modal-header {
  background: var(--theme-chrome-bg);
  color: var(--theme-chrome-text);
  border-color: var(--theme-chrome-border);
}

#quickAddVehicleModal .modal-footer {
  background: var(--theme-chrome-bg);
  color: var(--theme-chrome-text);
  border-color: var(--theme-chrome-border);
}

#quickAddVehicleModal .modal-body {
  background: var(--theme-surface);
}

#quickAddVehicleModal .modal-title {
  color: var(--theme-chrome-text);
}

#quickAddVehicleModal .btn-close {
  filter: invert(1) grayscale(1);
}

#quickAddVehicleModal .modal-footer .btn,
#quickAddVehicleModal .modal-footer .btn-primary {
  width: auto;
  margin-top: 0;
}

#quickAddVehicleModal .modal-footer .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  border-radius: 4px;
  border: 1px solid var(--theme-chrome-border);
  background: var(--theme-primary-btn-bg);
  color: var(--theme-primary-btn-text);
  font-size: 0.85rem;
  font-weight: 500;
  text-decoration: none;
}

#quickAddVehicleModal .modal-footer .btn:hover {
  background: var(--theme-primary-btn-hover-bg);
  border-color: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
}

#quickAddClientModal .modal-content,
#quickAddClientModal .modal-header,
#quickAddClientModal .modal-footer {
  border-radius: 0 !important;
}

#quickAddClientModal .modal-header {
  background: var(--theme-chrome-bg);
  color: var(--theme-chrome-text);
  border-color: var(--theme-chrome-border);
}

#quickAddClientModal .modal-footer {
  background: var(--theme-chrome-bg);
  color: var(--theme-chrome-text);
  border-color: var(--theme-chrome-border);
}

#quickAddClientModal .modal-body {
  background: var(--theme-surface);
}

#quickAddClientModal .modal-title {
  color: var(--theme-chrome-text);
}

#quickAddClientModal .btn-close {
  filter: invert(1) grayscale(1);
}

#quickAddClientModal .modal-footer .btn,
#quickAddClientModal .modal-footer .btn-primary {
  width: auto;
  margin-top: 0;
}

#quickAddClientModal .modal-footer .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  border-radius: 4px;
  border: 1px solid var(--theme-chrome-border);
  background: var(--theme-primary-btn-bg);
  color: var(--theme-primary-btn-text);
  font-size: 0.85rem;
  font-weight: 500;
  text-decoration: none;
}

#quickAddClientModal .modal-footer .btn:hover {
  background: var(--theme-primary-btn-hover-bg);
  border-color: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
}

#bookingModal > .modal-dialog-scrollable > .modal-content > .modal-body {
  max-height: none; /* Why: we don't rely on Bootstrap's max-height body calculation; the flex layout makes the body the scroll region. */
}

#bookingModal > .modal-dialog > .modal-content {
  display: flex; /* Why: enables header/body/footer layout with a pinned footer. */
  flex-direction: column; /* Why: stack header (top), body (middle), footer (bottom). */
}

#bookingModal > .modal-dialog > .modal-content > .modal-body {
  flex: 1 1 auto; /* Why: body takes remaining height and pushes footer to the bottom. */
  min-height: 0; /* Why: critical in flexbox: allows body to shrink; otherwise long content can push the footer outside the viewport. */
  overflow: auto; /* Why: keep header/footer fixed while allowing tab content to scroll. */
}

#invoiceModal > .modal-dialog-scrollable > .modal-content > .modal-body {
  max-height: none; /* Why: match booking modal scroll behavior; body is the scroll region. */
}

#invoiceModal > .modal-dialog > .modal-content {
  display: flex; /* Why: enables header/body/footer layout with a pinned footer. */
  flex-direction: column; /* Why: stack header (top), body (middle), footer (bottom). */
}

#invoiceModal > .modal-dialog > .modal-content > .modal-body {
  flex: 1 1 auto; /* Why: body takes remaining height and pushes footer to the bottom. */
  min-height: 0; /* Why: critical in flexbox so long content doesn't push footer off-screen. */
  overflow: auto; /* Why: keep header/footer fixed while allowing content to scroll. */
}

 #paymentModal > .modal-dialog-scrollable > .modal-content > .modal-body {
   max-height: none; /* Why: match booking/invoice modal scroll behavior; body is the scroll region. */
 }

 #paymentModal > .modal-dialog > .modal-content {
   display: flex; /* Why: enables header/body/footer layout with a pinned footer. */
   flex-direction: column; /* Why: stack header (top), body (middle), footer (bottom). */
 }

 #paymentModal > .modal-dialog > .modal-content > .modal-body {
   flex: 1 1 auto; /* Why: body takes remaining height and pushes footer to the bottom. */
   min-height: 0; /* Why: critical in flexbox so long content doesn't push footer off-screen. */
   overflow: auto; /* Why: keep header/footer fixed while allowing content to scroll. */
 }

/* Invoice modal height
   Why: New vs Update can have different content height (items list), which makes the dialog appear shorter/taller.
   We pin the overall dialog height to a viewport-based value so both modes are consistent and only the body scrolls. */
#invoiceModal > .modal-dialog {
  height: 80vh;
  max-height: 80vh;
}

#invoiceModal > .modal-dialog > .modal-content {
  height: 100%;
}

/* Create mode: keep Add Booking modal simple (no tabs). */
#bookingModal.is-create #bookingModalTabs {
  display: none; /* Why: tabs are only required for Update mode. */
}

#bookingModal.is-create #bookingModalTabContent {
  padding-top: 0 !important; /* Why: remove empty spacing when tabs are hidden. */
}

#bookingModal.is-create #bookingModalTabContent > .tab-pane:not(#booking-tab-pane) {
  display: none !important; /* Why: hide non-booking panes in create mode. */
}

#bookingModal.is-create #booking-tab-pane {
  display: block !important; /* Why: ensure booking fields still render without tabs. */
  opacity: 1 !important;
}

@media (max-width: 520px) {
  #bookingModal .modal-dialog {
    min-width: 0;
  }
}

#bookingModal > .modal-dialog > .modal-content,
#bookingModal > .modal-dialog > .modal-content > .modal-header,
#bookingModal > .modal-dialog > .modal-content > .modal-footer,
#invoiceModal > .modal-dialog > .modal-content,
#invoiceModal > .modal-dialog > .modal-content > .modal-header,
#invoiceModal > .modal-dialog > .modal-content > .modal-footer,
#paymentModal > .modal-dialog > .modal-content,
#paymentModal > .modal-dialog > .modal-content > .modal-header,
#paymentModal > .modal-dialog > .modal-content > .modal-footer {
  border-radius: 0 !important; /* Square outer edges for the modal container/header/footer (overrides Bootstrap rounding). */
}

/* Payment modal: apply the same header/footer chrome even if the DOM structure differs.
   Why: Payment modal is injected dynamically and we want identical visuals to Booking/Invoice without relying on direct-child selectors. */
#paymentModal .modal-content,
#paymentModal .modal-header,
#paymentModal .modal-footer {
  border-radius: 0 !important;
}

#paymentModal .modal-header {
  background: var(--theme-chrome-bg);
  color: var(--theme-chrome-text);
  border-color: var(--theme-chrome-border);
}

#paymentModal .modal-footer {
  background: var(--theme-chrome-bg);
  color: var(--theme-chrome-text);
  border-color: var(--theme-chrome-border);
}

#paymentModal .modal-body {
  background: var(--theme-surface);
}

#paymentModal .modal-title {
  color: var(--theme-chrome-text);
}

#paymentModal .btn-close {
  filter: invert(1) grayscale(1);
}

#bookingModal > .modal-dialog > .modal-content > .modal-header,
#invoiceModal > .modal-dialog > .modal-content > .modal-header,
#paymentModal > .modal-dialog > .modal-content > .modal-header {
  background: var(--theme-chrome-bg); /* Modal header background colour. */
  color: var(--theme-chrome-text); /* Modal header text colour. */
  border-color: var(--theme-chrome-border); /* Modal header divider/border colour. */
}

#bookingModal > .modal-dialog > .modal-content > .modal-footer,
#invoiceModal > .modal-dialog > .modal-content > .modal-footer,
#paymentModal > .modal-dialog > .modal-content > .modal-footer {
  background: var(--theme-chrome-bg); /* Modal footer background colour. */
  color: var(--theme-chrome-text); /* Modal footer text colour. */
  border-color: var(--theme-chrome-border); /* Modal footer divider/border colour. */
}

#bookingModal > .modal-dialog > .modal-content > .modal-body,
#invoiceModal > .modal-dialog > .modal-content > .modal-body,
#paymentModal > .modal-dialog > .modal-content > .modal-body {
  background: var(--theme-surface);
}

#bookingModal > .modal-dialog > .modal-content > .modal-header .modal-title,
#invoiceModal > .modal-dialog > .modal-content > .modal-header .modal-title,
#paymentModal > .modal-dialog > .modal-content > .modal-header .modal-title {
  color: var(--theme-chrome-text); /* Title text colour in the modal header. */
}

#bookingModal > .modal-dialog > .modal-content > .modal-header .btn-close,
#invoiceModal > .modal-dialog > .modal-content > .modal-header .btn-close,
#paymentModal > .modal-dialog > .modal-content > .modal-header .btn-close {
  filter: invert(1) grayscale(1); /* Make the close (X) icon readable on a dark header. */
}

#bookingModal > .modal-dialog > .modal-content > .modal-footer .btn,
#bookingModal > .modal-dialog > .modal-content > .modal-footer .btn-primary,
#invoiceModal > .modal-dialog > .modal-content > .modal-footer .btn,
#invoiceModal > .modal-dialog > .modal-content > .modal-footer .btn-primary,
#paymentModal > .modal-dialog > .modal-content > .modal-footer .btn,
#paymentModal > .modal-dialog > .modal-content > .modal-footer .btn-primary {
  width: auto; /* Prevent footer buttons from stretching full-width. */
  margin-top: 0; /* Remove the form button top margin so footer buttons align neatly. */
}

#bookingModal > .modal-dialog > .modal-content > .modal-footer .btn,
#invoiceModal > .modal-dialog > .modal-content > .modal-footer .btn,
#paymentModal > .modal-dialog > .modal-content > .modal-footer .btn {
  display: inline-flex; /* Keep icon/text aligned horizontally like a "chip" button. */
  align-items: center; /* Vertically center button content. */
  justify-content: center; /* Horizontally center button content. */
  height: 32px; /* Match overall modal button height across the app. */
  padding: 0 14px; /* Button horizontal padding. */
  border-radius: 4px; /* Match booking modal (square-ish). */
  border: 1px solid var(--theme-chrome-border); /* Border for non-primary footer buttons. */
  background: var(--theme-primary-btn-bg); /* Use the themed primary background even for secondary buttons (current app style). */
  color: var(--theme-primary-btn-text); /* Text colour on themed button background. */
  font-size: 0.85rem; /* Slightly larger than input text for emphasis. */
  font-weight: 500;
  text-decoration: none; /* Ensure links styled as buttons do not underline. */
}

#bookingModal > .modal-dialog > .modal-content > .modal-footer .btn:hover,
#invoiceModal > .modal-dialog > .modal-content > .modal-footer .btn:hover,
#paymentModal > .modal-dialog > .modal-content > .modal-footer .btn:hover {
  background: var(--theme-primary-btn-hover-bg); /* Hover background for non-primary footer buttons. */
  border-color: var(--theme-primary-btn-hover-bg); /* Hover border colour. */
  color: var(--theme-primary-btn-text); /* Hover text colour for contrast. */
}

/* Why: The modal footer has a generic hover style for secondary buttons.
   The Delete Booking button must retain Bootstrap danger styling (red) even on hover/focus/active. */
 #bookingModal > .modal-dialog > .modal-content > .modal-footer #bookingModalDeleteBtn.btn-danger:hover,
 #bookingModal > .modal-dialog > .modal-content > .modal-footer #bookingModalDeleteBtn.btn-danger:focus,
 #bookingModal > .modal-dialog > .modal-content > .modal-footer #bookingModalDeleteBtn.btn-danger:focus-visible,
 #bookingModal > .modal-dialog > .modal-content > .modal-footer #bookingModalDeleteBtn.btn-danger:active {
   background: var(--theme-primary-btn-hover-bg);
   border-color: var(--theme-primary-btn-hover-bg);
   color: var(--theme-primary-btn-text);
 }

#bookingModal > .modal-dialog > .modal-content > .modal-footer .btn-primary,
#invoiceModal > .modal-dialog > .modal-content > .modal-footer .btn-primary,
#paymentModal > .modal-dialog > .modal-content > .modal-footer .btn-primary {
  background: var(--theme-primary-btn-bg); /* Save button background (primary action). */
  border-color: var(--theme-primary-btn-bg); /* Save button border colour (matches background). */
  color: var(--theme-primary-btn-text); /* Save button text colour. */
}

#bookingModal > .modal-dialog > .modal-content > .modal-footer .btn-primary:hover,
#invoiceModal > .modal-dialog > .modal-content > .modal-footer .btn-primary:hover,
#paymentModal > .modal-dialog > .modal-content > .modal-footer .btn-primary:hover {
  background: var(--theme-primary-btn-hover-bg); /* Save button hover background. */
  border-color: var(--theme-primary-btn-hover-bg); /* Save button hover border colour. */
}

/* Booking modal: Quick Add buttons next to Select2 controls */
#bookingModal .booking-select-with-btn {
  display: flex;
  gap: 8px;
  align-items: center;
}

#bookingModal .booking-select-with-btn .select2-container {
  width: 100% !important;
  flex: 1 1 auto;
  min-width: 0;
}

#bookingModal .booking-select-with-btn .booking-quick-add-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 32px;
  height: 29px; /* Match Select2 height inside booking modal. */
  padding: 0;
  border-radius: 4px; /* Match booking modal footer button radius. */
  margin-top: 0;
  border: 1px solid var(--theme-primary-btn-bg);
  background: var(--theme-primary-btn-bg);
  color: var(--theme-primary-btn-text);
}

/* Ensure quick-add buttons use the same hover behaviour as booking modal footer buttons. */
#bookingModal .booking-select-with-btn .booking-quick-add-btn:hover,
#bookingModal .booking-select-with-btn .booking-quick-add-btn:focus,
#bookingModal .booking-select-with-btn .booking-quick-add-btn:focus-visible {
  background: var(--theme-primary-btn-hover-bg);
  border-color: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
}

#bookingModal #swapVehicleBtn.btn,
#bookingModal #downloadContractBtn.btn {
  display: inline-flex; /* Keep swap button aligned like other action buttons. */
  align-items: center; /* Vertically center swap button content. */
  justify-content: center; /* Horizontally center swap button content. */
  height: 32px; /* Swap button height (match modal footer buttons). */
  padding: 0 14px; /* Swap button horizontal padding (match modal footer buttons). */
  border-radius: 4px; /* Swap button corner radius (square-ish). */
  font-size: 0.85rem; /* Swap button text size (match footer buttons). */
  font-weight: 500; /* Swap button text weight (match footer buttons). */
}

#bookingModal #swapVehicleBtn.btn-warning,
#bookingModal #downloadContractBtn.btn-warning {
  border: 1px solid var(--theme-primary-btn-bg); /* Swap button border colour. */
  background: var(--theme-primary-btn-bg); /* Swap button background colour. */
  color: var(--theme-primary-btn-text); /* Swap button text colour. */
}

#bookingModal #swapVehicleBtn.btn-warning:hover,
#bookingModal #downloadContractBtn.btn-warning:hover {
  background: var(--theme-primary-btn-hover-bg); /* Swap button hover background. */
  border-color: var(--theme-primary-btn-hover-bg); /* Swap button hover border colour. */
  color: var(--theme-primary-btn-text); /* Swap button hover text colour. */
}

#bookingModal #bookingScheduleSaveBtn.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 500;
  white-space: nowrap;
}

#bookingModal #bookingScheduleSaveBtn.btn-primary {
  border: 1px solid var(--theme-primary-btn-bg);
  background: var(--theme-primary-btn-bg);
  color: var(--theme-primary-btn-text);
}

#bookingModal #bookingScheduleSaveBtn.btn-primary:hover,
#bookingModal #bookingScheduleSaveBtn.btn-primary:focus,
#bookingModal #bookingScheduleSaveBtn.btn-primary:focus-visible {
  background: var(--theme-primary-btn-hover-bg);
  border-color: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
}

#bookingModal #bookingScheduleDeleteBtn.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 500;
  white-space: nowrap;
  min-width: 140px;
}

#bookingModal #bookingScheduleDeleteBtn.btn-danger {
  border: 1px solid var(--theme-primary-btn-bg);
  background: var(--theme-primary-btn-bg);
  color: var(--theme-primary-btn-text);
}

#bookingModal #bookingScheduleDeleteBtn.btn-danger:hover,
#bookingModal #bookingScheduleDeleteBtn.btn-danger:focus,
#bookingModal #bookingScheduleDeleteBtn.btn-danger:focus-visible {
  background: var(--theme-primary-btn-hover-bg);
  border-color: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
}

#bookingModal .bookingScheduleQuickDates {
  /* Why: Quick-select row should be compact, wrap nicely, and feel like part of the modal button system. */
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: flex-start;
}

#bookingModal .bookingScheduleQuickDateBtn.btn {
  /* Why: Keep quick date buttons smaller than primary actions but consistent in height. */
  height: 30px;
  padding: 0 10px;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
}

#bookingModal .bookingScheduleQuickDateBtn.btn-outline-primary {
  /* Why: Match the booking modal button palette for a consistent, professional look.
     These are quick shortcuts, but they should feel like part of the same button system
     (same background + hover colours as modal actions). */
  border: 1px solid var(--theme-primary-btn-bg);
  background: var(--theme-primary-btn-bg);
  color: var(--theme-primary-btn-text);
}

#bookingModal .bookingScheduleQuickDateBtn.btn-outline-primary:hover,
#bookingModal .bookingScheduleQuickDateBtn.btn-outline-primary:focus,
#bookingModal .bookingScheduleQuickDateBtn.btn-outline-primary:focus-visible {
  border-color: var(--theme-primary-btn-hover-bg);
  background: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
}

#bookingModal .bookingScheduleQuickDateBtn.is-active {
  /* Why: Provide a clear selected state while staying within the same palette. */
  border-color: var(--theme-primary-btn-hover-bg);
  background: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.06) inset;
}

#bookingModal .bookingStatementActionBtn.btn {
  /* Why: Statement actions are “tools” (generate/download/email) and should visually match the
     app’s neon/purple accent button style shown elsewhere, while staying scoped to the modal. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
  border: 2px solid var(--theme-primary-btn-bg);
  background: var(--theme-chrome-bg);
  color: var(--theme-primary-btn-text);
  transition: box-shadow 160ms ease, transform 160ms ease, background-color 160ms ease, border-color 160ms ease;
}

#bookingModal .bookingStatementActionBtn.btn:hover,
#bookingModal .bookingStatementActionBtn.btn:focus,
#bookingModal .bookingStatementActionBtn.btn:focus-visible {
  /* Why: Subtle lift + glow communicates interactivity without changing layout. */
  border-color: var(--theme-chrome-bg);
  background: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
  box-shadow: none;
}

#bookingModal .bookingWalletActionBtn.btn {
  /* Why: Wallet actions (Add transaction) should match Statement tab action buttons for
     consistent modal UX and theming. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  padding: 8px 14px;
  border-radius: 4px;
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
  border: 2px solid var(--theme-primary-btn-bg);
  background: var(--theme-chrome-bg);
  color: var(--theme-primary-btn-text);
  transition: box-shadow 160ms ease, transform 160ms ease, background-color 160ms ease, border-color 160ms ease;
}

#bookingModal .bookingWalletActionBtn.btn:hover,
#bookingModal .bookingWalletActionBtn.btn:focus,
#bookingModal .bookingWalletActionBtn.btn:focus-visible {
  border-color: var(--theme-chrome-bg);
  background: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
  box-shadow: none;
}

#bookingModal .bookingModalDivider {
  /* Use a border rather than a 1px-tall background fill.
     Why: on some screens/zoom levels, a 1px element can render inconsistently due to
     sub-pixel rounding, making one divider appear thicker than the other. */
  height: 0; /* Divider is drawn by the border, not by element height. */
  border-top: 2px solid var(--theme-border); /* Higher contrast than chrome border so the divider is visible in the modal body. */
  background: transparent; /* Prevent any fill that could visually thicken the line. */
  margin: 12px 0; /* Why: give the divider breathing room so it reads as a section break. */
  width: 100%; /* Why: ensure the divider spans the full modal body width in grid layouts. */
}

#bookingModal #bookingScheduleAlert.alert {
  font-weight: 600;
  font-size: 0.85rem;
}

#bookingModal input[type="email"],
#bookingModal input[type="password"],
#bookingModal input[type="text"],
#bookingModal input[type="date"],
#bookingModal input[type="tel"],
#bookingModal input[type="number"],
#bookingModal input[type="datetime-local"],
#bookingModal select,
#bookingModal textarea,
#bookingModal .form-control {
  /* ~20% smaller than the global form-control sizing (scoped to booking modal only). */
  padding: 6px 8px; /* Controls overall control height/compactness. */
  border-radius: 4px; /* Square-ish corners for all controls in the booking modal. */
  font-size: 1.20rem; /* Control text size (labels inside inputs/selects). */
}

#invoiceModal input[type="email"],
#invoiceModal input[type="password"],
#invoiceModal input[type="text"],
#invoiceModal input[type="date"],
#invoiceModal input[type="tel"],
#invoiceModal input[type="number"],
#invoiceModal input[type="datetime-local"],
#invoiceModal select,
#invoiceModal textarea,
#invoiceModal .form-control {
  padding: 6px 8px; /* Why: match booking modal compact control sizing. */
  border-radius: 4px; /* Why: match booking modal square-ish corners. */
  font-size: 1.20rem; /* Why: match booking modal control text size. */
}

 #paymentModal input[type="email"],
 #paymentModal input[type="password"],
 #paymentModal input[type="text"],
 #paymentModal input[type="date"],
 #paymentModal input[type="tel"],
 #paymentModal input[type="number"],
 #paymentModal input[type="datetime-local"],
 #paymentModal select,
 #paymentModal textarea,
 #paymentModal .form-control {
   padding: 6px 8px; /* Why: match booking/invoice modal compact control sizing. */
   border-radius: 4px; /* Why: match booking/invoice modal square-ish corners. */
   font-size: 1.20rem; /* Why: match booking/invoice modal control text size. */
 }

#bookingModal textarea,
#bookingModal textarea.form-control {
  padding: 8px; /* Slightly larger padding for textarea for readability. */
}

#invoiceModal textarea,
#invoiceModal textarea.form-control {
  padding: 8px; /* Why: match booking modal textarea sizing. */
}

 #paymentModal textarea,
 #paymentModal textarea.form-control {
   padding: 8px; /* Why: match booking/invoice modal textarea sizing. */
 }

#bookingModal .select2-container .select2-selection--single {
  height: 29px; /* Select2 single-select height (must match input height visually). */
  border-radius: 4px; /* Select2 corner radius (square-ish). */
}

#invoiceModal .select2-container .select2-selection--single {
  height: 29px; /* Why: match booking modal Select2 height. */
  border-radius: 4px; /* Why: match booking modal Select2 radius. */
}

 #paymentModal .select2-container .select2-selection--single {
   height: 29px; /* Why: match booking/invoice modal Select2 height. */
   border-radius: 4px; /* Why: match booking/invoice modal Select2 radius. */
 }

#bookingModal .select2-container .select2-selection--single .select2-selection__rendered {
  line-height: 27px; /* Vertically centers the selected text inside the Select2 box. */
  padding-left: 8px; /* Left padding for the selected text. */
  padding-right: 22px; /* Right padding to avoid overlapping the dropdown arrow. */
  font-size: 1.20rem; /* Selected text size inside Select2. */
}

#invoiceModal .select2-container .select2-selection--single .select2-selection__rendered {
  line-height: 27px; /* Why: match booking modal Select2 alignment. */
  padding-left: 8px;
  padding-right: 22px;
  font-size: 1.20rem;
}

 #paymentModal .select2-container .select2-selection--single .select2-selection__rendered {
   line-height: 27px; /* Why: match booking/invoice modal Select2 alignment. */
   padding-left: 8px;
   padding-right: 22px;
   font-size: 1.20rem;
 }

/* Invoice modal: compact in-body buttons/cells (Add Item/Delete) */
#invoiceModal .invoice-item-btn.btn {
  /* Why: Match modal footer buttons (Cancel/Save) so in-body actions look consistent. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 14px;
  border-radius: 4px;
  border: 1px solid var(--theme-chrome-border);
  background: var(--theme-primary-btn-bg);
  color: var(--theme-primary-btn-text);
  font-size: 0.85rem;
  font-weight: 500;
  text-decoration: none;
  margin-top: 0;
}

#invoiceModal .invoice-item-btn.btn:hover {
  background: var(--theme-primary-btn-hover-bg);
  border-color: var(--theme-primary-btn-hover-bg);
  color: var(--theme-primary-btn-text);
}

#invoiceModal .invoice-item-cell.form-control {
  height: 32px; /* Why: match footer/in-body button height so rows align cleanly. */
  display: flex;
  align-items: center;
}

#invoiceModal .invoice-gst-cell {
  height: 32px; /* Why: keep GST checkbox aligned with Delete button height. */
}

#invoiceModal .invoice-item-action-cell {
  height: 32px; /* Why: keep Delete button aligned with other row controls. */
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
#bookingModal .select2-container .select2-selection--single .select2-selection__arrow {
  height: 27px; /* Height of the Select2 dropdown arrow container (keeps arrow vertically aligned). */
}

.planner-status-chip {
  border: 1px solid var(--theme-border);
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  height: 26px;
}

.planner-status-legend .planner-status-chip {
  /* Why: Planner status legend should read like colour "pills" (no border) and be slightly larger
     for scanability in the header bar. Scope to /planner only via the wrapper class. */
  border: 0;
  height: 29px; /* ~10% bigger than 26px */
  padding: 0 11px; /* ~10% bigger than 10px */
  font-size: 13px; /* ~10% bigger than 12px */
}

.planner-tooltip {
  position: fixed;
  z-index: 9999;
  display: none;
  max-width: 360px;
  padding: 10px 12px;
  background: var(--theme-chrome-bg); /* Why: allow centralized tooltip theming via tokens.css. */
  color: var(--theme-chrome-text); /* Why: keep tooltip contrast configurable without editing component CSS. */
  border: 1px solid var(--theme-chrome-border); /* Why: tooltip edge needs separate control for dark/light themes. */
  border-radius: 10px;
  box-shadow: 0 14px 30px var(--theme-shadow);
  font-size: 12px;
  line-height: 1.35;
}

.color-swatch {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  border: 1px solid var(--theme-border);
  display: inline-block;
}

.notes-counter {
  margin-top: 4px;
  font-size: 11px;
  color: var(--theme-muted);
}

details > summary::-webkit-details-marker {
  display: none;
}

details > summary {
  list-style: none;
}

.invoice-group-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 6px;
  border: 1px solid #e5e7eb;
  background: #fff;
  color: #111827;
  transition: transform 0.15s ease;
}

details[open] .invoice-group-toggle {
  transform: rotate(90deg);
}

 .invoice-booking-old {
  background: var(--theme-old-booking-bg);
 }

 .invoice-booking-old > summary {
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
 }
