/* Booking Engine (resources/views/operations/booking-engine.blade.php) */

/* Same divider rule as the OTA Allotments modals (operations.css) — copied
   rather than shared since that file is page-scoped and out of scope to
   touch; used inside the status popover. */

/* Negative left/right margin cancels out .modal-body's own horizontal
   padding (--space-6, every breakpoint — see components/modals.css) so
   the line spans the card edge-to-edge instead of stopping at the body's
   content box. Top/bottom margin is untouched, and nothing else in the
   modal has padding removed — only this element's own box shifts. */
.plx-modal-divider {
  border: 0;
  border-top: 1px solid var(--pm-accent-soft);
  margin: var(--space-4) calc(-1 * var(--space-6));
  opacity: 1;
}

/* Solid counterpart to the existing .plx-btn-success-outline (buttons.css)
   — the popover's "Select This Slot" action needs the filled/solid
   treatment shown in the Figma reference. */
.plx-btn-success {
  background-color: var(--color-available);
  border-color: var(--color-available);
  color: var(--text-inverse);
}

.plx-btn-success:hover:not(:disabled) {
  background-color: var(--color-success);
  border-color: var(--color-success);
}

/* ---- Wizard chrome — same generic header/body/footer treatment as the
   Create Property wizard (properties.css), copied rather than shared since
   that file is page-scoped to /properties and out of scope to touch. ---- */
.plx-wizard-card {
  padding: 0;
}

/* Step 2's own content (the floor plan) is just the bordered floor-cards
   sitting directly on the page in create-booking-2-v1.png — no surrounding
   card chrome around them, unlike every other step. :has() (already used
   in modals.css) lets one rule react to which panel is active without
   duplicating goToStep()'s own step-tracking into a second data-attribute
   here; steps 1/3/4 keep the card's normal background/border untouched. */
#plxBookingWizardCardJs:has(.plx-wizard-panel[data-plx-wizard-step="2"][data-plx-active="true"]) {
  background: transparent;
  border: 0;
}

/* Same idea for Step 3 (book flow) — create-booking-3-updated.png shows
   the Guest Information/Booking Summary cards sitting directly on the
   page with no surrounding card chrome, unlike the wizard card's normal
   look every other step (and the lease flow's own Step 3) keeps. Border-
   radius doesn't need its own line since there's no border left to round.

   overflow:visible overrides the shared .plx-card's overflow:hidden
   (cards.css — there to clip content to the card's own rounded corners),
   which doesn't serve any purpose here any more now that this card has no
   visible border/corners left to clip against — but left as hidden, it
   was quietly establishing a clipping/scroll container that capped the
   Booking Summary card's position:sticky travel range to this wizard
   card's own height instead of the full page, making it "catch up" and
   stop sticking far earlier than intended. */
#plxBookingWizardCardJs:has(.plx-wizard-panel[data-plx-wizard-step="3"][data-plx-flow="book"][data-plx-active="true"]) {
  background: transparent;
  border: 0;
  overflow: visible;
}

/* Same again for Step 4 — create-booking-4.png shows Payment Details/
   Final Bill the same cardless way. */
#plxBookingWizardCardJs:has(.plx-wizard-panel[data-plx-wizard-step="4"][data-plx-flow="book"][data-plx-active="true"]),
#plxBookingWizardCardJs:has(.plx-wizard-panel[data-plx-wizard-step="4"][data-plx-flow="lease"][data-plx-active="true"]) {
  background: transparent;
  border: 0;
  overflow: visible;
}

/* Lease flow Step 3 — Wireframe-45.png shows Tenant Information and Lease
   Summary sitting directly on the page (no outer card chrome), same treatment
   as book flow Steps 3 and 4 above. */
#plxBookingWizardCardJs:has(.plx-wizard-panel[data-plx-wizard-step="3"][data-plx-flow="lease"][data-plx-active="true"]) {
  background: transparent;
  border: 0;
  overflow: visible;
}

.plx-wizard-panel-header {
  align-items: center;
  border-bottom: 1px solid var(--border-default);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: space-between;
  padding: 15px 25px;
}

.plx-wizard-panel-title {
  color: var(--text-primary);
  font-size: 16px;
  font-weight: var(--weight-medium);
}

.plx-wizard-panel-body {
  display: flex;
  flex-direction: column;
  gap: 15px;
  padding: 15px 25px;
}

.plx-wizard-footer {
  align-items: center;
  display: flex;
  gap: 10px;
  justify-content: end;
  padding: 0 25px 20px;
}

@media (max-width: 575.98px) {
  .plx-wizard-footer {
    flex-direction: column;
    gap: var(--space-3);
    padding: 15px 20px 30px;
  }

  .plx-wizard-footer .plx-btn {
    width: 100%;
  }
}

@media (min-width: 1200px) and (max-width: 1535.98px) {
  .plx-wizard-panel-title {
    font-size: 15px;
  }
}

/* ---- Step 1: Booking Type card ---- */
/* Shown for unit-category properties (Skyview Apartment); hidden for
   room-category properties (Hotel Grand Plaza). JS toggles d-none via
   applyPropertyCategory(). Soft --bg-card panel with a neutral border,
   both sampled exactly off Frame 226.png (#F4F4F6 / #EBEBEF): one
   full-width container wrapping the label + button group. */
.plx-booking-type-field {
  background: var(--bg-card);
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  transition: border-color var(--transition-fast);
}

.plx-booking-type-field:focus-within {
  border-color: var(--border-focus);
}

/* Toggle is now just a flex layout row — the card above provides the
   visual container, so no separate border or padding is needed here. */
.plx-booking-type-toggle {
  display: flex;
  gap: var(--space-2);
  width: fit-content;
}

@media (max-width: 575.98px) {
  .plx-booking-type-toggle {
    flex-direction: column;
    width: 100%;
  }
}

.plx-booking-type-btn {
  align-items: center;
  background: var(--bg-surface);
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  cursor: pointer;
  display: inline-flex;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  gap: var(--space-2);
  height: 38px;
  padding: 0 var(--space-4);
  transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.plx-booking-type-btn .plx-icon {
  font-size: 18px;
}

.plx-booking-type-btn[data-plx-selected="true"] {
  background: var(--pm-primary);
  border-color: var(--pm-primary);
  color: var(--text-inverse);
}
:root[data-bs-theme="dark"] .plx-booking-type-btn:not([data-plx-selected="true"]):hover {
  border-color: var(--border-hover);
}
.plx-booking-type-btn:not([data-plx-selected="true"]):hover {
  border-color: var(--pm-primary);
}

/* Reused as-is from the Create Property wizard's own pattern (same
   read-only "computed value" treatment). */
.plx-nights-display {
  align-items: center;
  background: var(--bg-surface-muted);
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  display: flex;
  font-size: var(--text-base);
  height: 38px;
  padding: 0 var(--space-3);
}

.plx-nights-display strong {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
  margin-right: var(--space-1);
}

/* Skyview Apartment + Lease only (Wireframe - 48.png): Lease Duration's
   own value ("N Months") reads the brand indigo throughout, not just the
   number — pixel-matched against that reference, which is bolder/more
   saturated than the plain .plx-nights-display strong color the Book
   flow's own Nights field keeps untouched. */
.plx-lease-duration-display {
  color: var(--pm-primary);
  font-weight: var(--weight-semibold);
}

.plx-lease-duration-display strong {
  color: inherit;
  margin-right: 0;
}

/* Skyview Apartment + Lease only (Wireframe - 45.png): "Early Termination
   Allowed" is the one field in this whole flow shown as a toggle switch
   rather than a checkbox/select — no existing toggle-switch component was
   in the project to reuse, so this is a small new one, scoped to this page
   only. Matches the sibling fields' own 38px row height via margin-top so
   it lines up under its label the same way they do. */
.plx-toggle-switch {
  cursor: pointer;
  display: inline-block;
  height: 24px;
  margin-top: var(--space-2);
  position: relative;
  width: 44px;
}

.plx-toggle-switch input {
  height: 0;
  opacity: 0;
  position: absolute;
  width: 0;
}

.plx-toggle-switch-track {
  background: var(--border-default);
  border-radius: var(--radius-full);
  display: block;
  height: 100%;
  position: relative;
  transition: background-color var(--transition-fast);
  width: 100%;
}

.plx-toggle-switch-track::before {
  background: var(--bg-surface);
  border-radius: var(--radius-full);
  content: '';
  height: 18px;
  left: 3px;
  position: absolute;
  top: 3px;
  transition: transform var(--transition-fast);
  width: 18px;
}

.plx-toggle-switch input:checked + .plx-toggle-switch-track {
  background: var(--pm-primary);
}

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

.plx-toggle-switch input:focus-visible + .plx-toggle-switch-track {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}

/* ---- Step 1: Search Availability field spacing/widths (matches
   figma-ui-folder/screens/create-booking-1.png) ----

   forms.css' shared 1200-1535.98px rule compacts BOTH .plx-form-row's gap
   (60px -> 40px) and .plx-form-rows' gap (20px -> 10px) for every page
   using that pattern (Create Property, OTA Allotments, ...). The
   reference for this page measures noticeably more breathing room than
   that compacted value at this same width, so it's restored here scoped
   to Booking Engine's own wizard card only — every other page keeps
   today's shared compacted spacing untouched. */
@media (min-width: 1200px) and (max-width: 1535.98px) {
  #plxBookingWizardCardJs .plx-form-row {
    gap: 25px;
  }

  #plxBookingWizardCardJs .plx-form-rows {
    gap: 20px;
  }
}

/* Outside that one shared breakpoint the base/default gap (20px) already
   matches the reference, so only .plx-form-rows needs reaffirming there
   too — unconditional since 20px is also this page's own desired value
   at every other width. */
#plxBookingWizardCardJs .plx-form-rows {
  gap: 20px;
}

/* The Property select's selected-option highlight (formerly prototyped
   here) is now the project-wide .plx-select option:checked rule in
   components/forms.css, driven by the --select-selected-* tokens. */

/* OTA / Booking Source and Number of Room(s) are meant to be the same
   width as one of Search Availability's 4-up columns above (Property /
   Check-in / Check-out / Nights), not stretched to fill half the row each
   — see the two .plx-form-spacer-js placeholders in
   _booking_step1.blade.php that complete that same 4-column flex split
   without adding 2 more real fields. Scoped to >=768px since below that
   .plx-form-row already stacks every field to full width (forms.css) —
   the spacers are hidden there instead of widening anything. */
@media (max-width: 767.98px) {
  .plx-form-spacer-js {
    display: none;
  }
}

/* ---- Step 2: heading/meta/filters/legend section — sits above
   #plxBookingWizardCardJs as its own sibling (_booking_step2_header.blade.php),
   not inside it, matching create-booking-2-v1.png; shown/hidden in sync
   with the wizard step by goToStep() (booking-engine.js). Horizontal
   position is just the page's own default flow (no card padding to
   account for), so it lines up with the now-borderless floor-card below
   it without any extra alignment rule needed. ---- */
.plx-booking-step2-header-section {
  display: none;
  margin-bottom: var(--space-4);
}

.plx-booking-step2-header-section[data-plx-active="true"] {
  display: block;
}

/* ---- Step 2: Room Inventory summary card (create-booking-2.png) ----
   Sibling section above the step 2 header, same data-plx-active show/hide
   convention (toggled by goToStep in booking-engine.js). */
.plx-booking-inventory-section {
  display: none;
  margin-bottom: var(--space-5);
}

.plx-booking-inventory-section[data-plx-active="true"] {
  display: block;
}

/* Muted header band behind "Room Inventory" — sampled #FBFBFB off the
   reference. */
.plx-booking-inventory-card .plx-card-header {
  background: var(--bg-surface-muted);
}

.plx-booking-inventory-modes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
  margin-bottom: var(--space-4);
}

/* The reference reads these labels lighter than the shared .plx-label
   semibold — same override pattern as .plx-record-payment-later-box's
   label further down. */
.plx-booking-inventory-modes .plx-label {
  font-size: var(--text-base);
  font-weight: var(--weight-regular);
}

.plx-booking-inventory-tables {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr 1fr;
}

@media (max-width: 991.98px) {
  .plx-booking-inventory-tables {
    grid-template-columns: 1fr;
  }
}

/* Rounded outer frame, same treatment as the project's other framed
   tables (e.g. the Conversion History table in operations.css). */
.plx-booking-inventory-table-wrap {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
}

/* Project-standard table header band (--bg-thead tokens) and neutral row
   dividers; numeric columns center under their headers per the reference.
   Fonts match the reference: header and cells share --text-md, semibold
   ink for the header (table default) and regular weight for the cells.
   Horizontal cell padding is tighter than even .plx-table-compact — six
   nowrap columns must fit each half-width table without the wrap
   scrolling, exactly as dense as the reference draws them. */
.plx-booking-inventory-table thead th {
  background: var(--bg-thead);
  border-bottom-color: var(--border-default);
  color: var(--pm-primary);
  font-size: var(--text-base);
  position: relative;
}

.plx-booking-inventory-table tbody td {
  border-bottom-color: var(--border-default);
  font-weight: var(--weight-regular);
    font-size: var(--text-base);

  position: relative;
}

.plx-booking-inventory-table thead th,
.plx-booking-inventory-table tbody td {
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}

/* Checkbox column shrinks to its content */
.plx-booking-inventory-table thead th:first-child,
.plx-booking-inventory-table tbody td:first-child {
  padding-left: var(--space-3);
  width: 1%;
}

