/* POS System Styles */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --primary: #2196F3;
    --primary-dark: #1976D2;
    --secondary: #6c757d;
    --success: #4CAF50;
    --danger: #dc3545;
    --warning: #ff9800;
    --dark: #212529;
    --light: #f8f9fa;
    --border: #dee2e6;
    --shadow: 0 2px 4px rgba(0,0,0,0.1);
}

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    background: #1a1a2e;
    color: #fff;
    /* iPad Safari fix (2026-05-10): 100vh measures the FULL viewport including
       browser chrome that's actually visible (URL bar, bottom toolbar), so on
       iPad 10.9" landscape the lower buttons get pushed below the visible area.
       Dynamic viewport height (dvh) accounts for current chrome size; falls
       back to vh on older browsers. svh is the conservative pre-Safari-15.4
       hint. */
    height: 100vh;
    height: 100svh;
    height: 100dvh;
    overflow: hidden;
}

/* Container */
.pos-container {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100svh;
    height: 100dvh;
    /* Hard width clamp — nothing inside should ever push the container past
       the viewport. Pairs with body{overflow:hidden} and .pos-main grid to
       guarantee the right pane stays inside the visible area. */
    width: 100%;
    max-width: 100vw;
    overflow-x: hidden;
}

/* Header */
.pos-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 20px;
    background: #16213e;
    border-bottom: 1px solid #0f3460;
}

.header-left {
    display: flex;
    align-items: center;
    gap: 16px;
}

.header-left h1 {
    font-size: 20px;
    font-weight: 600;
    color: #fff;
}

.header-left .current-time {
    font-size: 14px;
    color: #aaa;
    margin-left: 20px;
}

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

.cashier-name {
    font-size: 14px;
    color: #aaa;
}

.btn-icon {
    background: transparent;
    border: none;
    color: #aaa;
    cursor: pointer;
    padding: 8px;
    border-radius: 4px;
    transition: all 0.2s;
}

.btn-icon:hover {
    background: rgba(255,255,255,0.1);
    color: #fff;
}

/* Main Layout */
.pos-main {
    display: flex;
    flex: 1;
    overflow: hidden;
    min-height: 0;
}

/* Left Panel */
.pos-left {
    flex: 1;
    /* min-width:0 lets the flex child shrink below its content's intrinsic
       width — without this, wide content (lagoon rows, calendar) pushes
       the parent past viewport and carries .pos-right off the right edge. */
    min-width: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    background: #1a1a2e;
    border-right: 1px solid #0f3460;
}

/* Category Tabs */
.category-tabs {
    display: flex;
    padding: 10px;
    gap: 8px;
    background: #16213e;
    border-bottom: 1px solid #0f3460;
    overflow-x: auto;
}

.tab-btn {
    padding: 10px 20px;
    border: none;
    background: transparent;
    color: #aaa;
    font-size: 14px;
    font-weight: 500;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s;
    white-space: nowrap;
}

.tab-btn:hover {
    background: rgba(255,255,255,0.1);
    color: #fff;
}

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

/* Quick Keys */
.quick-keys-container {
    flex: 1;
    overflow-y: auto;
    padding: 15px;
}

.quick-keys {
    display: grid;
    /* Bumped min from 140 → 160 so the session-type label, price, and
       direction info all fit on one row without crowding. */
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 12px;
}

.quick-key {
    /* Tile touch floor — was ~88-108px tall depending on content; pin
       the minimum so every tile reads at the same touch grade. */
    min-height: 88px;
    background: #16213e;
    border: 2px solid #0f3460;
    border-radius: 8px;
    padding: 16px 14px;
    text-align: center;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}

.quick-key:hover {
    background: #1f2b4a;
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}

