/**
 * Schedule Booking View — Grid-based court availability
 * Time rows (left) x Court columns (top) schedule grid
 *
 * Follows the "Athletic Precision" design system tokens
 * from booking-wizard.css (:root --wiz-* variables).
 */

/* ============ Design Tokens (Schedule-specific) ============ */
:root {
    /* Shared design tokens (same as booking-wizard.css, repeated for self-containment) */
    --wiz-font: 'Outfit', -apple-system, BlinkMacSystemFont, sans-serif;
    --wiz-primary: #4f46e5;
    --wiz-border: #e2e8f0;
    --wiz-text: #0f172a;
    --wiz-text-secondary: #64748b;
    --wiz-surface: #ffffff;
    --wiz-surface-raised: #f8fafc;
    --wiz-ease: cubic-bezier(0.4, 0, 0.2, 1);

    /* Cell state colors — aligned with Tailwind palette */
    --sched-open-bg: #ecfdf5;           /* green-50 */
    --sched-open-border: #a7f3d0;       /* green-200 */
    --sched-open-hover: #d1fae5;        /* green-100 */
    --sched-open-text: #15803d;         /* green-700 */

    --sched-selected-bg: #e0e7ff;       /* indigo-100 */
    --sched-selected-border: #a5b4fc;   /* indigo-300 */
    --sched-selected-text: #3730a3;     /* indigo-800 */
    --sched-selected-shadow: rgba(79, 70, 229, 0.25);

    --sched-booked-bg: #f3f4f6;         /* gray-100 */
    --sched-booked-border: #e5e7eb;     /* gray-200 */
    --sched-booked-text: #9ca3af;       /* gray-400 */

    --sched-past-bg: #f9fafb;           /* gray-50 */
    --sched-past-border: #f3f4f6;       /* gray-100 */
    --sched-past-text: #d1d5db;         /* gray-300 */

    /* Shared — sized to mirror dashboard's compact pill cells */
    --sched-cell-min-h: 32px;
    --sched-cell-pad: 0.375rem 0.5rem;
    /* Sized for the widest label at the range's stepped-down type
       ("11 AM - 12 PM"); the axis needs even less. */
    --sched-time-col-w: 100px;
}

/* ============ Grid Container ============ */
.schedule-grid {
    position: relative;
    overflow-x: auto;
    border: 1px solid var(--wiz-border);
    border-radius: var(--wiz-radius-md);
    background-color: var(--wiz-surface);
    -webkit-overflow-scrolling: touch;
}

/* Current-time indicator (only when viewing today) */
.schedule-now-indicator {
    position: absolute;
    left: 0;
    right: 0;
    height: 2px;
    background: #ef4444;
    z-index: 8;
    pointer-events: none;
}

.schedule-now-dot {
    position: absolute;
    left: 76px;
    top: -4px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #ef4444;
}

.schedule-grid table {
    width: 100%;
    min-width: 600px;
    border-collapse: collapse;
    table-layout: fixed;
}

/* ============ Header (Court Columns) ============ */
.schedule-grid thead {
    background-color: #f8fafc; /* slate-50 */
}

.schedule-grid th {
    position: sticky;
    top: 0;
    z-index: 10;
    background-color: #f8fafc; /* slate-50 — matches thead */
    border-bottom: 2px solid #cbd5e1; /* slate-300 — stronger separator */
    padding: 0.75rem 0.5rem;
    text-align: center;
    font-family: var(--wiz-font);
    font-size: 0.8125rem;
    font-weight: 600;
    color: #475569; /* slate-600 */
    white-space: nowrap;
    text-transform: uppercase;
    letter-spacing: 0.025em;
}

/* Time column header */
.schedule-grid thead th.time-col {
    background-color: #f1f5f9; /* slate-100 — slightly darker for corner */
    color: #64748b; /* slate-500 */
    text-align: center;
    border-right: 2px solid #cbd5e1; /* slate-300 — matches bottom border */
}

.schedule-grid th .court-name {
    display: block;
    font-weight: 700;
    color: #1e293b; /* slate-800 */
    line-height: 1.3;
    font-size: 0.8125rem;
    text-transform: none;
    letter-spacing: normal;
}

.schedule-grid th .court-type {
    display: block;
    font-size: 0.6875rem;
    font-weight: 500;
    color: #94a3b8; /* slate-400 */
    margin-top: 0.125rem;
    text-transform: none;
    letter-spacing: normal;
}

/* ============ Time Column ============ */
/*
 * A time AXIS, not a range on every row. The end of a row is the start of the
 * row beneath it, so a range printed each boundary twice, and a label carried
 * one meridiem or two depending on whether that row straddled noon — no two
 * were the same width, and centred there was nothing for the eye to line up
 * on. Right-aligned digits plus a fixed two-character suffix align themselves,
 * with no widths to keep in sync. Duration is read from the pill's height
 * here, and quoted in full by the cart and the review step.
 */
.schedule-grid .time-col {
    position: sticky;
    left: 0;
    /* Higher than the night-tint cells (auto) and any cell stacking contexts
       created by opacity/transform on booked/selected cells. */
    z-index: 15;
    background-color: #f8fafc; /* slate-50 — must stay opaque so scrolling cells don't bleed through */
    border-right: 2px solid #cbd5e1; /* slate-300 — stronger separator */
    min-width: var(--sched-time-col-w);
    width: var(--sched-time-col-w);
    padding: 0.5rem 0.625rem;
    font-family: var(--wiz-font);
    font-size: 0.8125rem;
    font-weight: 600;
    color: #475569; /* slate-600 */
    white-space: nowrap;
    /* Right, not centre: the digits are the thing to align, and they only line
       up against a fixed edge. Declared HERE rather than earlier in the block —
       the centre it replaces was the last declaration standing. */
    text-align: right;
    padding-right: 0.8rem;
    vertical-align: middle;
    /* Soft right-edge shadow makes the column visually float above scrolling cells. */
    box-shadow: 4px 0 6px -3px rgba(15, 23, 42, 0.08);
}

/* Subtle row separator */
.schedule-grid tbody tr {
    border-bottom: 1px solid var(--wiz-border-subtle);
}

.schedule-grid tbody tr:last-child {
    border-bottom: none;
}

/* ============ Cells (Base) ============ */
/* Wrapper <td> — provides the whitespace gutter around each pill so
   adjacent cells aren't edge-to-edge. Mirrors the dashboard's .dc-td-slot. */
.schedule-cell-wrap {
    padding: 4px 5px;
    vertical-align: middle;
    border-bottom: 1px solid #f1f5f9;
}

/* Pill — the colored chip that lives inside the wrapper <td>. Mirrors
   the dashboard's .dc-slot. Status variants below set bg/border/color. */
.schedule-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    padding: var(--sched-cell-pad);
    min-height: var(--sched-cell-min-h);
    text-align: center;
    font-family: var(--wiz-font);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
    cursor: pointer;
    border: 1px solid transparent;
    border-radius: 8px;
    transition: background-color 0.15s var(--wiz-ease),
                border-color 0.15s var(--wiz-ease),
                color 0.15s var(--wiz-ease),
                box-shadow 0.15s var(--wiz-ease),
                transform 0.12s ease;
    user-select: none;
    -webkit-user-select: none;
}