/* The Room Type cell wraps to two lines like the reference, keeping each
   half-width table inside its column. */
.plx-booking-inventory-table tbody td:nth-child(2) {
  white-space: normal;
}

/* Inset column dividers (equal top/bottom spacing) — the same
   project-standard treatment as the Rooms/Units/Conversion tables.
   ::before, since DataTables' sort arrows own th::after (tables.css). */
.plx-booking-inventory-table thead th:not(:last-child)::before,
.plx-booking-inventory-table tbody td:not(:last-child)::before {
  background: var(--border-default);
  bottom: var(--space-2);
  content: '';
  position: absolute;
  right: 0;
  top: var(--space-2);
  width: 1px;
}

.plx-booking-inventory-table thead th:nth-child(n+3),
.plx-booking-inventory-table tbody td:nth-child(n+3) {
  text-align: center;
}



/* ---- Step 2: floor plan ---- */
/* No horizontal padding — the header section above no longer lives inside
   #plxBookingWizardCardJs, so its own padding would otherwise indent the
   floor-card past where the heading/filters above it line up. padding-bottom
   reserves room below the floor plan so the fixed .plx-booking-coverage-bar
   (further down this file) never covers the last floor card. These values
   are only the pre-JS fallback — same pattern as .plx-page-has-sticky-footer
   (operations.css, used by OTA Allotments' own sticky bar): a ResizeObserver
   in booking-engine.js measures .plx-booking-coverage-bar's actual rendered
   height and overrides this via inline style on every resize, so it never
   falls out of sync with the bar's real height (which varies with the
   selection list and responsive wrapping) the way a single static value
   eventually would. */
.plx-booking-step2-body {
  padding-bottom: 200px;
  padding-left: 0;
  padding-right: 0;
  padding-top: 0;
}

@media (max-width: 767.98px) {
  .plx-booking-step2-body {
    /* Taller pre-JS fallback — footer is stacked on its own row below
       the coverage summary at all mobile widths, so the bar is taller.
       ResizeObserver in booking-engine.js replaces this with the measured
       value immediately on load, same as the base 200px rule above. */
    padding-bottom: 320px;
  }
}

.plx-booking-step2-header {
  margin-bottom: var(--space-5);
}

/* margin-bottom: 0 strips the <p>'s default 16px bottom margin — normally
   that margin collapses away, but flex items (.plx-booking-step2-header is
   one, via .plx-booking-step2-body's display:flex) never participate in
   margin collapsing, so it was stacking on top of the header's own
   margin-bottom + the body's flex gap, tripling the visual gap above the
   filters row. */
.plx-booking-step2-meta {
  color: var(--text-muted);
  font-size: var(--text-sm);
  margin-bottom: 0;
  margin-top: var(--space-1);
}

.plx-booking-filters-row {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  justify-content: space-between;
  margin-bottom: var(--space-2);
}

