/*
 * BackOffice base-page design system.
 * Ported from the approved base page template (BO_Base_Page_Template_v0.1).
 * Primitives are `bp-` namespaced and read design tokens below so a token change
 * recolours the whole system. Theme colours come from MudBlazor's --mud-palette-*.
 */

:root {
    /* yzen template tokens (Spruko) — cool blue-grey canvas, white surfaces,
       #e2e5e7 hairline borders, emerald accent, soft shadows, 8px radius. */
    --bp-bg: #F2F4F9;
    --bp-surface: #ffffff;
    --bp-surface-alt: #f9fafb;
    --bp-border: #e2e5e7;
    --bp-border-soft: #eeedf3;
    --bp-border-strong: #d3d9e2;
    --bp-text: #212529;
    --bp-text-muted: #61748f;
    --bp-text-faint: #8d9eb5;
    --bp-text-ghost: #a9b4c7;
    --bp-accent: #03B562;
    --bp-accent-strong: #029a53;
    --bp-accent-bg: rgba(3, 181, 98, 0.1);
    /* Selected grid row (§4.2): reads the yzen brand primary rather than the emerald --bp-accent,
       so the row tint and its left indicator bar (var(--mud-palette-primary), which yzen maps to
       rgb(var(--primary-rgb)) in assets/css/styles.css) are the same colour. Derived from
       --primary-rgb so a brand change recolours both together. */
    --bp-selected-bg: rgba(var(--primary-rgb), 0.1);
    /* Arctic blue — the sidebar's selected/active nav accent (design request 2026-07-16). Scoped to
       the nav rules below so the emerald --bp-accent stays the app-wide accent (filter chips,
       badges, sort carets). */
    --bp-nav-accent: #137AA7;
    --bp-nav-accent-bg: rgba(19, 122, 167, 0.1);
    --bp-radius: 8px;
    --bp-radius-md: 6px;
    --bp-radius-sm: 6px;
    /* Shared height for toolbar filter controls (search / pills / pickers) — matches
       the outlined-dense MudBlazor input so every filter lines up (§10.4). */
    --bp-filter-h: 40px;
    --bp-shadow-pane: -12px 0 40px rgba(20, 20, 43, 0.08);
    --bp-shadow-menu: 0 0.5rem 1rem rgba(20, 20, 43, 0.08);

    /* Bulk-action bar (§10.5): a dark filled rounded card that replaces the chip row
       while rows are selected. Reference design note (2026-07-13). */
    --bp-bulkbar-bg: #1f2733;
    --bp-bulkbar-fg: #ffffff;
    --bp-bulkbar-btn-border: rgba(255, 255, 255, 0.28);
    --bp-bulkbar-btn-hover: rgba(255, 255, 255, 0.12);
    --bp-bulkbar-danger: #ff8a9a;

    /* Dark surface + on-dark text (§10.14): the emphasised dark KPI/summary card (e.g. NPS score).
       Kept as tokens so the dark card tracks a palette change instead of baking hexes into markup. */
    --bp-surface-dark: #1f2733;
    --bp-on-dark: #ffffff;
    --bp-on-dark-muted: rgba(255, 255, 255, 0.7);
    --bp-on-dark-faint: rgba(255, 255, 255, 0.55);

    /* Soft semantic tints (§10.14): translucent fill + readable dark-ish foreground for inline
       chips/pills/alerts that aren't yzen `.badge`s. yzen exposes no --mud-palette-*-rgb vars, so
       these are named tokens (values match the previously hard-coded hexes 1:1 — no visual change).
       secondary = the violet accent (#7F67FF), plus warning / info / error families. */
    --bp-tint-secondary-bg: rgba(127, 103, 255, 0.12);
    --bp-tint-secondary-border: rgba(127, 103, 255, 0.3);
    --bp-tint-secondary-fg: #5b46d6;
    --bp-tint-secondary-fg-strong: #3c3489;
    --bp-tint-warning-bg: rgba(255, 169, 9, 0.14);
    --bp-tint-warning-fg: #b9770a;
    --bp-tint-info-bg: rgba(15, 188, 249, 0.12);
    --bp-tint-info-fg: #0a7fa8;
    --bp-tint-error-bg: #fdecea;
    --bp-tint-error-border: rgba(211, 47, 47, 0.3);
    --bp-tint-error-fg: #c62828;
    --bp-tint-success-bg: rgba(83, 196, 5, 0.08);
    --bp-tint-success-border: rgba(83, 196, 5, 0.35);
    --bp-tint-success-fg: #3a8a05;
    /* Softer secondary-tint variants: an even fainter fill (hover / editing-row) and a stronger
       violet border for an active/drag-over card. */
    --bp-tint-secondary-bg-soft: #faf9fe;
    --bp-tint-secondary-bg-hover: rgba(127, 103, 255, 0.06);
    --bp-tint-secondary-border-strong: #7f77dd;

    /* Section accent dots (navigation groups) — yzen-friendly hues. */
    --bp-dot-customer: #53C405;
    --bp-dot-booking: #FFA909;
    --bp-dot-product: #FE7C58;
    --bp-dot-revenue: #0FBCF9;
    --bp-dot-loyalty: #7F67FF;
    --bp-dot-admin: #8d9eb5;
}

