/* ======================================================================
   THEME COMPATIBILITY LAYER
   ======================================================================

   Why this file exists
   --------------------
   ACG Booking Core was built against the Kros site, whose Apollow theme
   leaves form controls alone. Uncode does not: it styles `select`, `input`
   and `button` globally (via `.style-light select:not([multiple])` and
   friends) with high enough specificity to beat the plugin's own rules.

   On Kana that produced visibly broken UI on the staff dashboard filters:

     * `select` got Uncode's SVG chevron background-image ON TOP of the
       plugin's own arrow, and because it is a repeating background the
       result was a column of stacked chevrons in every dropdown.
     * `button` inherited a transparent background, so the primary "Filter"
       action rendered as near-invisible grey-on-grey.
     * inputs picked up theme padding/height that no longer matched the
       adjacent controls, so filter rows sat at uneven heights.

   The fix is deliberately defensive rather than cosmetic: reset the handful
   of properties a theme is likely to fight us on, scoped strictly to the
   plugin's own containers so nothing here can leak into the theme, WooCommerce
   checkout, or wp-admin.

   Scoped roots: #acg-booking-wizard, .dashboard-container, .staff-filter-*.
   Loaded last (depends on the dashboard/wizard sheets) so it wins on order
   rather than by piling on !important.
   ====================================================================== */

/* ── Design tokens ────────────────────────────────────────────────────────
   THE root cause of the colour problems on Kana.

   132 rules across dashboard.css and staff-dashboard.css use var(--orange),
   var(--dark-grey) etc., but the plugin never defines them — on Kros they come
   from the Apollow theme (`assets/theme-css/main-style.css`, `:root` block).
   Under Uncode they resolved to nothing, so every one of those declarations
   was dropped and the theme's own greys won by default. That is why the
   primary "Filter" button rendered white-on-white.

   Defining them here makes the plugin self-sufficient on any theme.

   NOTE the variable is still named `--orange`: that name is baked into ~132
   rules across dashboard.css / staff-dashboard.css, so renaming it would mean
   touching all of them for no functional gain. It now holds Kana's BRAND
   GREEN, not an orange. Treat it as "--brand-accent" when reading the code.
   Kros value was #D16600; Kana uses #4B8226 — same hue family as the theme's
   #71b544 accent but darkened so white button text clears WCAG AA (4.65:1).
   `--brand-accent` is provided as a readable alias for any new rules. */
:root {
    --orange:       #4B8226;   /* legacy name — actually the brand accent */
    --brand-accent: #4B8226;   /* prefer this in new rules */
    --brand-accent-hover: #417021;
    --brand-tint:   #E8FADC;
    --dark-grey:  #2D2D2D;
    --light-grey: #6A6A6A;
    --white:      #FFFFFF;
}

/* ── Selects: exactly one arrow, ours ─────────────────────────────────── */
#acg-booking-wizard select,
.dashboard-container select,
.staff-filter-select {
    /* Kill the theme's chevron. The plugin draws its own via the rules below,
       so leaving the theme's in place is what stacks them. */
    background-image: none !important;
    background-repeat: no-repeat !important;

    -webkit-appearance: none !important;
    -moz-appearance: none !important;
    appearance: none !important;

    /* Our own single chevron, inline so there is no extra HTTP request and
       no dependency on an icon font being present. */
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23667' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E") !important;
    background-position: right 12px center !important;
    background-size: 16px 16px !important;

    /* Room for the arrow so long option text cannot run underneath it. */
    padding-right: 38px !important;

    min-height: 44px;
    line-height: 1.4;
    text-overflow: ellipsis;
}