.plx-booking-filters-group {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* border-color only (not the shared .plx-select base in forms.css, which
   every other select in the project still uses unchanged) — the filter
   selects specifically use an accent border in the reference. */
.plx-booking-filters-group .plx-select {
  /* border-color: var(--pm-accent); */
}
@media (min-width: 768px) {
  .plx-booking-filters-group .plx-select {
    width: 160px;
}
}
/* Tablet (768–1199px): selects grow from their 160px base to share the
   available row width, wrapping to a second row only when they genuinely
   don't fit — no forced column count, just clean natural fill. */
@media (min-width: 768px) and (max-width: 1199.98px) {
  .plx-booking-filters-group .plx-select {
    flex: 1 1 auto;
  }
}

/* Mobile (<768px): exactly 2 selects per row — first two on row 1,
   Status on row 2 (flex-grow fills the remaining space beside the
   auto-width reset button). Mirrors .plx-filter-bar's own mobile
   pattern in tabs.css. */
@media (max-width: 767.98px) {
  .plx-booking-filters-group .plx-select {
    flex: 1 1 calc((100% - var(--space-3)) / 2);
  }

  .plx-booking-filters-group .plx-btn {
    flex: 0 0 auto;
  }
}

.plx-booking-legend {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.plx-booking-legend-item {
  align-items: center;
  color: var(--text-muted);
  display: inline-flex;
  font-size: var(--text-sm);
  gap: var(--space-2);
}

/* Outlined swatch (border + soft tint fill) instead of a solid block —
   width/height are the fill box; the 2px border renders on top of that in
   the default content-box model, landing on the PNG's measured 14px
   fill/18px outer-edge swatch. Each status pairs the same bg/border tokens
   .plx-floor-chip already uses for its own status colors (untouched per
   the "do not modify .plx-floor-chip" instruction) — kept in sync on
   purpose so the legend always describes the chips' actual colors. */
.plx-booking-legend-item::before {
  border-radius: 0;
  border-style: solid;
  border-width: 2px;
  content: '';
  height: 16px;
  width: 16px;
}

.plx-booking-legend-item[data-plx-legend="available"]::before { background: var(--color-success-bg); border-color: var(--color-available); }
.plx-booking-legend-item[data-plx-legend="booked"]::before { background: var(--color-booked-bg); border-color: var(--color-booked); }
.plx-booking-legend-item[data-plx-legend="tentative"]::before { background: var(--color-warning-bg); border-color: var(--color-warning); }
/* Matched to Floor Chip 115/215's own unselected fill/border above
   (--plx-popover-partial-bg/-color) instead of the generic
   --color-partial/-bg every other legend swatch still pairs with its
   chip — keeps the legend describing the chips' actual "Partial" color. */
.plx-booking-legend-item[data-plx-legend="partial"]::before { background: var(--plx-popover-partial-bg); border-color: var(--plx-popover-partial-color); }
.plx-booking-legend-item[data-plx-legend="blocked"]::before { background: var(--color-blocked-bg); border-color: var(--color-blocked); }
.plx-booking-legend-item[data-plx-legend="ota"]::before { background: var(--color-danger-bg); border-color: var(--color-danger); }

/* Filters row + legend are 9 controls wide (3 selects + reset + 6 legend
   items) — at 1535px and below they no longer fit one row at the base
   160px select width and default gaps, so this range trims width/gaps
   (not text size) just enough to keep everything on a single row with no
   wrap and no horizontal scroll, same intent as the OTA Allotments
   chip-grid/card-padding trims in this same range (operations.css). */
@media (min-width: 1200px) and (max-width: 1535.98px) {
  .plx-booking-filters-row {
    flex-wrap: nowrap;
    gap: var(--space-2);
  }

  .plx-booking-filters-group {
    gap: var(--space-2);
  }

  .plx-booking-filters-group .plx-select {
    width: 148px;
  }

  .plx-booking-legend {
    gap: var(--space-2);
  }

  .plx-booking-legend-item {
    gap: 4px;
  }
}

#plxFloorPlanContainerJs {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Outer card look (background, border, border-radius, overflow) now comes
   from the shared .plx-card .plx-card-flush classes on the template root
   (_booking_step2.blade.php) — same combo OTA Allotments' "Floor 1" card
   uses (.plx-room-floor-card in operations.css). Only the page-specific
   accent touches stay here: a brand-accent header divider instead of the
   default gray, and a tighter, single-value body padding instead of the
   card's normal asymmetric one — both copied from .plx-room-floor-card. */
.plx-booking-floor-card[data-plx-hidden="true"] {
  display: none;
}

/* Group 15.png floor-card scheme (same as the OTA allotments create page's
   .plx-rnf-card-js): gray --bg-card fill with a neutral border, so the
   white room-type groups inside read as raised surfaces. */
.plx-booking-floor-card {
  background: var(--bg-card);
  border-color: var(--border-default);
}

/* The reference has no divider between the floor title and the groups. */
.plx-booking-floor-card .plx-card-header {
  border-bottom: 0;
  padding-bottom: 0;
}

.plx-booking-floor-card .plx-card-header .plx-section-title {
  font-size: var(--text-md);
}

/* Unit count shown in floor card header for unit-category properties
   (e.g. Skyview Apartment — "20 Units"). Hidden for room properties since
   the room-type group headers carry the count there instead. Same
   --pm-accent token the room-type count (.plx-booking-room-type-count)
   already uses — both are secondary counts that should read lighter than
   the dark section title beside them (pixel-matched against
   create-sh-ota-2 (1).png). */
.plx-booking-floor-count {
  color: var(--pm-accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.plx-booking-floor-card .plx-card-body {
  padding: 15px;
}

.plx-booking-room-type-groups-js {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Each room-type section (e.g. "Standard Room - King Bed" + its chip grid)
   sits directly on the floor-card's own body background in the
   reference — no border/radius/padding of its own, just its two children
   (.plx-booking-room-type-header below + .plx-floor-chip-grid) stacked via
   the parent's gap above. Explicit border:0/radius:0 here (rather than
   leaving them unset) documents that as intentional, so a future variant
   that DOES want a bordered sub-card only has to override this one rule. */
.plx-booking-room-type-group {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-6);
}

/* Border color/opacity copied from OTA Allotments' own .plx-room-type-header
   (operations.css) — same soft accent divider under each room-type's
   heading line, just ported here since that file is page-scoped. */
.plx-booking-room-type-header {
  align-items: baseline;
  border-bottom: 1px solid rgba(154, 162, 255, 0.25);
  color: var(--text-primary);
  display: flex;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  justify-content: space-between;
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-3);
}

/* Hotel Grand Plaza, Direct/Walk-In and Booking.com alike (Confirmed and
   Tentative alike too): each room type gets its own Auto/Manual Select
   pair in its own group header (booking-engine.js's
   wireBookingComTypeModeCheckboxes()/wireDirectTypeModeCheckboxes()) —
   ported from OTA Allotments' own .plx-rnf-type-modes (operations.css,
   same class name reused verbatim, not a lookalike copy) since that
   page's own per-room-type Auto/Manual is the reference design both
   combos now match. Scoped via :has() (already used elsewhere in this
   project, see components/modals.css) so only a header that actually gets
   this third child wraps onto a second line — Skyview's own plain 2-child
   header (title + count) is completely unaffected. */
.plx-booking-room-type-header:has(.plx-rnf-type-modes) {
  flex-wrap: wrap;
}

.plx-rnf-type-modes {
  display: flex;
  flex-basis: 100%;
  flex-wrap: wrap;
  gap: var(--space-5);
  justify-content: flex-end;
}

.plx-rnf-type-modes .plx-label {
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
}

.plx-booking-room-type-rate {
  color: var(--color-booked);
  font-weight: var(--weight-medium);
}

/* "20 Rooms" / "15 Rooms" — accent color, distinct from the dark
   .plx-booking-room-type-header text it sits beside. */
.plx-booking-room-type-count {
  color: var(--pm-accent);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

/* Same column-sizing scale as .plx-room-chip-grid (operations.css) at
   every width — including 1200-1535.98px, where that grid's own minmax
   stays at the 90px base value (its 70px attempt for that range is
   immediately re-overridden lower in the same file), so there's no
   override needed here either. */
.plx-floor-chip-grid {
  display: grid;
  gap: var(--space-2);
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
}

@media (min-width: 1536px) and (max-width: 1919.98px) {
  .plx-floor-chip-grid {
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  }
}

@media (min-width: 1920px) {
  .plx-floor-chip-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }
}

/* Floor Chips 106/107/108 (status=blocked) selected state reads through
   this ring + shadow pair instead of swapping background/border-color —
   see .plx-floor-chip[data-plx-selected="true"][data-plx-status="blocked"]
   below. Centralized here (not inlined in that rule) so retuning the
   look — or reusing it for another status later — only ever touches
   these two variables. Uses --pm-accent (brand accent) rather than
   --border-focus so the chip's selection ring stays branded independently
   of the neutral focus color used by form controls. */
:root {
  --plx-chip-active-ring: var(--pm-accent);
  --plx-chip-active-shadow: var(--shadow-md);
}

.plx-floor-chip {
  background: var(--bg-surface);
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  height: 38px;
  overflow: visible;
  position: relative;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.plx-floor-chip[data-plx-status="available"] {
  background: var(--color-success-bg);
  border-color: var(--color-available);
  /* color: var(--color-available); */
  color: var(--text-primary);
}

.plx-floor-chip[data-plx-status="booked"] {
  background: var(--color-booked-bg);
  border-color: var(--color-booked);
  color: var(--color-booked);
}

.plx-floor-chip[data-plx-status="tentative"] {
  background: var(--color-warning-bg);
  border-color: var(--color-warning);
  color: var(--color-warning);
}

.plx-floor-chip[data-plx-status="partial"] {
  background: var(--color-partial-bg);
  border-color: var(--color-partial);
  color: var(--color-partial);
}

/* Floor Chip 116 only — default (unselected) fill/border/text matched to
   the status popover's own .plx-popover-row-tentative (same
   --toggle-track-off/--color-notification-dot pair, see further down this
   file) instead of the generic --color-warning/-bg every other
   "tentative" chip elsewhere still uses. The combined [data-plx-status]
   +[data-plx-room-number] selector is required, not just convenience —
   room number 116 is reused with a different status in other properties
   (e.g. Skyview Apartment), so room-number alone would mis-color those. */
.plx-floor-chip[data-plx-status="tentative"][data-plx-room-number="116"] {
  background: var(--toggle-track-off);
  border-color: var(--color-notification-dot);
  color: var(--color-notification-dot);
}

/* Floor Chips 115 and 215 only — same idea, matched to .plx-popover-row-
   partial's --plx-popover-partial-bg/-color (already global, see :root
   further down) instead of the generic --color-partial/-bg. Room 115 is
   also reused with a different status elsewhere (Skyview's room 115 is
   "blocked"), hence the combined selector; 215 is unique to Hotel Grand
   Plaza but kept in the same qualified form for consistency. */
.plx-floor-chip[data-plx-status="partial"][data-plx-room-number="115"],
.plx-floor-chip[data-plx-status="partial"][data-plx-room-number="215"] {
  background: var(--plx-popover-partial-bg);
  border-color: var(--plx-popover-partial-color);
  color: var(--plx-popover-partial-color);
}

.plx-floor-chip[data-plx-status="blocked"] {
  background: repeating-linear-gradient(45deg, var(--color-blocked-bg), var(--color-blocked-bg) 6px, var(--bg-surface) 6px, var(--bg-surface) 12px);
  border-color: var(--color-blocked);
  color: var(--text-muted);
}

/* Floor Chips A-03/A-04/A-05/A-06 only — every "ota"-status unit across
   PROPERTY_DATA is one of these four, so this selector is already
   precisely scoped without needing a room-number qualifier (unlike
   115/116, whose room numbers are reused with other statuses elsewhere).
   Pixel-matched against Group 14-clr-mtc.png; reuses the same
   --plx-popover-ota-color the status popover's own .plx-popover-row-
   danger/.plx-pill-danger already use (see :root further down this
   file), so retuning one keeps the chip and its popover consistent. */
.plx-floor-chip[data-plx-status="ota"] {
  background: var(--plx-chip-ota-bg);
  border-color: var(--plx-popover-ota-color);
  color: var(--plx-popover-ota-color);
}

.plx-floor-chip[data-plx-selected="true"] {
  border-width: 2px;
  /* box-shadow: var(--shadow-focus); */
  box-shadow: 0 0 0 .5px var(--plx-chip-active-ring), var(--plx-chip-active-shadow);
  background: var(--bg-surface);
}

/* Text color now follows the selected border instead of staying on its
   status color (was green text under a blue selected border) — same
   override point as the border-color already here. */
.plx-floor-chip[data-plx-selected="true"][data-plx-status="available"] {
  border-color: var(--border-focus);
  /* color: var(--color-booked); */
  color: var(--text-primary);
}

/* OTA partial chips (112, 116, A-14) selected via modal "Select This Slot"
   — keep the unit's own OTA red background/border/text unchanged; selection
   is expressed only through a matching red-tinted ring + glow shadow
   (--plx-chip-ota-selected-shadow, defined in :root below). "Full"
   OTA chips (e.g. 111) switch to data-plx-status="available" on select, so
   this rule only ever fires for the partial/tentative units. */
.plx-floor-chip[data-plx-selected="true"][data-plx-status="ota"] {
  background: var(--plx-chip-ota-bg);
  border-color: var(--plx-popover-ota-color);
  color: var(--plx-popover-ota-color);
  box-shadow: 0 0 0 2.5px var(--plx-chip-ota-selected-shadow), 0 0 10px var(--plx-chip-ota-selected-shadow);
}

/* Floor Chips 106/107/108 — background and border-color intentionally
   stay on the chip's own default "blocked" values (striped pattern /
   --color-blocked) instead of the shared selected-state's white fill +
   purple border above; selection reads instead through a thin
   highlighted ring plus a soft ambient shadow (--plx-chip-active-ring/
   -shadow, defined near .plx-floor-chip above), layered in place of the
   base rule's blue glow without touching spacing or layout. */
.plx-floor-chip[data-plx-selected="true"][data-plx-status="blocked"] {
  background: repeating-linear-gradient(45deg, var(--color-blocked-bg), var(--color-blocked-bg) 6px, var(--bg-surface) 6px, var(--bg-surface) 12px);
  /* border-color: var(--color-blocked); */
  border-color: var(--border-focus);
  color: var(--text-muted);
  box-shadow: 0 0 0 .5px var(--plx-chip-active-ring), var(--plx-chip-active-shadow);
}

/* Floor Chip 115 (status=partial) selected state — pixel-matched against
   modal-components-dropdown-select-option-etc-etc/115.png. Box-shadow
   keeps the base rule's blue glow above (the reference's glow color
   matches that, not a magenta tint); only fill/border/text switch to the
   same --plx-popover-partial-* variables the status popover's own
   "Partial"/"Booked" row and pill already use (see :root below and
   .plx-popover-row-partial), so retuning one retunes both consistently. */
.plx-floor-chip[data-plx-selected="true"][data-plx-status="partial"] {
  background: var(--plx-popover-partial-bg);
  border-color: var(--plx-popover-partial-color);
  color: var(--plx-popover-partial-color);
}

/* OTA mode (Skyview + Booking.com) chip tooltip — dark pill positioned below
   the chip, fades in with a slight upward slide on hover. The ::before arrow
   points up toward the chip. Floor cards set overflow:visible so the tooltip
   is never clipped by the card's own overflow:hidden (cards.css). */
.plx-booking-floor-card,
.plx-booking-floor-card .plx-card-body {
  overflow: visible;
}

.plx-floor-chip-tooltip {
  background: #3c3c3e;
  border-radius: 6px;
  color: #fff;
  font-size: 11px;
  font-style: italic;
  font-weight: var(--weight-medium);
  left: 50%;
  letter-spacing: 0.01em;
  opacity: 0;
  padding: 4px 11px;
  pointer-events: none;
  position: absolute;
  top: calc(100% + 7px);
  transform: translateX(-50%) translateY(3px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  white-space: nowrap;
  z-index: 20;
}

.plx-floor-chip-tooltip::before {
  border-color: transparent transparent #3c3c3e transparent;
  border-style: solid;
  border-width: 0 5px 5px;
  content: '';
  left: 50%;
  position: absolute;
  top: -5px;
  transform: translateX(-50%);
}

.plx-floor-chip:hover .plx-floor-chip-tooltip {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}


/* ---- Step 2: coverage bar ----
   Same fixed-bottom-bar treatment as .plx-selected-rooms-bar (OTA
   Allotments, operations.css) — copied rather than shared since that file
   is page-scoped and out of scope to touch. #plxBookingWizardFooterJs gets
   physically moved in here (booking-engine.js's
   syncCoverageBarFooterPlacement) only while step 2 is active, landing as
   this bar's second grid child. Steps 1/3/4 never touch this bar, so their
   footer stays in its original static position, untouched. */
/* --plx-coverage-bar-max-height is the one knob to retune how much
   selection detail shows before .plx-booking-coverage-lines below takes
   over with its own scroll — everything else here derives from it instead
   of repeating the number, so the bar never has to grow without bound the
   way it did before (min-height only, no cap). */
/* Grid, not flex: a 2-column row (coverage summary | footer buttons).
   Top-aligned (align-items: start), not bottom — the summary column's
   heading/pill sit at the top of their own column (their natural
   position; the heading reads first, same as it always did), while the
   Back/Continue buttons are vertically centered independently via their
   own align-self (.plx-wizard-footer below), not tied to the summary
   column's height at all. A flex row with everything centered together
   was the old approach, and centering the summary column as a whole is
   exactly what made its heading drift as its own coverage lines grew —
   top-aligning it means growth only extends the column downward, it
   never moves the heading above it. Below 1200px this collapses to a
   single column, stacking the footer as its own full-width row
   underneath (see that breakpoint below). */
.plx-booking-coverage-bar {
  --plx-coverage-bar-max-height: 180px;
  align-items: start;
  background: var(--bg-surface);
  border-top: 1px solid var(--border-default);
  bottom: 0;
  box-shadow: 0 -4px 12px rgba(17, 24, 39, 0.05);
  column-gap: var(--space-4);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  left: var(--sidebar-width);
  max-height: var(--plx-coverage-bar-max-height);
  padding: var(--space-2) var(--space-8);
  position: fixed;
  right: 0;
  z-index: 1015;
}

@media (min-width: 992px) {
  .plx-booking-coverage-bar {
    min-height: 81px; /* matches .plx-sidebar-user's own height by default */
  }
}

@media (min-width: 1200px) and (max-width: 1535.98px) {
  .plx-booking-coverage-bar {
    min-height: 73px; /* .plx-sidebar-user's own height at this breakpoint */
    padding: var(--space-1) var(--space-8);
  }
}

@media (max-width: 991.98px) {
  .plx-booking-coverage-bar {
    left: 0;
  }
}

@media (max-width: 767.98px) {
  .plx-booking-coverage-bar {
    /* Taller cap and tighter horizontal padding — the stacked wizard
       footer adds an extra row at all mobile widths, so the bar needs
       more vertical room. Horizontal padding matches the tighter page
       edge at narrow viewports (no sidebar at these widths). */
    --plx-coverage-bar-max-height: 320px;
    padding: var(--space-3) var(--space-4);
  }
}

/* Below 1200px: the grid collapses to a single column, so the coverage
   summary (row 1) and the wizard footer (row 2) stack instead of sitting
   side by side — the footer then becomes its own full-width row below the
   summary, and stacks its own Back/Continue buttons vertically at full
   width — matching Step 1's mobile footer layout. Scoped to the coverage
   bar so Steps 1/3/4 (whose footers sit in the wizard card, not here) are
   completely unaffected. The taller max-height cap gives the bar room for
   the extra row. */
@media (max-width: 1199.98px) {
  .plx-booking-coverage-bar {
    --plx-coverage-bar-max-height: 320px;
    grid-template-columns: 1fr;
    row-gap: var(--space-3);
  }

  .plx-booking-coverage-bar .plx-wizard-footer {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }

  .plx-booking-coverage-bar .plx-wizard-footer .plx-btn {
    width: 100%;
  }
}

/* The footer's own padding (meant for sitting at the bottom of a
   non-fixed card) would double up with this bar's own padding above once
   nested inside it — every other footer property (button order, mobile
   stacking, etc.) is untouched. */
.plx-booking-coverage-bar .plx-wizard-footer {
  padding: 0;
  /* Centered within its own column height, overriding the bar's own
     align-items: start just for this one grid item — the summary column
     stays top-aligned (its heading never moves), but the buttons read
     better vertically centered against it regardless of that column's
     height. */
  align-self: center;
}

.plx-booking-coverage-summary {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--space-3);
  row-gap: var(--space-1);
  max-height: 100%;
  /* Grid items (this is column 1 of .plx-booking-coverage-bar's grid)
     default to a min-width equal to their own unbroken content width,
     which would otherwise force the grid column — and the whole bar —
     wider than available as the Stay Coverage text grows, instead of
     letting that text wrap within its own column. */
  min-width: 0;
}

.plx-booking-coverage-label {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}

/* .plx-pill-active (badges.css) is the shared light-tint "active" badge
   used wherever else it might apply app-wide — the "Fully Covered" pill
   in the PNG is a solid-filled chip instead (same treatment as the
   existing .plx-btn-success), so it's overridden here scoped to this
   pill only, leaving the shared class itself untouched for any other
   page/usage. */
#plxCoveragePillJs.plx-pill-active {
  background: var(--color-available);
  border-color: var(--color-available);
  color: var(--text-inverse);
}

/* ---- Step 1: No. of Rooms Required section ----
   Room-category (Hotel Grand Plaza) + book mode only; JS-rendered via
   renderStep1RoomTypes(). applyPropertyCategory() toggles d-none on
   the wrapper when the property switches between room/unit category. */
.plx-step1-room-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.plx-step1-room-section-title {
  color: var(--text-primary);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
}

.plx-step1-room-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 1199.98px) {
  .plx-step1-room-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 767.98px) {
  .plx-step1-room-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 575.98px) {
  .plx-step1-room-grid {
    grid-template-columns: 1fr;
  }
}

.plx-step1-room-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card-hover);
  overflow: hidden;
      transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.plx-step1-room-card:hover {
  border-color: var(--border-hover);
  box-shadow: var(--shadow-md);
}
:root[data-bs-theme="dark"] .plx-step1-room-card:hover {
  box-shadow: var(--shadow-md);
}
.plx-step1-room-card:active {
    box-shadow: var(--shadow-card-hover);

}
.plx-step1-room-card-header {
  align-items: center;
  background: var(--bg-hover);
  border-bottom: 1px solid var(--border-default);
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
}

.plx-step1-room-card-header .plx-icon.plx-icon-md {
  align-self: center;
  background-color: var(--bg-surface);
  border-radius: var(--radius-sm);
  color: var(--pm-primary);
  flex-shrink: 0;
  height: 34px;
  padding: 8px;
  width: 34px;
}