/* ═══ PAGE HEADER ═══ */
.bp-page-breadcrumb {
    font-size: 11px;
    color: var(--bp-text-faint);
    margin-bottom: 4px;
}

    .bp-page-breadcrumb b {
        color: var(--bp-text-muted);
        font-weight: 500;
    }

.bp-page-title {
    font-size: 20px;
    font-weight: 600;
    color: var(--bp-text);
    margin-bottom: 2px;
}

.bp-page-sub {
    font-size: 13px;
    color: var(--bp-text-muted);
    margin-bottom: 16px;
}

/* ═══ LIST + PANE SPLIT ═══ */
/* The list region owns the full width; the details pane is position:fixed (see .bp-details-pane
   below), so it is out of this flex flow and OVERLAYS the list at 40% width when open — the list
   is never squeezed. */
.bp-split {
    display: flex;
    align-items: stretch;
    position: relative;
    min-height: calc(100vh - 140px);
}

/* ═══ CARD ═══ */
.bp-card {
    background: var(--bp-surface);
    border: 0.5px solid var(--bp-border);
    border-radius: var(--bp-radius);
    margin-bottom: 12px;
    overflow: hidden;
}

/* ═══ TOOLBAR ═══ */
.bp-toolbar {
    display: flex;
    /* Align controls on their bottom edge: outlined inputs float their label above the
       field, so a shared bottom baseline lines the fields (and the filter pill) up. */
    align-items: flex-end;
    gap: 16px;
    margin-bottom: 10px;
    flex-wrap: wrap;
    mix-blend-mode: multiply;
}

.bp-toolbar-spacer {
    flex: 1;
}

/* One shared control height (§10.4) so the search box, filter-menu pills, date
   pickers and selects sit on a single baseline. The outlined-dense MudBlazor input
   computes to 40px (10.5+10.5 padding + 19 slot); the outlined menu pill only
   computes to ~32px (5+5 padding + 1+1 border + 20 label), so it needs pinning up.
   !important guards against MudBlazor's own variant/size rules winning the cascade. */
.bp-toolbar .filter-select .mud-input.mud-input-outlined,
.bp-toolbar .bp-filter-btn .mud-button-root,
.bp-toolbar .bp-filter-btn.mud-button-root {
    height: var(--bp-filter-h) !important;
    min-height: var(--bp-filter-h) !important;
    box-sizing: border-box;
}

/* ═══ FILTER INPUTS (search + date pickers) ═══ */
/* The outlined MudBlazor filter inputs (search box, date pickers) share the exact
   border, radius, hover and text/placeholder colour of the FilterMenu pill so the
   whole toolbar reads as one set of controls (§10.4). MudBlazor's outlined border
   defaults to a darker line (--mud-palette-lines-inputs, which yzen leaves unset);
   pin it to the same yzen hairline the pill uses instead. */
.bp-toolbar .filter-select .mud-input-outlined-border {
    border-color: var(--bp-border) !important;
    border-width: 1px !important;
    border-radius: var(--bp-radius-sm);
}

.bp-toolbar .filter-select .mud-input-outlined:hover .mud-input-outlined-border {
    border-color: var(--bp-border-strong) !important;
}