/* ── Side-by-side selects must be allowed to shrink ───────────────────── */
/* Uncode's style.css sets a bare `select { min-width: 100%; width: 100% }`.
   That is harmless for a select that owns its row, but the add-on card puts a
   start and end time select SIDE BY SIDE in a flex row. `min-width:100%` makes
   each one demand the wrapper's full width, and min-width overrides flex
   shrinking — so two of them plus the separator and gap cannot fit, and the
   second select is pushed outside the card entirely (visible as the end-time
   dropdown floating past the card's right edge on mobile).

   Reset min-width and let flex distribute the space instead. Scoped to the
   time-controls wrapper so no other select changes behaviour. */
.time-controls-wrapper {
    min-width: 0;
}

.time-controls-wrapper .time-select {
    min-width: 0 !important;
    width: auto !important;
    flex: 1 1 0 !important;
}

.time-controls-wrapper .time-separator {
    flex: 0 0 auto;
}

/* ── Inputs: consistent height with the selects beside them ───────────── */
#acg-booking-wizard input[type="text"],
#acg-booking-wizard input[type="search"],
#acg-booking-wizard input[type="email"],
#acg-booking-wizard input[type="number"],
#acg-booking-wizard input[type="date"],
.dashboard-container input[type="text"],
.dashboard-container input[type="search"],
.dashboard-container input[type="email"],
.dashboard-container input[type="number"],
.dashboard-container input[type="date"],
.staff-filter-input {
    min-height: 44px;
    line-height: 1.4;
    /* 16px stops iOS Safari zooming the viewport when the field is focused. */
    font-size: 16px;
    box-sizing: border-box;
}

/* Native date pickers vary wildly; keep the calendar affordance tappable. */
#acg-booking-wizard input[type="date"]::-webkit-calendar-picker-indicator,
.dashboard-container input[type="date"]::-webkit-calendar-picker-indicator {
    opacity: .6;
    cursor: pointer;
    padding: 4px;
}

/* ── Buttons ──────────────────────────────────────────────────────────────
   With the tokens defined above, staff-dashboard.css already colours these
   correctly (`background: var(--dark-grey)`). The only remaining problem is
   Uncode's `.style-light ... button` compound selector, which out-specifies a
   single class. Re-assert the plugin's own values at matching specificity —
   no new colours are invented here.

   NB `.staff-filter-btn` is shared by Filter AND the grey Reset/Clear, which
   set their own background inline; inline styles still win, as intended. */