.plx-step1-room-card-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.plx-step1-room-card-name {
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.plx-step1-room-card-rate {
  color: var(--color-info);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.plx-step1-room-card-body {
  display: flex;
  flex-direction: column;
}

.plx-step1-room-row {
  align-items: stretch;
  border-top: 1px solid var(--border-default);
  display: flex;
}

.plx-step1-room-row:first-child {
  border-top: 0;
}

.plx-step1-room-row-label {
  align-items: center;
  color: var(--text-primary);
  display: flex;
  flex: 1;
  font-size: var(--text-sm);
  padding: 14px var(--space-4);
}

/* Right column: fixed width keeps the divider at the same x-position across
   all three rows — min-width alone would shift it on the stepper row. */
.plx-step1-room-row-right {
  align-items: center;
  display: flex;
  flex-shrink: 0;
  justify-content: center;
  padding: 14px var(--space-3);
  position: relative;
  width: 132px;
}

.plx-step1-room-row-right::before {
  background: var(--border-default);
  bottom: 8px;
  content: '';
  left: 0;
  position: absolute;
  top: 8px;
  width: 1px;
}

.plx-step1-room-row-value {
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.plx-step1-room-row-value.plx-text-available {
  color: var(--color-available);
}

/* Stepper: segmented pill — outer border wraps [−] | value | [+] */
.plx-step1-stepper {
  align-items: center;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  display: inline-flex;
  height: 28px;
  overflow: hidden;
}

.plx-step1-stepper-btn {
  align-items: center;
  background: var(--bg-surface);
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  display: inline-flex;
  flex-shrink: 0;
  height: 100%;
  justify-content: center;
  padding: 0;
  transition: background-color var(--transition-fast), color var(--transition-fast);
  width: 28px;
}

/* Internal separator: dec gets a right border, inc gets a left border */
.plx-step1-stepper-btn[data-plx-step1-action="dec"] {
  border-right: 1px solid var(--border-default);
}

.plx-step1-stepper-btn[data-plx-step1-action="inc"] {
  border-left: 1px solid var(--border-default);
}

.plx-step1-stepper-btn:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--pm-primary);
}

.plx-step1-stepper-btn:active:not(:disabled) {
  background: var(--border-default);
  color: var(--text-primary);
}

.plx-step1-stepper-btn:focus-visible {
  outline: 2px solid var(--outline-focus);
  outline-offset: -2px;
  position: relative;
  z-index: 1;
}

.plx-step1-stepper-btn:disabled {
  cursor: not-allowed;
  opacity: 0.35;
}

.plx-step1-stepper-val {
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  min-width: 40px;
  text-align: center;
}

/* ---- Step 1: Tentative info bar ---- */
.plx-step1-tentative-info {
  background-color: var(--pm-accent-soft);
  border-left: 4px solid var(--pm-accent);
  border-radius: var(--radius-sm);
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
}

.plx-step1-tentative-info-text {
  color: var(--color-info);
  font-size: var(--text-sm);
  margin: 0;
}

/* Same solid-fill treatment for "Partially Covered" — pixel-matched
   against 115-click-bottom bar.png. Scoped to the coverage pill's own
   .plx-pill-warning (not the shared light-tint class used elsewhere), and
   distinct from the shared .plx-pill-pending the JS still uses for this
   element's other, unrelated "No room(s) selected" empty state. */
#plxCoveragePillJs.plx-pill-warning {
  background: var(--color-warning);
  border-color: var(--color-warning);
  color: var(--text-inverse);
}

/* The one part of the bar that actually grows with the selection — capped
   to its own scroll instead of pushing .plx-booking-coverage-bar past its
   max-height, so "Stay Coverage : <pill>" stays put and content never
   crowds the bar's top/bottom padding. */
.plx-booking-coverage-lines {
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  /* Starts reserved for 2 lines' worth of space (cleaner at rest) and grows
     up to 4 as the selection adds lines, then scrolls internally past
     that — sized off the same tokens the lines themselves already use
     (--text-sm, --space-1) so both figures stay correct if either is
     retuned later. Both min-height AND max-height still matter: with no
     min-height at all, this box would collapse to 0/1-line height with
     few/no lines selected. It no longer needs to reserve a *constant*
     4-line height the way it used to, though — that was specifically to
     compensate for align-items: end on .plx-booking-coverage-bar, which
     bottom-anchored this whole column and let a taller box push "Stay
     Coverage : <pill>" upward with it. Now that the bar top-aligns the
     column instead (align-items: start), this box growing only extends
     the column downward — the heading above it never moves regardless of
     how tall this gets. */
  min-height: calc(2 * var(--text-sm) * 1.21 + var(--space-1));
  max-height: calc(4 * var(--text-sm) * 1.21 + 3 * var(--space-1));
  overflow-y: auto;
  /* Same reasoning as .plx-booking-coverage-summary's own min-width: 0 —
     this flex item's default min-width is its longest line's unbroken
     width, which would defeat the wrap below by widening the column
     instead. */
  min-width: 0;
}

.plx-coverage-line {
  font-size: var(--text-sm);
  margin: 0;
  /* Long room lists/date ranges wrap onto multiple lines within their own
     column instead of forcing the bar (and the footer beside it) wider. */
  overflow-wrap: break-word;
}

.plx-coverage-line-covered {
  color: var(--color-available);
}

/* --color-warning (not --color-danger) — pixel-matched against
   115-click-bottom bar.png, whose "Not Covered" line reads the same
   amber as the "Partially Covered" pill above it, not red. */
.plx-coverage-line-gap {
  color: var(--color-warning);
}

/* "Continue to Guest Details" disabled state (not fully covered yet) —
   pixel-matched against 115-click-bottom bar.png, a flat neutral gray
   rather than the shared .plx-btn:disabled's faded-primary-color/opacity
   treatment, so it's overridden here scoped to this one button only. */
#plxBookingNextBtnJs:disabled {
  background-color: var(--border-default);
  border-color: var(--border-default);
  color: var(--text-muted);
  opacity: 1;
}

/* ---- Step 3/4: two-column layout (form + summary sidebar) ---- */
.plx-booking-step3-layout {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1.7fr 1fr;
  padding: 20px 25px 30px;
}

/* No container padding for either step's book flow or lease flow Step 3 —
   the surrounding wizard card has no chrome left to pad against once the
   :has() transparency rules above fire. */
.plx-wizard-panel[data-plx-flow="book"] .plx-booking-step3-layout,
.plx-wizard-panel[data-plx-flow="lease"] .plx-booking-step3-layout {
  padding: 0;
}

/* Step 3 only — the left column (guest card + charges accordion) is a
   .plx-booking-step3-left-col flex-column wrapper (see below), so the grid
   only needs two direct items: that wrapper on the left and .plx-booking-
   summary-col on the right. This avoids the multi-row spanning that was
   previously needed and prevents the summary column's height from forcing
   the guest row to expand (which left a gap below the guest card when
   Booking Status = Tentative). Step 4 has only two children (Payment
   Details, then .plx-booking-summary-col), so it also uses the plain
   2-column definition above with no named areas of its own. */
.plx-wizard-panel[data-plx-wizard-step="3"][data-plx-flow="book"] .plx-booking-step3-layout {
  grid-template-columns: 1.7fr 1fr;
}

/* Left column: Guest Information card stacked above the Charges accordion
   via flex-direction:column. Using the same gap as the outer grid so
   spacing between card and accordion matches the column-gap on the right. */
.plx-booking-step3-left-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* --bg-surface-muted (not the shared .plx-card-header's plain --bg-surface
   inherited from .plx-card) — pixel-matched against
   create-booking-3-updated.png/create-booking-4.png/Wireframe-45.png, where
   the left card's (Guest/Tenant Information/Payment Details) and right card's
   (Booking Summary/Lease Summary/Final Bill) headers both read a hair
   off-white against the pure-white card body below them. Already defined for
   both themes (variables.css/theme-dark.css), so no new tokens needed. */
.plx-wizard-panel[data-plx-wizard-step="3"][data-plx-flow="book"] .plx-booking-step3-guest-card .plx-card-header,
.plx-wizard-panel[data-plx-wizard-step="3"][data-plx-flow="lease"] .plx-booking-step3-guest-card .plx-card-header,
.plx-wizard-panel[data-plx-flow="book"] .plx-booking-payment-card .plx-card-header,
.plx-wizard-panel[data-plx-flow="book"] .plx-booking-summary-card .plx-card-header,
.plx-wizard-panel[data-plx-flow="lease"] .plx-booking-summary-card .plx-card-header {
  background: var(--bg-surface-muted);
}

/* align-self:start — Step 4's two cards are a plain single-row grid pair
   (unlike Step 3's, where "guest" only spans row 1), so without this the
   grid's default align-items:stretch grows Payment Details to match
   whatever the Final Bill column's own height is (it gets tall fast once
   a few rooms are selected), leaving a block of empty white space below
   Payment Details' own last field — create-booking-4.png shows the card
   ending right at its own content (Notes) instead, sized independently
   of its neighbor. */
.plx-wizard-panel[data-plx-wizard-step="4"][data-plx-flow="book"] .plx-booking-payment-card,
.plx-wizard-panel[data-plx-wizard-step="4"][data-plx-flow="lease"] .plx-booking-payment-card {
  align-self: start;
}

/* top:0 here (not var(--space-5) on the card, like the lease flow's own
   summary uses) — on Step 3 this wrapper spans the guest-card's row and
   the charges-accordion's row, where a nonzero top offset pushed the card
   below the Guest Information card's own top instead of lining up with
   it, pixel-confirmed against create-booking-3-updated.png where both
   card headers sit flush on the same line (Step 4's two cards are a
   simple single-row pair, so this isn't strictly required there, but 0
   keeps both steps' right-hand cards starting flush with their left-hand
   sibling consistently). Stacks the card and the relocated footer with a
   plain gap (no grid-row tricks), so the footer always lands directly
   under the card. Shared by Steps 3 and 4 — see
   _booking_step3_book.blade.php/_booking_step4_book.blade.php.

   --plx-summary-sticky-clearance is how far this wrapper sits below the
   viewport top once stuck — the page's own sticky topbar (layout/
   topbar.css) already occupies that space and is --topbar-height tall
   (itself responsive — 80px/70px depending on breakpoint, see
   variables.css/topbar.css), so reusing that variable instead of a fixed
   px value keeps this correctly clear of the topbar at every breakpoint
   without it. max-height mirrors the same clearance on the *bottom* edge
   of the viewport, so the wrapper (card + footer) can never render taller
   than the space actually available between the topbar and the bottom of
   the screen — if the card's own content is taller than that,
   .plx-card-body (below) scrolls internally instead, and the footer
   (flex-shrink:0, also below) is never the one pushed off-screen. */
.plx-wizard-panel[data-plx-flow="book"] .plx-booking-summary-col,
.plx-wizard-panel[data-plx-flow="lease"] .plx-booking-summary-col {
  --plx-summary-sticky-clearance: calc(var(--topbar-height) + var(--space-5));
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-height: calc(100vh - var(--plx-summary-sticky-clearance) - var(--space-5));
  position: sticky;
  top: var(--plx-summary-sticky-clearance);
}

@media (max-width: 1199.98px) {
  /* The Step 3 book-flow rule above has specificity (0,4,0); the plain
     .plx-booking-step3-layout selector is only (0,1,0) and would be
     overridden by that higher-specificity rule even inside a media query.
     Both selectors are listed here so each path is reset to 1fr. */
  .plx-booking-step3-layout,
  .plx-wizard-panel[data-plx-wizard-step="3"][data-plx-flow="book"] .plx-booking-step3-layout {
    grid-template-columns: 1fr;
  }

  /* max-height:none alongside position:static — below this breakpoint the
     card isn't sticky any more (full requirement is desktop-only, like
     every other position:sticky in this file), so it shouldn't still be
     height-capped/internally scrolling either; the whole card renders at
     its natural height inline with the rest of the single-column page. */
  .plx-wizard-panel[data-plx-flow="book"] .plx-booking-summary-col,
  .plx-wizard-panel[data-plx-flow="lease"] .plx-booking-summary-col {
    max-height: none;
    position: static;
  }
}

.plx-booking-summary-card {
  align-self: start;
  position: sticky;
  top: var(--space-5);
}

@media (max-width: 1199.98px) {
  .plx-booking-summary-card {
    position: static;
  }
}

/* Form-row gap in the booking wizard falls back to forms.css's 60px base
   below 1200px — the same density fix that scopes 25px at 1200–1536px
   (above) is extended here so form rows in the now-full-width Step 3/4
   cards remain comfortable at every sub-1200px breakpoint including
   the stacked single-column layout at 768–1199px and the column-stacked
   fields below 768px. */
@media (max-width: 1199.98px) {
  #plxBookingWizardCardJs .plx-form-row {
    gap: 20px;
  }
}

/* Steps 3 and 4 (book flow) + Step 3 (lease flow) — the card is a flex
   child of .plx-booking-summary-col now (not a direct grid item), which
   already handles sticky positioning for the card + relocated footer
   together. Without this reset, the shared rule above's align-self:start
   would shrink/left-align the card instead of letting it fill the wrapper's
   width, and its own position:sticky would double up with the wrapper's.

   display:flex + min-height:0 turns the card itself into a column (header,
   then body) that's allowed to shrink below its content's natural height
   when the wrapper's own max-height runs out of room — min-height:0
   overrides flexbox's default min-height:auto, which would otherwise keep
   forcing the card to its full content height regardless of the wrapper's
   max-height. The header stays put; .plx-card-body (below) is the part
   that actually scrolls, so "Booking Summary"/"Lease Summary"/"Final Bill"
   and the card's rounded top corner stay visible above a long, scrolling
   list rather than the whole card just overflowing the wrapper. */
.plx-wizard-panel[data-plx-flow="book"] .plx-booking-summary-card,
.plx-wizard-panel[data-plx-flow="lease"] .plx-booking-summary-card {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: static;
}

.plx-wizard-panel[data-plx-flow="book"] .plx-booking-summary-card .plx-card-body,
.plx-wizard-panel[data-plx-flow="lease"] .plx-booking-summary-card .plx-card-body {
  min-height: 0;
  overflow-y: auto;
}