/* Placeholder text and the leading/trailing adornment icons read in the same
   muted/faint palette as the pill's label and chevron, so the search prompt, the
   date-picker prompts and "Status" all match at rest. */
.bp-toolbar .filter-select input::placeholder {
    color: var(--bp-text-muted);
    opacity: 1;
}

.bp-toolbar .filter-select .mud-input-adornment .mud-icon-root {
    color: var(--bp-text-faint);
}

/* ═══ FILTER MENU (§10.4) ═══ */
/* The dropdown filter is styled to read as a yzen outlined-dense input (the same
   language as MudSelect): white surface, hairline border, 6px radius, a left-pinned
   caption and a faint chevron hard against the right edge. At rest the caption is the
   filter's name ("Status") and reads as a PROMPT, so it takes the same muted colour as
   an empty input's placeholder. With a value applied it reads "Status: Confirmed" —
   see the --selected rule below. */
.bp-toolbar .bp-filter-btn .mud-button-root,
.bp-toolbar .bp-filter-btn.mud-button-root {
    min-width: 150px;
    justify-content: space-between;
    padding: 0 8px 0 14px;
    text-transform: none;
    font-weight: 400;
    font-size: 0.8125rem;
    color: var(--bp-text-muted);
    background: var(--bp-surface);
    border: 1px solid var(--bp-border);
    border-radius: var(--bp-radius-sm);
    box-shadow: none;
}

/* An applied filter's caption is CONTENT, not a prompt, so it drops the muted colour
   for normal text — the same distinction as a filled input's value vs its placeholder.
   Without this an active filter reads as faint as an inactive one, which is exactly
   the signal the caption exists to give (§4.4).

   Matches both forms because MudMenu may put Class on its wrapper or straight onto the
   activator button (the base rule above hedges the same way); equal specificity to that
   rule, so it must stay AFTER it to win. The chevron keeps --bp-text-faint: it is
   chrome, not content. */
.bp-toolbar .bp-filter-btn--selected .mud-button-root,
.bp-toolbar .bp-filter-btn--selected.mud-button-root {
    color: var(--bp-text);
}

/* Let the label span the free width so text stays left and the chevron sits right. */
.bp-toolbar .bp-filter-btn .mud-button-label {
    width: 100%;
    justify-content: space-between;
}

/* Chevron: faint and sized like a select's dropdown arrow (no button-icon margin). */
.bp-toolbar .bp-filter-btn .mud-button-label .mud-icon-root {
    margin: 0;
    font-size: 1.25rem;
    color: var(--bp-text-faint);
}

/* Hover matches an outlined input (darker hairline, surface stays white) — not the
   grey fill a default MudButton would take. */
.bp-toolbar .bp-filter-btn .mud-button-root:hover {
    border-color: var(--bp-border-strong);
    background: var(--bp-surface);
}

/* Two MudBlazor quirks knock the pill off the inputs' baseline:
   1. MudMenu's root sets `align-self: center`, fighting the toolbar's `flex-end`.
   2. Dense inputs carry `.mud-input-control-margin-dense { margin: 4px 0 }`, so their
      bordered box sits 4px ABOVE the flex-item bottom. The menu wrapper has no such
      margin, so `flex-end` dropped the pill's border 4px BELOW the inputs' borders.
   Pin the wrapper to `flex-end` and mirror the 4px bottom margin so every bordered
   control shares exactly one bottom edge. */
.bp-toolbar .bp-filter-btn {
    align-self: flex-end !important;
    margin-bottom: 4px;
}

/* ═══ FILTER CHIPS ═══ */
/* MudChip-based active-filter row (see FilterChips.razor). The row lays out the chipset + the
   "Clear all" text button; chip visuals come from MudBlazor, nudged to the compact base-page
   scale and muted palette. */
.bp-chip-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 12px;
    flex-wrap: wrap;
    min-height: 24px;
}

    /* Solid emerald (Filled Primary) chip at the compact base-page scale; the filled variant
       supplies the emerald fill + white text, so we only set size/spacing here. */
    .bp-chip-row .mud-chip {
        margin: 0;
        font-size: 12px;
    }

    .bp-chip-row .mud-chip b {
        font-weight: 600;
    }

