/* Brand script face used for tagline / welcome headings (Event Landing,
   future marketing surfaces). Self-hosted under /fonts so we don't take
   a runtime dependency on jbfsale.com or a third-party CDN.
   font-display:swap renders the fallback (sans-serif) immediately and
   re-paints with Authenia as soon as the file finishes downloading -
   no FOIT (flash of invisible text) on first load. */
@font-face {
    font-family: "Authenia";
    src: url("/fonts/FontsFree-Net-Authenia.ttf") format("truetype");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

:root {
    /* Toast / Growl notifications
       Radzen DOM: .rz-growl-container > .rz-growl-message-{severity} > .rz-growl-item
       Uses --jbf-toast-* tokens (JBF brand colors, fully opaque).
       Radzen maps Warning -> rz-growl-message-warn (short form). */

    /* Reset Radzen base padding */
    .rz-growl-item {
        padding: 0 !important;
    }

    /* Outer wrapper - the visible card */
    .rz-growl-message-info,
    .rz-growl-message-success,
    .rz-growl-message-warn,
    .rz-growl-message-error {
        border-radius: 12px;
        overflow: hidden;
        box-shadow: 0 2px 12px rgba(13, 29, 37, 0.08), 0 1px 3px rgba(0, 0, 0, 0.06);
        margin-bottom: 8px;
    }

    /* Inner item - inherits card background */
    .rz-growl-message-info > .rz-growl-item,
    .rz-growl-message-success > .rz-growl-item,
    .rz-growl-message-warn > .rz-growl-item,
    .rz-growl-message-error > .rz-growl-item {
        background: inherit !important;
        color: inherit !important;
        border-radius: 0;
        box-shadow: none;
        border: none;
        padding: 0.5rem 0.875rem !important;
    }

    /* Typography */
    .rz-growl-message-info > .rz-growl-item .rz-growl-summary,
    .rz-growl-message-success > .rz-growl-item .rz-growl-summary,
    .rz-growl-message-warn > .rz-growl-item .rz-growl-summary,
    .rz-growl-message-error > .rz-growl-item .rz-growl-summary {
        font-weight: 700;
        font-size: 0.875rem;
        line-height: 1.3;
        margin-bottom: 0.125rem;
    }

    .rz-growl-message-info > .rz-growl-item .rz-growl-detail,
    .rz-growl-message-success > .rz-growl-item .rz-growl-detail,
    .rz-growl-message-warn > .rz-growl-item .rz-growl-detail,
    .rz-growl-message-error > .rz-growl-item .rz-growl-detail {
        font-size: 0.8125rem;
        line-height: 1.35;
    }

    /* JBF brand colors */
    .rz-growl-message-info {
        background-color: var(--jbf-toast-info-bg) !important;
        color: var(--jbf-toast-info-fg) !important;
        border: 1px solid var(--jbf-toast-info-border);
    }

    .rz-growl-message-success {
        background-color: var(--jbf-toast-success-bg) !important;
        color: var(--jbf-toast-success-fg) !important;
        border: 1px solid var(--jbf-toast-success-border);
    }

    .rz-growl-message-warn {
        background-color: var(--jbf-toast-warning-bg) !important;
        color: var(--jbf-toast-warning-fg) !important;
        border: 1px solid var(--jbf-toast-warning-border);
    }

    .rz-growl-message-error {
        background-color: var(--jbf-toast-error-bg) !important;
        color: var(--jbf-toast-error-fg) !important;
        border: 1px solid var(--jbf-toast-error-border);
    }

    /* rz-notification-* classes */
    .rz-notification-info    { background-color: var(--jbf-toast-info-bg) !important;    color: var(--jbf-toast-info-fg) !important;    border: 1px solid var(--jbf-toast-info-border);    border-radius: 12px; padding: 0.5rem 0.875rem; }
    .rz-notification-success { background-color: var(--jbf-toast-success-bg) !important; color: var(--jbf-toast-success-fg) !important; border: 1px solid var(--jbf-toast-success-border); border-radius: 12px; padding: 0.5rem 0.875rem; }
    .rz-notification-warn    { background-color: var(--jbf-toast-warning-bg) !important; color: var(--jbf-toast-warning-fg) !important; border: 1px solid var(--jbf-toast-warning-border); border-radius: 12px; padding: 0.5rem 0.875rem; }
    .rz-notification-error   { background-color: var(--jbf-toast-error-bg) !important;   color: var(--jbf-toast-error-fg) !important;   border: 1px solid var(--jbf-toast-error-border);   border-radius: 12px; padding: 0.5rem 0.875rem; }

    @media (prefers-reduced-motion: reduce) {
        .rz-growl-message-info,
        .rz-growl-message-success,
        .rz-growl-message-warn,
        .rz-growl-message-error {
            transition: none !important;
            animation: none !important;
        }
    }

    /* JBF brand primitives (single source of truth) */
    --jbf-mauve: #a282a6;
    --jbf-plum: #7d5b81;
    --jbf-lilac: #cdb4d3;
    --jbf-teal: #76b8b7;
    --jbf-cyan: #00a8ba;
    --jbf-mint: #00a891;
    --jbf-amber: #fdb526;
    --jbf-magenta: #d23c77;
    --jbf-red: #d80f3d;
    /* Single canonical "soft canvas" lavender used app-wide.
       Replaces the four near-identical values that previously lived in
       auth.css (--auth-bg), onboarding.css (--onb-bg), team-scheduling.css
       (--tsb-canvas), corporate-user-management.css (--cum-secondary),
       consignors.css (--cn-surface), event-landing.css (.evl-content-col),
       and site.css (--jbf-sidebar-shell-bg, --stripe-background-color).
       All of those now point at this token. */
    --jbf-canvas: #f5f1f7;
    /* Brand script face. @font-face is declared at the top of this file
       (FontsFree-Net-Authenia.ttf, font-display:swap). Used for welcome
       headings on /auth, /event-landing, and the dashboard. */
    --font-authenia: "Authenia", sans-serif;
    /* Legacy aliases */
    --jbf-purple: var(--jbf-mauve);
    --jbf-pink: var(--jbf-plum);
    /* Semantic status (chips, badges, alerts) */
    --jbf-status-success-bg: rgba(0, 168, 145, 0.12);
    --jbf-status-success-fg: #007a6a;
    --jbf-status-danger-bg: rgba(216, 15, 61, 0.1);
    --jbf-status-danger-fg: var(--jbf-red);
    --jbf-status-warning-bg: rgba(253, 181, 38, 0.22);
    --jbf-status-warning-fg: #8a6309;
    --jbf-status-info-bg: rgba(0, 168, 186, 0.12);
    --jbf-status-info-fg: #008696;
    /* Toast-specific solid colors (opaque â€” NOT the badge rgba tokens above) */
    --jbf-toast-info-bg: #e0f5f7;
    --jbf-toast-info-fg: #006f7d;
    --jbf-toast-info-border: #76b8b7;
    --jbf-toast-success-bg: #e0f4f1;
    --jbf-toast-success-fg: #007363;
    --jbf-toast-success-border: #00a891;
    --jbf-toast-warning-bg: #fff9e6;
    --jbf-toast-warning-fg: #8a6309;
    --jbf-toast-warning-border: #fdb526;
    --jbf-toast-error-bg: #fde8ec;
    --jbf-toast-error-fg: #ad0c31;
    --jbf-toast-error-border: #d80f3d;
    --jbf-status-magenta-bg: rgba(210, 60, 119, 0.12);
    --jbf-status-magenta-fg: #b83262;
    --jbf-status-neutral-bg: rgba(128, 140, 145, 0.12);
    --jbf-status-neutral-fg: #5c6570;
    --jbf-status-neutral-strong-bg: rgba(128, 140, 145, 0.18);
    --jbf-status-neutral-strong-fg: #4b5563;
    /* Radzen theme â€” JBF palette */
    --rz-primary: var(--jbf-mauve);
    --rz-primary-light: var(--jbf-lilac);
    --rz-primary-lighter: #f2ebf3;
    --rz-primary-dark: var(--jbf-plum);
    --rz-primary-darker: #58405b;
    --rz-secondary: var(--jbf-teal);
    --rz-secondary-light: #9dcccb;
    --rz-secondary-lighter: #e7f4f6;
    --rz-secondary-dark: #5e9e9d;
    --rz-secondary-darker: #2f7f7e;
    --rz-info: var(--jbf-cyan);
    --rz-info-light: #33b8c7;
    --rz-info-lighter: rgba(0, 168, 186, 0.2);
    --rz-info-dark: #008699;
    --rz-info-darker: #006f7d;
    --rz-success: var(--jbf-mint);
    --rz-success-light: #33b9a7;
    --rz-success-lighter: rgba(0, 168, 145, 0.16);
    --rz-success-dark: #008a75;
    --rz-success-darker: #007363;
    --rz-warning: var(--jbf-amber);
    --rz-warning-light: #fdc44d;
    --rz-warning-lighter: rgba(253, 181, 38, 0.22);
    --rz-warning-dark: #ca911e;
    --rz-warning-darker: #8a6309;
    --rz-danger: var(--jbf-red);
    --rz-danger-light: #e8486b;
    --rz-danger-lighter: rgba(216, 15, 61, 0.2);
    --rz-danger-dark: #ad0c31;
    --rz-danger-darker: #8a0a27;
    /* Link colors â€” override the stock Radzen theme (which ships a teal/green
       hover color) so every <a> across the app honors JBF brand purples.
       Applies to link text, :hover, :visited, and :focus via the global
       `a { color: var(--rz-link-color); }` rule below. */
    --rz-link-color: var(--jbf-plum);
    --rz-link-hover-color: var(--rz-primary-darker);
    /* Corporate / communications shell */
    --cum-primary-hover: var(--rz-primary-darker);
    /* â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
       Responsive breakpoints â€” JBFOne 5-tier system (single source of truth).
       Mirror of Application/Common/Viewport/ViewportTier.cs and jbf-viewport.js.
       Use these via `@media (min-width: var(--bp-md))` or the shorter
       body[data-tier="..."] selectors below. Do NOT introduce new pixel
       literals (768/820/900/1023/1024/1100/1300...) â€” they cause C#/CSS drift.
       â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
    --bp-sm: 480px;     /* phone landscape / phablet */
    --bp-md: 768px;     /* iPad mini / iPad portrait */
    --bp-lg: 1024px;    /* iPad Pro landscape / 13" laptop / 1366Ã-768 PC */
    --bp-xl: 1280px;    /* standard laptop / desktop â€” visuals frozen */
    --bp-xxl: 1536px;   /* large desktop â€” visuals frozen */
    /* Mobile-shell cutoff. Components branch on this single knob to decide
       "do I render the desktop shell or the mobile drawer?". Default `lg`
       means anything below 1024px (incl. iPad portrait) gets the mobile shell.
       Change once here to retune iPad-portrait behavior across the entire app. */
    --bp-mobile-shell-cutoff: var(--bp-lg);
    /* Page layout offsets â€” used by .jbf-page height calc */
    --jbf-layout-offset: 148px;        /* Radzen header + body padding */
    --jbf-layout-offset-mobile: 116px; /* 56px (MobileTopHeader --mth-h) + 60px (MobileBottomTabBar --mbt-h) */
    /* Main nav column (Sidebar.razor, checklist modal interior nav) */
    --jbf-sidebar-shell-bg: var(--jbf-canvas);
    /* Right panel width presets (PaginatedTable + JbfRightPanel) */
    --jbf-panel-width-compact: min(33.33vw, 480px);
    --jbf-panel-width-expanded: min(66vw, 720px);
    /* App header height â€” sticky AppHeader on desktop is logo (65px) + 8pxÃ-2 padding
       + 1px border = 82px. Used by .jbf-shell__leftnav to clamp the contextual
       left rail to the visible viewport so long menus scroll independently. */
    --jbf-header-h: 82px;
    /* Contextual left-nav width. Used by .jbf-leftnav (rail width) and by
       .header-desktop-left in AppHeader (logo column width) so the first TopNav
       item lines up exactly with the body's left edge. Change once, both update. */
    --jbf-leftnav-w: 264px;
    /* Top segmented tab bars (Events, Schedules, Communications, System, Consignors) */
    --jbf-segment-bg: #ffffff;
    --jbf-segment-border: var(--events-border-light-color, #e6e8e9);
    --jbf-segment-radius-outer: 12px;
    --jbf-segment-radius-inner: 8px;
    --jbf-segment-padding: 5px;
    --jbf-segment-shadow: 0 1px 3px rgba(45, 27, 61, 0.08), 0 1px 2px rgba(0, 0, 0, 0.05);
    --jbf-segment-active-bg: var(--jbf-plum);
    --jbf-segment-active-fg: #ffffff;
    --jbf-segment-inactive-fg: #4a5d68;
    --jbf-segment-inactive-hover-fg: #1f2c33;
    --jbf-segment-font-size: 13px;
    /* Neutrals */
    font-size: var(--rz-root-font-size);
    --rz-white: #ffffff;
    --rz-black: #000000;
    --rz-base-50: #fafafa;
    --rz-base-100: #f5f5f5;
    --rz-base-200: #eeeeee;
    --rz-base-300: #e0e0e0;
    --rz-base-400: #bdbdbd;
    --rz-base-500: #9e9e9e;
    --rz-base-600: #757575;
    --rz-base-700: #616161;
    --rz-base-800: #424242;
    --rz-base-900: #212121;
    --rz-on-primary-lighter: var(--rz-black);
    --rz-on-secondary-lighter: var(--rz-black);
    --rz-on-info-lighter: var(--rz-info);
    --rz-on-success-lighter: var(--rz-success);
    --rz-on-warning-lighter: var(--rz-warning);
    --rz-on-danger-lighter: var(--rz-danger);
    /* Typography */
    --rz-text-font-family: Monserrat, sans-serif;
    --font-overpass: 'Overpass', sans-serif;
    /* Legacy / app */
    --border-color: #d1d5d7;
    --text-primary: #4e5e65;
    --text-secondary: #808c91;
    --mobile-card-text: #35474E;
    --stripe-background-color: var(--jbf-canvas);
    --rz-body-background-color: var(--rz-white);
    --events-text-color: #021922;
    --events-border-color: #b3babd;
    --events-border-light-color: #e6e8e9;
    /* Component / UI */
    --rz-header-background-color: var(--rz-secondary);
    --rz-panel-menu-color: #393e41;
    --rz-panel-menu-hover-background-color: var(--rz-primary-lighter);
    --rz-panel-menu-hover-color: var(--rz-primary-darker);
    --rz-panel-menu-item-active-background-color: var(--jbf-pink);
    --rz-grid-stripe-background-color: var(--stripe-background-color);
    --mobile-primary-color: var(--jbf-magenta);
    --rz-grid-header-color: var(--jbf-pink);
    --rz-grid-sort-icon-color: var(--rz-primary-light);
    --rz-grid-header-filter-icon-hover-color: var(--jbf-pink);
    --rz-grid-header-filter-icon-active-color: var(--jbf-pink);
    --rz-sidebar-toggle-hover-color: var(--rz-white);
    --rz-sidebar-toggle-hover-background-color: var(--rz-secondary);
    --rz-panel-menu-item-active-color: var(--rz-white);
    --rz-shadow-1: 0px;
    --rz-shadow-2: 0px;
    --rz-shadow-3: 0px;
    --rz-shadow-4: 0px;
    --rz-shadow-5: 0px;
    --rz-shadow-6: 0px;
    --rz-shadow-7: 0px;
    --rz-shadow-8: 0px;
    --rz-shadow-9: 0px;
    --rz-shadow-10: 0px;
    --rz-sidebar-toggle-focus-outline: 2px solid var(--rz-secondary-light);
    --rz-panel-menu-item-active-indicator: var(--rz-primary-lighter);

    /* Brand the native UA accent color so the browser's built-in blue stops
       leaking through on every native form control. Affects:
         <input type="time">    selected hour/minute segment background
         <input type="date">    selected day in the popup calendar
         <input type="datetime-local">
         <input type="checkbox"> <input type="radio">  filled state
         <input type="range">    track + thumb fill
         <progress>             bar fill
       accent-color is inheritable, so applying it once at :root cascades to
       every native control without per-component CSS. The schedule editor's
       time pickers (.eec-time-input) were the visible trigger for this rule
       (selected segment was bright system blue against a purple brand). */
    accent-color: var(--jbf-purple);
}
/* â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
   Responsive tier hooks â€” body[data-tier="â€¦"] is set by jbf-viewport.js on
   first paint and on every tier transition. Pages get a CSS-only branch
   without injecting IViewportService. Tokens match ViewportTier.ToCssToken().
   Usage examples:
     body[data-tier="xs"] .my-feature__sidebar { display: none; }
     body[data-tier="md"] .my-feature__grid    { grid-template-columns: 1fr; }
     body[data-orientation="portrait"] .x      { ... }
   Pre-paint defaults (before jbf-viewport.js seeds the attribute) avoid a
   mobile-shell flash for desktop users â€” we render desktop until proven mobile.
   â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
body:not([data-tier]) { /* pre-init: assume desktop so the shell doesn't flash mobile */ }
/* ═══════════════════════════════════════════════════════════════════════
   THIN ALWAYS-VISIBLE SCROLLBAR - SITE-WIDE STANDARD
   ═══════════════════════════════════════════════════════════════════════
   Goal: every scrollable surface in the app uses the same quiet, thin,
   always-visible scrollbar with the JBF brand plum thumb. The thumb is
   subtle at rest (light plum tint) but always present so users know the
   region scrolls - fully auto-hiding bars hurt discoverability on long
   data tables and side panels. Thumb darkens on hover for click affordance.

   Implementation:
   1. UNIVERSAL DEFAULTS - applied to every scrollable element on the page
      via the `*` selector below. Browser-default thick gray bars never show.
   2. EXPLICIT UTILITIES - `.jbf-scroll-y` / `.jbf-scroll-x` /
      `.jbf-scroll-auto` for elements that want overflow + thin scrollbar
      behavior in one class.

   Visual contract:
   - Width: 8px desktop / 6px mobile (track), thumb has 2px transparent
     border so the visible thumb is 4px desktop / 2px mobile - gives a
     subtle margin between thumb and content edge.
   - Thumb: plum at 28% opacity at rest, 55% on hover (more clickable),
     70% when actively dragged.
   - Track: fully transparent (no visible gutter).
   - Firefox: scrollbar-width: thin + scrollbar-color (track plum + transparent).
   - Touch (iOS): -webkit-overflow-scrolling: touch for momentum.
   ─────────────────────────────────────────────────────────────────────── */

/* ── Universal defaults - apply to every scrollable element on the page ──
   Always visible thin bar so users know content scrolls. Per-page custom
   ::-webkit-scrollbar rules can still override (specificity wins) but the
   overall app baseline is uniform. */
* {
    scrollbar-width: thin;
    scrollbar-color: rgba(125, 91, 129, 0.28) transparent;
}

*:hover,
*:focus-within {
    scrollbar-color: rgba(125, 91, 129, 0.55) transparent;
}

*::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

*::-webkit-scrollbar-track {
    background: transparent;
}

/* Thumb has a 2px transparent border so the visible thumb is ~4px wide,
   leaving subtle margin between the thumb and content. background-clip
   makes the border render as gap rather than colored. */
*::-webkit-scrollbar-thumb {
    background-color: rgba(125, 91, 129, 0.28);
    border: 2px solid transparent;
    background-clip: padding-box;
    border-radius: 6px;
    min-height: 32px;
    min-width: 32px;
}

*:hover::-webkit-scrollbar-thumb,
*:focus-within::-webkit-scrollbar-thumb {
    background-color: rgba(125, 91, 129, 0.55);
}

*::-webkit-scrollbar-thumb:hover {
    background-color: rgba(125, 91, 129, 0.7);
}

*::-webkit-scrollbar-thumb:active {
    background-color: rgba(125, 91, 129, 0.85);
}

*::-webkit-scrollbar-corner {
    background: transparent;
}

/* Page-level (html/body) scrollbar - same 8px size as everything else
   so it never reads as "the big one" next to inner panel scrollbars. */
html,
body {
    scrollbar-color: rgba(125, 91, 129, 0.32) transparent;
}

/* When the page uses the shell architecture (`.jbf-shell` is pinned to
   `100vh - header`), the inner `.jbf-shell__body` owns ALL scrolling.
   The DOM between body and the shell looks like:

     body > .rz-layout > .rz-body > .jbf-shell > .jbf-shell__body

   Radzen's default `.rz-body` is `overflow: auto`, and any ancestor that
   becomes a scroll container creates a SECOND visible scrollbar stacked
   at the right edge - the user sees one bar inside the page (the
   meaningful `.jbf-shell__body` scroll) AND a wrapper bar outside it,
   producing the "multi-scroll" bug.

   Fix: clip every wrapper from body down to `.rz-body` so nothing above
   `.jbf-shell` can scroll. `.jbf-shell` already has `overflow: hidden`
   internally; only `.jbf-shell__body` (or `.jbf-shell__leftnav`)
   actually scrolls.

   `overflow: clip` is preferred over `hidden` because clip does not
   create a new scroll context (no programmatic scrollLeft/scrollTop, no
   accidental focus traps). Evergreen Chromium / Safari / Firefox all
   support it. Mobile (xs/sm/md) opts out of this rule via the
   max-width: 1023.98px override below - at those tiers the shell
   intentionally releases its `100vh` clamp so the document scrolls. */
body:has(.jbf-shell),
body:has(.jbf-shell) .rz-layout,
body:has(.jbf-shell) .rz-body,
body:has(.jbf-shell) .jbf-main {
    overflow: clip;
}

/* xs/sm/md tier (max-width 1023.98px mirrors --bp-lg). Mobile/tablet
   uses document-level scroll (the shell releases its 100vh clamp via
   `.jbf-shell { height: auto; overflow: visible }` in two-level-nav.css).
   Re-enable scroll on body + wrappers so the page actually scrolls. */
@media (max-width: 1023.98px) {
    body:has(.jbf-shell),
    body:has(.jbf-shell) .rz-layout,
    body:has(.jbf-shell) .rz-body,
    body:has(.jbf-shell) .jbf-main {
        overflow: visible;
    }
}

html::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb {
    background-color: rgba(125, 91, 129, 0.32);
    border: 2px solid transparent;
    background-clip: padding-box;
    border-radius: 6px;
}

/* xs/sm/md tier (max-width 1023.98px mirrors --bp-lg). Mobile/tablet:
   thinner overlay bars (touch devices already have native thin scrollbars,
   we just want consistent color). 6px track / 2px visible thumb. */
@media (max-width: 1023.98px) {
    * {
        scrollbar-color: rgba(125, 91, 129, 0.32) transparent;
    }
    *::-webkit-scrollbar {
        width: 6px;
        height: 6px;
    }
    *::-webkit-scrollbar-thumb {
        background-color: rgba(125, 91, 129, 0.32);
        border: 1px solid transparent;
        background-clip: padding-box;
        border-radius: 4px;
        min-height: 24px;
        min-width: 24px;
    }
    *:active::-webkit-scrollbar-thumb {
        background-color: rgba(125, 91, 129, 0.6);
    }

    html::-webkit-scrollbar,
    body::-webkit-scrollbar {
        width: 6px;
        height: 6px;
    }
    html::-webkit-scrollbar-thumb,
    body::-webkit-scrollbar-thumb {
        border-width: 1px;
        border-radius: 4px;
    }
}

/* ── Explicit utility classes - opt-in for elements that want both
   overflow behavior AND the thin scrollbar in a single class. Visuals
   inherit from the universal `*` rules above (always-visible thin plum). */
.jbf-scroll-auto { overflow: auto; -webkit-overflow-scrolling: touch; }
.jbf-scroll-y    { overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; }
.jbf-scroll-x    { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; }

/* Auto-hiding variant - for surfaces where a permanent thumb feels noisy
   (e.g. inside a small floating panel). Use sparingly; the always-visible
   default is preferred so users never miss that content scrolls. */
.jbf-scroll-hide-idle {
    scrollbar-color: transparent transparent;
}
.jbf-scroll-hide-idle:hover,
.jbf-scroll-hide-idle:focus-within {
    scrollbar-color: rgba(125, 91, 129, 0.55) transparent;
}
.jbf-scroll-hide-idle::-webkit-scrollbar-thumb {
    background-color: transparent;
}
.jbf-scroll-hide-idle:hover::-webkit-scrollbar-thumb,
.jbf-scroll-hide-idle:focus-within::-webkit-scrollbar-thumb {
    background-color: rgba(125, 91, 129, 0.55);
}

/* Screen-reader only (shell + hub controls) */
.jbf-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/*
 * Shared inline field-error token used by every form field across the app.
 * Paired with role="alert" + aria-live="assertive" on the span, and driven by
 * the _showValidation gate in code-behind so errors only appear after a save
 * attempt. See field-validation-requirements.mdc §3 for the full pattern.
 *
 * Best-practice UX: the parent wrapper should also carry an `--invalid` class
 * that paints the input border red - the inline message alone is too easy to
 * miss on a long form (proven by the 2026-05-01 Local Website Event Info bug).
 *
 * Pages may alias this as `.feature-field-error` for local CSS organisation
 * but must NOT invent a new red shade - always compose with `var(--rz-danger)`.
 */
.jbf-field-error {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin-top: 6px;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--rz-danger);
    font-weight: 500;
}
.jbf-field-error i,
.jbf-field-error svg {
    flex: 0 0 auto;
    margin-top: 1px;
    color: var(--rz-danger);
}
/*
 * Skip link: off-viewport until Tab (avoids default link styling showing in the header band).
 * Navigates to dashboard href from markup â€” not an in-page #fragment.
 */