/* flex-shrink:0 — Confirm/Back buttons must always render at their full
   height and never be the part that gives way when the sticky wrapper above
   runs out of vertical room; .plx-card-body's own overflow-y:auto (above)
   is what absorbs long content instead, so these buttons stay fully visible
   within the viewport at all times. */
.plx-wizard-panel[data-plx-flow="book"] .plx-wizard-footer,
.plx-wizard-panel[data-plx-flow="lease"] .plx-wizard-footer {
  flex-shrink: 0;
}

.plx-booking-summary-line {
  border-bottom: 1px dashed var(--pm-accent-soft);
  padding: var(--space-3) 0;
}

.plx-booking-summary-line:first-child {
  padding-top: 0;
}

/* --weight-semibold (not -medium) — pixel-matched against
   create-booking-3.png, whose per-room total reads noticeably heavier
   than this page's other "medium" text. */
.plx-booking-summary-line-main {
  display: flex;
  font-weight: var(--weight-semibold);
  justify-content: space-between;
}

/* Lease-only "(N Months)" suffix inside the summary line room label —
   visually secondary vs the unit number beside it: matches the muted gray
   of .plx-booking-summary-line-meta-js (₹2,500/m), smaller size, and
   regular weight (the parent .plx-booking-summary-line-main is semibold). */
.plx-lease-summary-line-months {
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
}

.plx-booking-summary-line-meta-js {
  color: var(--text-muted);
  font-size: var(--text-xs);
  margin: var(--space-1) 0 0;
}

.plx-booking-summary-line-rate-row {
  display: flex;
  font-weight: var(--weight-semibold);
  justify-content: space-between;
  margin-top: var(--space-1);
}

.plx-booking-summary-line-rate {
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
}

/* Hotel Grand Plaza + Direct/Walk-In (Confirmed: create-booking-3.png,
   Tentative: Frame 16.png) — property name + dates/nights/room count, shown
   above the room-type cards below instead of the flat per-room lines every
   other combo keeps. No border/padding of its own (Frame 16.png shows the
   room cards sitting right below it with just a tight margin, not a second
   divider under .plx-card-header's own) — margin-bottom alone closes the
   gap down to that room-card row. Shared by both Step 3's Booking Summary
   card and Step 4's Final Bill card (same combo, same header markup/CSS). */
.plx-booking-summary-header {
  margin: 0 0 var(--space-3);
  padding: 0;
}

.plx-booking-summary-header-property {
  color: var(--pm-primary);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  margin: 0 0 var(--space-1);
}
.plx-booking-summary-header-meta {
  color: var(--text-secondary);
  font-size: var(--text-sm);
  margin: 0;
}

.plx-booking-summary-header-rooms {
  color: var(--color-booked);
  font-weight: var(--weight-medium);
}

/* One bordered card per room type (Grand Plaza Direct/Walk-In or
   Booking.com), or one card per unit pool (Skyview Apartment, book or lease
   flow — no room "types" of its own, see renderGroupedRoomSummary() in
   booking-engine.js) — room/unit-number chips replace the flat line's plain
   unit list, and the group's own subtotal sits in its own column instead of
   inline with the room label. */
.plx-booking-summary-group-card {
  /* Local to this card so every .plx-booking-summary-group-total/-chip
     inside shares the same two measurements regardless of its own content. */
  --plx-summary-total-width: 120px;
  --plx-summary-chip-width: 48px;
  align-items: stretch;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  display: flex;
  gap: var(--space-4);
  justify-content: space-between;
  margin-bottom: var(--space-3);
  padding: var(--space-4);
}

.plx-booking-summary-group-card:last-child {
  margin-bottom: 0;
}

.plx-booking-summary-group-info {
  min-width: 0;
}

.plx-booking-summary-group-name {
  color: var(--text-primary);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  margin: 0;
}

.plx-booking-summary-group-meta {
  color: var(--text-muted);
  font-size: var(--text-sm);
  margin: var(--space-1) 0 0;
}

.plx-booking-summary-group-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.plx-booking-summary-group-chip {
  align-items: center;
  background: var(--pm-accent-soft);
  border-radius: var(--radius-sm);
  color: var(--color-booked);
  display: flex;
  flex-direction: column;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  justify-content: center;
  padding: var(--space-1) var(--space-2);
  text-align: center;
  width: var(--plx-summary-chip-width);
}

.plx-booking-summary-group-chip:has(.plx-booking-summary-group-chip-date) {
  padding-inline: var(--space-1);
  width: auto;
}

.plx-booking-summary-group-chip-date {
  color: var(--color-partial, var(--color-booked));
  display: block;
  font-size: 0.65rem;
  font-weight: var(--weight-regular);
  opacity: 0.8;
  white-space: nowrap;
}

/* align-items: stretch on .plx-booking-summary-group-card (above) makes this
   a full-height flex item first; the negative top/bottom margins then
   extend it back out over the card's own padding so its border-left reaches
   the card's actual top/bottom edges (pixel-matched against the
   reference) instead of stopping at the padded content box. Its own flex +
   centering keeps the price vertically centered within that full height. */
.plx-booking-summary-group-total {
  align-items: center;
  border-left: 1px solid var(--border-default);
  color: var(--color-booked);
  display: flex;
  flex-shrink: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  justify-content: flex-end;
  margin-bottom: calc(-1 * var(--space-4));
  margin-top: calc(-1 * var(--space-4));
  padding-left: var(--space-4);
  width: var(--plx-summary-total-width);
}

/* Dashed divider matches .plx-booking-summary-line's own border above —
   same dotted rhythm continues from the room lines through Discount/
   Taxes, pixel-matched against create-booking-3.png. The last row
   (Additional Charges) opts back out since .plx-booking-summary-total-row
   below already supplies its own solid divider immediately after it. */
.plx-booking-summary-charge-row {
  align-items: center;
  color: var(--text-muted);
  display: flex;
  font-size: var(--text-sm);
  justify-content: space-between;
  padding: var(--space-2) 0;
}

/* Border lives on the adjacent-sibling combinator rather than
   ":last-of-type { border-bottom: 0 }" on the base rule — the row group
   is always followed by .plx-booking-summary-total-row (also a <div>),
   which is what's actually "last of type" for the <div> tag, so that
   approach never matched anything. This draws a divider above every
   charge row except the first instead (the same N-1 dividers a working
   "border-bottom on all but the last" rule would produce), which is
   correct regardless of what element follows the group. */
.plx-booking-summary-charge-row + .plx-booking-summary-charge-row {
  border-top: 1px dashed var(--pm-accent-soft);
}

.plx-booking-summary-charge-value {
  color: var(--text-primary);
}

/* --color-available (green) — pixel-matched against create-booking-3.png,
   whose Discount value reads green rather than this row group's shared
   dark --text-primary. Scoped to the id so Taxes/Additional Charges keep
   the shared dark value untouched. */
#plxSummaryDiscountJs,
#plxFinalBillDiscountJs {
  color: var(--color-available);
}

/* --pm-accent (not --border-default) — pixel-matched against
   create-booking-3.png, whose divider just above "Grand Total" reads as
   a full-strength indigo rather than the page's usual neutral border. */
.plx-booking-summary-total-row {
  align-items: baseline;
  border-top: 1px solid var(--pm-accent);
  display: flex;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  justify-content: space-between;
  margin-top: var(--space-2);
  padding-top: var(--space-3);
}

.plx-booking-summary-total-row small {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
}

.plx-booking-summary-total-row > span:last-child {
  color: var(--color-booked);
}

/* Hotel Grand Plaza + Direct/Walk-In + Tentative only (Step 3 Booking
   Summary reference PNG): Total Amount becomes its own boxed section
   instead of the shared indigo border-top divider above — border/radius/
   padding pixel-matched to .plx-booking-summary-group-card so it reads as
   one more card in the same stack. Layered on top of the base rule above
   via this modifier class alone (toggled by renderBookingSummary() in
   booking-engine.js), so every other combo — including this same one when
   Confirmed, Step 4's Final Bill, and the Lease flow's own total row below
   — keeps its existing look untouched. */
.plx-booking-summary-total-row-boxed {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  margin-top: var(--space-3);
  padding: var(--space-4);
}

/* --pm-primary (not the shared --color-booked above) — pixel-matched
   against create-booking-3-updated.png/Wireframe-45.png, whose Grand Total
   and Total Lease Value read a deep indigo rather than the page's usual
   bright blue. All three ids share the same treatment so the total row
   reads consistently across book flow Steps 3/4 and the lease flow. */
#plxSummaryGrandTotalJs,
#plxFinalBillGrandTotalJs,
#plxLeaseTotalValueJs,
#plxLeaseFinalTotalValueJs,
#plxLeaseFinalTotalValueJs {
  color: var(--pm-primary);
  font-size: var(--text-lg);
}

/* Dashed divider after the Total Lease Value row, separating it from the
   footnote — Wireframe-45.png shows this separator; the book flow has no
   equivalent (its footnote is absent). Negative horizontal margins extend
   the element to the card body's inner edges so the dashed bottom border
   is edge-to-edge; padding-left/right compensate so the text content stays
   at the original inset position. The base border-top (solid) is suppressed
   here because it would also go edge-to-edge on the widened element — a
   ::before pseudo-element re-adds it at the original inset width. */
.plx-wizard-panel[data-plx-flow="lease"] .plx-booking-summary-total-row {
  border-bottom: 1px dashed var(--pm-accent-soft);
  border-top: 0;
  margin-bottom: var(--space-3);
  margin-left: calc(-1 * var(--space-4));
  margin-right: calc(-1 * var(--space-4));
  padding-bottom: var(--space-3);
  padding-left: var(--space-4);
  padding-right: var(--space-4);
  position: relative;
}

.plx-wizard-panel[data-plx-flow="lease"] .plx-booking-summary-total-row::before {
  border-top: 1px solid var(--pm-accent);
  content: '';
  left: var(--space-4);
  position: absolute;
  right: var(--space-4);
  top: 0;
}

.plx-booking-summary-footnote {
  color: var(--text-muted);
  font-size: var(--text-xs);
  margin: var(--space-3) 0 0;
}

/* Grand Plaza + Direct/Walk-In + Tentative only (Step 4 Final Bill,
   Frame 16.png): dotted divider above this one footnote, edge-to-edge like
   the boxed Total Amount row above it — negative side margins + matching
   padding keep the text at its original inset position (same technique
   the Lease flow's own divider uses on .plx-booking-summary-total-row
   below). Scoped to this id rather than the shared .plx-booking-summary-
   footnote class above so the Lease flow's own footnote (with its own,
   different divider already on the row above it) is untouched. */
#plxFinalBillTentativeNoteJs {
  border-top: 1px dashed var(--pm-accent-soft);
  margin: var(--space-3) calc(-1 * var(--space-4)) 0;
  padding: var(--space-4) var(--space-4) 0;
}

/* Booking Date is intentionally locked once Step 2's dates are chosen —
   .plx-input:disabled (forms.css) already supplies the muted background/
   text/cursor; only .plx-date-icon's own pointer cursor and brand-colored
   icon need a scoped override here so the field reads as fully disabled.
   Scoped to this one field's id, not the shared .plx-date-icon class,
   since Step 1/OTA Allotments' own date-icon fields stay interactive. */
#plxBookingDateJs:disabled {
  cursor: not-allowed;
}

.plx-date-icon:has(#plxBookingDateJs:disabled) .plx-icon {
  color: var(--text-muted);
}

/* "Room Rate / Discount / Taxes / Additional Charges" quick-add list —
   replaces the Booking Summary card's old per-row "Edit" affordances
   (see _booking_step3_book.blade.php), each button reusing the same
   modal triggers via data-bs-toggle. Pixel-matched against
   create-booking-3-updated.png: each row is its own bordered/rounded box
   (not one continuous list), stacked with a small gap. No padding of its
   own — it's a sibling of the Guest Information card now (not nested
   inside it), so its rows sit flush with that card's own left/right
   edges instead of being inset from them. */