.bp-chip-clear-btn.mud-button-root {
    font-size: 12px;
    font-weight: 400;
    text-transform: none;
    color: var(--bp-text-faint);
    min-width: 0;
    padding: 0 6px;
}

    .bp-chip-clear-btn.mud-button-root:hover {
        color: var(--bp-text);
        background: transparent;
    }

/* ═══ DATATABLE CARD (§4.5) ═══ */
/* StandardGrid's own presentation (grid card, tinted toolbar surface, separators, header weight,
   row states, sort-caret affordance, custom pager, bulk-action bar) lives in its scoped companion
   StandardGrid.razor.css (§2/§6/§8.5), not here. Only the shared .bp-bulk-btn pill (owned by
   BulkActionButton) remains global. */

/* White outlined pill buttons on the dark bar. Targets the MudButton rendered by
   BulkActionButton so pages stay declarative. */
.bp-bulk-btn.mud-button-root {
    text-transform: none;
    color: var(--bp-bulkbar-fg);
    border-color: var(--bp-bulkbar-btn-border);
    border-radius: 20px;
    padding: 3px 14px;
    min-width: 0;
    background: transparent;
}

.bp-bulk-btn.mud-button-root:hover {
    background: var(--bp-bulkbar-btn-hover);
    border-color: rgba(255, 255, 255, 0.5);
}

.bp-bulk-btn--danger.mud-button-root {
    color: var(--bp-bulkbar-danger);
}

/* ═══ STATUS BADGES ═══ */
.bp-badge {
    display: inline-block;
    font-size: 11px;
    padding: 2px 8px;
    border-radius: 20px;
    font-weight: 500;
    white-space: nowrap;
}

.bp-badge-active {
    background: rgba(3, 181, 98, 0.1);
    color: #029a53;
}

.bp-badge-draft {
    background: rgba(255, 169, 9, 0.14);
    color: #b9770a;
}

.bp-badge-archived {
    background: #eef0f3;
    color: #61748f;
}

.bp-badge-cancelled {
    background: rgba(253, 73, 99, 0.12);
    color: #d81b3f;
}

/* ═══ DETAILS PANE (Asana-style slide-in) ═══ */
.bp-list-region {
    flex: 1;
    min-width: 0;
    /* Bounded to the viewport (a flex column of fixed height) so a list can never grow the PAGE:
       the grid card below the page title/toolbar is flex:1 and takes the leftover height, then
       scrolls its own rows INSIDE the grid (see StandardGrid.razor.css). This region itself does
       not scroll for a StandardGrid page — the grid fits exactly — so the scroll stays in the grid,
       not here; overflow-y:auto is only a fallback for any non-grid content taller than the region.
       The 140px offset clears the fixed app-header + page padding (matches .bp-split's floor). */
    display: flex;
    flex-direction: column;
    height: calc(100vh - 140px);
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
}

/* The pane is a FIXED drawer flush to the screen's right edge (§10.2), below the fixed 4.35rem
   app-header. position:fixed pins it to the viewport — so its right edge is the actual screen
   edge (not the page container it lives inside), and being out of flow it cannot
   overflow its parent. It starts fully off-screen (translateX(100%)) and slides in from the edge
   to translateX(0). It is 40% of the viewport width and OVERLAYS the list — the content is NOT
   pushed aside; the pane floats above it (z-index) with a soft seam shadow marking the edge.

   Width keeps a floor so the pane stays usable when 40% would be too narrow for the property
   grid / tabs / fields the pane pattern assumes: max(40%, …) takes the larger of 40% and the
   previous min(480px, 92vw) rule, so wide screens get 40% (1920px → 768px), mid screens settle
   at the old 480px, and narrow ones fall back to 92vw (375px → 345px) instead of ~150px. */
.bp-details-pane {
    position: fixed;
    top: 4.35rem;
    right: 0;
    bottom: 0;
    width: max(40%, min(480px, 92vw));
    background: var(--bp-surface);
    transform: translateX(100%);
    transition: transform .28s cubic-bezier(0.4, 0, 0.2, 1);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    z-index: 40;
}

    .bp-details-pane.bp-open {
        transform: translateX(0);
        box-shadow: var(--bp-shadow-pane);
    }