/* -- Sub-hour grids: fill the rows a cell spans --
   When courts disagree about slot length the rows are cut at the GCD and each
   longer court's <td> carries a rowspan. Left alone the pill keeps its own
   min-height and floats in the middle of that taller cell, so a 60-minute
   court beside a 30-minute one reads as a chip with a blank row under it.
   `height: 1px` gives the <td> a definite height for `height: 100%` to
   resolve against — the row's real height still wins — so the pill grows to
   cover its whole span and the columns line up edge to edge.
   Scoped to .schedule-grid--substep: an all-60-minute grid is untouched. */
.schedule-grid--substep .schedule-cell-wrap {
    height: 1px;
}

.schedule-grid--substep .schedule-cell {
    height: 100%;
}

/* ============ Cell States ============ */

/* -- Open (available for booking) — match dashboard "Available" pill -- */
.schedule-cell--open {
    background: linear-gradient(135deg, #ecfdf5, #d1fae5);
    color: #065f46;
    border: 1px solid #a7f3d0;
    border-radius: 8px;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.schedule-cell--open:hover {
    transform: scale(1.02);
    box-shadow: 0 4px 12px rgba(16, 185, 129, 0.18);
}

.schedule-cell--open:active {
    background: linear-gradient(135deg, #d1fae5, #a7f3d0);
}

/* -- Selected (user has chosen this slot) -- */
.schedule-cell--selected {
    background-color: var(--sched-selected-bg);
    border-color: var(--sched-selected-border);
    color: var(--sched-selected-text);
    font-weight: 700;
    box-shadow: 0 1px 4px var(--sched-selected-shadow);
}

.schedule-cell--selected:hover {
    background-color: #c7d2fe; /* indigo-200 */
}

/* ============================================================
   Slot Promotion FREE state — selected cell the active "buy X get Y"
   promo would currently gift. Painted by ScheduleBooking._renderGrid
   when the cell's "courtId|HH:MM" key is in _freePromoKeys. Visually
   distinct from a plain selected cell so the FREE callout reads at a
   glance even on a dense multi-court grid.
   ============================================================ */
.schedule-cell--selected.schedule-cell--free {
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    border-color: #047857;
    color: #ffffff;
    font-weight: 700;
    box-shadow: 0 1px 6px rgba(5, 150, 105, 0.35),
                inset 0 0 0 1px rgba(255, 255, 255, 0.18);
    text-align: center;
    vertical-align: middle;
}

.schedule-cell--selected.schedule-cell--free:hover {
    background: linear-gradient(135deg, #34d399 0%, #10b981 100%);
}

.schedule-cell-free-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    color: #ffffff;
    font-size: 0.65rem;
    font-weight: 800;
    letter-spacing: 0.05em;
    padding: 0.125rem 0.4375rem;
    background: rgba(255, 255, 255, 0.18);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 9999px;
    backdrop-filter: blur(4px);
    text-transform: uppercase;
    line-height: 1;
}

.schedule-cell-free-pill i {
    font-size: 0.625rem;
}

/* -- Booked (already taken) — inline layout, MUST stay table-cell to keep
   column alignment intact across courts. Do not switch to flex. -- */
.schedule-cell--booked {
    background-color: var(--sched-booked-bg);
    border-color: var(--sched-booked-border);
    color: var(--sched-booked-text);
    cursor: not-allowed;
    opacity: 0.92;
    text-align: center;
    vertical-align: middle;
    line-height: 1.35;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.schedule-cell-name {
    display: inline;
    font-weight: 600;
    font-size: 0.78rem;
    vertical-align: middle;
}

.schedule-cell-badge {
    display: inline-block;
    font-size: 0.55rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    padding: 1px 6px;
    margin-left: 0.25rem;
    border-radius: 999px;
    background-color: rgba(255, 255, 255, 0.6);
    color: #1d4ed8;
    text-transform: uppercase;
    vertical-align: middle;
}

.schedule-cell-badge--hold {
    background-color: rgba(249, 115, 22, 0.15);
    color: #c2410c;
}

.schedule-cell-badge--pending {
    background-color: rgba(245, 158, 11, 0.18);
    color: #b45309;
}

.schedule-cell-badge--blocked {
    background-color: rgba(239, 68, 68, 0.15);
    color: #b91c1c;
}

/* Tint per booking type — match dashboard slot palette (gradient + border) */
.schedule-cell--confirmed {
    background: linear-gradient(135deg, #eff6ff, #dbeafe);
    color: #1e40af;
    border: 1px solid #bfdbfe;
    border-radius: 8px;
}

.schedule-cell--hold {
    background: linear-gradient(135deg, #fff7ed, #ffedd5);
    color: #9a3412;
    border: 1px solid #fed7aa;
    border-radius: 8px;
}

.schedule-cell--pending {
    background: linear-gradient(135deg, #fffbeb, #fef3c7);
    color: #92400e;
    border: 1px solid #fde68a;
    border-radius: 8px;
}

.schedule-cell--blocked {
    background: linear-gradient(135deg, #fef2f2, #fecaca);
    color: #991b1b;
    border: 1px solid #fca5a5;
    border-radius: 8px;
}

.schedule-cell--open-play {
    background: linear-gradient(135deg, #f5f3ff, #ede9fe);
    color: #5b21b6;
    border: 1px solid #c4b5fd;
    border-radius: 8px;
}

/* Player-facing private hours. Deliberately NEUTRAL, not the red of
   .schedule-cell--blocked: nothing is wrong with this slot, the venue just
   doesn't sell it online. Red reads as an error and disagreed with the grey
   legend swatch. Overrides every blocked property it inherits — tokens
   shared with the legend pill below so the two agree. */
.schedule-cell--private {
    background: var(--wiz-surface-raised);
    background-image: none;
    color: var(--wiz-text-secondary);
    border: 1px solid var(--wiz-border);
    border-radius: 8px;
    cursor: default;
}

/* Staff-facing: the slot is still sellable, but the boundary must be visible
   so nobody sells an Open Play court to a walk-in by accident. */
.schedule-cell--private-admin {
    background-image: repeating-linear-gradient(
        45deg,
        transparent,
        transparent 4px,
        rgba(0, 0, 0, 0.06) 4px,
        rgba(0, 0, 0, 0.06) 8px
    );
}

/* ============ Legend — Pill Style (mirrors dashboard) ============ */
.schedule-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 12px 0 4px;
    margin-top: 0.75rem;
    margin-bottom: 1rem;
}

.schedule-legend-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 6px;
    border-radius: 20px;
    font-family: var(--wiz-font);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.schedule-legend-pill:hover {
    transform: translateY(-1px);
}

.schedule-legend-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

.schedule-legend-pill[data-status="available"] {
    background: linear-gradient(135deg, #ecfdf5, #d1fae5);
    color: #065f46;
    border: 1px solid #a7f3d0;
}
.schedule-legend-pill[data-status="available"] .schedule-legend-dot { background: #10b981; }

.schedule-legend-pill[data-status="selected"] {
    background: linear-gradient(135deg, #eef2ff, #e0e7ff);
    color: #4338ca;
    border: 1px solid #c7d2fe;
}
.schedule-legend-pill[data-status="selected"] .schedule-legend-dot {
    background: transparent;
    border: 2px solid #6366f1;
    border-radius: 4px;
    width: 12px;
    height: 12px;
}

.schedule-legend-pill[data-status="confirmed"] {
    background: linear-gradient(135deg, #eff6ff, #dbeafe);
    color: #1e40af;
    border: 1px solid #bfdbfe;
}
.schedule-legend-pill[data-status="confirmed"] .schedule-legend-dot { background: #3b82f6; }

.schedule-legend-pill[data-status="pending"] {
    background: linear-gradient(135deg, #fffbeb, #fef3c7);
    color: #92400e;
    border: 1px solid #fde68a;
}
.schedule-legend-pill[data-status="pending"] .schedule-legend-dot { background: #f59e0b; }

.schedule-legend-pill[data-status="hold"] {
    background: linear-gradient(135deg, #fff7ed, #ffedd5);
    color: #9a3412;
    border: 1px solid #fed7aa;
}
.schedule-legend-pill[data-status="hold"] .schedule-legend-dot { background: #f97316; }

.schedule-legend-pill[data-status="blocked"] {
    background: linear-gradient(135deg, #fef2f2, #fecaca);
    color: #991b1b;
    border: 1px solid #fca5a5;
}
.schedule-legend-pill[data-status="blocked"] .schedule-legend-dot { background: #ef4444; }

.schedule-legend-pill[data-status="private"] {
    background: linear-gradient(135deg, #f8fafc, #f1f5f9);
    color: #475569;
    border: 1px solid #cbd5e1;
}
.schedule-legend-pill[data-status="private"] .schedule-legend-dot { background: #64748b; }

.schedule-legend-pill[data-status="open_play"] {
    background: linear-gradient(135deg, #f5f3ff, #ede9fe);
    color: #5b21b6;
    border: 1px solid #c4b5fd;
}
.schedule-legend-pill[data-status="open_play"] .schedule-legend-dot { background: #8b5cf6; }

.schedule-legend-pill[data-status="past"] {
    background: #f1f5f9;
    color: #94a3b8;
    border: 1px solid #e2e8f0;
}
.schedule-legend-pill[data-status="past"] .schedule-legend-dot { background: #cbd5e1; }

/* ============ Tooltip ============ */
.schedule-tooltip {
    position: absolute;
    z-index: 60;
    min-width: 200px;
    max-width: 280px;
    padding: 10px 12px;
    background-color: #1f2937;
    color: #f9fafb;
    border-radius: 8px;
    font-size: 0.8125rem;
    line-height: 1.35;
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.25);
    pointer-events: none;
    animation: schedule-tooltip-fade 0.15s ease-out;
}

@keyframes schedule-tooltip-fade {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

.schedule-tooltip-title {
    font-weight: 700;
    font-size: 0.9rem;
    margin-bottom: 4px;
}

.schedule-tooltip-detail {
    color: #d1d5db;
    margin-top: 2px;
    word-wrap: break-word;
}

.schedule-tooltip-status {
    display: inline-block;
    margin-top: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    background-color: rgba(255, 255, 255, 0.12);
    color: #f3f4f6;
}

.schedule-tooltip-status--confirmed { background-color: rgba(59, 130, 246, 0.25); color: #93c5fd; }
.schedule-tooltip-status--hold { background-color: rgba(249, 115, 22, 0.25); color: #fdba74; }
.schedule-tooltip-status--pending { background-color: rgba(245, 158, 11, 0.25); color: #fcd34d; }
.schedule-tooltip-status--blocked { background-color: rgba(239, 68, 68, 0.25); color: #fca5a5; }

/* ============ Row Striping & Night Hours ============ */
.schedule-grid tbody tr.schedule-row-alt {
    background: rgba(15, 23, 42, 0.02);
}

/* Night-hour rows: keep an opaque base color so the sticky time column
   stays opaque while the body cells scroll under it. The translucent indigo
   tint is layered on top via background-image so it composites against the
   opaque base, not against scrolling cells behind. */
.schedule-grid tbody tr.schedule-row-night .time-col {
    background-color: #f8fafc;
    background-image: linear-gradient(rgba(99, 102, 241, 0.04), rgba(99, 102, 241, 0.04));
    color: #475569;
}

.schedule-grid tbody tr.schedule-row-night.schedule-row-alt .time-col {
    background-color: #f8fafc;
    background-image: linear-gradient(rgba(99, 102, 241, 0.06), rgba(99, 102, 241, 0.06));
}

/* ============ NEXT DAY Separator ============ */
/* tabular figures so a 1 is as wide as an 8 and the rows cannot wobble against
   each other; the suffix recedes so the number leads. */
.time-col--axis .time-col-num {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

.time-col--axis .time-col-ap {
    font-size: 0.68em;
    font-weight: 600;
    letter-spacing: 0.06em;
    opacity: 0.72;
}

/* The hour is the unit a court is sold in, so it takes the weight and the half
   hours read as subdivisions of it rather than as an undifferentiated list. */
.time-col--hour .time-col-num {
    font-weight: 700;
}

/* Uniform grids label each row with its full range ("8 - 9 AM"), the same
   text the dashboard calendar prints. A range is a phrase, not a tick on an
   axis, so it centres like the dashboard's; the right-alignment above exists
   to line up bare numbers, which a range's varying shape defeats anyway.

   And it is WAYFINDING, not content: a step smaller and a shade quieter than
   the cells it labels, with the dash and meridiems receding so the numerals
   carry the row. Set at the cell's own size and weight it out-shouted every
   price and name beside it. */
.schedule-grid .time-col--range {
    text-align: center;
    padding-right: 0.625rem;
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    font-size: 0.71875rem; /* 11.5px vs the cells' 13px */
    color: #64748b; /* slate-500 — one step back from the cells' slate-600 */
}

.time-col--range .time-col-ap {
    font-size: 0.68em;
    font-weight: 600;
    letter-spacing: 0.06em;
    opacity: 0.72;
}

.time-col--range .time-col-dash {
    font-weight: 400;
    opacity: 0.45;
}

.schedule-midnight-separator {
    background-color: rgba(99, 102, 241, 0.06);
}

.schedule-midnight-cell {
    text-align: left;
    padding: 8px 12px !important;
    border-top: 2px solid rgba(99, 102, 241, 0.45) !important;
    border-bottom: 1px solid rgba(99, 102, 241, 0.20);
    height: auto !important;
    min-height: 0 !important;
}

.schedule-midnight-label {
    display: inline-block;
    /* Pinned to the left edge of the scroll viewport. The cell spans every
       court, so a centred label on a grid wider than the screen sits somewhere
       off to the right and the band reads as an unexplained blank stripe —
       which is exactly how an "is this venue open at midnight?" question gets
       asked. Sticky keeps the answer beside the rows it explains. */
    position: sticky;
    left: 0.75rem;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    color: #4338ca;
    text-transform: uppercase;
}

/* "PREVIOUS NIGHT" header: the after-midnight overflow of yesterday's
   operating session that physically falls on the requested date. Styled
   with a warmer purple tint to distinguish from the "NEXT DAY" header. */
.schedule-prev-night-separator {
    background-color: rgba(139, 92, 246, 0.08);
}
.schedule-prev-night-separator .schedule-midnight-cell {
    border-top: none !important;
    border-bottom: 2px solid rgba(139, 92, 246, 0.45);
}
.schedule-prev-night-separator .schedule-midnight-label {
    color: #6d28d9;
}
.schedule-grid tbody tr.schedule-row-prev-night .time-col {
    color: #7c3aed;
    font-weight: 600;
}

/* "NEXT DAY" header uses the cooler indigo tint already applied via
   .schedule-midnight-separator; this rule just adds a touch more weight
   to the bottom border so the next-day block reads as visually
   "anchored" to the same booking date as the main grid (and clearly
   distinct from the warmer previous-night block above). */
.schedule-next-day-separator .schedule-midnight-cell {
    border-bottom: 2px solid rgba(99, 102, 241, 0.45) !important;
}

/* ============ Booking Mode Toggle (Single date / Multi-date) ============
   Segmented-control pattern. Active button gets the brand emerald fill;
   inactive buttons stay flat on the parent track. Self-contained so
   Tailwind purge can't strip the active styling at build time. */
.booking-mode-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    margin-bottom: 0.75rem;
    flex-wrap: wrap;
}

.booking-mode-toggle__label {
    font-family: var(--wiz-font);
    font-size: 0.8125rem;
    font-weight: 500;
    color: #475569; /* slate-600 */
    letter-spacing: 0.01em;
}

.booking-mode-toggle__track {
    display: inline-flex;
    padding: 4px;
    background-color: #f1f5f9;     /* slate-100 — track sits flush on cards */
    border: 1px solid #e2e8f0;     /* slate-200 */
    border-radius: 10px;
    gap: 2px;
}

.booking-mode-toggle__btn {
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    background: transparent;
    padding: 6px 14px;
    min-width: 96px;
    font-family: var(--wiz-font);
    font-size: 0.8125rem;
    font-weight: 600;
    color: #64748b;                /* slate-500 — inactive label */
    border-radius: 7px;
    cursor: pointer;
    transition: background-color 0.15s var(--wiz-ease),
                color 0.15s var(--wiz-ease),
                box-shadow 0.15s var(--wiz-ease),
                transform 0.1s var(--wiz-ease);
    user-select: none;
    -webkit-user-select: none;
    line-height: 1.25;
}

.booking-mode-toggle__btn:hover:not(.is-active) {
    color: #0f172a;                /* slate-900 — hint of darker on hover */
    background-color: rgba(255, 255, 255, 0.6);
}

.booking-mode-toggle__btn:active:not(.is-active) {
    transform: scale(0.98);
}

.booking-mode-toggle__btn:focus-visible {
    outline: 2px solid rgba(79, 70, 229, 0.45); /* indigo-600 ring */
    outline-offset: 2px;
}

.booking-mode-toggle__btn.is-active {
    background-color: #ffffff;
    color: #047857;                /* emerald-700 */
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06),
                0 0 0 1px rgba(5, 150, 105, 0.35);
}

.booking-mode-toggle__btn.is-active::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-right: 8px;
    border-radius: 50%;
    background-color: #10b981;     /* emerald-500 — active dot */
    vertical-align: middle;
}

/* -- Past (time has elapsed) -- additive: stacks on top of any status
   class so booked / blocked / open-play / available cells keep their
   colour but appear dimmed, mirroring the dashboard's behaviour.
   pointer-events stays enabled so the hover-tooltip still works on past
   booked/blocked cells; the click handler is gated separately in JS. */
.schedule-cell--past {
    opacity: 0.4;
    cursor: not-allowed !important;
}

/* When the cell is past AND no other status class is present (e.g. an
   empty/unknown slot), fall back to the muted grey treatment. */
.schedule-cell--past:not(.schedule-cell--open):not(.schedule-cell--booked):not(.schedule-cell--confirmed):not(.schedule-cell--pending):not(.schedule-cell--hold):not(.schedule-cell--blocked):not(.schedule-cell--open-play):not(.schedule-cell--selected) {
    background-color: var(--sched-past-bg);
    border-color: var(--sched-past-border);
    color: var(--sched-past-text);
}

.schedule-cell--past:hover {
    transform: none !important;
    box-shadow: none !important;
}

/* ============ Court Type Tabs ============ */
.court-type-tabs {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}

.court-type-tab {
    display: inline-flex;
    align-items: center;
    padding: 0.375rem 1rem;
    border-radius: 9999px;
    font-family: var(--wiz-font);
    font-size: 0.8125rem;
    font-weight: 600;
    border: 1.5px solid transparent;
    cursor: pointer;
    transition: all 0.2s var(--wiz-ease);
    white-space: nowrap;
}

.court-type-tab--active {
    background-color: #4f46e5; /* indigo-600 */
    color: #ffffff;
    border-color: #4f46e5;
    box-shadow: 0 2px 8px rgba(79, 70, 229, 0.25);
}

.court-type-tab--active:hover {
    background-color: #4338ca; /* indigo-700 */
    border-color: #4338ca;
}

.court-type-tab--inactive {
    background-color: var(--wiz-surface);
    color: var(--wiz-text-secondary);
    border-color: var(--wiz-border);
}

.court-type-tab--inactive:hover {
    background-color: var(--wiz-surface-raised);
    border-color: #94a3b8;
    color: var(--wiz-text);
}

/* ============ View Switcher ============ */
.view-switcher {
    display: inline-flex;
    align-items: center;
    border-radius: var(--wiz-radius-md);
    border: 1.5px solid var(--wiz-border);
    background-color: var(--wiz-surface);
    padding: 0.25rem;
    gap: 0;
}

.view-switcher a,
.view-switcher button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 0.5rem 1rem;
    font-family: var(--wiz-font);
    font-size: 0.8125rem;
    font-weight: 600;
    border-radius: var(--wiz-radius-sm);
    border: none;
    background: none;
    cursor: pointer;
    transition: all 0.2s var(--wiz-ease);
    text-decoration: none;
    white-space: nowrap;
}

.view-switcher a.active,
.view-switcher button.active {
    background: linear-gradient(135deg, var(--wiz-primary), #6366f1);
    color: #ffffff;
    box-shadow: var(--wiz-shadow-colored);
}

.view-switcher a:not(.active),
.view-switcher button:not(.active) {
    color: var(--wiz-text-secondary);
}

.view-switcher a:not(.active):hover,
.view-switcher button:not(.active):hover {
    background-color: var(--wiz-surface-raised);
    color: var(--wiz-text);
}

/* ============ Pricing Summary ============ */
.pricing-line-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.25rem 0;
    font-family: var(--wiz-font);
    font-size: 0.875rem;
    color: var(--wiz-text-secondary);
}

.pricing-line-item span:last-child {
    font-weight: 600;
    color: var(--wiz-text);
}

.pricing-total {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-top: 0.75rem;
    margin-top: 0.75rem;
    border-top: 2px solid var(--wiz-border);
    font-family: var(--wiz-font);
    font-size: 1rem;
    font-weight: 700;
    color: var(--wiz-text);
}

.pricing-total span:last-child {
    font-size: 1.125rem;
    font-weight: 800;
    color: var(--wiz-primary);
}

/* ============ Toast Notification ============ */
.schedule-toast {
    position: fixed;
    bottom: 1rem;
    right: 1rem;
    background-color: #dc2626; /* red-600 */
    color: #ffffff;
    padding: 0.75rem 1rem;
    border-radius: var(--wiz-radius-sm);
    box-shadow: var(--wiz-shadow-lg);
    z-index: 50;
    font-family: var(--wiz-font);
    font-size: 0.875rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 22rem;
    transition: transform 0.3s var(--wiz-ease),
                opacity 0.3s var(--wiz-ease);
}

.schedule-toast--show {
    transform: translateY(0);
    opacity: 1;
}

.schedule-toast--hide {
    transform: translateY(0.5rem);
    opacity: 0;
    pointer-events: none;
}

/* ============ Loading State ============ */
.schedule-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    color: var(--wiz-text-muted);
}

.schedule-loading .spinner {
    width: 2rem;
    height: 2rem;
    border: 3px solid var(--wiz-border);
    border-top-color: var(--wiz-primary);
    border-radius: 50%;
    animation: schedSpin 0.75s linear infinite;
    margin-bottom: 0.75rem;
}

@keyframes schedSpin {
    to { transform: rotate(360deg); }
}

.schedule-loading p {
    font-family: var(--wiz-font);
    font-size: 0.875rem;
    font-weight: 500;
}

/* ============ Mobile Responsive (< 640px) ============ */
@media (max-width: 639px) {
    :root {
        --sched-cell-min-h: 40px;
        --sched-cell-pad: 6px;
        --sched-time-col-w: 90px;
    }

    .schedule-grid table {
        min-width: 540px;
    }

    .schedule-cell {
        font-size: 0.6875rem;
    }

    .schedule-grid th {
        padding: 0.5rem 0.375rem;
        font-size: 0.6875rem;
    }

    .schedule-grid th .court-name {
        font-size: 0.75rem;
    }

    .schedule-grid th .court-type {
        font-size: 0.5625rem;
    }

    .schedule-grid .time-col {
        padding: 0.375rem 0.45rem 0.375rem 0.3rem;
        font-size: 0.6875rem;
        line-height: 1.2;
    }

    /* This later block outweighs the desktop range rule at equal specificity,
       so the range's step-down must be restated for the phone too. */
    .schedule-grid .time-col--range {
        font-size: 0.625rem;
    }

    .court-type-tabs {
        gap: 0.375rem;
    }

    .court-type-tab {
        font-size: 0.75rem;
        padding: 0.3125rem 0.75rem;
    }

    .view-switcher a,
    .view-switcher button {
        padding: 0.375rem 0.75rem;
        font-size: 0.75rem;
    }

    .schedule-toast {
        left: 1rem;
        right: 1rem;
        bottom: 0.75rem;
        max-width: none;
    }
}

/* ============ Tablet+ (>= 640px) ============ */
@media (min-width: 640px) {
    .schedule-grid table {
        min-width: 700px;
    }
}
/* ============ Multi-date bottom dock + sheet + review modal ============
   The dock is a sticky bar at the bottom of the viewport in multi-date
   mode. The sheet is a slide-up panel that expands to show the full
   line list. The review modal opens on Checkout. */

:root {
    --mdc-z-dock:    40;
    --mdc-z-sheet:   50;
    --mdc-z-modal:   60;
    --mdc-emerald:   #059669;
    --mdc-emerald-2: #047857;
    --mdc-emerald-3: #065f46;
    --mdc-emerald-l: #10b981;
    --mdc-radius:    14px;
    --mdc-radius-sm: 10px;
}

/* When the dock is visible, hide the on-grid actions row (the dock
   owns the primary CTA in both single-date and multi-date). */
body.mdc-has-dock #schedule-actions {
    display: none !important;
}

/* The booking dock (#mdc-dock, z-index var --mdc-z-dock = 40) and the
   global mobile tab bar (.mobile-tabbar, z-index 50) are both fixed to
   bottom: 0. Without this rule the tab bar paints over the dock on
   phones, hiding the cart summary + the Continue/checkout CTA — so a
   single-date selection looks like it has "no next button" and a
   multi-date selection looks like its slots vanished after a date
   change. While a booking is in progress the dock owns the bottom bar,
   so the global tab bar yields to it. The same applies while the
   single-date review/checkout panel is open (is-schedule-review), so
   its Confirm button is never hidden behind the tab bar either. */
body.mdc-has-dock .mobile-tabbar,
body.is-schedule-review .mobile-tabbar {
    display: none !important;
}

/* While the existing single-date review panel is open the user is
   committing a checkout — hide the booking-type toggle so they can't
   accidentally switch modes mid-flight (the dock is already hidden
   via syncDockVisibility). */
body.is-schedule-review #booking-mode-toggle {
    display: none !important;
}

/* Reserve scroll room INSIDE the schedule container so the page can
   scroll past the dock. We pad the container — not the body — so the
   sidebar (same flex layout) keeps its full height and doesn't show
   a gap at the viewport's bottom edge. */
body.mdc-has-dock #schedule-container {
    padding-bottom: 88px;
}
@media (min-width: 768px) {
    body.mdc-has-dock #schedule-container {
        padding-bottom: 80px;
    }
}

/* ─── Dock ─────────────────────────────────────────────────────────────── */
#mdc-dock {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--mdc-z-dock);
    font-family: var(--wiz-font);
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: saturate(140%) blur(10px);
    -webkit-backdrop-filter: saturate(140%) blur(10px);
    border-top: 1px solid #e2e8f0;
    box-shadow: 0 -8px 24px -10px rgba(15, 23, 42, 0.12);
    transition: transform 220ms var(--wiz-ease);
    /* Respect iOS safe area */
    padding-bottom: env(safe-area-inset-bottom);
}

.mdc-dock-inner {
    max-width: 980px;
    margin: 0 auto;
    padding: 0.625rem 0.875rem;
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-height: 64px;
}

/* Empty hint */
.mdc-dock-empty {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.625rem;
    color: #64748b;
    font-size: 0.8125rem;
    line-height: 1.4;
}
.mdc-dock-icon {
    width: 1.125rem;
    height: 1.125rem;
    flex-shrink: 0;
    color: #94a3b8;
}

/* Summary button (left side) */
.mdc-dock-summary {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.75rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--mdc-radius-sm);
    color: #1e293b;
    text-align: left;
    cursor: pointer;
    transition: background-color 140ms var(--wiz-ease);
    min-width: 0;
}
.mdc-dock-summary:hover {
    background: #f1f5f9;
}
.mdc-dock-summary:focus-visible {
    outline: 2px solid var(--wiz-primary);
    outline-offset: 2px;
}

.mdc-dock-chevron {
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 9999px;
    background: #e0e7ff;
    color: var(--wiz-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: transform 200ms var(--wiz-ease);
}
.mdc-dock-summary[aria-expanded="true"] .mdc-dock-chevron {
    transform: rotate(180deg);
}
.mdc-dock-chevron svg { width: 0.875rem; height: 0.875rem; }

.mdc-dock-counts {
    flex: 1;
    min-width: 0;
    font-size: 0.8125rem;
    color: #475569;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mdc-dock-counts strong {
    color: #0f172a;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.mdc-dock-sep {
    color: #cbd5e1;
    margin: 0 0.125rem;
}

.mdc-dock-total {
    font-size: 1rem;
    font-weight: 700;
    color: #0f172a;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    padding-left: 0.625rem;
    border-left: 1px solid #e2e8f0;
    flex-shrink: 0;
}

/* Primary CTA on the dock — emerald gradient */
.mdc-dock-cta {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.625rem 1rem;
    border-radius: var(--mdc-radius-sm);
    background: linear-gradient(180deg, var(--mdc-emerald-l) 0%, var(--mdc-emerald) 100%);
    color: #ffffff;
    border: 1px solid var(--mdc-emerald-2);
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(5, 150, 105, 0.25),
                0 1px 0 rgba(255, 255, 255, 0.18) inset;
    transition: transform 140ms var(--wiz-ease),
                box-shadow 140ms var(--wiz-ease),
                background 140ms var(--wiz-ease);
    white-space: nowrap;
}
.mdc-dock-cta:hover {
    background: linear-gradient(180deg, var(--mdc-emerald) 0%, var(--mdc-emerald-2) 100%);
    box-shadow: 0 4px 12px -2px rgba(5, 150, 105, 0.4),
                0 1px 0 rgba(255, 255, 255, 0.18) inset;
    transform: translateY(-1px);
}
.mdc-dock-cta:active {
    transform: translateY(0);
}
.mdc-dock-cta:focus-visible {
    outline: 2px solid var(--mdc-emerald-3);
    outline-offset: 2px;
}
.mdc-dock-arrow {
    width: 0.875rem;
    height: 0.875rem;
}

/* Ghost trash button on the dock — clears the entire slot selection.
   Neutral at rest, red on hover, so the emerald CTA stays primary. */
.mdc-dock-clear {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--mdc-radius-sm);
    background: #ffffff;
    color: #64748b;
    border: 1px solid #e2e8f0;
    cursor: pointer;
    transition: color 140ms var(--wiz-ease),
                border-color 140ms var(--wiz-ease),
                background 140ms var(--wiz-ease);
}
.mdc-dock-clear:hover {
    color: #b91c1c;
    border-color: #fecaca;
    background: #fef2f2;
}
.mdc-dock-clear:focus-visible {
    outline: 2px solid #ef4444;
    outline-offset: 2px;
}
.mdc-dock-clear svg {
    width: 1rem;
    height: 1rem;
}

/* Compact dock on small screens */
@media (max-width: 480px) {
    .mdc-dock-inner { padding: 0.5rem 0.625rem; gap: 0.5rem; }
    .mdc-dock-counts { font-size: 0.75rem; }
    .mdc-dock-total { font-size: 0.9375rem; padding-left: 0.5rem; }
    .mdc-dock-cta { padding: 0.5rem 0.75rem; font-size: 0.75rem; }
    .mdc-dock-cta span,
    .mdc-dock-cta { gap: 0.25rem; }
    .mdc-dock-stale { font-size: 0.6875rem; padding: 0.0625rem 0.375rem; }
    .mdc-dock-clear { width: 2rem; height: 2rem; }
}

/* Stale-slot pill on the dock + warning CTA variant. Shown when
   background revalidation flagged at least one cart line as
   unavailable — gives the user a single tap to clean the cart. */
.mdc-dock-stale {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: 0.625rem;
    padding: 0.125rem 0.5rem;
    background: #fee2e2;
    color: #b91c1c;
    border-radius: 9999px;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    flex-shrink: 0;
}
.mdc-dock-stale svg { width: 0.875rem; height: 0.875rem; flex-shrink: 0; }
.mdc-dock-cta.mdc-dock-cta--warning {
    background: linear-gradient(180deg, #ef4444 0%, #b91c1c 100%);
    border-color: #991b1b;
    box-shadow: 0 1px 2px rgba(185, 28, 28, 0.3),
                0 1px 0 rgba(255, 255, 255, 0.18) inset;
}
.mdc-dock-cta.mdc-dock-cta--warning:hover {
    background: linear-gradient(180deg, #dc2626 0%, #991b1b 100%);
    box-shadow: 0 4px 12px -2px rgba(185, 28, 28, 0.4),
                0 1px 0 rgba(255, 255, 255, 0.18) inset;
}
.mdc-dock-cta.mdc-dock-cta--warning:focus-visible {
    outline-color: #ef4444;
}
.mdc-dock-cta.mdc-dock-cta--warning svg { width: 0.875rem; height: 0.875rem; }

/* Stale banner — shown at the top of the sheet and above the action
   row of the legacy review modal whenever the cart contains any line
   that the latest revalidate marked unavailable. */
.mdc-stale-banner {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin: 0.625rem 1rem 0;
    padding: 0.625rem 0.75rem;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 0.625rem;
    color: #7f1d1d;
}
.mdc-stale-banner > svg {
    width: 1.125rem;
    height: 1.125rem;
    flex-shrink: 0;
    color: #b91c1c;
}
.mdc-stale-banner-text {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    line-height: 1.3;
}
.mdc-stale-banner-text strong {
    font-size: 0.8125rem;
    font-weight: 700;
    color: #991b1b;
}
.mdc-stale-banner-text span {
    font-size: 0.75rem;
    color: #7f1d1d;
}
.mdc-stale-banner-btn {
    flex-shrink: 0;
    padding: 0.375rem 0.625rem;
    border-radius: 0.375rem;
    background: #ffffff;
    border: 1px solid #fca5a5;
    color: #b91c1c;
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background 140ms ease, border-color 140ms ease;
}
.mdc-stale-banner-btn:hover {
    background: #fef2f2;
    border-color: #f87171;
}
.mdc-stale-banner--review {
    margin: 0 0 0.75rem;
}

/* Apply the same stale strikethrough treatment used in the sheet to
   review-modal lines so the user sees which slot the banner is
   talking about without scrolling guesswork. */
.mdc-review-slots li.is-stale > span:first-child {
    color: #b91c1c;
    text-decoration: line-through;
    text-decoration-color: #ef4444;
}
.mdc-review-slots li.is-stale .mdc-review-price {
    color: #94a3b8;
    text-decoration: line-through;
}

/* Disabled-state for primary CTAs while stale lines block checkout. */
.mdc-btn-primary:disabled,
.mdc-btn-primary[disabled],
.mdc-btn-primary[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}
.mdc-btn-primary:disabled:hover,
.mdc-btn-primary[disabled]:hover,
.mdc-btn-primary[aria-disabled="true"]:hover {
    transform: none;
}

/* ─── Sheet (expanded line list) ───────────────────────────────────────── */
#mdc-sheet {
    position: fixed;
    inset: 0;
    z-index: var(--mdc-z-sheet);
    pointer-events: none;
}
#mdc-sheet.is-open { pointer-events: auto; }

.mdc-sheet-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.32);
    opacity: 0;
    transition: opacity 220ms var(--wiz-ease);
}
#mdc-sheet.is-open .mdc-sheet-backdrop { opacity: 1; }

.mdc-sheet-panel {
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translate(-50%, 100%);
    width: 100%;
    max-width: 560px;
    max-height: 78vh;
    display: flex;
    flex-direction: column;
    background: #ffffff;
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -16px 48px -12px rgba(15, 23, 42, 0.25);
    transition: transform 240ms var(--wiz-ease);
    font-family: var(--wiz-font);
    padding-bottom: env(safe-area-inset-bottom);
}
#mdc-sheet.is-open .mdc-sheet-panel { transform: translate(-50%, 0); }

.mdc-sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.125rem 0.625rem;
    border-bottom: 1px solid #f1f5f9;
}
.mdc-sheet-title {
    margin: 0;
    font-size: 1.0625rem;
    font-weight: 700;
    color: #0f172a;
    letter-spacing: -0.01em;
}
.mdc-sheet-sub {
    margin: 0.125rem 0 0;
    font-size: 0.75rem;
    color: #64748b;
}

.mdc-sheet-body {
    overflow-y: auto;
    padding: 0.5rem 1.125rem 0.875rem;
    -webkit-overflow-scrolling: touch;
}

.mdc-date-group + .mdc-date-group { margin-top: 0.875rem; }
.mdc-date-head {
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #64748b;
    padding: 0.5rem 0 0.375rem;
    border-bottom: 1px dashed #e2e8f0;
}

.mdc-line-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.mdc-line {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid #f8fafc;
}
.mdc-line:last-child { border-bottom: none; }
.mdc-line-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    column-gap: 0.5rem;
    row-gap: 0.125rem;
    align-items: baseline;
}
.mdc-line-court {
    font-size: 0.875rem;
    font-weight: 600;
    color: #0f172a;
}
.mdc-line-time {
    font-size: 0.8125rem;
    color: #475569;
    font-variant-numeric: tabular-nums;
}
.mdc-line-stale {
    font-size: 0.6875rem;
    font-weight: 600;
    color: #b91c1c;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.0625rem 0.375rem;
    background: #fee2e2;
    border-radius: 9999px;
}

/* "overnight" tag for slots whose physical clock-time falls on the
   day the user was viewing, but whose booking session belongs to the
   previous calendar day (e.g. Fri 00:00–02:00 → Thu's session). */
.mdc-line-tag {
    display: inline-flex;
    align-items: center;
    font-size: 0.625rem;
    font-weight: 700;
    color: #6d28d9;            /* violet-700 */
    background: #ede9fe;       /* violet-100 */
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 0.0625rem 0.375rem;
    border-radius: 9999px;
    cursor: help;
}
.mdc-line.is-stale .mdc-line-court,
.mdc-line.is-stale .mdc-line-time {
    color: #b91c1c;
    text-decoration: line-through;
    text-decoration-color: #ef4444;
}
.mdc-line-price {
    font-size: 0.875rem;
    font-weight: 600;
    color: #0f172a;
    font-variant-numeric: tabular-nums;
    min-width: 4ch;
    text-align: right;
}
.mdc-line-remove {
    color: #94a3b8;
}
.mdc-line-remove:hover {
    background: #fee2e2;
    color: #dc2626;
}

.mdc-sheet-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.875rem 1.125rem 1rem;
    border-top: 1px solid #f1f5f9;
    background: #fafbfd;
}
.mdc-sheet-total {
    display: flex;
    flex-direction: column;
}
.mdc-sheet-total-label {
    font-size: 0.6875rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}
.mdc-sheet-total-value {
    font-size: 1.25rem;
    font-weight: 700;
    color: #0f172a;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}
.mdc-sheet-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

/* ─── Slot promotion decoration (cart sheet + dock) ───────────────────── */
.mdc-line-price-wrap {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}
.mdc-line-price--struck {
    color: #94a3b8;
    text-decoration: line-through;
    font-weight: 600;
}
.mdc-line-promo-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    color: #ffffff;
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.05em;
    padding: 0.1875rem 0.5rem;
    border-radius: 9999px;
    box-shadow: 0 1px 2px rgba(5, 150, 105, 0.25);
    text-transform: uppercase;
    line-height: 1;
}
.mdc-line-promo-pill svg {
    width: 0.75rem;
    height: 0.75rem;
    flex-shrink: 0;
}
.mdc-line--promo .mdc-line-time {
    color: #059669;
    font-weight: 600;
}

.mdc-sheet-promo-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    flex-basis: 100%;
    margin-bottom: 0.5rem;
    padding: 0.5rem 0.75rem;
    background: linear-gradient(135deg, rgba(16, 185, 129, 0.10) 0%, rgba(5, 150, 105, 0.06) 100%);
    border: 1px solid rgba(16, 185, 129, 0.30);
    border-radius: 0.5rem;
    color: #064e3b;
    font-size: 0.8125rem;
    font-weight: 600;
}
.mdc-sheet-promo-label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.mdc-sheet-promo-label svg {
    width: 0.875rem;
    height: 0.875rem;
    color: #059669;
}
.mdc-sheet-promo-value {
    color: #047857;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.mdc-sheet-foot {
    flex-wrap: wrap;
}
.mdc-sheet-total-stack {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
}
.mdc-sheet-total-original {
    font-size: 0.875rem;
    font-weight: 600;
    color: #94a3b8;
    text-decoration: line-through;
    font-variant-numeric: tabular-nums;
}

.mdc-dock-total--has-promo {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
}
.mdc-dock-total-original {
    font-size: 0.8125rem;
    color: #94a3b8;
    text-decoration: line-through;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.mdc-dock-total-now {
    color: #059669;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* ─── Review modal ─────────────────────────────────────────────────────── */
#mdc-review-modal {
    position: fixed;
    inset: 0;
    z-index: var(--mdc-z-modal);
    pointer-events: none;
}
#mdc-review-modal.is-open { pointer-events: auto; }

.mdc-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    opacity: 0;
    transition: opacity 220ms var(--wiz-ease);
}
#mdc-review-modal.is-open .mdc-modal-backdrop { opacity: 1; }

.mdc-modal-panel {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -45%);
    width: calc(100% - 2rem);
    max-width: 640px;
    max-height: 86vh;
    display: flex;
    flex-direction: column;
    background: #ffffff;
    border-radius: 18px;
    box-shadow: 0 24px 64px -16px rgba(15, 23, 42, 0.4);
    font-family: var(--wiz-font);
    opacity: 0;
    transition: transform 240ms var(--wiz-ease), opacity 200ms var(--wiz-ease);
}
#mdc-review-modal.is-open .mdc-modal-panel {
    transform: translate(-50%, -50%);
    opacity: 1;
}

.mdc-modal-head {
    position: relative;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.125rem 1.25rem 0.75rem;
    border-bottom: 1px solid #f1f5f9;
}
.mdc-modal-title {
    margin: 0;
    font-size: 1.125rem;
    font-weight: 700;
    color: #0f172a;
    letter-spacing: -0.015em;
}
.mdc-modal-sub {
    margin: 0.125rem 0 0;
    font-size: 0.75rem;
    color: #64748b;
}
.mdc-modal-close { color: #94a3b8; }
.mdc-modal-close:hover { background: #f1f5f9; color: #0f172a; }

.mdc-modal-body {
    overflow-y: auto;
    padding: 1rem 1.25rem;
    -webkit-overflow-scrolling: touch;
}

.mdc-review-card {
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: var(--mdc-radius);
    padding: 0.875rem 1rem;
    margin-bottom: 1rem;
}
.mdc-review-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}
.mdc-review-card-head h3 {
    margin: 0;
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #475569;
}
.mdc-link-btn {
    background: transparent;
    border: 0;
    color: var(--wiz-primary);
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    padding: 0.125rem 0.25rem;
    border-radius: 4px;
}
.mdc-link-btn:hover { text-decoration: underline; }

.mdc-review-group + .mdc-review-group {
    margin-top: 0.625rem;
    padding-top: 0.625rem;
    border-top: 1px dashed #e2e8f0;
}
.mdc-review-date {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 700;
    color: #0f172a;
    margin-bottom: 0.25rem;
}

/* Remove controls in the review modal.
   Removal already existed in the dock sheet but not here, so an operator who
   spotted a wrong date at review had to close the modal, open the sheet, remove
   it and re-review. Muted at rest so the summary still reads as a summary; red
   only on approach, since this deletes a line. */
/* The slot row was two children under space-between, so the price sat hard
   right. Adding the remove button makes three, which would strand the price in
   the middle — the label takes the slack instead, keeping price and X paired at
   the end of the row. */
.mdc-review-slots li > span:first-child { flex: 1 1 auto; min-width: 0; }

.mdc-review-remove {
    flex: 0 0 auto;
    width: 1.5rem;
    height: 1.5rem;
    color: #cbd5e1;
    background: transparent;
    border: 0;
    border-radius: 0.375rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color 120ms ease, background 120ms ease;
}
.mdc-review-remove svg { width: 0.875rem; height: 0.875rem; }
.mdc-review-remove:hover { color: #b91c1c; background: #fef2f2; }
.mdc-review-remove:focus-visible {
    outline: 2px solid #ef4444;
    outline-offset: 1px;
    color: #b91c1c;
}
.mdc-review-slots {
    list-style: none;
    margin: 0;
    padding: 0;
}
.mdc-review-slots li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.25rem 0;
    font-size: 0.8125rem;
    color: #334155;
}
.mdc-review-price {
    font-weight: 600;
    color: #0f172a;
    font-variant-numeric: tabular-nums;
}

.mdc-review-field {
    margin-bottom: 1rem;
}
.mdc-review-field label {
    display: block;
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #475569;
    margin-bottom: 0.375rem;
}
.mdc-field-hint {
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: #94a3b8;
}
.mdc-review-field textarea {
    display: block;
    width: 100%;
    border-radius: var(--mdc-radius-sm);
    border: 1px solid #cbd5e1;
    padding: 0.5rem 0.75rem;
    font-family: inherit;
    font-size: 0.875rem;
    color: #0f172a;
    background: #ffffff;
    resize: vertical;
    min-height: 2.75rem;
    transition: border-color 140ms var(--wiz-ease), box-shadow 140ms var(--wiz-ease);
}
.mdc-review-field textarea:focus {
    outline: none;
    border-color: var(--wiz-primary);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.18);
}

.mdc-payment-options {
    display: flex;
    flex-direction: column;
    gap: 0.4375rem;
}
.mdc-payment-opt {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.625rem 0.75rem;
    border: 1px solid #e2e8f0;
    border-radius: var(--mdc-radius-sm);
    background: #ffffff;
    cursor: pointer;
    transition: border-color 140ms var(--wiz-ease), background-color 140ms var(--wiz-ease);
    font-size: 0.8125rem;
    color: #334155;
}
.mdc-payment-opt:hover {
    border-color: #cbd5e1;
    background: #f8fafc;
}
.mdc-payment-opt input[type="radio"] {
    accent-color: var(--wiz-primary);
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
}
.mdc-payment-opt:has(input:checked) {
    border-color: var(--wiz-primary);
    background: #eef2ff;
    color: #1e1b4b;
    font-weight: 600;
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}

.mdc-review-fineprint {
    margin: 0.5rem 0 0;
    font-size: 0.6875rem;
    color: #94a3b8;
    line-height: 1.4;
}

.mdc-review-hold-note {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.75rem 0 0;
    padding: 0.75rem 0.875rem;
    background: #fff7ed;
    border: 1px solid #fed7aa;
    border-radius: 10px;
    font-size: 0.8125rem;
    color: #9a3412;
    line-height: 1.4;
}

.mdc-review-hold-note svg {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin-top: 1px;
    color: #ea580c;
}

.mdc-review-hold-note strong {
    font-weight: 600;
    letter-spacing: 0.02em;
}

.mdc-modal-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.875rem;
    padding: 1rem 1.25rem;
    border-top: 1px solid #f1f5f9;
    background: #fafbfd;
    border-radius: 0 0 18px 18px;
    flex-wrap: wrap;
}
.mdc-modal-total {
    display: flex;
    flex-direction: column;
}
.mdc-modal-total-label {
    font-size: 0.6875rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}
.mdc-modal-total-value {
    font-size: 1.375rem;
    font-weight: 700;
    color: #0f172a;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.015em;
}
.mdc-modal-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    margin-left: auto;
}

/* Repeat-on popover (inside review modal) */
.mdc-repeat-popover {
    background: #fffbeb;
    border: 1px solid #fde68a;
    border-radius: var(--mdc-radius-sm);
    padding: 0.75rem 0.875rem;
    margin-bottom: 1rem;
}
.mdc-repeat-title {
    font-size: 0.75rem;
    font-weight: 700;
    color: #92400e;
    margin-bottom: 0.5rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
#mdc-repeat-date {
    display: block;
    width: 100%;
    border-radius: var(--mdc-radius-sm);
    border: 1px solid #fcd34d;
    padding: 0.4375rem 0.625rem;
    font-size: 0.8125rem;
    background: #ffffff;
    margin-bottom: 0.5rem;
}
.mdc-repeat-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
}

/* Modal-open page lock */
body.mdc-modal-open {
    overflow: hidden;
}

/* ─── Shared button primitives ────────────────────────────────────────── */
.mdc-icon-btn {
    width: 2rem;
    height: 2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    background: transparent;
    border: 0;
    color: #64748b;
    cursor: pointer;
    transition: background-color 140ms var(--wiz-ease), color 140ms var(--wiz-ease);
}
.mdc-icon-btn:hover { background: #f1f5f9; color: #0f172a; }
.mdc-icon-btn svg { width: 1rem; height: 1rem; }

.mdc-btn-ghost,
.mdc-btn-secondary,
.mdc-btn-primary {
    border-radius: var(--mdc-radius-sm);
    font-size: 0.8125rem;
    font-weight: 600;
    padding: 0.5rem 0.875rem;
    cursor: pointer;
    border: 1px solid transparent;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-family: inherit;
    transition: background-color 140ms var(--wiz-ease),
                border-color 140ms var(--wiz-ease),
                color 140ms var(--wiz-ease),
                box-shadow 140ms var(--wiz-ease),
                transform 140ms var(--wiz-ease);
    white-space: nowrap;
}

.mdc-btn-ghost {
    background: transparent;
    color: #475569;
}
.mdc-btn-ghost:hover {
    background: #f1f5f9;
    color: #0f172a;
}

.mdc-btn-secondary {
    background: #ffffff;
    border-color: #cbd5e1;
    color: #1e293b;
}
.mdc-btn-secondary:hover {
    background: #f8fafc;
    border-color: #94a3b8;
}

.mdc-btn-primary {
    background: linear-gradient(180deg, var(--mdc-emerald-l) 0%, var(--mdc-emerald) 100%);
    border-color: var(--mdc-emerald-2);
    color: #ffffff;
    box-shadow: 0 1px 2px rgba(5, 150, 105, 0.25),
                0 1px 0 rgba(255, 255, 255, 0.18) inset;
}
.mdc-btn-primary:hover {
    background: linear-gradient(180deg, var(--mdc-emerald) 0%, var(--mdc-emerald-2) 100%);
    box-shadow: 0 4px 12px -2px rgba(5, 150, 105, 0.4),
                0 1px 0 rgba(255, 255, 255, 0.18) inset;
    transform: translateY(-1px);
}
.mdc-btn-primary:active { transform: translateY(0); }
.mdc-btn-primary:disabled,
.mdc-btn-primary.is-loading {
    opacity: 0.65;
    cursor: not-allowed;
    transform: none;
}
.mdc-btn-primary svg { width: 0.875rem; height: 0.875rem; }

/* -- Peak-hour slot (weekly quota applies) -- */
.schedule-cell--peak { position: relative; }
.schedule-cell--peak::after {
    content: 'peak';
    position: absolute; top: 2px; right: 4px;
    font-size: 0.55rem; line-height: 1; letter-spacing: .02em; text-transform: uppercase;
    color: #b45309; background: #fef3c7; border: 1px solid #fcd34d; border-radius: 4px; padding: 1px 3px;
}
.peak-quota--exhausted { border-color: #fca5a5 !important; background: #fef2f2 !important; color: #991b1b !important; }