.plx-charges-accordion {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.plx-charges-row {
  align-items: center;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  text-align: left;
  width: 100%;
}

.plx-charges-row-icon {
  align-items: center;
  background: var(--pm-accent-soft);
  border-radius: var(--radius-sm);
  color: var(--pm-primary);
  display: flex;
  flex-shrink: 0;
  height: 32px;
  justify-content: center;
  width: 32px;
}

.plx-charges-row-label {
  color: var(--text-primary);
  flex: 1;
  font-weight: var(--weight-medium);
}

.plx-charges-row-add {
  align-items: center;
  color: var(--color-booked);
  display: inline-flex;
  flex-shrink: 0;
  font-weight: var(--weight-medium);
  gap: var(--space-1);
}

.plx-charges-row-add .plx-icon {
  font-size: 18px;
}

/* ---- Step 3 "Guest documents" upload row (Frame 95.png/create-booking-
   3.png) ----
   Sits first in .plx-charges-accordion above, reusing that same list's row
   gap. Unlike the other rows (plain buttons that open a modal), this one
   is a <div> that expands in place — .plx-document-upload-header reuses
   .plx-charges-row-icon/.plx-charges-row-label as-is (same 32px icon
   square, same label weight) so only the outer shape (dashed border,
   div instead of button) and the added subtitle/toggle button are new. */
.plx-document-upload {
  background: var(--bg-surface);
  border: 1px dashed var(--pm-accent);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
}

/* Upload/Close toggle — pixel-matched against Frame 95.png: border stays
   the shared .plx-btn-outline's own --pm-accent, but the text (and its
   hover fill) reads a more saturated indigo-blue than that class's default
   --pm-primary. Scoped to this component rather than editing .plx-btn-
   outline itself, since that class is also used by the Properties wizard
   (resources/views/properties/partials/_wizard_step3*.blade.php) and must
   keep its own existing look untouched there. */
.plx-document-upload .plx-btn-outline {
  color: var(--color-info);
}

.plx-document-upload .plx-btn-outline:hover:not(:disabled) {
  background-color: var(--color-info-bg);
}

.plx-document-upload-header {
  align-items: center;
  cursor: pointer;
  display: flex;
  gap: var(--space-3);
}

.plx-document-upload-heading {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.plx-document-upload-count {
  color: var(--color-available);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.plx-document-upload-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.plx-document-dropzone {
  align-items: center;
  border: 1px dashed var(--pm-accent);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  gap: var(--space-2);
  justify-content: center;
  padding: var(--space-5);
  background: color-mix(in srgb, var(--pm-accent-soft) 20%, transparent);
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.plx-document-dropzone:hover,
.plx-document-dropzone-active {
  background: var(--pm-accent-light);
  border-color: var(--pm-accent);
}

.plx-document-upload-grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(2, 1fr);
}

.plx-document-card {
  align-items: center;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3);
}

.plx-document-card-icon {
  align-items: center;
  border-radius: var(--radius-sm);
  color: var(--text-inverse);
  display: flex;
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  height: 36px;
  justify-content: center;
  width: 36px;
}

/* One class per DEFAULT_TYPE_COLORS entry (document-upload.js) — add a
   matching rule here for any new key added to that map. */
.plx-document-card-icon-danger {
  background: var(--color-danger);
}
.plx-document-card-icon-info {
  background: var(--color-info);
}
.plx-document-card-icon-available {
  background: var(--color-available);
}
.plx-document-card-icon-partial {
  background: var(--color-partial);
}
.plx-document-card-icon-muted {
  background: var(--text-muted);
}

.plx-document-card-info {
  flex: 1;
  min-width: 0;
}

.plx-document-card-name {
  color: var(--text-primary);
  font-weight: var(--weight-medium);
  margin-bottom: var(--space-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.plx-document-card-meta {
  color: var(--text-muted);
  font-size: var(--text-sm);
  margin-top: var(--space-1);
  margin-bottom: 0;
}

.plx-document-card-remove {
  align-items: center;
  background: none;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  display: inline-flex;
  flex-shrink: 0;
  height: 24px;
  justify-content: center;
  padding: 0;
  width: 24px;
}

.plx-document-card-remove:hover {
  color: var(--color-danger);
}

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

/* Steps 3 and 4 (book flow) + Step 3 (lease flow) footer — full-width,
   stacked with Confirm above Back (column-reverse keeps Back first in the
   DOM/tab order while showing it second), relocated to sit directly below
   the Booking Summary/Lease Summary/Final Bill card — see
   syncWizardFooterPlacement() in booking-engine.js, which appends it to
   .plx-booking-summary-col instead of its usual spot under the whole
   wizard card, matching create-booking-3-updated.png/create-booking-4.png/
   Wireframe-45.png's cardless footer stacked right under the summary card.
   Steps 1/2 keep the shared side-by-side .plx-wizard-footer untouched
   (the footer is outside all wizard panels at those steps, so these
   [data-plx-flow] descendant selectors never fire). */
.plx-wizard-panel[data-plx-flow="book"] .plx-wizard-footer,
.plx-wizard-panel[data-plx-flow="lease"] .plx-wizard-footer {
  background: transparent;
  flex-direction: column-reverse;
  gap: var(--space-3);
  padding: 0;
}

.plx-wizard-panel[data-plx-flow="book"] .plx-wizard-footer .plx-btn,
.plx-wizard-panel[data-plx-flow="lease"] .plx-wizard-footer .plx-btn {
  width: 100%;
}

/* ---- Step 4: Record Payment Later + payment mode grid ---- */
/* margin-bottom:var(--space-6) (not the shared .plx-highlight-box's
   --space-5) — pixel-matched against create-booking-4.png, whose gap to
   "Payment Mode" below reads slightly more generous than the default. */
.plx-record-payment-later-box {
  align-items: center;
  background: var(--bg-surface);
  border: 1.5px solid var(--color-notification-dot);
  border-radius: var(--radius-sm);
  display: flex;
  gap: var(--space-4);
  justify-content: space-between;
  margin-bottom: var(--space-6);
  padding: var(--space-4) var(--space-5);
}
/* #input-lease_record_payment_later — Skyview Apartment + Lease's own
   "Record Payment Later" checkbox (Wireframe - 49.png, Step 4), same
   checkbox/box markup as the book flow's own but under its own name so the
   two don't share an id — same size override needed here too. */
#input-record_payment_later,
#input-lease_record_payment_later {
  height: 25px;
  width: 25px;
}
#input-record_payment_later:checked::after,
#input-lease_record_payment_later:checked::after {

    height: 13px;
    left: 9px;
    top: 3px;
    width: 5px;
}
.plx-record-payment-later-box .plx-highlight-box-label {
  display: block;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
}

.plx-record-payment-later-desc {
  color: var(--text-muted);
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-regular);
  margin-top: 2px;
}

/* "Enable" label — pixel-matched against create-booking-4.png, which
   reads it in the same muted tone/weight as "Payment Mode" below rather
   than the shared .plx-checkbox-group label's usual dark/semibold
   styling. */
.plx-record-payment-later-box .plx-checkbox-group .plx-label {
  color: var(--text-muted);
  font-weight: var(--weight-regular);
}

/* "Payment Mode" label — pixel-matched against create-booking-4.png,
   which reads it muted/lighter than the form's other (dark, semibold)
   field labels like "Receiving Bank". Its own class rather than touching
   the shared .plx-label, which every other label on this card keeps. */
.plx-payment-mode-label {
  color: var(--text-muted);
  font-weight: var(--weight-medium);
}

.plx-payment-mode-grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 767.98px) {
  .plx-payment-mode-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* height:48px (not 40px) and color:var(--text-muted) (not --text-primary)
   — pixel-matched against create-booking-4.png: the buttons read taller
   than before, and an unselected button's label is a visibly lighter
   gray than the page's usual primary text color. */
.plx-payment-mode-btn {
  background: var(--bg-surface);
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  height: 48px;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.plx-payment-mode-btn:hover {
  border-color: var(--border-hover);
}

/* color:var(--pm-primary) — the selected button's own label reads a deep
   indigo in the reference, not the same muted gray every other (or the
   shared --text-primary) the base rule above uses. */
.plx-payment-mode-btn[data-plx-selected="true"] {
  border-color: var(--border-focus);
  border-width: 2px;
  box-shadow: var(--shadow-focus);
  color: var(--pm-primary);
}

/* --bg-page (not the shared .plx-input:disabled's --bg-surface-muted) and
   bold colored values — pixel-matched against create-booking-4.png:
   Total Bill reads in the same blue as the rest of the page's booked/
   info accents, Balance Due reads green (it's a positive/no-balance
   amount), and both are noticeably heavier than the plain disabled-input
   look every other read-only field on the page (Total Bill/Balance Due's
   own siblings included) keeps. */
#plxTotalBillDisplayJs,
#plxBalanceDueDisplayJs {
  background: var(--bg-page);
  font-weight: var(--weight-semibold);
}

#plxTotalBillDisplayJs {
  color: var(--color-booked);
}

#plxBalanceDueDisplayJs {
  color: var(--color-available);
}

/* Skyview Apartment + Lease, Step 4 (Wireframe - 49.png) — Total Lease
   Amount reuses this exact same --bg-page/bold/blue treatment as Total
   Bill above, matching that reference's own bold blue value. Lease has no
   Balance Due equivalent (Security Deposit takes that slot as a plain
   editable field), so only this one selector is added here. */
#plxLeaseTotalAmountDisplayJs {
  background: var(--bg-page);
  font-weight: var(--weight-semibold);
  color: var(--color-booked);
}

/* ---- Status popover (#plxStatusPopoverModalJs) ---- */
/* This modal's own .modal-body top padding is shorter than the shared
   .plx-modal default (components/modals.css) — pixel-matched against
   under-maintenance-1.png/par-book-pop-up-1.png, both of which sit
   .plx-popover-icon noticeably closer to the card's top edge. Scoped to
   this modal only; every other modal keeps the shared default. */
#plxStatusPopoverModalJs .modal-body {
  padding-top: var(--space-4);
}

/* x-ui.modal's "bare" header (no title prop passed — see
   _booking_modals.blade.php) normally sits as its own flex row above
   .modal-body, which would otherwise leave the close button floating
   above .plx-popover-header instead of level with it, as in the
   references above. Taking it out of flow and pinning it to the same
   inset .modal-body now uses lines its 36px-tall box up with
   .plx-popover-icon's own 36px, so both center on the same row without
   touching x-ui.modal itself (shared by every other modal). */
#plxStatusPopoverModalJs .modal-header.plx-modal-header-bare {
  align-items: center;
  display: flex;
  height: 36px;
  padding: 0;
  position: absolute;
  right: var(--space-6);
  top: var(--space-4);
  z-index: 1;
}

.plx-popover-header {
  align-items: flex-start;
  display: flex;
  gap: var(--space-3);
}

.plx-popover-icon {
  align-items: center;
  background: var(--pm-accent-light);
  border-radius: var(--radius-sm);
  color: var(--pm-primary);
  display: flex;
  flex-shrink: 0;
  height: 36px;
  justify-content: center;
  width: 36px;
}

.plx-popover-title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  margin: 0;
}

.plx-popover-subtitle {
  color: var(--text-muted);
  font-size: var(--text-sm);
  margin: var(--space-1) 0 0;
}

.plx-popover-row {
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-2);
  padding: var(--space-3);
}

/* align-items:center so .plx-popover-row-right (a badge or the "Select
   This Slot" button) centers against the FULL left side — including
   .plx-popover-row-sub below the main line, now nested inside
   .plx-popover-row-left-group — instead of just the first line, matching
   modal-components-dropdown-select-option-etc-etc/par-book-pop-up-1.png. */
.plx-popover-row-main {
  align-items: center;
  display: flex;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  gap: var(--space-3);
  justify-content: space-between;
}

.plx-popover-row-left-group {
  display: flex;
  flex-direction: column;
}

.plx-popover-row-sub {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  margin: var(--space-1) 0 0;
}

/* --pm-accent (not --pm-accent-soft/-light) for both border and the
   left-side label — pixel-matched against
   modal-components-dropdown-select-option-etc-etc/under-maintenance-1.png,
   whose accent row reads as a plain white fill with a full-strength accent
   border/text, not the soft tint .plx-popover-row-accent used before. The
   right-side value stays --text-secondary via the rule below, same as
   every other row's right side. */
.plx-popover-row-accent { background: var(--bg-surface); color: var(--pm-accent); border: 1px solid var(--pm-accent); }
/* --plx-popover-booked-bg (not --color-booked-bg) — pixel-matched
   against booked-pop-1.png, whose card reads a flat light gray rather
   than --color-booked-bg's blue-tinted near-white; border/text keep
   --color-booked itself since that measured as an exact match (also
   reused by .plx-pill-booked in components/badges.css). */
.plx-popover-row-blue { background: var(--plx-popover-booked-bg); border: 1px solid var(--color-booked); color: var(--color-booked); }
/* --color-notification-dot/--toggle-track-off (not --color-warning/-bg) —
   pixel-matched against tentive-book-pop-up-1.png, whose card reads a
   brighter orange on a warmer cream than --color-warning's usual
   mustard/pale-yellow pairing elsewhere. Same pair .plx-pill-pending
   (components/badges.css) already uses, reused here for the
   "Tentative Booking" pill too (see booking-engine-modals.js) so both
   read as one consistent accent. */
.plx-popover-row-tentative { background: var(--toggle-track-off); border: 1px solid var(--color-notification-dot); color: var(--color-notification-dot); }
/* Pixel-matched against
   modal-components-dropdown-select-option-etc-etc/par-book-pop-up-1.png —
   a brighter magenta than --color-partial/-bg (used by the floor plan's
   own "Partial" status chips elsewhere), so it's its own scoped pair of
   variables rather than retuning that shared token. Defined on :root
   (not locally on .plx-popover-row-partial) so Floor Chip 115's own
   selected-state rule above can reuse the same pair — see 115.png, an
   exact pixel match to this same fill/border/text. .plx-pill-partial
   (components/badges.css) also reads --plx-popover-partial-color for its
   border/text. */
:root {
  --plx-popover-partial-bg: #FCEFFF;
  --plx-popover-partial-color: #C755DE;
  /* Pixel-matched against ota-reserved-1.png — a brighter crimson on a
     near-white card than --color-danger's usual orange-red pairing
     elsewhere, used by Room/Unit A-03/A-04/A-05/A-06's "Allotted to
     Booking.com" popover (.plx-popover-row-danger below, plus
     .plx-pill-danger in components/badges.css). */
  --plx-popover-ota-bg: #FDFDFF;
  --plx-popover-ota-color: #D72149;
  /* Pixel-matched against Group 14-clr-mtc.png — Floor Chips
     A-03/A-04/A-05/A-06 read a visibly more tinted pink than the popover
     card's own near-white --plx-popover-ota-bg at this small chip size,
     so it's its own variable; border/text reuse --plx-popover-ota-color
     directly since that measured as an exact match. See
     .plx-floor-chip[data-plx-status="ota"] below. */
  --plx-chip-ota-bg: #FFF3F5;
  /* RGBA shadow derived from --plx-popover-ota-color (#D72149) — used by
     .plx-floor-chip[data-plx-selected][data-plx-status="ota"] to highlight
     partial OTA chips (112, 116, A-14) without switching their status color. */
  --plx-chip-ota-selected-shadow: rgba(215, 33, 73, 0.22);
  /* Pixel-matched against booked-pop-1.png — A-14/A-15's "Fully Booked"
     row/card. See .plx-popover-row-blue below. */
  --plx-popover-booked-bg: #F8F8F8;
}