/* Inner fills the fixed drawer; the whole drawer slides, so the inner is a plain flex column. */
.bp-pane-inner {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
}

    /* Focused programmatically on open (so Esc works) — don't paint a ring around the whole pane. */
    .bp-pane-inner:focus,
    .bp-pane-inner:focus-visible {
        outline: none;
    }

    /* Temporarily locked while a list bulk action runs (the element is also `inert`): dim + wait
       cursor so the user sees why clicks don't land during the (brief) bulk loop. */
    .bp-pane-inner.bp-pane-busy {
        opacity: 0.6;
        cursor: wait;
        transition: opacity 0.12s ease;
        /* `inert` (on the element) is the real guard — blocks clicks/focus/keyboard. This is a
           mouse-only fallback for any browser without inert support. */
        pointer-events: none;
    }

/* The pane OVERLAYS the content — the page is deliberately NOT padded/pushed while a pane is
   open (§10.1). The fixed drawer floats above the list (z-index + seam shadow); the list stays
   put at full width underneath. */

@media (prefers-reduced-motion: reduce) {
    .bp-details-pane {
        transition: none;
    }
}

.bp-pane-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border-bottom: 0.5px solid var(--bp-border);
    flex-shrink: 0;
    min-height: 52px;
}

.bp-pane-body {
    flex: 1;
    min-height: 0; /* allow the flex child to shrink so its own scrollbar engages (overflow stays inside the pane) */
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px;
}

.bp-pane-footer {
    flex-shrink: 0;
    border-top: 0.5px solid var(--bp-border-soft);
    padding: 10px 12px;
    font-size: 11px;
    color: var(--bp-text-ghost);
    background: var(--bp-surface-alt);
}

.bp-save-hint {
    font-size: 11px;
    color: var(--bp-text-faint);
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

    .bp-save-hint .bp-save-dot {
        width: 6px;
        height: 6px;
        border-radius: 50%;
        background: var(--bp-dot-customer);
    }

    .bp-save-hint.bp-saving .bp-save-dot {
        background: var(--bp-text-ghost);
    }

/* Pane title field — the entity name reads as a heading. `input` for editable panes,
   the element itself for read-only panes that render the title as plain text. */
.bp-pane-title-field input,
div.bp-pane-title-field {
    font-size: 20px;
    font-weight: 600;
}

div.bp-pane-title-field {
    margin-bottom: 8px;
}

/* Leading back arrow shown when a pane is stacked over another (cross-entity nav, §4.9).
   Pulled left to sit flush with the header padding like the trailing close button. */
.bp-pane-back {
    margin-left: -6px;
}

/* ═══ PROPERTY GRID + SECTION TITLES ═══ */
.bp-prop-grid {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 2px 12px;
    margin-bottom: 18px;
    align-items: center;
}

.bp-prop-label {
    font-size: 12px;
    color: var(--bp-text-faint);
    padding: 8px 0;
    display: flex;
    align-items: center;
}

.bp-prop-value {
    min-width: 0;
}

.bp-section-title {
    font-size: 12px;
    font-weight: 500;
    color: #999;
    text-transform: uppercase;
    letter-spacing: .06em;
    margin: 18px 0 8px;
}

.bp-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: 18px 0 8px;
}

    .bp-section-head .bp-section-title {
        margin: 0;
    }

/* ═══ ACTIVITY TIMELINE ═══ */
.bp-timeline {
    padding: 4px 0;
}

.bp-timeline-item {
    display: flex;
    gap: 12px;
    padding: 8px 0;
    position: relative;
}

    .bp-timeline-item:not(:last-child)::before {
        content: '';
        position: absolute;
        left: 11px;
        top: 28px;
        bottom: -8px;
        width: 1px;
        background: var(--bp-border);
    }

.bp-timeline-dot {
    width: 23px;
    height: 23px;
    border-radius: 50%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    margin-top: 1px;
}

    .bp-timeline-dot.bp-green {
        background: rgba(3, 181, 98, 0.12);
        color: #029a53;
        border: 1px solid rgba(3, 181, 98, 0.3);
    }

    .bp-timeline-dot.bp-blue {
        background: rgba(15, 188, 249, 0.12);
        color: #0a7fa8;
        border: 1px solid rgba(15, 188, 249, 0.3);
    }

    .bp-timeline-dot.bp-gray {
        background: #f2f4f5;
        color: #61748f;
        border: 1px solid #e2e5e7;
    }