.jbf-skip-link {
    position: fixed;
    left: 12px;
    top: -120px;
    z-index: 10001;
    padding: 10px 16px;
    margin: 0;
    background: var(--jbf-plum);
    color: var(--rz-white) !important;
    font-weight: 600;
    font-size: 14px;
    text-decoration: none !important;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    transition: top 0.18s ease;
}
.jbf-skip-link:focus,
.jbf-skip-link:focus-visible {
    top: 12px;
    outline: 2px solid var(--jbf-teal);
    outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
    .jbf-skip-link {
        transition: none;
    }
}
.jbf-main {
    min-height: 0;
}
/* Baseline focus visibility (hubs + shell; do not strip outlines without replacement) */
a:focus-visible,
button:focus-visible,
.rz-button:focus-visible,
[role="tab"]:focus-visible,
.menu-btn:focus-visible {
    outline: 2px solid var(--cum-primary, var(--jbf-plum));
    outline-offset: 2px;
}
/* â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
   Sitewide RadzenButton polish (.rz-button)
   Goals:
   â€¢ Modern, brand-correct look across every page (no all-caps shouting,
     no flat washed-out chips like the old default).
   â€¢ Uses Radzen's own --rz-primary / --rz-primary-dark tokens so each
     project that overrides those tokens gets a consistent treatment.
   â€¢ NO !important â€” page-scoped overrides (team-scheduling.css,
     fsc-library.css, etc.) still win when needed.
   â€¢ No colour changes on Light/Secondary/Info/Success/Warning/Danger
     variants â€” only typography, spacing, depth, hover lift, focus ring,
     disabled state. Variant identity stays intact.
   â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.rz-button {
    /* Typography â€” kill the dated all-caps default, tighten hierarchy. */
    text-transform: none;
    letter-spacing: 0.01em;
    font-weight: 600;
    /* Shape + depth */
    border-radius: 8px;
    box-shadow: 0 1px 2px rgba(2, 25, 34, 0.06);
    /* Smooth all interactions (no transform â€” buttons stay put on hover). */
    transition: background-color 140ms ease-out,
                border-color     140ms ease-out,
                color            140ms ease-out,
                box-shadow       140ms ease-out,
                opacity          140ms ease-out;
}
/* Slightly tighter icon spacing (Radzen defaults to 0.5rem which can look loose). */
.rz-button .rz-button-icon-left,
.rz-button .rz-button-icon-right {
    margin-right: 0.4rem;
}
.rz-button .rz-button-icon-right {
    margin-right: 0;
    margin-left: 0.4rem;
}
/* Hover: slightly stronger shadow only (no lift). Color shift is per-variant. */
.rz-button:hover:not(:disabled):not(.rz-state-disabled) {
    box-shadow: 0 3px 8px rgba(2, 25, 34, 0.12);
}
/* Press state: flatten the shadow for a subtle "pressed" feel. */
.rz-button:active:not(:disabled):not(.rz-state-disabled) {
    box-shadow: 0 1px 2px rgba(2, 25, 34, 0.08);
}
/* Primary variant â€” darken on hover to the plum token. The two selectors
   cover both Radzen's class form (.rz-primary) and the rz-button-primary
   alias used by some Radzen versions. */