:root[data-bs-theme="dark"] {
  --plx-popover-partial-bg: #2E1A33;
  --plx-popover-partial-color: #E29CF0;
  --plx-popover-ota-bg: #2A1820;
  --plx-popover-ota-color: #FF7A93;
  --plx-chip-ota-bg: #2A1820;
  --plx-chip-ota-selected-shadow: rgb(255 122 147 / 48%);
  --plx-popover-booked-bg: #20222C;
}

.plx-popover-row-partial {
  background: var(--plx-popover-partial-bg);
  border: 1px solid var(--plx-popover-partial-color);
  color: var(--plx-popover-partial-color);
}
.plx-popover-row-gray { background: var(--color-blocked-bg); border: 1px solid var(--color-blocked); color: var(--text-secondary); }
.plx-popover-row-danger { background: var(--plx-popover-ota-bg); border: 1px solid var(--plx-popover-ota-color); color: var(--plx-popover-ota-color); }
.plx-popover-row-success { background: var(--color-success-bg); border: 1px solid var(--color-available); color: var(--color-available); }

.plx-popover-row-accent .plx-popover-row-right,
.plx-popover-row-danger .plx-popover-row-right:not(:has(.plx-pill)) {
  color: var(--text-secondary);
}

/* No status colorClass forces dark text on .plx-popover-row-main anymore
   — .plx-popover-row-partial/-tentative/-danger/-blue all keep their own
   accent color instead, pixel-matched against par-book-pop-up-1.png /
   tentive-book-pop-up-1.png / ota-reserved-1.png / booked-pop-1.png,
   same treatment .plx-popover-row-success already gets from its own
   color above. .plx-popover-row-danger is the one partial exception:
   it's reused for both a plain-text-right "Allotment Date Range" row and
   a pill-right "Booked via OTA" row, and only the former goes back to
   --text-secondary (see the rule above) — the :not(:has(.plx-pill))
   guard keeps that scoped so .plx-pill-danger's own crimson is never
   overridden. */

/* --step-pending (not --text-muted) — pixel-matched against
   under-maintenance-1.png/par-book-pop-up-1.png, whose caption reads
   noticeably lighter than --text-muted's other usages (e.g.
   .plx-popover-subtitle just above it). */
.plx-popover-caption {
  color: var(--step-pending);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
  margin: var(--space-4) 0 var(--space-2);
  text-transform: uppercase;
}

.plx-popover-footer-caption {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
  margin-top: var(--space-3);
  text-align: center;
  text-transform: uppercase;
}

/* Room 116's tentative-booking popover and A-03/A-04/A-05/A-06's OTA
   popover only (see booking-engine-modals.js, which adds/removes this
   modifier alongside .d-none) — pixel-matched against
   tentive-book-pop-up-1.png/ota-reserved-1.png, whose footer caption is
   left-aligned with more top spacing and the same lighter --step-pending
   gray as .plx-popover-caption above it, instead of the shared centered/
   --text-muted default every other status keeps. */
.plx-popover-footer-caption-left {
  color: var(--step-pending);
  margin-top: var(--space-4);
  text-align: left;
}

/* ---- Charges modals (Room Rate / Discount / Taxes / Other Charges) ----
   Pixel-matched against room-rate.png/discount.png/taxes.png/
   other-charges.png: a plain white card with no visible title bar — just
   the floating close button. The title prop (and its <h2>) stay in the
   DOM — plx-room-rate-modal's title text is rewritten on every open by
   booking-engine-modals.js ("Room Rate" vs "Unit Rate" depending on
   property type), and removing the element outright would throw on that
   .textContent assignment — so it's visually hidden with the existing
   .plx-sr-only utility instead, keeping the accessible name and that
   dynamic-noun behavior intact while matching the reference's bare look.
   No border between the body and the footer's Confirm button either.
   --bg-surface (not the shared modal's inherited --bs-body-bg/--bg-page)
   matches the reference's pure-white body in light mode and the correct
   dark surface in dark mode. Each modal's own width is pixel-matched to
   its reference rather than reusing the shared .plx-modal-sm/-md classes,
   so the Country & Currency modal (also size="sm") and any other modal on
   the site keep their current width. */
#plxRoomRateModalJs .modal-content,
#plxDiscountModalJs .modal-content,
#plxTaxesModalJs .modal-content,
#plxOtherChargesModalJs .modal-content {
  background: var(--bg-surface);
}
#plxRoomRateModalJs .plx-modal-close,
#plxDiscountModalJs .plx-modal-close,
#plxTaxesModalJs .plx-modal-close,
#plxOtherChargesModalJs .plx-modal-close {
  justify-content: end;
}
#plxRoomRateModalJs .modal-header,
#plxDiscountModalJs .modal-header,
#plxTaxesModalJs .modal-header,
#plxOtherChargesModalJs .modal-header {
  border-bottom: 0;
  justify-content: flex-end;
  padding: var(--space-3) var(--space-6) 0;
}
#plxRoomRateModalJs .plx-room-rate-row,
#plxDiscountModalJs .plx-room-rate-row,
#plxTaxesModalJs .plx-room-rate-row,
#plxOtherChargesModalJs .plx-room-rate-row {
  margin-bottom: 0;
}
#plxRoomRateModalJs .plx-modal-heading,
#plxDiscountModalJs .plx-modal-heading,
#plxTaxesModalJs .plx-modal-heading,
#plxOtherChargesModalJs .plx-modal-heading {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* --space-4 bottom (not the shared rule's --space-5) — pixel-matched
   against the references, all 4 of which land the Confirm button's
   bottom edge 16px above the modal's own bottom edge. */
#plxRoomRateModalJs .modal-footer,
#plxDiscountModalJs .modal-footer,
#plxTaxesModalJs .modal-footer,
#plxOtherChargesModalJs .modal-footer {
  border-top: 0;
  padding-bottom: var(--space-4);
  padding-top: 0;
}
#plxRoomRateModalJs .modal-footer .plx-btn,
#plxDiscountModalJs .modal-footer .plx-btn,
#plxTaxesModalJs .modal-footer .plx-btn,
#plxOtherChargesModalJs .modal-footer .plx-btn {
  margin: 0;
}

#plxDiscountModalJs .modal-dialog,
#plxTaxesModalJs .modal-dialog {
  max-width: 450px;
}
#plxRoomRateModalJs .modal-dialog {
  max-width: 500px;
}

#plxOtherChargesModalJs .modal-dialog {
  max-width: 700px;
}

/* ---- Discount / Taxes modals ----
   Pixel-matched against discount.png/taxes.png: label (or checkbox+label)
   on the left, a single wider input on the right — not the narrow 100px
   box this used to be. */
.plx-charge-row {
  align-items: center;
  display: flex;
  gap: var(--space-4);
  justify-content: space-between;
  margin-bottom: var(--space-4);
}

/* Not 0 — pixel-matched against discount.png/taxes.png: the gap from the
   last row's input to the Confirm button (28px) is bigger than a plain
   row-to-row gap, but smaller than this row keeping its own full
   var(--space-4) row gap on top of .modal-footer's existing space above
   Confirm — var(--space-3) on just this last row lands the combined gap
   on 28px without affecting the row-to-row gap above it. */
.plx-charge-row:last-child {
  margin-bottom: var(--space-3);
}

/* --border-medium (not the shared .plx-input's --border-default) —
   pixel-matched against discount.png/taxes.png, whose input borders read
   a noticeably darker gray than this field's usual default. Already
   themed for both Light and Dark mode, and :focus still falls through to
   the shared .plx-input:focus rule (forms.css), so the design system's
   existing focus treatment is untouched. */
.plx-charge-row-input {
  border-color: var(--border-medium);
  flex: 0 0 auto;
  width: 240px;
}
#plxTaxesModalJs .plx-charge-row-input {
    width: 220px;
}

#plxTaxesModalJs .plx-checkbox-group {
  gap: var(--space-3);
}


/* .plx-checkbox-custom itself (base appearance/checked/hover/focus states)
   moved to components/forms.css — it's no longer booking-engine-scoped now
   that /operations/ota-allotments' Release Dates modals reuse it too; see
   that file for the rule and the reasoning. Still referenced here by the
   warning variant just below, and by every .plx-checkbox-custom usage on
   this page (Step 2 Room Inventory, Taxes modal, tax-dropdown rows). */

/* Orange/warning checked-state variant of the shared .plx-checkbox-custom
   above — reusable wherever a checkbox needs to match a warning-toned
   highlight box (Frame 27.png) instead of the shared default blue.
   Toggled onto the "Record Payment Later" checkbox for Hotel Grand Plaza +
   Direct/Walk-In and Hotel Grand Plaza + Booking.com (see
   applyRecordPaymentLaterMode() in booking-engine.js); every other
   .plx-checkbox-custom elsewhere (Taxes modal, tax-dropdown rows, this
   same checkbox on every other combo) keeps the shared blue look
   untouched. */
.plx-checkbox-custom.plx-checkbox-custom-warning:hover:not(:checked) {
  border-color: var(--color-notification-dot);
}

.plx-checkbox-custom.plx-checkbox-custom-warning:checked {
  background: var(--color-notification-dot);
  border-color: var(--color-notification-dot);
}

/* Hotel Grand Plaza + Direct/Walk-In, and Hotel Grand Plaza + Booking.com
   (Frame 27.png): replaces the Payment Mode/Receiving Bank/Total Bill
   fields while "Record Payment Later" is checked — reuses the same
   bordered, rounded surface as .plx-highlight-box/.plx-room-detail-card
   (--border-default/--radius-md) rather than introducing another card
   shape. */
.plx-record-payment-later-notice {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-6) var(--space-5);
  text-align: center;
}

.plx-record-payment-later-notice-title {
  color: var(--pm-primary);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  margin: 0 0 var(--space-2);
}

.plx-record-payment-later-notice-desc {
  color: var(--text-muted);
  font-size: var(--text-md);
  margin: 0;
}

/* ---- Other Charges modal ----
   Pixel-matched against other-charges.png: the charge name sits in its
   own left column (regular case/weight, not the all-caps semibold label
   this used to be), vertically centered against the row, with the
   Amount/Tax Amount/Total Amount field group to its right — not stacked
   above the fields like before. */
.plx-other-charges-rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-height: 60vh;
  overflow-y: auto;
}

.plx-other-charge-row {
  align-items: center;
  display: flex;
  gap: var(--space-4);
}
#plxBookingPropertyDisplayWrapJs .plx-form-group,
#plxBookingPropertySelectWrapJs .plx-form-group {
  margin-bottom: 0;
}
.plx-other-charge-label {
  color: var(--text-primary);
  flex: 0 0 200px;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
}
.plx-other-charge-fields .plx-label {
  font-weight: var(--weight-regular);
    font-size: var(--text-base);
}
.plx-other-charge-fields {
  display: grid;
  flex: 1;
  gap: var(--space-3);
  grid-template-columns: repeat(4, 1fr);
}

/* Other Charges modal uses a lg-size Bootstrap modal (~900px) — at tablet
   widths the 4-column field grid inside each row is too tight. Drop to 2
   columns at 768–991px; the full stack to 1 column below 768px follows. */