.dashboard-container .staff-filter-btn:not([style*="background"]),
.dashboard-container button.staff-filter-btn:not([style*="background"]),
.style-light .dashboard-container button.staff-filter-btn:not([style*="background"]),
.style-light .dashboard-container a.staff-filter-btn:not([style*="background"]) {
    /* !important is warranted here: Uncode's `.style-light … button` chain sets
       the background at a specificity we cannot exceed without absurd selectors,
       and it loads from style-custom.css after everything else. The Reset/Clear
       links carry inline styles, which still beat !important — so those keep
       their grey, exactly as the markup intends. */
    background: var(--dark-grey, #2D2D2D) !important;
    color: var(--white, #fff) !important;
    border: none;
    min-height: 44px;
    padding: 10px 22px;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
    transition: filter .16s ease;
}
.dashboard-container .staff-filter-btn:hover {
    filter: brightness(1.15);
}

/* Secondary actions (Reset / Clear) keep the grey their inline style sets;
   only give them the same shape and legible text as the primaries. */
.dashboard-container .staff-filter-btn[style*="background"] {
    color: var(--white, #fff) !important;
    border: none;
    min-height: 44px;
    padding: 10px 22px;
    border-radius: 8px;
    font-weight: 600;
    cursor: pointer;
}


/* Disabled state must be obvious but never mistaken for "invisible". */
#acg-booking-wizard button:disabled,
.dashboard-container button:disabled {
    opacity: .55;
    cursor: not-allowed;
}

/* ── Filter row layout ────────────────────────────────────────────────── */
/* Stack the filters on a phone so labels and controls stay aligned instead
   of wrapping mid-row. */
@media (max-width: 782px) {
    .staff-bookings-filters {
        display: flex;
        flex-direction: column;
        gap: 12px;
    }
    .staff-bookings-filters .staff-filter-group {
        width: 100%;
    }
    .staff-filter-btn {
        width: 100%;
    }
}


/* ══════════════════════════════════════════════════════════════════════════
   DASHBOARD SHELL: full width + working scroll
   ══════════════════════════════════════════════════════════════════════════

   Two problems, same cause — the dashboard is a `height:100vh; overflow:hidden`
   app shell (dashboard.css:73) whose inner `.dashboard-content` does the
   scrolling, with its scrollbar deliberately hidden. That works on Kros, where
   the shortcode renders full-bleed. Under Uncode it is nested inside the
   theme's page wrappers, and:

     * `.row-parent.limit-width` caps the row at 1200px, so on a 1440px screen
       the dashboard got 888px and sat in a narrow column.
     * the 100vh shell + hidden scrollbar meant the page looked unscrollable:
       the outer document had nothing to scroll, and the inner scroller gave no
       visual cue that it could be.

   Fix: let the dashboard break out of the theme's width cap, and let it grow
   with its content so the PAGE scrolls normally instead of an invisible inner
   box. Scoped to pages that actually contain the dashboard.
   ══════════════════════════════════════════════════════════════════════════ */

/* --- Break out of Uncode's centred, max-width row ------------------------ */
.page-dashboard .row-parent.limit-width,
.page-staff-dashboard .row-parent.limit-width,
body:has(.dashboard-container) .row-parent.limit-width {
    max-width: 100% !important;
    width: 100% !important;
}
.page-dashboard .row-inner,
.page-staff-dashboard .row-inner,
body:has(.dashboard-container) .row-inner {
    max-width: 100% !important;
}
/* Uncode adds generous column padding that shrinks the usable area further. */
body:has(.dashboard-container) .post-content > .row-container > .row-parent {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* --- Let the page scroll instead of a hidden inner scroller -------------- */
.dashboard-container {
    /* min-height, not height: the shell can still fill a short screen but is
       free to grow past the viewport when content is taller. */
    height: auto !important;
    min-height: 100vh;
    overflow: visible !important;
}

.dashboard-content {
    height: auto !important;
    min-height: 100vh;
    /* The document scrolls now, so the inner scroller must not also scroll —
       nested scroll regions are exactly what made this feel stuck. */
    overflow-y: visible !important;
    /* `clip`, NOT `hidden`. Both stop sideways page jitter, but `hidden`
       establishes a scroll container, which silently disabled the horizontal
       scrolling that .staff-table-wrap depends on (staff-dashboard.css:356).
       On a 390px phone the bookings table is far wider than the viewport and
       Actions is the RIGHTMOST column, so View/Cancel rendered but could not
       be reached — no scrollbar existed to get to them. `clip` does not create
       a scroll container, so descendants keep their own scrolling.

       `!important` is required, not stylistic: dashboard.css sets
       `.dashboard-content{overflow-x:hidden}` at the SAME specificity (0,1,0)
       and is enqueued after this sheet, so without it the later rule wins and
       `hidden` silently comes back. Verified in the browser — the computed
       value was `hidden` until this was flagged. */
    overflow-x: clip !important;
}

/* The staff tables are intentionally wider than a phone viewport and scroll
   sideways themselves (see the note at staff-dashboard.css:1158). Restated
   here so no ancestor clip can silently break them again. */
.staff-table-wrap {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
}

/* ══════════════════════════════════════════════════════════════════════════
   Hide the theme's page title above the dashboard shell
   ══════════════════════════════════════════════════════════════════════════
   Uncode renders `<h1 class="post-title">` (35px) from the WP page title, so
   the dashboard was topped by a stray "My Bookings" heading sitting OUTSIDE
   the app shell — duplicating the sidebar nav item, pushing the whole
   interface down ~97px, and reading as a layout fault rather than a title.

   The dashboards are full-screen applications with their own headers, so the
   page title is redundant. Scoped to pages containing the dashboard so no
   other page on the site loses its title. */
body:has(.dashboard-container) .post-title-wrapper,
body:has(.dashboard-container) .post-title,
.page-dashboard .post-title-wrapper,
.page-staff-dashboard .post-title-wrapper {
    display: none !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   Remove the theme's frame above and below the dashboard shell
   ══════════════════════════════════════════════════════════════════════════
   Uncode wraps page content in `.row-parent` with `padding: 25px … 36px`.
   On a normal page that is correct breathing room; on a full-screen dashboard
   it reads as a stray gap band at the top and bottom, and stops the dark
   sidebar meeting the viewport edges. */
body:has(.dashboard-container) .row-parent,
body:has(.dashboard-container) .post-content > .row-container > .row-parent {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   MODALS: the theme's 35px heading override reaches inside dialogs too
   ══════════════════════════════════════════════════════════════════════════
   Modals are appended to <body>, OUTSIDE `.dashboard-container`, so the type
   scale further down this file never applied to them. Uncode's inline
   `h3 { font-size:35px }` therefore won unopposed: in the staff booking modal
   the section headings ("Booking", "Customer", "Facility & Slots") rendered
   at 35px — LARGER than the 29px dialog title they sit under — while their
   content sat at ~14px.

   Scoped to the plugin's own dialogs so no theme modal is affected. */
.acg-modal h2:not([class*="fontsize-"]),
#staff-booking-modal h2:not([class*="fontsize-"]),
#acg-booking-details-modal h2:not([class*="fontsize-"]),
.acg-modal .modal-title {
    font-size: 20px !important;
    line-height: 1.3 !important;
}

.acg-modal h3:not([class*="fontsize-"]),
#staff-booking-modal h3:not([class*="fontsize-"]),
#acg-booking-details-modal h3:not([class*="fontsize-"]) {
    /* A section label inside a dialog, not a page heading. */
    font-size: 13px !important;
    line-height: 1.35 !important;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #647382;
    margin: 0 0 10px !important;
}

.acg-modal h4:not([class*="fontsize-"]),
#staff-booking-modal h4:not([class*="fontsize-"]) {
    font-size: 15px !important;
    line-height: 1.35 !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   STAFF TABLES: rows ran together with no separator
   ══════════════════════════════════════════════════════════════════════════
   `.staff-table` rows computed `border-bottom: 0px none`, so 17 bookings
   rendered as one undifferentiated block. Same fault the customer table had,
   but a different class name — the earlier `.dash-table` fix did not reach
   these. Left padding was also 0 against 12px on the right, so the first
   column sat flush to the card edge. */
.dashboard-container .staff-table th,
.dashboard-container .staff-table td {
    /* Uniform 14px all round. Setting only left/right left the original
       vertical values in place (th `0 12px 14px 0`, td `13px 12px 13px 0`),
       so the cells kept uneven top/bottom spacing and the header sat flush
       against the row beneath it. */
    padding: 14px !important;
}

.dashboard-container .staff-table tbody tr:not(:last-child) {
    border-bottom: 1px solid #EDEFF2 !important;
}

/* Kill the theme's per-cell box border.
   Uncode ships `table td, table th { border: 1px solid }`, which drew a
   vertical rule between EVERY column and made the booking and customer lists
   read like a spreadsheet grid. Only the first cell in each row escaped it
   (its left border collapses against the table edge) — which is exactly why
   spot-checking one cell missed this. Horizontal row rules are kept; the
   vertical ones add noise without separating anything meaningful. */
.dashboard-container .staff-table td,
.dashboard-container .staff-table th,
.dashboard-container .dash-table td,
.dashboard-container .dash-table th {
    border-left: 0 !important;
    border-right: 0 !important;
    border-top: 0 !important;
}

.dashboard-container .staff-table tbody tr:hover {
    background: #FAFBFC;
}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE DRAWER: match the desktop sidebar, and stop the header eating a link
   ══════════════════════════════════════════════════════════════════════════
   Two separate faults, both only visible on a phone:

   1. The drawer painted itself `#4B8226` (the rebranded Kros accent — the
      source comment still reads "theme --orange") while the desktop sidebar
      is `#2D2D2D`. Same navigation, two entirely different colours depending
      on screen width.

   2. The fixed header bar occupies y=0–60 at `z-index: 1100`; the drawer
      starts at y=0 with `z-index: 1000`. The FIRST nav item — "Dashboard" —
      rendered underneath it and was completely unreachable. The menu appeared
      to begin at "My Bookings".

   Offsetting the drawer's content by the header height fixes the second
   without touching the slide-in animation, which transforms the whole panel. */
@media (max-width: 768px) {
    .dashboard-sidebar {
        background-color: #2D2D2D !important;
    }

    .dashboard-sidebar .dashboard-nav {
        padding-top: 60px;
    }

    /* Log Out sits at the drawer's foot; keep it clear of the floating chat
       widget pinned to the same corner. */
    .dashboard-sidebar .dashboard-logout,
    .dashboard-sidebar .sidebar-footer {
        margin-bottom: 76px;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   SETTINGS FORM: inputs were browser-default width in a full-width card
   ══════════════════════════════════════════════════════════════════════════
   No width was ever declared on these fields, so they fell back to the UA
   default of ~208px inside a 1014px container — a column of tiny boxes
   stranded against acres of white, with the email address visibly truncated
   mid-value. Fill the field, and pair them into two columns on wide screens
   so the form reads as a form rather than a ribbon. */
.dashboard-container .dash-field input[type="text"],
.dashboard-container .dash-field input[type="email"],
.dashboard-container .dash-field input[type="tel"],
.dashboard-container .dash-field input[type="password"],
.dashboard-container .dash-field select,
.dashboard-container .dash-form input[type="text"],
.dashboard-container .dash-form input[type="email"],
.dashboard-container .dash-form input[type="tel"],
.dashboard-container .dash-form input[type="password"] {
    width: 100% !important;
    max-width: 420px;
    box-sizing: border-box;
}

.dashboard-container .dash-field {
    margin-bottom: 16px;
}

.dashboard-container .dash-field label {
    display: block;
    margin-bottom: 6px;
}

/* Two columns on desktop: the fields are short, so a single stack wastes the
   width the card already occupies. */
@media (min-width: 900px) {
    .dashboard-container .dash-form-grid,
    .dashboard-container .dash-card form .dash-fields {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0 24px;
    }
}

/* The intl-tel country dropdown rendered as a bare grey square next to the
   phone field; give it the same height as the input it sits against. */
.dashboard-container .iti,
.dashboard-container .iti__flag-container {
    width: 100%;
    max-width: 420px;
}

/* ══════════════════════════════════════════════════════════════════════════
   SIDEBAR COLUMN: no white void under Log Out on long pages
   ══════════════════════════════════════════════════════════════════════════
   The sidebar is `sticky` at `height: 100vh` so it stays pinned while the
   page scrolls — correct behaviour, but it means the dark panel is only ever
   one viewport tall. On a 1545px-high Settings page that left ~645px of bare
   white below it inside the sidebar's own column.

   Painting the column on the CONTAINER (rather than stretching the sidebar)
   keeps the sticky behaviour intact and costs no extra element: the strip is
   exactly the sidebar's width and spans the container's full height. */
@media (min-width: 992px) {
    .dashboard-container {
        background: linear-gradient(
            to right,
            #2D2D2D 0,
            #2D2D2D 240px,
            transparent 240px
        ) no-repeat;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   BOOKING / ORDER TABLES: column padding and row separators
   ══════════════════════════════════════════════════════════════════════════
   `th` carried `8px 18px 15px` but `td` only `15px 0` — zero horizontal
   padding. Header labels therefore sat 18px inboard of the data beneath them,
   so no column actually lined up, and the cells ran edge to edge with nothing
   between them. Rows also computed `border-bottom: 0px none`, leaving the
   list with no visual separation at all. Match the cells to the headers and
   give each row a hairline rule. */
.dashboard-container .dash-table td,
.dashboard-container #bookingsTable td,
.dashboard-container #ordersTable td {
    padding: 14px 18px !important;
    vertical-align: middle;
}

.dashboard-container .dash-table th,
.dashboard-container #bookingsTable th,
.dashboard-container #ordersTable th {
    padding: 10px 18px 12px !important;
}

.dashboard-container .dash-table tbody tr:not(:last-child) {
    border-bottom: 1px solid #EDEFF2 !important;
}

/* Actions column: keep the buttons from crowding each other. */
.dashboard-container .dash-table-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

/* ══════════════════════════════════════════════════════════════════════════
   TITLE SPACING: headings sat flush against the content below them
   ══════════════════════════════════════════════════════════════════════════
   Both the tab title and the card title computed `margin-bottom: 0`, so
   "My Bookings" and "All bookings" touched the toolbar/table directly. */
.dashboard-container .dashboard-tab-title {
    margin: 0 0 18px !important;
}

.dashboard-container .dash-card-title {
    margin: 0 0 14px !important;
}

.dashboard-container .dashboard-tab-head {
    margin-bottom: 18px;
}

/* The tab panel's own top offset — 27px of margin above the first heading
   duplicated the shell padding. */
.dashboard-container .dashboard-tab-panel > *:first-child {
    margin-top: 0 !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   TYPE SCALE: stop the theme forcing every dashboard heading to 35px
   ══════════════════════════════════════════════════════════════════════════
   Uncode injects an INLINE rule `h3:not([class*="fontsize-"]) { font-size:35px }`.
   An inline <style> block beats the plugin's stylesheet, so
   `.quick-action-title { font-size:16px }` was silently discarded and every
   h3 — "Book a Court", "Membership", "Activity", section headings — rendered
   at the same 35px. The result was no hierarchy at all: card labels shouted
   at the same volume as the page title while booking rows sat at 12px.

   These restore the plugin's intended scale. `!important` is required to beat
   the theme's inline block. */
.dashboard-container .quick-action-title {
    font-size: 17px !important;
    line-height: 1.3 !important;
}

.dashboard-container .dash-card-title,
.dashboard-container .dashboard-tab-title {
    font-size: 20px !important;
    line-height: 1.35 !important;
}

.dashboard-container h3:not([class*="fontsize-"]) {
    font-size: 18px !important;
    line-height: 1.35 !important;
}

/* Section headings ("Quick Actions", "Upcoming Bookings") sat at 29px, nearly
   as loud as the 35px page title. One clear step down. */
.dashboard-container .section-title,
.dashboard-container .dashboard-content h2:not([class*="fontsize-"]) {
    font-size: 21px !important;
    line-height: 1.35 !important;
}

/* The welcome line is the one legitimately large element; 35px is oversized
   next to a 21px section heading. */
.dashboard-container .dashboard-welcome,
.dashboard-container .dashboard-header h1 {
    font-size: 26px !important;
    line-height: 1.25 !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   QUICK ACTION CARDS: 253px tall for one icon and one word
   ══════════════════════════════════════════════════════════════════════════
   `padding: 40px 30px` was tuned when the label was 16px. With the theme
   inflating it to 35px the cards ballooned and the text stranded in the
   middle. Now the type is corrected, the padding can come back too. */
.dashboard-container .quick-action-card {
    padding: 22px 18px !important;
    gap: 10px;
}

/* ══════════════════════════════════════════════════════════════════════════
   VERTICAL RHYTHM: 45px between every section is too airy at this type scale
   ══════════════════════════════════════════════════════════════════════════ */
.dashboard-container .dashboard-header,
.dashboard-container .quick-actions-section,
.dashboard-container .upcoming-bookings-section {
    margin-bottom: 28px !important;
}

.dashboard-container .dashboard-bottom-grid {
    margin-bottom: 24px !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   SIDEBAR: full height + the page must scroll from anywhere
   ══════════════════════════════════════════════════════════════════════════
   The sidebar computed to `position: fixed; height: 900px` (one viewport),
   which caused BOTH reported problems:

     * it stopped ~324px short of the content, leaving a white void under
       Log Out on any page taller than the viewport;
     * being fixed with `overflow-y: hidden`, it swallowed wheel events over
       the whole left 240px — so the page would not scroll unless you grabbed
       the scrollbar itself.

   `sticky` keeps it visually pinned while leaving it in normal flow, so the
   document scrolls from anywhere and the dark panel spans the full column.
   The plugin's own `position: fixed` is more specific in source order, hence
   !important. */
@media (min-width: 992px) {
    .dashboard-sidebar {
        position: sticky !important;
        top: 0;
        height: 100vh !important;
        max-height: 100vh;
        overflow-y: auto !important;
        align-self: flex-start;
        flex: 0 0 240px;
    }

    /* A `fixed` sidebar was out of flow, so the content reserved space for it
       with `margin-left: 240px`. Now that it is `sticky` it occupies a real
       flex column — keeping the margin would indent the content by a second
       240px and shrink the usable area. */
    .dashboard-content {
        margin-left: 0 !important;
    }

    /* The shell must be a flex row for the sticky column to sit beside the
       content rather than above it. */
    .dashboard-container {
        display: flex;
        align-items: flex-start;
    }
}

/* The sidebar only becomes an off-canvas drawer at <=768px (dashboard.css:
   `.dashboard-sidebar { transform: translateX(-100%) }`). Between 769px and
   991px it is still ON SCREEN at 200px wide, and the plugin correctly pairs
   that with `margin-left: 200px` on the content.

   This block used to fire at <=991px and killed that margin while the sidebar
   was still visible, so the first 200px of every table (customer name, email)
   sat hidden underneath it -- reported at 974px on the staff Customers tab.
   Scope it to the drawer breakpoint so the two agree. */
@media (max-width: 768px) {
    .dashboard-content {
        margin-left: 0 !important;
        padding: 20px 16px 40px !important;
    }
}


/* --- Keep the sidebar's Log Out clear of the floating chat bubble -------- */
/* The site's WhatsApp widget is fixed bottom-left, exactly where the sidebar
   footer sits, and was covering the Log Out control. Lift the footer above it
   rather than moving the widget, which belongs to the theme. */
/* Applies from 769px up, i.e. whenever the sidebar is actually on screen --
   NOT from 992px. Scoped to 992px it left Log Out sitting under the chat
   bubble across the whole 769-991px tablet band. */
@media (min-width: 769px) {
    .dashboard-sidebar .dashboard-logout,
    .dashboard-sidebar .sidebar-footer {
        margin-bottom: 72px;
    }
}


/* ── Mobile: content must be allowed to shrink, and clear the fixed header ──
   Two separate faults found at 390px on 2026-08-19.

   1) `.dashboard-container` is display:flex and `.dashboard-content` is a flex
      item. A flex item defaults to `min-width:auto`, which refuses to shrink
      below its content's intrinsic width — so on the staff dashboard the main
      column measured 602px inside a 375px viewport. Because `.dashboard-content`
      also carries `overflow-x: clip` (added earlier to stop page jitter), the
      document reported ZERO overflow while ~227px of every card, stat and table
      was silently cut off and unreachable. `min-width: 0` is the canonical
      release for this; genuinely wide descendants still scroll inside their own
      `.staff-table-wrap { overflow-x:auto }`.

      Same failure mode as the wizard's side-by-side time selects — min-width
      beats flex shrinking. Worth recognising on sight.

   2) The mobile header (`.dashboard-hamburger-btn-wrap`) is fixed, 60px tall,
      z-index 1100. The content only had 20px of top padding, so the customer
      dashboard's "Welcome Back, …" greeting rendered underneath it —
      elementFromPoint at the greeting's centre returned the header, not the
      heading. Pad the content past the header instead of moving the header. */
@media (max-width: 991px) {
    /* Safe at any width: only releases the flex-shrink floor. */
    .dashboard-content { min-width: 0 !important; }
}

/* The paddings below compensate for the fixed mobile header and the floating
   chat bubble, both of which only exist once the drawer takes over at 768px.
   Applying them at 991px pushed content down 76px on tablets that have a
   normal visible sidebar and no fixed header. */
@media (max-width: 768px) {
    .dashboard-content {
        padding-top: 76px !important;   /* 60px header + 16px breathing room */
        /* Bottom clearance. The previous 40px was not enough to clear the
           60px floating chat bubble plus browser chrome, so the final row of
           the last card ("Late Cancels", "Book Again") sat under the window
           edge and read as unscrollable. Reserve real space instead. */
        padding-bottom: 240px !important;
    }

    /* Belt-and-braces: a spacer after the last card guarantees the final row
       clears the window edge even when the OS taskbar or browser chrome eats
       part of the reported viewport, which is why padding alone kept coming up
       short on the reporter's machine. */
    .dashboard-content > *:last-child {
        margin-bottom: 80px !important;
    }
}


/* -- Mobile: let JS show/hide beat the card-ification rule ------------------
   At <=768px dashboard.css turns the tables into stacked cards with
   `.dash-table, .dash-table thead, .dash-table tbody, .dash-table tr {
    display: block !important }`.

   That `!important` outranks the inline `display:none` jQuery writes, so
   `.hide()` silently does nothing on mobile. Every JS-driven show/hide on
   these tables was therefore dead below 768px: the My Bookings filter chips
   (All / Upcoming / Completed / Cancelled) appeared to do nothing, and the
   10-per-page pagination showed every row at once. Desktop was unaffected,
   which is why this only ever reproduced on a phone.

   Re-assert the hidden state at the same weight, keyed off the inline style
   jQuery sets. Fixes the filters, the bookings pagination and the orders
   pagination in one place, without touching dashboard.js. */
@media (max-width: 768px) {
    .dash-table tr[style*="display: none"],
    .dash-table tr[style*="display:none"],
    .staff-table tr[style*="display: none"],
    .staff-table tr[style*="display:none"] {
        display: none !important;
    }
}

/* Slot section dividers: keep the range hint on the title's baseline.
 *
 * The dividers render as  <div class="…slot-section-label">
 *                             <span>Early morning</span><small>00:00 – 06:00</small>
 *                         </div>
 * inside a flex row. Uncode's global typography rule
 *
 *     p, li, dt, dd, dl, address, label, small, pre, code, span.tab-excerpt
 *         { line-height: 1.75; margin: 18px 0 0; }
 *
 * matches the bare <small>, so the hint inherits an 18px top margin and a 1.75
 * line-height. That dropped it ~6px below the title it is meant to sit beside and
 * inflated its box from 14px to 19px, breaking the dashed rule either side of it.
 * The plugin's own `.slot-section-label small` rules set margin-LEFT but never
 * reset margin-top, so the theme kept winning the top edge.
 *
 * All three surfaces build the same markup, so all three are reset here:
 *   .slot-section-label            — booking wizard      (booking-wizard.js)
 *   .reschedule-slot-section-label — customer dashboard  (booking-actions.js)
 *   .walkin-slot-section-label     — staff dashboard     (staff-dashboard.js)
 */
.slot-section-label small,
.reschedule-slot-section-label small,
.walkin-slot-section-label small {
    margin-top: 0;
    margin-bottom: 0;
    line-height: 1;
}