.bp-timeline-content {
    flex: 1;
}

.bp-timeline-action {
    font-size: 13px;
    font-weight: 500;
    margin-bottom: 1px;
}

.bp-timeline-meta {
    font-size: 11px;
    color: var(--bp-text-faint);
}

/* ═══ SETTINGS ROWS (explicit controls, per note 11) ═══ */
.bp-settings-layout {
    display: flex;
    gap: 16px;
    align-items: stretch;
    /* Fill the viewport-bounded .bp-list-region so the content column can own its own scroll
       (min-height:0 lets the flex children shrink below their content size). No max-width cap:
       embedded module pages (Journeys, API keys, connectors) bring their own list + pane and
       need the full content width to lay out. */
    flex: 1;
    min-height: 0;
}

.bp-settings-nav {
    width: 210px;
    flex-shrink: 0;
    /* Only as tall as its items — the content column stretches/scrolls, the nav does not. */
    align-self: flex-start;
    background: var(--bp-surface);
    border: 0.5px solid var(--bp-border);
    border-radius: var(--bp-radius);
    padding: 10px;
}

.bp-set-nav-item {
    padding: 7px 10px;
    border-radius: var(--bp-radius-sm);
    font-size: 13px;
    color: var(--bp-text-muted);
    cursor: pointer;
    margin-bottom: 2px;
}

    .bp-set-nav-item:hover {
        background: #f5f6f7;
    }

    .bp-set-nav-item.bp-active {
        background: var(--bp-accent-bg);
        color: var(--bp-accent-strong);
        font-weight: 500;
    }

/* Section header in the settings vertical sub-nav (grouped layout). */
.bp-set-nav-section {
    font-size: 12px;
    font-weight: 700;
    color: var(--bp-text);
    padding: 16px 10px 6px;
}

    .bp-set-nav-section:first-child {
        padding-top: 4px;
    }

.bp-settings-content {
    flex: 1;
    min-width: 0;
    /* Content never grows the page: it fills the bounded layout and scrolls INSIDE this container
       when an embedded module page is taller than the viewport. */
    min-height: 0;
    height: 100%;
    overflow-y: auto;
}

/* Each setting is its own card (name + description left, control right) — modelled on the
   reference Settings layout's stacked toggle cards. */
.bp-setting-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    background: var(--bp-surface);
    border: 0.5px solid var(--bp-border);
    border-radius: var(--bp-radius);
    padding: 18px 20px;
    margin-bottom: 12px;
}

.bp-setting-info {
    flex: 1;
}

.bp-setting-name {
    font-size: 13px;
    font-weight: 500;
    margin-bottom: 2px;
}

.bp-setting-desc {
    font-size: 12px;
    color: var(--bp-text-muted);
    line-height: 1.5;
}