.quick-key.session { border-left: 4px solid var(--primary); }
.quick-key.rental { border-left: 4px solid var(--success); }
.quick-key.pass { border-left: 4px solid var(--warning); }
.quick-key.cabana { border-left: 4px solid #e91e63; }
.quick-key.retail { border-left: 4px solid #9c27b0; }
/* Issues-RetailProductImages-001: product photo on the retail tile */
.quick-key-img { width: 100%; max-width: 150px; aspect-ratio: 1 / 1; margin: 0 auto 8px; border-radius: 6px; overflow: hidden; background: #0f1a33; }
.quick-key-img img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Issues-POSSessionGrey-001 / Issues-Rentals-003 parity: an unavailable tile
   (sold-out rental, request-only / unreleased session type) renders greyed-out
   + non-clickable with a red X badge so the operator sees it is not bookable
   UPFRONT rather than erroring after selecting it. The reason ("Request only" /
   "Sold out" / "Reserved") shows in .quick-key-info. */
.quick-key.disabled {
    opacity: 0.4;
    cursor: not-allowed;
    background: #2d2d2d;
    border-color: #5a2a2a;
    position: relative;
    pointer-events: none;
}
.quick-key.disabled:hover {
    transform: none;
    box-shadow: none;
    background: #2d2d2d;
}
.quick-key.disabled::after {
    content: '\2715';
    position: absolute;
    top: 6px;
    right: 8px;
    color: #e53935;
    font-size: 16px;
    font-weight: 700;
    line-height: 1;
}

/* Issues-PastTimePurchaseOverride-001: a session that already started IS still
   clickable (manager-override path, pos.js _addPastTimeSessionWithOverride) --
   .disabled alone sets pointer-events:none, which would silently swallow that
   click. Re-enable pointer events + swap the red X for an amber one so staff
   can tell "blocked" apart from "blocked, but overridable" at a glance. */
.quick-key.disabled.overridable {
    opacity: 0.65;
    cursor: pointer;
    pointer-events: auto;
    border-color: #7a5a1a;
}
.quick-key.disabled.overridable:hover {
    background: #3a331f;
}
.quick-key.disabled.overridable::after {
    content: '\26A0';
    color: var(--warning, #ff9800);
}

.quick-key-name {
    font-weight: 700;
    font-size: 15px;
    margin-bottom: 6px;
    color: #fff;
    line-height: 1.25;
}

.quick-key-price {
    /* Price was 16px — too quiet for the most important data on the tile. */
    font-size: 18px;
    font-weight: 700;
    color: var(--success);
}

.quick-key-info {
    /* Direction (Left/Right/Center) was 11px — at touch distance on a
       1024px terminal that's borderline unreadable. Bumped to 13px. */
    font-size: 13px;
    color: #aaa;
    margin-top: 6px;
}

.quick-key-spec {
    font-size: 12px;
    color: #6b7280;
    margin-top: 4px;
    line-height: 1.3;
}

/* POS Sessions picker — accordion behavior (2026-05-22).
   The lagoon + time panels collapse into a header-only chip after the
   operator picks a value, and the next step auto-expands. Tapping a
   collapsed header re-expands that step. The header always stays
   visible so the operator can jump back. Only ONE panel body is
   expanded at a time. */

/* All three accordion panels (Steps 1 / 2 / 3) share the same chrome —
   bg, padding, top divider, panel-level flex behavior. Per-section rules
   used to set background/padding individually and drifted; AutoQA 2026-05-24
   found 3 visual defects from that drift. Single source of truth here. */
.pos-acc-panel {
    background-color: #16213e;
    border-top: 1px solid #0f3460;
    /* Defect 4 fix: Steps 1 + 2 are content-sized chips. Step 3 overrides
       this back to flex:1 immediately below — same selector specificity
       wouldn't win (source order would prefer the .quick-keys-container
       rule earlier in this file), so the override uses a compound selector
       that bumps specificity to 0,2,0. */
    flex: 0 0 auto;
}

.pos-acc-panel.quick-keys-container {
    /* Step 3 is the destination tile grid — must claim remaining vertical
       space so the grid + lesson-toggle sit at the right anchor. Stays
       flex:1 even though the shared .pos-acc-panel rule wants 0 0 auto. */
    flex: 1 1 0%;
}

/* Defect 2 fix — collapsed strip height. With base padding 15px and no
   body content, the collapsed strip rendered ~51px tall (vs an expanded
   header strip's ~36px). Drop vertical padding when collapsed; horizontal
   padding stays so chevron + summary keep their right-edge anchor. */
.pos-acc-panel.acc-collapsed {
    padding-block: 8px;
}

.pos-acc-panel .pos-acc-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    cursor: pointer;
    user-select: none;
    padding: 0;
}

.pos-acc-panel .pos-acc-header h3 {
    /* Override the inherited `.session-selector h3 { margin-bottom: 10px }`
       and the .step-heading rule — the 10px below the h3 sneaks past the
       flex layout (cross-axis margin) and makes the collapsed chip 10px
       taller than its content, which read as a gap. */
    margin: 0 !important;
    flex: 0 0 auto;
}

.pos-acc-panel .pos-acc-header::after {
    content: '▾';
    font-size: 16px;
    color: #888;
    transition: transform 0.18s;
    margin-left: auto;
}

.pos-acc-panel.acc-collapsed .pos-acc-header::after {
    transform: rotate(-90deg);
}

.pos-acc-panel .acc-summary {
    flex: 1 1 auto;
    text-align: right;
    color: var(--primary, #4361ee);
    font-weight: 700;
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pos-acc-panel .pos-acc-body {
    margin-top: 12px;
    transition: opacity 0.18s;
}

.pos-acc-panel.acc-collapsed .pos-acc-body {
    display: none;
}

/* AUTO-Admi-POS-PICKER-HEADER-NORMALIZE-STEP3-ACCORDION (2026-05-24):
   The earlier `padding: 10px 15px` override on collapsed panels made
   Step 2's chip tighter than Step 1/3's expanded body, creating an
   asymmetric look. WO author wants uniform `padding: 15px` across all
   three panels regardless of collapsed/expanded state — the chevron
   rotation + the chip's smaller content height already telegraph the
   collapsed state without a padding shift. */

/* When a panel collapses, the next sibling should sit closer to it — the
   default 15px-top padding combined with the collapsed chip's bottom
   padding reads as a gap. After the 2026-05-24 hoist of #sessionSelector
   out of #posSessionsPicker, all three picker steps are direct siblings,
   so a single + selector catches every adjacency. */
.pos-acc-panel.acc-collapsed + .pos-acc-panel {
    /* No double border between adjacent collapsed chips. */
    border-top-color: transparent;
}

/* AUTO-Admi-035: Sessions-tab guided picker — Lagoon selector (step 1).
   Background + border-top now live on .pos-acc-panel (single source of
   truth). Only padding stays here as the shared base size. */
.lagoon-selector {
    padding: 15px;
}

.lagoon-selector h3,
.session-selector h3,
.step-heading {
    font-size: 14px;
    /* margin removed (was 0 0 10px). The header lives inside .pos-acc-header
       which already zeroes h3 margins; the body's margin-top:12px handles
       spacing below. Bottom margin here was redundant and made the
       collapsed chip taller than the chevron column. */
    margin: 0;
    color: #aaa;
    font-weight: 700;
}

.lagoon-buttons {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.lagoon-btn {
    flex: 1;
    min-width: 120px;
    /* Touch-target floor per Apple HIG (44pt ≈ 58px). Was 41.5px tall. */
    min-height: 58px;
    padding: 14px 18px;
    background: #1a1a2e;
    color: #fff;
    border: 2px solid #0f3460;
    border-radius: 8px;
    font-weight: 600;
    font-size: 15px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.lagoon-btn:hover {
    background: #233057;
}

.lagoon-btn.active {
    background: var(--primary, #4361ee);
    border-color: var(--primary, #4361ee);
    /* Stronger selected-state contrast — the old version only changed
       background, which was easy to miss on the dark theme. */
    box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.25);
}

/* Lesson attach (step 4) */
.lesson-toggle {
    background: #16213e;
    padding: 12px 15px;
    border-top: 1px solid #0f3460;
}

.lesson-toggle label {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #fff;
    font-weight: 600;
    cursor: pointer;
    font-size: 14px;
}

.lesson-toggle small {
    display: block;
    color: #888;
    font-size: 11px;
    margin-top: 4px;
    margin-left: 24px;
}

/* Session Selector — background + border-top now on .pos-acc-panel. */
.session-selector {
    padding: 15px;
}

.session-selector h3 {
    font-size: 14px;
    margin-bottom: 10px;
    color: #aaa;
}

.date-picker {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 15px;
}

.date-picker input[type="date"] {
    flex: 1;
    /* Match touch-target floor with the arrows. Was 33.5px tall. */
    min-height: 58px;
    padding: 14px 16px;
    background: #1a1a2e;
    border: 2px solid #0f3460;
    border-radius: 8px;
    color: #fff;
    font-size: 15px;
    font-weight: 600;
}

.date-nav {
    /* Square 58×58 button — was ~33×33.5. */
    min-width: 58px;
    min-height: 58px;
    padding: 14px 18px;
    background: #1a1a2e;
    border: 2px solid #0f3460;
    border-radius: 8px;
    color: #fff;
    font-size: 18px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.date-nav:hover {
    background: #0f3460;
    border-color: var(--primary, #4361ee);
}

.session-times {
    display: grid;
    /* Bumped min from 100 → 120 so each slot has touch-room.
       Removed max-height/overflow-y so all 13 hourly slots wrap into rows
       and stay visible without a vertical scroll inside the panel. */
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 10px;
}

.session-time {
    /* Touch-target floor 58px (was ~68px which was ok, but padding bump
       gives more breathing room around the time + availability rows). */
    min-height: 64px;
    padding: 14px 12px;
    background: #1a1a2e;
    border: 2px solid #0f3460;
    border-radius: 8px;
    text-align: center;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.session-time:hover {
    background: #0f3460;
    border-color: var(--primary, #4361ee);
}

.session-time.selected {
    background: var(--primary);
    border-color: var(--primary);
    /* Match lagoon-btn.active ring so selected-state reads consistently. */
    box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.25);
}

.session-time.full {
    opacity: 0.4;
    cursor: not-allowed;
    background: #2d2d2d;
    border-color: #5a2a2a;
    /* Issues-POSSessionGrey-001: unbookable time tiles (FULL or request-only /
       unreleased / buyout) render greyed with a red X badge upfront -- mirroring
       the customer-site rental treatment (Issues-Rentals-003) -- instead of
       erroring on select. pointer-events:none belts the no-click intent. */
    position: relative;
    pointer-events: none;
}
.session-time.full::after {
    content: '\2715';
    position: absolute;
    top: 5px;
    right: 8px;
    color: #e53935;
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
}

.session-time .time {
    font-weight: 700;
    font-size: 16px;
}

.session-time .availability {
    font-size: 12px;
    color: #aaa;
    margin-top: 4px;
}

.session-time.selected .availability {
    color: rgba(255,255,255,0.8);
}

/* Right Panel */
.pos-right {
    width: 400px;
    /* flex-shrink:0 pins the right pane at 400px so .pos-left absorbs all
       viewport shrinkage. Pair with min-width:0 on .pos-left above. */
    flex-shrink: 0;
    min-width: 0;
    /* Issues-POSStoreCreditClip-001: keep horizontal clipping, but let the
       checkout column scroll vertically. When the optional Store Credit panel
       (+ redeem panel + pay buttons) is shown the footer can exceed a short
       viewport; overflow:hidden was clipping the store-credit card off-screen.
       overflow-y:auto makes it reachable instead of cut off. */
    overflow-x: hidden;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    background: #16213e;
}

/* Customer Section */
.customer-section {
    padding: 15px;
    border-bottom: 1px solid #0f3460;
}

.customer-search {
    display: flex;
    gap: 10px;
}

.customer-search input {
    flex: 1;
    padding: 10px 12px;
    background: #1a1a2e;
    border: 1px solid #0f3460;
    border-radius: 4px;
    color: #fff;
    font-size: 14px;
}

.customer-search input::placeholder {
    color: #666;
}

.btn-small {
    padding: 10px 15px;
    background: var(--primary);
    border: none;
    border-radius: 4px;
    color: #fff;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}

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

.customer-info {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    margin-top: 10px;
    padding: 10px;
    background: #1a1a2e;
    border-radius: 6px;
}
/* POS-CUSTOMER-PROFILE-001: #customerProfile (Surfer Info) and #customerNotes
   (Staff Log) are large, variable-length content panels living as flex ITEMS
   of .customer-info alongside the name/Edit/Staff-Log/Clear row. Without
   flex-wrap above, a long note/profile forced the whole row wider (flex
   items default to shrink-resist their content's natural width) instead of
   wrapping — this pins them to their own full-width row once wrapped, and
   constrains their own growth independently below. */
.customer-info > .customer-profile,
.customer-info > .customer-notes {
    flex: 1 1 100%;
    min-width: 0;
}
/* Surfer Info had no height cap at all (unlike the notes list below, which
   already scrolls at 140px) — long experienceNotes/medical/emergency text
   grew the whole module vertically without bound. Match the notes list's
   existing pattern instead of introducing a new one. */
.customer-profile {
    max-height: 160px;
    overflow-y: auto;
    overflow-wrap: break-word;
    word-break: break-word;
}
/* A single long unbroken token (a URL, a run-on paste) in a staff note could
   still force the row wider even with flex-wrap above, since normal text
   flow doesn't break mid-word by default. */
#customerNotesList,
#customerNotesList > div {
    overflow-wrap: break-word;
    word-break: break-word;
}

.customer-details {
    display: flex;
    flex-direction: column;
    gap: 3px;
    /* POS-CUSTOMER-PROFILE-001 (found in deep-debug pass): same overflow class
       as the Staff Log / Surfer Info panels, but via the name/email column —
       it's a flex item of .customer-info too and defaults to shrink-resist
       its content's natural width without min-width:0. */
    min-width: 0;
}

.customer-details strong {
    font-size: 14px;
    overflow-wrap: break-word;
    word-break: break-word;
}

.customer-details span {
    font-size: 12px;
    color: #888;
    overflow-wrap: break-word;
    word-break: break-word;
}

.membership-badge {
    display: inline-block;
    padding: 2px 8px;
    background: linear-gradient(135deg, #ffd700, #ff9800);
    color: #000;
    border-radius: 10px;
    font-size: 10px;
    font-weight: 600;
    margin-top: 3px;
}

.btn-text {
    background: none;
    border: none;
    color: var(--primary);
    font-size: 13px;
    cursor: pointer;
}

/* POS-CUSTOMER-PROFILE-001: Clear detaches the customer from the sale — it
   does not delete their record, but it's easy to hit by accident sitting
   flush against Edit/Staff Log. Push it to the far right of the row
   (margin-left:auto, same flex row) and give it a warning color so it reads
   as a distinct, secondary action rather than routine profile editing. */
.btn-text-danger {
    margin-left: auto;
    color: #dc2626;
}
.btn-text-danger:hover {
    color: #b91c1c;
}

.btn-text:hover {
    text-decoration: underline;
}

.customer-results {
    margin-top: 10px;
    max-height: 200px;
    overflow-y: auto;
    background: #1a1a2e;
    border-radius: 6px;
}

.customer-result {
    padding: 10px;
    border-bottom: 1px solid #0f3460;
    cursor: pointer;
    transition: all 0.2s;
}

.customer-result:hover {
    background: #0f3460;
}

.customer-result:last-child {
    border-bottom: none;
}

/* Cart Section */
.cart-section {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Issues-POSStoreCreditClip-001: allow the cart list to yield height to the
       totals / store-credit / pay footer so the footer is never clipped (the
       cart list keeps its own inner overflow-y:auto). */
    min-height: 0;
}

.cart-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 15px;
    background: #0f3460;
}

.cart-header span {
    font-weight: 600;
    font-size: 14px;
}

.cart-items {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
}

.empty-cart {
    text-align: center;
    color: #666;
    padding: 40px;
    font-size: 14px;
}

.cart-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px;
    background: #1a1a2e;
    border-radius: 6px;
    margin-bottom: 8px;
}

.cart-item-info {
    flex: 1;
    /* min-width:0 lets this flex column shrink below its content width so a
       long session/product name wraps instead of forcing the whole row wide
       (which used to trigger the horizontal scrollbar in Current Sale). */
    min-width: 0;
}

.cart-item-name {
    font-weight: 500;
    font-size: 14px;
    margin-bottom: 3px;
    /* wrap long names within the column rather than overflowing the row */
    overflow-wrap: anywhere;
    word-break: break-word;
}

.cart-item-details {
    font-size: 12px;
    color: #888;
}

/* qty selector + line total stacked vertically so the row stays narrow
   (owner request 2026-08-16 — dollar amount now sits under the qty stepper). */
.cart-item-qtyprice {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    margin: 0 10px;
    flex-shrink: 0;
}

.cart-item-qty {
    display: flex;
    align-items: center;
    gap: 8px;
}

.qty-btn {
    width: 28px;
    height: 28px;
    background: #0f3460;
    border: none;
    border-radius: 4px;
    color: #fff;
    font-size: 16px;
    cursor: pointer;
    transition: all 0.2s;
}

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

.cart-item-qty span {
    min-width: 20px;
    text-align: center;
    font-weight: 600;
}

.cart-item-price {
    font-weight: 600;
    font-size: 14px;
    color: var(--success);
    text-align: center;
    white-space: nowrap;
}

.cart-item-remove {
    background: none;
    border: none;
    color: #666;
    cursor: pointer;
    padding: 5px;
    margin-left: 10px;
}

.cart-item-remove:hover {
    color: var(--danger);
}

/* Totals Section */
.totals-section {
    padding: 15px;
    background: #0f3460;
}

.total-row {
    display: flex;
    justify-content: space-between;
    padding: 8px 0;
    font-size: 14px;
    color: #aaa;
}

.total-grand {
    font-size: 20px;
    font-weight: 700;
    color: #fff;
    padding-top: 12px;
    margin-top: 8px;
    border-top: 1px solid #1a1a2e;
}

/* Action Buttons */
.action-buttons {
    padding: 15px;
    background: #16213e;
}

.secondary-actions {
    display: grid;
    /* 2 columns is the right density for the 320-400px right pane:
       7 buttons × 2 cols = 4 rows (last row has 1 button). Each button
       is ~180px wide at the 400px pane — comfortable for "Tax Exempt"
       / "Find Sale" labels on one line. Earlier 4-column layout was a
       relic from a wider pane and made buttons cramped at every size. */
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-bottom: 10px;
}
.secondary-actions > .btn-secondary {
    min-width: 0;
    /* Truncate with ellipsis if a label is ever too long — better than
       growing the button vertically. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.btn-secondary {
    padding: 12px;
    background: #1a1a2e;
    border: 1px solid #0f3460;
    border-radius: 6px;
    color: #fff;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}

.btn-secondary:hover {
    background: #0f3460;
}

.primary-actions {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 10px;
}
/* Same min-width:0 guard as .secondary-actions so the Cash / Card / COMP
   buttons can shrink (rather than force the parent wider) when the pane
   is narrow. */
.primary-actions > .btn-pay { min-width: 0; }

.btn-pay {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 20px;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
}

.btn-pay.cash {
    background: linear-gradient(135deg, #4CAF50, #2e7d32);
    color: #fff;
}

.btn-pay.card {
    background: linear-gradient(135deg, #2196F3, #1565c0);
    color: #fff;
}

.btn-pay:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}

.pay-icon {
    font-size: 24px;
}

/* Modals */
.modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0,0,0,0.7);
    z-index: 1000;
    align-items: center;
    justify-content: center;
}

/* ISSUES-REFUND-002: posManagerApprove() (pos.js) opens #approverModal WITHOUT
   hiding whichever modal is already open underneath it (Rapid Refund, and every
   other money-sensitive action that requires manager sign-off -- tax-exempt,
   comp payment, etc. all share this same approval modal). Every .modal shares
   the SAME z-index above, so with two modals simultaneously .active, plain DOM
   order decided which one painted on top -- and #approverModal is declared
   EARLIER in index.html than #refundModal, so Rapid Refund's own backdrop was
   rendering OVER the approval form, making its real Cancel/Approve buttons
   completely unclickable (confirmed live: elementFromPoint() at their on-screen
   position hit #refundModal, not the approver buttons underneath) while a
   second, correctly-clickable "Cancel"/"Approve" pair from the HIDDEN modal
   still visually peeked out at the bottom edge -- exactly the kind of stacked,
   near-identical button pair an operator could misclick under time pressure,
   which is the most likely mechanism behind "Cancel unexpectedly processes the
   refund". Pin #approverModal permanently above every other modal so it's
   always the one actually on top and actually clickable, regardless of DOM
   order or which modal opened it. */
#approverModal {
    z-index: 1100;
}

.modal.active {
    display: flex;
}

.modal-content {
    background: #16213e;
    border-radius: 12px;
    width: 90%;
    max-width: 500px;
    max-height: 90vh;
    overflow-y: auto;
}

.modal-content.modal-small {
    max-width: 400px;
}

.modal-content.modal-large {
    max-width: 600px;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px;
    border-bottom: 1px solid #0f3460;
}

.modal-header h2 {
    font-size: 18px;
    font-weight: 600;
}

.modal-close {
    background: none;
    border: none;
    color: #888;
    font-size: 24px;
    cursor: pointer;
}

.modal-close:hover {
    color: #fff;
}

.modal-body {
    padding: 20px;
}

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 20px;
    border-top: 1px solid #0f3460;
}

.btn-primary {
    padding: 12px 24px;
    background: var(--primary);
    border: none;
    border-radius: 6px;
    color: #fff;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}

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

/* Form Elements */
.form-group {
    margin-bottom: 15px;
}

.form-group label {
    display: block;
    margin-bottom: 5px;
    font-size: 13px;
    color: #aaa;
}

.form-group input,
.form-group select {
    width: 100%;
    padding: 10px 12px;
    background: #1a1a2e;
    border: 1px solid #0f3460;
    border-radius: 4px;
    color: #fff;
    font-size: 14px;
}

.form-group input:focus,
.form-group select:focus {
    outline: none;
    border-color: var(--primary);
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 15px;
}

/* Payment Modal Specific */
.payment-amount {
    text-align: center;
    padding: 20px;
    background: #1a1a2e;
    border-radius: 8px;
    margin-bottom: 20px;
}

.payment-amount span:first-child {
    display: block;
    font-size: 14px;
    color: #888;
    margin-bottom: 5px;
}

.payment-amount .amount {
    font-size: 36px;
    font-weight: 700;
    color: var(--success);
}

.quick-cash-buttons {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    margin-top: 15px;
}

.quick-cash-buttons button {
    padding: 12px;
    background: #1a1a2e;
    border: 1px solid #0f3460;
    border-radius: 6px;
    color: #fff;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}

.quick-cash-buttons button:hover {
    background: #0f3460;
}

.change-due {
    display: flex;
    justify-content: space-between;
    padding: 15px;
    background: var(--success);
    border-radius: 8px;
    margin-top: 20px;
    font-size: 18px;
    font-weight: 600;
}

.card-terminal-status {
    text-align: center;
    padding: 30px;
}

.terminal-icon {
    margin-bottom: 15px;
    color: var(--primary);
}

.terminal-waiting {
    color: #888;
    font-size: 14px;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

/* Discount Modal */
.discount-type-toggle {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.toggle-btn {
    flex: 1;
    padding: 12px;
    background: #1a1a2e;
    border: 1px solid #0f3460;
    border-radius: 6px;
    color: #fff;
    font-size: 14px;
    cursor: pointer;
    transition: all 0.2s;
}

.toggle-btn.active {
    background: var(--primary);
    border-color: var(--primary);
}

/* Tip Modal */
.tip-buttons {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}

.tip-btn {
    padding: 20px;
    background: #1a1a2e;
    border: 1px solid #0f3460;
    border-radius: 8px;
    color: #fff;
    font-size: 18px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
}

.tip-btn:hover {
    background: var(--warning);
    border-color: var(--warning);
}

/* Receipt Modal */
.receipt-success {
    text-align: center;
    padding: 30px;
}

.success-icon {
    width: 60px;
    height: 60px;
    background: var(--success);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 30px;
    margin: 0 auto 15px;
}

.receipt-success h3 {
    font-size: 20px;
    margin-bottom: 5px;
}

.receipt-options {
    display: flex;
    justify-content: center;
    gap: 15px;
    margin-top: 20px;
}

.receipt-options button {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Parked Sales */
.parked-sales-list {
    max-height: 400px;
    overflow-y: auto;
}

.parked-sale-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px;
    background: #1a1a2e;
    border-radius: 8px;
    margin-bottom: 10px;
    cursor: pointer;
    transition: all 0.2s;
}

.parked-sale-item:hover {
    background: #0f3460;
}

.parked-sale-info h4 {
    font-size: 14px;
    margin-bottom: 5px;
}

.parked-sale-info p {
    font-size: 12px;
    color: #888;
}

.parked-sale-total {
    font-size: 16px;
    font-weight: 600;
    color: var(--success);
}

.empty-message {
    text-align: center;
    color: #666;
    padding: 40px;
}

/* Scrollbar */
::-webkit-scrollbar {
    width: 6px;
}

::-webkit-scrollbar-track {
    background: #1a1a2e;
}

::-webkit-scrollbar-thumb {
    background: #0f3460;
    border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--primary);
}

/* Responsive */
@media (max-width: 1024px) {
    .pos-main {
        flex-direction: column;
    }
    .pos-left {
        flex: none;
        height: 50%;
    }
    .pos-right {
        width: 100%;
        flex: 1;
        flex-shrink: 1;
    }
}

/* POSSessionScroll-001: small/low-res laptops + tablets squeezed Step 3
   (session type) into a blank, unscrollable sliver. min-height:0 lets the flex
   chain shrink so the panel's overflow-y:auto works; on short viewports the whole
   builder column scrolls with Step 3 content-sized so every type is reachable. */
.pos-left { min-height: 0; }
.pos-acc-panel.quick-keys-container { min-height: 0; }

@media (max-height: 900px) {
    .pos-left { overflow-y: auto; overflow-x: hidden; }
    /* SELENA-SessionBuilderOrder-001 (D2): was `overflow: visible`, which let the
       content-sized type grid SPILL out of a shrunk panel and paint over the coach
       row below. Contain it — the panel is content-sized (flex 0 0 auto below) so
       the host column scrolls; this is just belt-and-suspenders against any spill. */
    .pos-acc-panel.quick-keys-container { flex: 0 0 auto; overflow-y: auto; overflow-x: hidden; }
}

/* Issues-POSSessionExtras-001 (owner 2026-08-19): the inline rentals rail must
   never squeeze the session-type panel into looking collapsed. The expanded
   panel keeps a working height (its grid scrolls inside it) and the host
   column — which already has overflow-y:auto — scrolls instead. */
.quick-keys-container:not(.acc-collapsed) {
    /* Owner 2026-08-19 follow-up: flex:1 made the open panel STRETCH to fill
       the whole column even when nearly empty — an oversized white card in
       the light theme. Hug the content instead (still never below 180px,
       never squeezable); long grids grow and the column scrolls.
       SELENA-SessionBuilderOrder-001 (D2): flex-shrink was 1 (`0 1 auto`), which
       let the panel collapse to the 180px floor while its grid stayed 328px —
       combined with the short-viewport `overflow:visible` the grid spilled over
       the coach row. flex-shrink:0 keeps the panel content-sized on every
       viewport; the host column (overflow-y:auto) scrolls when it's tall. */
    flex: 0 0 auto;
    /* Issues-POSSessionTypeSpacing-002: 300px left ~92px of dead blank space
       below the grid whenever a slot had only a handful of session types
       (a common case, not an edge case) — the "hug content" fix above still
       lost to this leftover fixed floor. 180px still comfortably clears the
       ORIGINAL squeeze bug this floor exists for (Issues-POSSessionExtras-001:
       the panel was squeezed toward near-zero, not merely "smaller than 300"),
       while being close enough to one row's natural height that it rarely
       binds in the common case. Measured live: a 3-tile row now leaves
       ~0-30px below the grid (varies with tile content) instead of ~92px. */
    min-height: 180px;
}

/* Owner 2026-08-19: a COLLAPSED type panel must give its height back — it kept
   flex:1 with a hidden body, stretching an empty box over the column (the
   'lot of unused blank space'). Collapsed = shrink to the header strip. */
.quick-keys-container.acc-collapsed {
    flex: 0 0 auto;
    min-height: 0;
}

/* SELENA-SessionBuilderOrder-001 (D1): in the SESSION BUILDER the intended step
   order is Lagoon (1) -> Session type (2) -> Day & time (3), but #quickKeysContainer
   (the Session type panel) is ALSO the rentals/retail product grid and must stay
   AFTER the rental-window controls in the DOM — so it physically sits below
   #sessionSelector ("3. Day & time"), making the panels read 1 -> 3 -> 2.
   We reorder VISUALLY with flexbox instead of moving the shared node. The
   `builder-type-first` class is toggled onto .pos-left-host by selectCategory()
   ONLY on the Sessions tab, so Rentals/Retail keep their natural DOM order (the
   grid stays after the rental controls). Rental-only panels are display:none in
   this mode, so they drop out of the flex flow and don't need an order. */
.pos-left-host.builder-type-first > #rsCustomerHub         { order: 1; }
.pos-left-host.builder-type-first > #rsRegisterGate        { order: 1; }
.pos-left-host.builder-type-first > #posSessionsViewToggle { order: 2; }
.pos-left-host.builder-type-first > #lagoonSelector        { order: 3; }
.pos-left-host.builder-type-first > #quickKeysContainer    { order: 4; }  /* Session type — hoisted above Day & time */
.pos-left-host.builder-type-first > #sessionSelector       { order: 5; }  /* Day & time */
.pos-left-host.builder-type-first > #lessonToggle          { order: 6; }
.pos-left-host.builder-type-first > #extrasRentals         { order: 7; }
.pos-left-host.builder-type-first > #posSessionCalendar    { order: 8; }

/* ── POS Session Finder (Step 2: type chips × mini calendar; Step 3: grouped results) ── */
/* #quickKeys (.quick-keys) and #sessionTimes (.session-times) are CSS grids with
   auto-fill 160px / 120px tracks, so anything the finder appends would land in ONE
   narrow column (and each day header / results block in its own cell). Span the row.
   The .empty-message rules are scoped to those two hosts so other pages are unaffected. */
.sf-wrap,
.sf-day-header,
.sf-results,
.sf-error,
#quickKeys > .empty-message,
#sessionTimes > .empty-message { grid-column: 1 / -1; }
.sf-wrap { display:flex; gap:16px; align-items:flex-start; flex-wrap:wrap; }
.sf-types { flex:1 1 220px; display:flex; flex-wrap:wrap; gap:8px; align-content:flex-start; }
.sf-cal { flex:2 1 360px; }
.sf-col-title { flex-basis:100%; font-size:11px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; color:#6b7280; margin:0 0 4px; }
.sf-chip { display:inline-flex; align-items:center; gap:8px; padding:8px 12px; border:1px solid #d1d5db; border-radius:999px; background:#fff; font-family:inherit; font-size:14px; cursor:pointer; }
.sf-chip.selected { border-color:#16213e; background:#16213e; color:#fff; }
.sf-chip.dim { opacity:.45; }
.sf-chip-all { border-style:dashed; font-weight:700; }
.sf-chip-all.selected { border-style:solid; }
.sf-chip-count { font-size:12px; padding:1px 7px; border-radius:999px; background:rgba(0,0,0,.08); }
.sf-chip.selected .sf-chip-count { background:rgba(255,255,255,.22); }
.sf-month { margin-bottom:10px; }
.sf-month-title { font-weight:600; font-size:13px; margin:4px 0; }
/* POS-SESSION-DATES-001 — real month navigation, so widening the booking window doesn't
   dump 18 months of grids into one unpaginated scroll (renderCalendar() now shows ONE
   month at a time, lazily fetched as the operator navigates). */
.sf-cal-nav { display:flex; align-items:center; gap:8px; margin-bottom:8px; }
.sf-cal-nav-btn { padding:6px 10px; border:1px solid #d1d5db; border-radius:6px; background:#fff; font-family:inherit; font-size:14px; cursor:pointer; min-height:32px; }
.sf-cal-nav-btn:hover:not(:disabled) { background:#f3f4f6; }
.sf-cal-nav-btn:disabled { opacity:.35; cursor:not-allowed; }
.sf-cal-nav select { flex:1; padding:6px 8px; border:1px solid #d1d5db; border-radius:6px; background:#fff; font-family:inherit; font-size:13px; }
.sf-grid { display:grid; grid-template-columns:repeat(7, 1fr); gap:3px; }
.sf-dow { font-size:10px; text-align:center; color:#9ca3af; }
.sf-day { position:relative; min-height:40px; border:1px solid #e5e7eb; border-radius:6px; background:#fff; cursor:pointer; padding:3px 2px; display:flex; flex-direction:column; align-items:center; font-family:inherit; font-size:13px; }
.sf-day.blank { border:none; background:transparent; }
.sf-day.disabled { opacity:.25; cursor:default; }
.sf-day.dim { color:#9ca3af; }
.sf-day-count { font-size:10px; color:#2563eb; }
.sf-day.dim .sf-day-count { color:#9ca3af; }
.sf-day.in-range { background:#dbeafe; border-color:#93c5fd; }
.sf-day.start, .sf-day.end { background:#16213e; color:#fff; border-color:#16213e; }
.sf-day.start .sf-day-count, .sf-day.end .sf-day-count { color:#bfdbfe; }
.sf-day.excluded { background:#fff; color:#9ca3af; text-decoration:line-through; border-style:dashed; }
.sf-cal-foot { display:flex; justify-content:space-between; align-items:center; gap:8px; margin-top:6px; }
.sf-hint { font-size:12px; color:#6b7280; }
.sf-clear { padding:5px 10px; font-size:12px; }
.sf-day-header { font-weight:700; font-size:13px; margin:12px 0 6px; padding-bottom:4px; border-bottom:1px solid #e5e7eb; }
.sf-results { display:grid; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); gap:8px; }
.sf-error { flex-basis:100%; color:#b91c1c; font-size:12px; margin:0 0 6px; }
.sf-retry { color:#2563eb; text-decoration:underline; cursor:pointer; }
@media (max-width: 900px) { .sf-wrap { flex-direction:column; } .sf-cal { flex-basis:auto; width:100%; } }

/* POS Session Finder: sessions already in the cart (dev.zintarweb 2026-08-27) */
.quick-key.session.in-cart { border-color: var(--success, #16a34a); box-shadow: inset 0 0 0 2px var(--success, #16a34a); }
.sf-incart-badge { position:absolute; top:6px; right:6px; padding:2px 7px; border-radius:999px; background: var(--success, #16a34a); color:#fff; font-size:10px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; pointer-events:none; }

/* Issues-POSDiscountModal-001: manager approval on the Apply Discount page */
.disc-approve { margin-top: 14px; padding-top: 12px; border-top: 1px solid rgba(148,163,184,.3); }
.disc-approve-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: #94a3b8; margin-bottom: 8px; }
.disc-band { margin-bottom: 4px; }
.disc-band input { border-style: dashed; }
.disc-band small { display: block; margin-top: 4px; font-size: 12px; color: #94a3b8; }
.disc-login-toggle { background: none; border: none; padding: 8px 0; margin: 4px 0; font: inherit; font-size: 13px; color: var(--primary, #2196F3); text-decoration: underline; cursor: pointer; }