@media (min-width: 768px) and (max-width: 991.98px) {
  .plx-other-charge-fields {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 767.98px) {
  .plx-other-charge-row {
    align-items: stretch;
    flex-direction: column;
  }

  .plx-other-charge-label {
    flex-basis: auto;
  }

  .plx-other-charge-fields {
    grid-template-columns: 1fr;
  }
}

/* ---- Other Charges modal: Tax Amount field ----
   Pixel-matched against tax-dropdown.png. Same trigger+panel shape as the
   Phone No. country picker (.plx-country-dropdown/country-picker.js) —
   reused tokens (--bg-surface/--border-default/--radius-sm/--shadow-lg)
   and the same absolute/top:100% positioning for visual and interaction
   consistency with that established pattern. See
   forms/tax-dropdown.blade.php and components/tax-dropdown.js. */
.plx-tax-dropdown {
  position: relative;
}

.plx-tax-dropdown-input {
  padding-right: var(--space-8);
}
.plx-tax-dropdown-input-wrap input {
  cursor: pointer;
}
.plx-tax-dropdown-chevron {
  align-items: center;
  background: none;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  display: inline-flex;
  height: 100%;
  justify-content: center;
  padding: 0;
  position: absolute;
  right: var(--space-2);
  top: 0;
  width: 24px;
}

.plx-tax-dropdown-chevron .plx-icon {
  font-size: 16px;
  transition: transform var(--transition-fast);
  -webkit-transition: transform var(--transition-fast);
  -moz-transition: transform var(--transition-fast);
  -ms-transition: transform var(--transition-fast);
  -o-transition: transform var(--transition-fast);
}

.plx-tax-dropdown-chevron[aria-expanded="true"] .plx-icon {
  transform: rotate(180deg);
}

.plx-tax-dropdown-panel {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  left: 0;
  margin-top: var(--space-2);
  padding: var(--space-2);
  position: absolute;
  top: 100%;
  width: max(180px, 100%);
  z-index: 20;
}

.plx-tax-dropdown-row {
  align-items: center;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
}

.plx-tax-dropdown-row:hover {
  background: var(--bg-hover);
}

.plx-tax-dropdown-row span {
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

/* ---- Room/Unit Rate modal ----
   Pixel-matched against room-rate.png: the room number sits to the left
   of its Current/New Rate fields, vertically centered against them — not
   stacked above the fields like before. */
.plx-room-rate-row {
  align-items: center;
  display: flex;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.plx-room-rate-row:last-child {
  margin-bottom: 0;
}

.plx-room-rate-row-label {
  color: var(--text-primary);
  flex: 0 0 90px;
  font-weight: var(--weight-semibold);
  font-size: var(--text-md);
}
.plx-room-rate-current-label,
.plx-room-rate-new-label {
  font-weight: var(--weight-regular);
  font-size: var(--text-base);
}

.plx-room-rate-row-fields {
  display: grid;
  flex: 1;
  gap: var(--space-3);
  grid-template-columns: repeat(2, 1fr);
}

@media (max-width: 767.98px) {
  .plx-room-rate-row {
    align-items: stretch;
    flex-direction: column;
  }

  .plx-room-rate-row-label {
    flex-basis: auto;
  }
}

/* ---- Step 2 modals: responsive below 768px ----
   All row layouts that use fixed-width side-by-side items are stacked
   vertically at mobile so content stays readable and tappable inside
   a narrow modal dialog. No changes above 768px. */
@media (max-width: 767.98px) {
  /* Discount / Taxes: stack label/checkbox above the amount input so the
     input can fill the full modal body width instead of competing for
     space with a fixed-width box in a ≈310px content area. */
  .plx-charge-row {
    align-items: stretch;
    flex-direction: column;
    gap: var(--space-2);
  }

  .plx-charge-row-input,
  #plxTaxesModalJs .plx-charge-row-input {
    width: 100%;
  }

  /* Status Popover: JS can inject many room rows; cap the body height and
     let it scroll so the close button is never pushed off-screen. */
  #plxStatusPopoverModalJs .modal-body {
    max-height: 65vh;
    overflow-y: auto;
  }

  /* Room Rate: JS can inject one row per selected room; cap the body
     height and let it scroll when the rate list is long. */
  #plxRoomRateModalJs .modal-body {
    max-height: 55vh;
    overflow-y: auto;
  }
}

/* ---- Step 2 modals: mobile header spacing & status-card stacking ---- */
@media (max-width: 767.98px) {
  /* Bare-header modals (Discount / Taxes / Room Rate / Other Charges):
     add bottom padding to the close-button row so there is clear
     breathing room between the × and the first field in the body below. */
  #plxRoomRateModalJs .modal-header,
  #plxDiscountModalJs .modal-header,
  #plxTaxesModalJs .modal-header,
  #plxOtherChargesModalJs .modal-header {
    padding-bottom: var(--space-2);
  }

  /* Status Popover: close button is position:absolute at the top-right
     of the modal body — reserve explicit right clearance on the header
     container so the room title text cannot slide underneath the × on
     narrow viewports (28px button + var(--space-3) breathing gap). */
  .plx-popover-header {
    padding-right: calc(28px + var(--space-3));
  }

  /* Status card rows: stack the left-group (date/label text + sub-line)
     above the right element (pill badge or action button) instead of
     the desktop side-by-side layout, which runs out of horizontal room
     on phone-sized viewports. Applies to every .plx-popover-row variant
     (booked / tentative / partial / blocked / OTA / accent / success)
     since they all share .plx-popover-row-main. */
  .plx-popover-row-main {
    align-items: flex-start;
    flex-direction: column;
    gap: var(--space-2);
  }

  /* "Select This Slot" button: go full-width for a comfortable tap
     target; all other row-right elements (pills, plain text) size
     themselves naturally to their content. */
  .plx-popover-row-right .plx-btn {
    justify-content: center;
    width: 100%;
  }
}

/* ---- Success screen ---- */
/* --bg-card panel with a soft accent border — both sampled exactly off
   create-booking-5.png (#F4F4F6 / #E9EAFF); the white field tiles inside
   read as raised surfaces against it. */
.plx-booking-success-card {
  background: var(--bg-card);
  border: 1px solid var(--pm-accent-soft);
  border-radius: var(--radius-lg);
  margin-top: 20px;
  padding: 48px 32px 40px;
  text-align: center;
}

/* 88px circle (not 72px) with a soft green ambient shadow — pixel-matched
   against create-booking-5.png. Uses the plain check.svg (just the
   V-checkmark path, no starburst border) sized to 44px so it fills the
   circle proportionally. The rgba shadow value is the same green as
   --color-available (rgb 79, 177, 115). */
.plx-booking-success-icon {
  align-items: center;
  background: var(--bg-surface);
  border-radius: var(--radius-full);
  box-shadow: 0 6px 28px rgba(79, 177, 115, 0.30);
  color: var(--color-available);
  display: flex;
  height: 88px;
  justify-content: center;
  margin: 0 auto var(--space-5);
  width: 88px;
}

/* The check.svg has width="20" height="20" HTML attributes that browsers
   honour over CSS width/height rules even with !important on the svg element.
   transform:scale(2.2) on the wrapper span is the reliable fix: 20px × 2.2
   ≈ 44px visual size, centred by the parent flex container without fighting
   the SVG attribute system. Uses transform-origin:center so the scaling
   radiates from the exact middle of the circle. */
.plx-booking-success-icon .plx-icon {
  transform: scale(2.2);
  transform-origin: center;
}

.plx-booking-success-icon .plx-icon svg path {
  stroke-width: 2.5;
}

.plx-booking-success-title {
  color: var(--text-primary);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  line-height: 1.2;
  margin: 0;
}

.plx-booking-success-subtitle {
  color: var(--text-muted);
  font-size: var(--text-base);
  margin: var(--space-2) 0 var(--space-5);
}

.plx-booking-success-code {
  background: var(--bg-surface);
  border-color: var(--color-booked);
  border-radius: 8px;
  color: var(--color-booked);
  display: inline-flex;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  margin: 0 auto var(--space-6);
  padding: var(--space-2) var(--space-6);
}

.plx-booking-success-code::before {
  display: none;
}

.plx-booking-success-grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(2, 1fr);
  margin-bottom: var(--space-6);
  text-align: left;
}

@media (max-width: 575.98px) {
  .plx-booking-success-grid {
    grid-template-columns: 1fr;
  }
}

.plx-booking-success-field {
  background: var(--bg-surface);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4) var(--space-5);
}

/* --text-sm + --weight-medium (not xs/semibold/uppercase) — pixel-matched
   against create-booking-5.png, whose labels read as plain title-case text
   (e.g. "Guest Name", "Check-In") at a slightly smaller/lighter weight
   than the values below them, without the all-caps treatment the old rule
   applied. */
.plx-booking-success-label {
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.plx-booking-success-value {
  color: var(--text-primary);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
}

/* Two outlined buttons (Print Confirmation / View All Bookings) side by
   side, pixel-matched against create-booking-5.png — both share the same
   border/height/radius/gap treatment, with just their icons and labels
   differing. */
.plx-booking-success-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: center;
}

.plx-booking-success-btn {
  align-items: center;
  background: transparent;
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  cursor: pointer;
  display: inline-flex;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  gap: var(--space-2);
  height: 40px;
  padding: 0 var(--space-5);
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

/* The two actions carry distinct palettes in create-booking-5.png (sampled:
   neutral #EAEAEE/#B0B1C7 fill/border with --pm-primary ink vs lavender
   #F0F0F6/#B2B7F8 with --color-info ink), so each gets its own id-scoped
   colors below; icons inherit via currentColor. Focus stays on the global
   :focus-visible outline (base/utilities.css). */
#plxBookingPrintBtnJs {
  background: var(--border-default);
  border-color: var(--border-medium);
  color: var(--pm-primary);
}

#plxBookingPrintBtnJs:hover {
  border-color: var(--border-focus);
}

#plxBookingNewBtnJs {
  background: var(--pm-accent-light);
  border-color: var(--pm-accent);
  color: var(--color-info);
}

#plxBookingNewBtnJs:hover {
  background: var(--pm-accent-soft);
}

/* 16×16 for button icons (not the default 20/20 from the SVG attributes) —
   scales cleanly inside the 40px button height without crowding the text. */
.plx-booking-success-btn .plx-icon svg {
  height: 16px;
  width: 16px;
}

/* ---- Step 3: searchable country picker (Phone No. only) ----
   Scoped to .plx-phone-input-searchable (searchable-phone-input.blade.php)
   so the shared .plx-phone-input-country/-flag in components/forms.css —
   a static flag+code span used by every other phone field in the
   project — stays completely untouched. This picker uses a clickable
   button and an emoji flag instead of an <img>, pixel-matched against
   country-flag.png. */
.plx-phone-input-searchable .plx-input {
  padding-left: 84px;
}

.plx-phone-input-searchable .plx-phone-input-country {
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 0;
}

/* SVG flag (public/assets/svg/country-flags/, vendored from flag-icons —
   see searchable-phone-input.blade.php) instead of an emoji character, so
   sized as an image (4:3 source aspect ratio) rather than via font-size.
   country-picker.js swaps this <img>'s src on selection, no re-render of
   the whole button needed. */
.plx-phone-input-searchable .plx-phone-input-flag {
  border-radius: 2px;
  display: block;
  height: 14px;
  object-fit: cover;
  width: 18px;
}

.plx-phone-input-searchable .plx-phone-input-chevron {
  color: var(--text-muted);
  font-size: 12px;
}

.plx-country-dropdown {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  left: 0;
  margin-top: var(--space-2);
  max-height: 320px;
  position: absolute;
  top: 100%;
  width: max(280px, 100%);
  z-index: 20;
}

@media (max-width: 575.98px) {
  .plx-country-dropdown {
    width: min(320px, calc(100vw - var(--space-8)));
  }
}

.plx-country-dropdown-search {
  align-items: center;
  border-bottom: 1px solid var(--border-default);
  display: flex;
  flex-shrink: 0;
  gap: var(--space-2);
  padding: var(--space-3);
}

.plx-country-dropdown-search .plx-icon {
  color: var(--text-muted);
  flex-shrink: 0;
  font-size: 16px;
}

.plx-country-dropdown-search-input {
  background: transparent;
  border: 0;
  color: var(--text-primary);
  flex: 1;
  font-size: var(--text-sm);
  min-width: 0;
  outline: none;
}

.plx-country-dropdown-list {
  list-style: none;
  margin: 0;
  overflow-y: auto;
  padding: var(--space-2);
}

.plx-country-option {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: flex;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  text-align: left;
  transition: background-color var(--transition-fast);
  width: 100%;
}

.plx-country-option:hover {
  background: var(--bg-hover);
}

/* Keyboard focus — :focus-visible only (not plain :focus) so mouse
   clicks/selection don't show a ring, matching this project's other
   interactive-list conventions. */
.plx-country-option:focus-visible {
  background: var(--bg-hover);
  outline: 2px solid var(--outline-focus);
  outline-offset: -2px;
}

/* Currently-selected row (country-picker.js/bank-select.js set
   aria-selected when the dropdown opens) — the project-wide selected-row
   treatment, reading the same --select-selected-* tokens as
   .plx-select option:checked (components/forms.css). The color on the row
   covers plain-text options (bank picker); the name span sets it again
   because it otherwise carries its own --text-secondary. */
.plx-country-option[aria-selected="true"] {
  background: var(--select-selected-bg);
  color: var(--select-selected-text);
  font-weight: var(--weight-semibold);
}

.plx-country-option[aria-selected="true"] .plx-country-option-name {
  color: var(--select-selected-text);
  font-weight: var(--weight-semibold);
}

.plx-country-option-flag {
  border-radius: 2px;
  flex-shrink: 0;
  height: 14px;
  object-fit: cover;
  width: 18px;
}

/* --text-secondary (not -primary) — pixel-matched against
   country-flag.png; the native name in parens reads the exact same
   color as the country name, not a muted one, so it's inherited rather
   than set on .plx-country-option-native separately. */
.plx-country-option-name {
  color: var(--text-secondary);
  /* flex: 1; */
  font-size: var(--text-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.plx-country-option-dial {
  color: var(--text-muted);
  flex-shrink: 0;
  font-size: var(--text-sm);
}

.plx-country-dropdown-empty {
  color: var(--text-muted);
  font-size: var(--text-sm);
  padding: var(--space-5) var(--space-3);
  text-align: center;
}

/* ---- Payment step: searchable Receiving Bank select
   (searchable-bank-select.blade.php / bank-select.js) ----
   The dropdown panel reuses .plx-country-dropdown wholesale (above); only
   the trigger needs its own rules — a .plx-select-styled <button>, which
   inherits the select chrome (border, height, chevron) but not a native
   select's left-aligned text or pointer. */
.plx-bank-select {
  position: relative;
}

.plx-bank-select-trigger {
  cursor: pointer;
  text-align: left;
}

/* Placeholder tint until a bank is chosen — bank-select.js removes the
   attribute on selection, letting the trigger's own --text-primary show. */
.plx-bank-select-value[data-plx-bank-placeholder="true"] {
  color: var(--text-muted);
}