.bp-setting-control {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ═══ REFERENCED-COLLECTION HINT ═══ */
.bp-ref-hint {
    font-size: 11px;
    color: #999;
    margin-top: 8px;
    line-height: 1.5;
}

/* ═══ PAGE CONTENT CONTAINER ═══
   Wraps every module page's content in the area to the right of the sidebar, with a flat 16px
   padding at every breakpoint. There is no max-width cap, so the container spans the full content
   area and margin-inline:auto is inert — it is kept as the hook that would centre the column if a
   cap is ever introduced. */
.bp-page-container {
    margin-inline: auto;
    padding: 16px;
}

/* ═══ COLLAPSED SIDEBAR LOGO ═══
   yzen swaps in a small "toggle" logo when the sidebar collapses to the icon rail, but we ship a
   single wide brand logo. So hide the logo entirely while the rail is collapsed (icon-overlay,
   not hover-expanded); it reappears at full width and while hovered open. */
/* !important beats yzen's per-variant show rule (e.g. [data-menu-styles=dark]…toggle-dark
   { display:block }, specificity 0,8,0) which otherwise keeps a logo variant visible. */
[data-vertical-style="overlay"][data-toggled="icon-overlay-close"]:not([data-icon-overlay="open"]) .app-sidebar .main-sidebar-header .header-logo img {
    display: none !important;
}

/* ═══ NATIVE SIDEBAR SCROLL ═══
   The menu column used to scroll via a Blazor overlay-scrollbar component (WMBOS), which was
   removed together with the server-side nav (every gesture cost a SignalR round-trip and lagged
   on staging). yzen sets `.main-sidebar { height: 100vh }` assuming that inner component owns the
   scroll; with plain markup we cap it to the space below the fixed header and scroll natively. */
.app-sidebar .main-sidebar {
    height: calc(100vh - 4.25rem);
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    scrollbar-width: thin;
}
/* Sub-menu accordion: keep collapsed groups hidden until the client JS slides them open.
   The height animation is applied inline by sidebar-nav.js. */
.app-sidebar .slide.has-sub > .side-menu__item {
    cursor: pointer;
}

/* ═══ SIDEBAR SUB-ITEM HOVER & ACTIVE STATE ═══
   Two yzen defaults read wrong for us on the leaf links (e.g. "Bookings" under Bookings):
     1. yzen positions the sub-item bullet (:before) 4px OUTSIDE the item box, so on hover the
        bullet overhangs the highlight to the left.
     2. yzen gives the active sub-item a transparent background (only the parent rail item ever
        tints), so the current page is indistinguishable from its siblings.
   Fix: move the indentation off the <li> and onto the item's own padding so the item's
   background (hover/active) extends far enough left to contain the bullet; then give the active
   row a distinct emerald tint + emerald text/bullet so the current page always reads.
   The [data-menu-styles=light] prefix (the app's only menu style — see backoffice-ui.md §10.14)
   matches yzen's .child1/.child2/.child3 specificity so these — loading after styles.css — win. */
[data-menu-styles=light] .app-sidebar .slide-menu li {
    /* Was 2.25rem on the <li>; shift most of the indent onto the item (below) so its
       highlight box reaches left of the bullet. Text indent is preserved (1.5 + 1.75rem). */
    padding-inline-start: 1.5rem;
}
[data-menu-styles=light] .app-sidebar .slide-menu .side-menu__item {
    padding-inline-start: 1.75rem;   /* room for the bullet inside the highlight box */
    margin-inline-end: 0.5rem;
    border-radius: var(--bp-radius);  /* fully rounded pill (yzen squares off the left edge) */
}
[data-menu-styles=light] .app-sidebar .slide-menu .side-menu__item:before,
[data-menu-styles=light] .app-sidebar .slide-menu .side-menu__item.active:before {
    inset-inline-start: 0.6rem;       /* bullet now sits inside the item's padding box */
}
/* Active leaf: arctic-blue tint + arctic-blue text/bullet (yzen left this transparent). */
[data-menu-styles=light] .app-sidebar .slide-menu .side-menu__item.active {
    background-color: var(--bp-nav-accent-bg);
    color: var(--bp-nav-accent);
    font-weight: 600;
}
[data-menu-styles=light] .app-sidebar .slide-menu .side-menu__item.active:before {
    color: var(--bp-nav-accent);
    opacity: 1;
}
/* Parent section header of the active leaf: tint its label + icon arctic-blue too, so the section
   that owns the current page reads as active even when scanning the collapsed top level. Keyed
   off the active descendant via :has() — no JS change; the leaf already carries .active. */
[data-menu-styles=light] .app-sidebar .slide.has-sub:has(.slide-menu .side-menu__item.active) > .side-menu__item .side-menu__label {
    color: var(--bp-nav-accent);
}
[data-menu-styles=light] .app-sidebar .slide.has-sub:has(.slide-menu .side-menu__item.active) > .side-menu__item .side-menu__icon {
    color: var(--bp-nav-accent);
    fill: var(--bp-nav-accent);
}

/* Global navigation progress bar (§10 reactivity): a thin fixed accent bar pinned to the
   very top of the viewport while an internal navigation is in flight. Sits above the fixed
   app-header so the click is acknowledged instantly. */
.bp-nav-progress {
    position: fixed;
    top: 0;
    inset-inline: 0;
    height: 3px;
    z-index: 1200;
}