.rz-button.rz-primary:hover:not(:disabled):not(.rz-state-disabled),
.rz-button.rz-button-primary:hover:not(:disabled):not(.rz-state-disabled) {
    background-color: var(--rz-primary-dark, #7d5b81);
    border-color: var(--rz-primary-dark, #7d5b81);
}
/* Secondary â€” use the existing dark teal token on hover. */
.rz-button.rz-secondary:hover:not(:disabled):not(.rz-state-disabled),
.rz-button.rz-button-secondary:hover:not(:disabled):not(.rz-state-disabled) {
    background-color: var(--rz-secondary-dark, #5e9e9d);
    border-color: var(--rz-secondary-dark, #5e9e9d);
}
/* Light variant â€” give it a defined hover so it doesn't look "dead". */
.rz-button.rz-light:hover:not(:disabled):not(.rz-state-disabled),
.rz-button.rz-button-light:hover:not(:disabled):not(.rz-state-disabled) {
    background-color: #eceff1;
    border-color: #cfd8dc;
}
/* Disabled â€” Radzen default is very faint. Keep readable but clearly off. */
.rz-button:disabled,
.rz-button.rz-state-disabled,
.rz-button[disabled] {
    opacity: 0.55;
    box-shadow: none;
    cursor: not-allowed;
}
/* Icon-only buttons (Radzen sets .rz-button-icon-only) â€” slightly softer
   hover shadow so toolbar/inline icon actions don't pop too hard. */
.rz-button.rz-button-icon-only:hover:not(:disabled):not(.rz-state-disabled) {
    box-shadow: 0 2px 5px rgba(2, 25, 34, 0.10);
}
@media (prefers-reduced-motion: reduce) {
    .rz-button {
        transition: none;
    }
}
@media (prefers-reduced-motion: reduce) {
    .sidebar-menu {
        transition: none !important;
    }
    .jbf-right-panel,
    .jbf-panel-backdrop {
        transition: none !important;
    }
}
/* â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
   Radzen DatePicker â€” vertically center the prev/next arrows with the
   month/year selector boxes in the calendar header. Default Radzen styling
   leaves the arrows pinned to the top of the header row while the
   dropdowns (which are taller pill-shaped controls) sit lower, producing
   a noticeable misalignment.
   â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.rz-datepicker-header {
    align-items: center;
}
.rz-datepicker-prev,
.rz-datepicker-next {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: center;
}
/* Shared pinned panel footer row (Save left, Cancel right) â€” hubs + modals */
.jbf-panel-footer-actions {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-start;
    align-items: center;
    width: 100%;
    box-sizing: border-box;
}
.page-title {
    font-size: large !important;
}
.rz-menuitem,
.rz-autocomplete-list-item,
.rz-multiselect-item,
.rz-autocomplete-items li,
.rz-dropdown-items li,
.rz-multiselect-items li,
.rz-dropdown-item,
.rz-dropdown-label {
    font-size: 12px;
    color: var(--text-primary);
    font-weight: 500;
}
.rz-dropdown-panel {
    position: absolute;
    right: 0;
    margin-top: 0.5rem;
    background-color: var(--rz-white);
    border-radius: 1rem;
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
    border: 1px solid #e5e7eb;
    z-index: 10;
    border-top: 4px solid var(--jbf-purple);
    width: 180px;
}
    .rz-dropdown-panel:before {
        content: '';
        position: absolute;
        top: -10px;
        left: 80%;
        width: 0;
        height: 0;
        border-left: 10px solid transparent;
        border-right: 10px solid transparent;
        border-bottom: 8px solid var(--jbf-purple);
    }
.rz-dropdown, .rz-textarea, .rz-textbox {
    border-radius: 0.5rem;
}

/* ─────────────────────────────────────────────────────────────────────────
   Radzen DropDown / MultiSelect: consistent vertical text centering.

   PROBLEM (visible everywhere a RadzenDropDown / RadzenDropDownDataGrid /
   RadzenMultiSelect is rendered): the Material base theme applies the
   floating-label padding pattern to the trigger label — roughly 16px top
   padding, 8px bottom — to reserve space above the input for an animated
   floating label. We never use floating labels (form labels live in
   sibling .lws-field-label / .cum-preview-label elements), so that
   reserved top-padding band just shoves the selected value visually
   above the wrapper's geometric midline.

   The existing site.css rule already flexed the label, but because flex
   `align-items: center` centers within the label's *content box* (which
   sits inside that asymmetric padding), the text still landed off-center
   relative to the wrapper. Pages that needed it centered worked around
   it by stacking their own min-height + padding overrides — hence the
   "very inconsistent" appearance across the app.

   FIX: zero the asymmetric vertical padding on the label, stretch the
   label to the wrapper's full height, then flex-center its text. Done
   once globally so every dropdown the app renders agrees on a single
   centered baseline. Page-specific overrides that need a taller trigger
   only have to set min-height on the wrapper now — the centering Just
   Works.
   ───────────────────────────────────────────────────────────────────── */

.rz-dropdown,
.rz-multiselect {
    display: inline-flex;
    align-items: stretch;
}

.rz-dropdown .rz-dropdown-label.rz-inputtext,
.rz-dropdown > span.rz-dropdown-label.rz-inputtext,
.rz-multiselect .rz-multiselect-label-container {
    display: flex !important;
    align-items: center !important;
    box-sizing: border-box;
    line-height: 1.25 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    margin-top: 0;
    margin-bottom: 0;
    min-width: 0;
    width: 100%;
    height: auto;
    min-height: 100%;
}

/* Chips (multi-select inside the trigger) inherit the flex/center pattern
   so single-line and chip-mode triggers share the same baseline. */
.rz-dropdown .rz-dropdown-chips {
    display: flex;
    align-items: center;
}
.rz-dropdown .rz-dropdown-chips .rz-dropdown-chips-wrapper {
    align-items: center;
}
.rz-chkbox-box, .rz-chkbox-box.rz-state-active {
    border-radius: 0.3rem;
}
.rz-spinner input[type=number], .rz-spinner input[type=text] {
    padding: 0.5rem !important;
    font-size: 13px;
}
.k-menu:not(.k-context-menu) > .k-item, 
.k-menu:not(.k-context-menu) > .k-item:hover {
    color: var(--jbf-magenta) !important;
}
#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}
#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}
#components-reconnect-modal {
    display: none;
}
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: none !important;
}
/* xs/sm tier (max-width 767.98px mirrors --bp-md). Media queries cannot deref CSS vars. */
@media (max-width: 767.98px) {
    #components-reconnect-modal.components-reconnect-show,
    #components-reconnect-modal.components-reconnect-failed,
    #components-reconnect-modal.components-reconnect-rejected {
        display: block !important;
    }
}
/* Hide empty toast containers */
.rz-growl-container:empty,
.rz-notifications:empty {
    display: none !important;
}
/* ── Toast / Growl notifications ───────────────────────────────────────────
   Radzen DOM: .rz-growl-container > .rz-growl-message-{severity} > .rz-growl-item
   Outer wrapper = the visible card. Inner .rz-growl-item inherits and adds no chrome.
   Uses --jbf-toast-* tokens (fully opaque solid colors, never the badge rgba tokens).
   ────────────────────────────────────────────────────────────────────────── */
/* Outer wrapper - the card shell */
.rz-growl-message-info,
.rz-growl-message-success,
.rz-growl-message-warn,
.rz-growl-message-error {
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 8px 28px rgba(13, 29, 37, 0.18);
    margin-bottom: 8px;
}
/* Inner item - inherits card background, no own chrome */
.rz-growl-message-info > .rz-growl-item,
.rz-growl-message-success > .rz-growl-item,
.rz-growl-message-warn > .rz-growl-item,
.rz-growl-message-error > .rz-growl-item {
    background: inherit !important;
    color: inherit !important;
    border-radius: 0;
    box-shadow: none;
    border: none;
    padding: 0.875rem 1rem;
}
/* Typography */
.rz-growl-message-info > .rz-growl-item .rz-growl-summary,
.rz-growl-message-success > .rz-growl-item .rz-growl-summary,
.rz-growl-message-warn > .rz-growl-item .rz-growl-summary,
.rz-growl-message-error > .rz-growl-item .rz-growl-summary {
    font-weight: 700;
    font-size: 0.9375rem;
    line-height: 1.3;
    margin-bottom: 0.125rem;
}
.rz-growl-message-info > .rz-growl-item .rz-growl-detail,
.rz-growl-message-success > .rz-growl-item .rz-growl-detail,
.rz-growl-message-warn > .rz-growl-item .rz-growl-detail,
.rz-growl-message-error > .rz-growl-item .rz-growl-detail {
    font-size: 0.875rem;
    line-height: 1.4;
}
/* Solid opaque severity colors on the outer wrapper (the card) */
.rz-growl-message-info {
    background-color: var(--jbf-toast-info-bg) !important;
    color: var(--jbf-toast-info-fg) !important;
    border: 1px solid var(--jbf-toast-info-border);
}
.rz-growl-message-success {
    background-color: var(--jbf-toast-success-bg) !important;
    color: var(--jbf-toast-success-fg) !important;
    border: 1px solid var(--jbf-toast-success-border);
}
.rz-growl-message-warn {
    background-color: var(--jbf-toast-warning-bg) !important;
    color: var(--jbf-toast-warning-fg) !important;
    border: 1px solid var(--jbf-toast-warning-border);
}
.rz-growl-message-error {
    background-color: var(--jbf-toast-error-bg) !important;
    color: var(--jbf-toast-error-fg) !important;
    border: 1px solid var(--jbf-toast-error-border);
}
/* rz-notification-* classes used by some inline alert areas */
.rz-notification-info    { background-color: var(--jbf-toast-info-bg) !important;    color: var(--jbf-toast-info-fg) !important;    border: 1px solid var(--jbf-toast-info-border);    border-radius: 12px; padding: 0.875rem 1rem; }
.rz-notification-success { background-color: var(--jbf-toast-success-bg) !important; color: var(--jbf-toast-success-fg) !important; border: 1px solid var(--jbf-toast-success-border); border-radius: 12px; padding: 0.875rem 1rem; }
.rz-notification-warn { background-color: var(--jbf-toast-warning-bg) !important; color: var(--jbf-toast-warning-fg) !important; border: 1px solid var(--jbf-toast-warning-border); border-radius: 12px; padding: 0.875rem 1rem; }
.rz-notification-error   { background-color: var(--jbf-toast-error-bg) !important;   color: var(--jbf-toast-error-fg) !important;   border: 1px solid var(--jbf-toast-error-border);   border-radius: 12px; padding: 0.875rem 1rem; }
@media (prefers-reduced-motion: reduce) {
    .rz-growl-message-info,
    .rz-growl-message-success,
    .rz-growl-message-warn,
    .rz-growl-message-error {
        transition: none !important;
        animation: none !important;
    }
}
.form-control:focus,
textarea:focus,
select:focus {
    border: 1px solid var(--jbf-pink) !important;
    border-radius: 0.5rem;
    outline: none;
}
.gap-12px{
    gap: 12px !important;
}
.min-h-200{
    min-height : 200px;
}
.w-128{
 width: 128px;
}
body {
    font-family: var(--rz-text-font-family);
    color: var(--rz-text-color);
    font-size: var(--rz-body-font-size);
    line-height: var(--rz-body-line-height);
    background-color: var(--rz-body-background-color);
}
.rz-body {
    --rz-body-padding: 0;
    /* Radzen's default RadzenBody adds horizontal padding via this token, which
       was pushing the contextual left rail away from the viewport edge. Zero it
       out so the rail sits flush against the screen edge. The rail then owns
       its own internal padding (see .jbf-leftnav). */
    --rz-layout-body-padding: 0;
    padding: 0;
}
/* â”€â”€ Global page skeleton â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
   .jbf-page / .jbf-header / .jbf-toolbar / .jbf-body are the structural layout
   classes shared across all full-page admin routes. Pages that also load
   corporate-user-management.css get token-based colour overrides layered on top.
   â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
/* PR-6 (global flatten): .jbf-page is now a FLAT page surface - no
   border-radius, no drop-shadow. The 8px margin keeps the page inset from
   the viewport edges (so the AppHeader's plum bottom border is visually
   separated from page content) but the surface itself is a plain rectangle.
   Inner cards (e.g. .me-section-card, .ms-page__calendar, dashboard
   widget cards) carry ALL the elevation, eliminating the "card-around-card"
   anti-pattern that previously read as nested chrome on every admin page.
   Background stays #fafafa (subtle off-white canvas) so inner #fff cards
   still register as elevated; per-page overrides (e.g. .ms-page → #fff,
   .dashboard-landing-main-card → --jbf-canvas) tune the canvas tint. */
.jbf-page {
    /* page surface (flat, no chrome) */
    margin: 8px;
    overflow: clip;
    background: #fafafa;
    /* full-page flex layout */
    display: flex;
    flex-direction: column;
    width: calc(100% - 16px);
    max-width: calc(100% - 16px);
    min-width: 0;
    height: calc(100vh - var(--jbf-layout-offset) - 16px);
    max-height: calc(100vh - var(--jbf-layout-offset) - 16px);
    min-height: 0;
}
@supports (height: 100dvh) {
    .jbf-page {
        height: calc(100dvh - var(--jbf-layout-offset) - 16px);
        max-height: calc(100dvh - var(--jbf-layout-offset) - 16px);
    }
}

/* Fullscreen mode (FullscreenService.IsFullscreen == true).
   MainLayout removes the AppHeader (82px) + ContextualLeftNav from the DOM,
   but the default `.jbf-shell` height (`100vh - --jbf-header-h`) and the
   `.jbf-page` height (`100dvh - --jbf-layout-offset - 16px`) still bake in
   the header offset, so the page is sized 82px shorter than the viewport
   and a blank band shows up under the bottom toolbar (e.g. /consignors
   pagination row floats with empty space below it). When the layout flips
   to fullscreen we release those clamps so the page actually fills the
   viewport edge-to-edge. The 8px margin + 16px width subtraction on
   `.jbf-page` are kept so the page still has its small viewport gutter. */
.is-fullscreen .jbf-shell {
    height: 100vh;
}
@supports (height: 100dvh) {
    .is-fullscreen .jbf-shell {
        height: 100dvh;
    }
}
.is-fullscreen .jbf-page {
    height: calc(100vh - 16px);
    max-height: calc(100vh - 16px);
}
@supports (height: 100dvh) {
    .is-fullscreen .jbf-page {
        height: calc(100dvh - 16px);
        max-height: calc(100dvh - 16px);
    }
}

.jbf-header {
    padding: 24px 32px;
    border-bottom: 1px solid #e6e8e9;
    background: #ffffff;
}
.jbf-header h1 {
    margin: 0;
    font-size: 24px;
    font-weight: 700;
    color: #4a5d68;
}
.jbf-toolbar {
    padding: 16px 32px;
    border-bottom: 1px solid #e6e8e9;
    background: #ffffff;
    overflow: visible;
    position: relative;
    z-index: 6;
}
.jbf-toolbar.jbf-toolbar--stack {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
}
.jbf-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
/* Dashboard landing: full-bleed canvas surface that fills the .jbf-shell__body
   container edge-to-edge (no side gutters, no bottom strip). The previous
   viewport-math sizing (100vh - --jbf-layout-offset) was 66 px shorter than
   .jbf-shell__body's actual height (100vh - --jbf-header-h = 100vh - 82px)
   because --jbf-layout-offset bakes in 66 px of "Radzen body padding" that
   .jbf-shell already absorbed - leaving a stripe of body white below the
   cards. Sizing to `min-height: 100%` lets the shell exactly match its
   container regardless of what the AppHeader resolves to. */
.dashboard-landing-shell {
    display: flex;
    flex-direction: column;
    min-height: 100%;
    width: 100%;
    max-width: 100%;
    margin: 0;
    background: var(--jbf-canvas);
}

/* Belt-and-suspenders: paint the parent shell-body the canvas color whenever
   the dashboard route is rendered. Catches any sub-pixel rounding gap between
   the shell and its container, and means the side scrollbar gutter (when the
   page content overflows on short viewports) also reads lavender instead of
   pure white. :has() is in evergreen browsers - the app already requires
   modern Chromium/Safari/Firefox. */
.jbf-shell__body:has(.dashboard-landing-shell) {
    background: var(--jbf-canvas);
}
/* PR-5: dashboard's main body panel uses --jbf-canvas (matches the public
   Event Landing page background). The base .jbf-page is #fafafa for module
   pages with their own card grids; the dashboard uses canvas so the card
   tiles read as floating chips on a soft lavender field, matching the
   visual treatment of /event-landing. Scoped via .dashboard-landing-main-card
   so other .jbf-page hosts keep their existing background. */
.jbf-page.dashboard-landing-main-card {
    flex: 1;
    min-height: 0;
    height: auto;
    max-height: none;
    background: var(--jbf-canvas);
}
/* Welcome header on /dashboard intentionally has NO bottom rule - the
   floating .jbf-page card below it already provides a visual boundary, so
   the generic .jbf-header divider just adds visual noise. Scoped via the
   shell class so every other page that uses .jbf-header keeps its rule.
   The default 24px / 32px padding inherited from .jbf-header is preserved
   so the welcome script aligns horizontally with the card content below
   it (cards live inside .jbf-page which has its own 8 px gutter + card
   padding ≈ 32 px from the shell's left edge). */
.dashboard-landing-shell > .jbf-header {
    border-bottom: none;
    background: transparent;
}
/* PR-7: brand-script welcome heading on /dashboard. Plum + Authenia + clamp
   sizing matches .auth-title--welcome-script (login page magenta variant)
   and .evl-welcome-heading (Event Landing magenta variant) so the same
   greeting voice carries across all entry surfaces. Dashboard is plum
   (vs. magenta on the public surfaces) per UX direction - the signed-in
   surface uses the calmer brand purple. Scoped to .dashboard-landing-shell
   so /events, /my-tags, etc. keep their existing .jbf-header h1 treatment. */
.dashboard-landing-shell > .jbf-header h1 {
    margin: 0;
    font-family: var(--font-authenia);
    font-weight: 400;
    color: var(--jbf-plum);
    font-size: clamp(28px, 4.5vw, 44px);
    line-height: 1.1;
    letter-spacing: 0.005em;
}
.dashboard-welcome-header {
    padding: 0 0 12px 0;
}
.dashboard-welcome-title {
    margin: 0;
    font-size: 24px;
    font-weight: 700;
    color: #021922;
}
/* Dashboard widget cards: same light lift as .event-admin-tab-toggle (corporate-user-management.css). */
.dashboard-landing-body .rz-card {
    border-radius: var(--jbf-segment-radius-outer, 12px);
    border: 1px solid var(--jbf-segment-border, var(--cum-border, #e6e8e9));
    box-shadow: var(--jbf-segment-shadow, 0 1px 3px rgba(0, 0, 0, 0.06)) !important;
    /* Clip the title-bar's bottom border to the rounded outer corners. The
       title bar bleeds edge-to-edge past the card's default 1rem padding via
       the negative margins in .dashboard-card-title-bar; without overflow
       hidden, those bled corners would extend past the card's border-radius
       and look like a misaligned divider. */
    overflow: hidden;
}

/* ──────────────────────────────────────────────────────────────────────────
   Dashboard / SellerMyTagsCard title bar.
   Mirrors the .evl-card__title pattern from the public Event Landing 2x2
   grid (Web/wwwroot/css/event-landing.css) so the dashboard widgets, the
   page-content zones (.pcz-card / .pcz-card__title in announcements.css),
   and the public landing cards all read as ONE family of components --
   centered pink heading, hairline divider underneath, padding 12/22 -- not
   three near-misses with subtly different chrome.

   The bar sits as the FIRST element inside a RadzenCard. Negative horizontal
   + top margins compensate for the card's default 1rem (--rz-card-padding)
   padding so the bar bleeds edge-to-edge of the card frame and the divider
   visually completes the card's border. The 1rem bottom margin keeps natural
   breathing room between the bar and the body content below; !important on
   margin defeats Bootstrap utilities like `mb-3` / `mb-0` that the heading
   element typically already carries (left in for backward compatibility with
   the current `<h3 class="h6 mb-3 dashboard-section-title-accent">` markup).

   The font / color tokens (#D23C77, weight 600) live on
   .dashboard-section-title-accent which the heading also carries -- this
   class only adds the BAR treatment so existing color-only call sites
   continue to work without breakage. font-size / letter-spacing are
   re-asserted here because Bootstrap's `.h6` would otherwise win.
   ────────────────────────────────────────────────────────────────────── */
.dashboard-card-title-bar {
    padding: 12px 22px;
    margin: -1rem -1rem 1rem !important;
    font-size: 18px;
    text-align: center;
    border-bottom: 1px solid #e6e8e9;
    letter-spacing: 0.005em;
    line-height: 1.4;
    /* When used as a wrapping div with a heading + action button inside, flex
       does the layout (see --with-action below). When applied directly to a
       single heading element the flex centering still works because there's
       only one child (the text) -- no behavior difference. */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
}

/* Modifier for cards that pair the title with a right-aligned action (e.g.
   the Launch Pad "View all" button). The title element gets flex:1 so it
   fills the remaining space and stays visually centered; the action sits
   flush right and never wraps. The whole bar still bleeds edge-to-edge so
   the underline divider remains uninterrupted by the button. */
.dashboard-card-title-bar--with-action > :first-child {
    flex: 1;
    margin: 0;
    text-align: center;
}

.dashboard-card-title-bar--with-action > :last-child {
    flex-shrink: 0;
}

/* xs/sm tier mirrors --bp-md (768px); media queries can't deref CSS vars. */
@media (max-width: 767.98px) {
    .dashboard-card-title-bar {
        padding: 10px 18px;
        font-size: 14.5px;
    }
}

/* ── Seller event card (My Events on /dashboard) ─────────────────────
   Single-column layout per UX spec:
     row 1 - Location Name (with Active/Upcoming pill inline)
     row 2 - Event Name + dates
     row 3 - Venue + address (with map-pin icon)
     blank
     "Next Up:" - earliest future of {Drop Off, Shopping, Pick Up}
     blank
     buttons - View Event + Join the Team
   The legacy two-column layout (left content / right "Your schedule"
   panel) was retired: surfacing the single most relevant upcoming
   appointment as a "Next Up" line is more actionable than a static
   schedule panel that mostly read as duplicated event data.
   The card itself reuses Bootstrap's .card border + .shadow-sm so
   it stays elevated against the (now-flat) .jbf-page-card surface. */
/* Hover/focus surface tint - light plum wash matches the Next Up pill family
   so the entire card visibly responds when the seller mouses over it without
   competing with the inner banners. focus-within keeps the same affordance
   for keyboard users tabbing into the View Event / Join the Team buttons. */
/* The whole card is now a single click target (replaces the legacy
   "View Event" button), so it carries pointer/cursor + a visible
   focus ring for keyboard users. The hover background switches from
   the previous tinted plum to --jbf-canvas (the dashboard page's
   lavender canvas behind the My Events card) so the card visibly
   "sinks into" the page background on hover/focus - a clearer
   click affordance than the faint plum tint we had before, and it
   matches the page's existing color palette. */
.seller-event-card {
    cursor: pointer;
    transition: background-color 120ms ease, box-shadow 120ms ease;
}

.seller-event-card:hover,
.seller-event-card:focus-visible,
.seller-event-card:focus-within {
    background-color: var(--jbf-canvas, #f5f1f7);
}

.seller-event-card:focus-visible {
    outline: 2px solid var(--jbf-purple, #7d5b81);
    outline-offset: 2px;
}

/* Venue address link - visually identical to the surrounding muted
   text by default so the row still reads as a single venue+address
   block, with a hover treatment that nods to its underlying anchor
   semantics ("this is clickable"). The stopPropagation on the anchor
   keeps it from also firing the card-level navigate; the outer card
   click handler uses standard Blazor @onclick which obeys event
   bubbling so the inline event.stopPropagation() is sufficient. */
.seller-event-card__venue-address-link {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

.seller-event-card__venue-address-link:hover .seller-event-card__venue-address,
.seller-event-card__venue-address-link:focus-visible .seller-event-card__venue-address {
    color: var(--jbf-purple, #7d5b81);
    text-decoration: underline;
}

.seller-event-card__venue-address-link:focus-visible {
    outline: 2px solid var(--jbf-purple, #7d5b81);
    outline-offset: 2px;
    border-radius: 2px;
}

.seller-event-card__body {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.seller-event-card__row-location {
    /* Tight gap between location name and the inline status pill so
       they read as a unit rather than two separate header bits. */
    line-height: 1.2;
}

.seller-event-card__location-name {
    font-size: 18px;
    font-weight: 700;
    color: var(--jbf-plum, #7d5b81);
    text-transform: none;
    letter-spacing: 0;
    line-height: 1.25;
}

.seller-event-card__row-event {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.seller-event-card__event-name {
    font-size: 15px;
    font-weight: 600;
    color: var(--rz-text-color, #021922);
}

.seller-event-card__event-dates {
    font-size: 14px;
    color: var(--rz-text-color, #021922);
}

.seller-event-card__row-venue {
    line-height: 1.35;
}

.seller-event-card__venue-name {
    font-weight: 600;
    color: var(--rz-text-color, #021922);
}

.seller-event-card__venue-address {
    color: var(--rz-text-tertiary-color, #6c757d);
}

/* "Next Up:" row. Padded into a tinted plum pill so it reads as the
   single most actionable line on the card without competing visually
   with the buttons or the balance banner. */
.seller-event-card__next-up {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
    padding: 10px 14px;
    background: rgba(125, 91, 129, 0.08);
    border-left: 3px solid var(--jbf-purple, #7d5b81);
    border-radius: 6px;
}

.seller-event-card__next-up-label {
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--jbf-purple, #7d5b81);
}

.seller-event-card__next-up-value {
    font-size: 15px;
    font-weight: 600;
    color: var(--rz-text-color, #021922);
}

.seller-event-card__actions {
    margin-top: 4px;
}

@media (max-width: 480px) {
    .seller-event-card__body { gap: 12px; }
    .seller-event-card__next-up { padding: 8px 12px; }
    .seller-event-card__next-up-value { font-size: 14px; }
}
@media (max-width: 768px) {
    .jbf-page {
        margin: 4px;
        width: calc(100% - 8px);
        max-width: calc(100% - 8px);
        height: calc(100vh - var(--jbf-layout-offset-mobile) - 8px);
        max-height: calc(100vh - var(--jbf-layout-offset-mobile) - 8px);
    }
    @supports (height: 100dvh) {
        .jbf-page {
            height: calc(100dvh - var(--jbf-layout-offset-mobile) - 8px);
            max-height: calc(100dvh - var(--jbf-layout-offset-mobile) - 8px);
        }
    }
    /* Mobile/tablet - same full-bleed model as desktop. The previous mobile
       rule subtracted --jbf-layout-offset-mobile from the viewport height,
       which was wrong for the same reason as the desktop rule (parent
       .jbf-shell__body already accounts for header height). Letting the
       shell grow with content + min-height:100% keeps the canvas painted
       even when the cards stack and the page becomes scrollable. */
    .dashboard-landing-shell {
        margin: 0;
        width: 100%;
        max-width: 100%;
        min-height: 100%;
    }
    .dashboard-welcome-title {
        font-size: 20px;
    }
    .jbf-header  { padding: 16px; }
    .jbf-header h1 { font-size: 20px; }
    .jbf-toolbar { padding: 12px 16px; }
}
@media (max-width: 480px) {
    .jbf-header  { padding: 12px; }
    .jbf-toolbar { padding: 10px 12px; }
}
/* PR-6 (global flatten): generic outer page surface applied by MainLayout
   to all non-full-page routes (My Tags, My Profile, /events sub-pages, etc.).
   Now a FLAT white panel - no border-radius, no drop-shadow - so inner page
   cards (e.g. .me-section-card) are the only elevated elements. Mirrors the
   .jbf-page treatment so both wrappers behave consistently. The 8px side/
   bottom margin keeps a small gutter from the viewport edges; no top margin
   so the surface sits flush under the AppHeader's plum bottom border. */
.jbf-page-card {
    margin: 0 8px 8px 8px;
    overflow: clip;
    background: #ffffff;
}
@media (max-width: 768px) {
    .jbf-page-card {
        margin: 0 4px 4px 4px;
    }
}
a {
    color: var(--rz-link-color);
}
    a:hover,
    a:focus {
        color: var(--rz-link-hover-color);
    }
.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: var(--rz-white);
}
.blazor-error-boundary::after {
    content: "An error has occurred."
}
.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}
    .loading-progress circle {
        fill: none;
        stroke: var(--rz-base-300);
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }
        .loading-progress circle:last-child {
            stroke: #1b6ec2;
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }
.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}
    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }
.spinner-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.88);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
}
.jbf-loader {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
}
.jbf-loader-logo {
    width: 72px;
    height: 72px;
    animation: jbfPulse 1.8s ease-in-out infinite;
    filter: drop-shadow(0 2px 8px rgba(125, 91, 129, 0.18));
}
.jbf-loader-sm .jbf-loader-logo {
    width: 48px;
    height: 48px;
}
.jbf-loader-text {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.3px;
    color: var(--jbf-pink);
}
.jbf-loader-sm .jbf-loader-text {
    font-size: 12px;
}
.jbf-loader-centered {
    justify-content: center;
    min-height: 200px;
    width: 100%;
    padding: 2rem 1rem;
}
@keyframes jbfPulse {
    0%, 100% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.08); opacity: 0.85; }
}
/* Full-viewport curtain so auth lazy-CSS wait does not flash a white body (matches app shell intent). */
.lazy-stylesheet-loader {
    position: fixed;
    inset: 0;
    z-index: 99998;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: var(--rz-primary-lighter);
    box-sizing: border-box;
}
.lazy-stylesheet-spinner {
    width: 48px;
    height: 48px;
    object-fit: contain;
}
/* Main shell: desktop sidebar column width + icon rail (MainLayout layout-sidebar-rail) */
@media (min-width: 1024px) {
    .header.rz-layout > .sidebar-menu:not(.d-none) {
        width: 260px;
        min-width: 260px;
        max-width: 260px;
        box-sizing: border-box;
    }
    /* Tight icon rail: two controls (first nav + label toggle) share the top row inside Sidebar.razor */
    .header.rz-layout.layout-sidebar-rail > .sidebar-menu:not(.d-none) {
        width: 60px;
        min-width: 60px;
        max-width: 60px;
    }
}
/* xs/sm tier (max-width 767.98px mirrors --bp-md). Float toasts above the
   sticky bottom tab bar so they don't get covered by mobile navigation. */
@media (max-width: 767.98px) {
    .rz-growl-container,
    .rz-notifications {
        bottom: 88px !important;
    }
}

/* ───────────────────────────────────────────────────────────────────────────
   .jbf-resource-dialog -- shared Radzen dialog chrome for seller-resources
   modals opened from BOTH /my-events (EventSellerResourceSectionDialog) and
   /my-tags (TagGuidanceSectionPreviewDialog). Wired in via DialogOptions.
   CssClass at each call site so the two surfaces stay visually identical
   without forking a layout component.

   Purpose: make the modal read like an extension of the milestone cards on
   the page behind it -- 12 px rounded corners (same radius as
   .me-section-card), centered pink title (#D23C77, same as the desktop
   `.me-section-card__title` band) with a thin bottom rule, no surrounding
   chrome chrome. So the click "section row → modal" feels like the same
   card just zoomed in, not a foreign popup.
   ─────────────────────────────────────────────────────────────────────── */
.jbf-resource-dialog .rz-dialog {
    /* Match .me-section-card border-radius. `overflow: hidden` so the title
       bar's bottom border respects the rounded corners instead of bleeding
       past them at the top. */
    border-radius: 12px;
    overflow: hidden;
}

.jbf-resource-dialog .rz-dialog-titlebar {
    /* Force the titlebar to be a centered flex row so the title lands at
       the dead horizontal *and* vertical center of the bar. Three things
       have to all win at once for vertical centering to actually look
       centered:

         1. `display: flex + align-items: center` -- standard cross-axis
            centering of the title against the bar.
         2. *Symmetric* `padding: 0 16px` -- Radzen Material ships the bar
            with asymmetric top/bottom padding (~.65rem top, larger
            bottom), so even with `align-items: center` the visual centre
            sat above the geometric centre. Forcing 0 vertical padding +
            a fixed `min-height: 52px` gives the bar a balanced content
            box for flex to centre into.
         3. `min-height: 52px !important` -- clamps Radzen's intrinsic
            height to a deterministic value so the title can never drift
            depending on theme version or close-button hit-area changes.

       `position: relative` is the anchor for the absolutely-positioned
       close button below. */
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    position: relative;
    padding: 0 16px !important;
    min-height: 52px !important;
    border-bottom: 1px solid var(--events-border-light-color, #e6e8e9);
    background: #fff;
}

.jbf-resource-dialog .rz-dialog-titlebar .rz-dialog-title {
    /* Literal #D23C77 (NOT `--jbf-pink`) because the global token is
       aliased to `--jbf-plum` for theme-wide consistency (see site.css
       ":root"). This dialog is one of the few surfaces that wants the
       *real* pink to match `.me-section-card__title`'s desktop band hex.
       `line-height: 1` drops the title's intrinsic leading so the vertical
       centering against the titlebar lands on the optical middle. We do
       NOT set `flex: 1` here -- the title is sized to its content and
       centered by the parent's `justify-content: center`, which keeps the
       title at the absolute center of the bar regardless of the close
       button's width (the close is positioned absolutely below so it
       doesn't eat into the title's flex space and pull it left). */
    color: #D23C77 !important;
    font-size: 16px;
    font-weight: 600;
    line-height: 1;
    text-transform: none;
    letter-spacing: 0.005em;
    text-align: center;
    margin: 0;
}

/* Pin the close X to the right edge, vertically centered. Radzen's default
   stylesheet puts the close button inline at the end of the titlebar with
   theme-defined padding -- pulling it out of normal flow lets the title
   center on the bar (above) while the close still sits flush right and
   centered. `transform: translateY(-50%)` pairs with `top: 50%` so the
   centering tracks any titlebar height the theme decides on without us
   having to know it up front. The selector covers both the wrapper
   (`.rz-dialog-titlebar-icons`) and the inner anchor variants Radzen has
   used across versions. */
.jbf-resource-dialog .rz-dialog-titlebar .rz-dialog-titlebar-icons,
.jbf-resource-dialog .rz-dialog-titlebar .rz-dialog-titlebar-icon,
.jbf-resource-dialog .rz-dialog-titlebar .rz-dialog-titlebar-close {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    margin: 0 !important;
}
/* xs/sm/md tiers (max-width 1023.98px mirrors --bp-lg). PaginatedTable mobile
   scroll fix: release the viewport height clamp on .jbf-page so pages with
   FillAvailableHeight scroll naturally with the document. Without this,
   .jbf-body caps at 100vh and .table-and-panel-host clips cards past 50vh. */
@media (max-width: 1023.98px) {
    body[data-tier="xs"] .jbf-page,
    body[data-tier="sm"] .jbf-page,
    body[data-tier="md"] .jbf-page {
        height: auto;
        max-height: none;
        min-height: 0;
    }
    body[data-tier="xs"] .jbf-body,
    body[data-tier="sm"] .jbf-body,
    body[data-tier="md"] .jbf-body {
        flex: 0 0 auto;
        min-height: 0;
    }
}


