/* ==========================================================================
   Brand theming — map the Rejuvicon design tokens (rejuvicon-brand.css) onto
   the Radzen theme variables so the whole app chrome adopts the slate + coral
   palette. Loaded after standard.css so these win.
   ========================================================================== */
:root {
    /* Modern clean sans-serif — Inter (loaded in App.razor), with a system fallback.
       Drives both the brand wordmark token and Radzen's global text font. */
    --rjv-font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --rz-text-font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

    /* Primary = brand slate (links, active nav, selection, avatar) */
    --rz-primary:         var(--rjv-slate);
    --rz-primary-light:   var(--rjv-slate-light);
    --rz-primary-lighter: rgba(90, 143, 207, 0.16);
    --rz-primary-dark:    var(--rjv-slate-deep);
    --rz-primary-darker:  #2d4a73;
    --rz-on-primary:      var(--rjv-white);
    --rz-series-1:        var(--rjv-slate);

    /* Info = brand slate-blue. Radzen's default info palette is cyan/aqua, which
       clashes with the Rejuvicon slate theme and makes info alert text too bright. */
    --rz-info:         var(--rjv-slate-deep);
    --rz-info-light:   var(--rjv-slate);
    --rz-info-lighter: rgba(55, 89, 138, 0.18);
    --rz-info-dark:    var(--rjv-slate-deep);
    --rz-info-darker:  #2d4a73;
    --rz-on-info:         var(--rjv-white);
    --rz-on-info-light:   var(--rjv-white);
    --rz-on-info-lighter: var(--rjv-ink);
    --rz-on-info-dark:    var(--rjv-white);
    --rz-on-info-darker:  var(--rjv-white);

    /* Secondary = brand coral (accents / CTAs) */
    --rz-secondary:         var(--rjv-coral);
    --rz-secondary-light:   var(--rjv-coral-soft);
    --rz-secondary-lighter: rgba(255, 122, 92, 0.16);
    --rz-secondary-dark:    #e85f43;
    --rz-on-secondary:      var(--rjv-white);

    /* Surfaces & text */
    --rz-body-background-color: var(--rjv-surface);
    --rz-text-color:            var(--rjv-ink);
    --rz-header-color:          var(--rjv-slate-deep);

    /* Shared clinical-workspace surfaces. These keep record and Settings screens quiet by
       default, leaving slate and coral available for navigation, focus, and real actions. */
    --rjv-workspace-border: rgba(43, 58, 72, 0.14);
    --rjv-workspace-shadow: 0 1px 3px rgba(43, 58, 72, 0.08);
    --rjv-workspace-shadow-hover: 0 8px 24px rgba(43, 58, 72, 0.12);
    --rjv-workspace-radius: 12px;
    --rjv-workspace-surface: var(--rjv-white);

    /* Sidebar = brand deep-slate dark surface */
    --rz-sidebar-background-color: var(--rjv-slate-deep);

    /* Expanded sidebar width: 30% narrower than Radzen's 250px default. */
    --rz-sidebar-width: 175px;

    /* Sidebar menu items: blend into the slate sidebar (Radzen's defaults are
       dark greys that read as a clashing band). Hover/active use lighter slate
       tints; the active row gets a coral indicator. */
    --rz-panel-menu-item-background-color: transparent;
    --rz-panel-menu-item-border: none;
    --rz-panel-menu-item-color: var(--rjv-white);
    --rz-panel-menu-icon-color: var(--rjv-white);
    --rz-panel-menu-item-hover-background-color: rgba(255, 255, 255, 0.1);
    --rz-panel-menu-item-active-background-color: rgba(255, 255, 255, 0.16);
    --rz-panel-menu-item-active-indicator: var(--rjv-coral);

    /* Current width of the app sidebar. Defaults to the collapsed rail width; the
       :root:has() rule below swaps to the expanded width whenever the sidebar is open.
       Content-area overlays (e.g. the full-width edit drawer) subtract this so they span
       exactly up to the sidebar edge in either state. */
    --rjv-sidebar-width: 3.25rem;
    --rjv-content-drawer-width: calc(100vw - var(--rjv-sidebar-width));
}

/* When the sidebar is expanded it carries .rz-sidebar-expanded; track its real width so
   --rjv-content-drawer-width follows the sidebar as it expands/collapses (document-wide
   :has, so it applies regardless of where the drawer overlay is mounted). */
:root:has(.rz-sidebar.sidebar.rz-sidebar-expanded) {
    --rjv-sidebar-width: var(--rz-sidebar-width, 250px);
}

/* ==========================================================================
   Shared form layout + field appearance. Use these generic classes on edit
   forms (drawers, detail pages) instead of redeclaring per-component widths,
   label styles, field grids, or the outlined+rounded field look. Opt in by adding
   .rjv-form to the form wrapper and .rjv-form-field to each RadzenFormField.
   ========================================================================== */

/* Full-width field — replaces repeating Style="width: 100%;" on every RadzenFormField. */
.rjv-form-field {
    width: 100%;
}

/* Responsive field grid: two columns, collapsing to one on narrow drawers/screens. */
.rjv-form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

/* Standalone label above a control that is not itself a RadzenFormField (e.g. an image
   upload or a composite input). */
.rjv-field-label {
    font-size: 0.8125rem;
    color: var(--rz-text-secondary-color, #6c757d);
}

/* Shared status chip treatment. Apply this opt-in class to RadzenBadge status labels so
   informational, warning, success, and danger chips retain their semantic theme colour. */
.rjv-status-chip {
    flex: 0 0 auto;
    padding: 0.3rem 0.65rem;
    border: 1px solid currentColor;
    border-radius: 999px;
    font-weight: 700;
}

/* Outlined + rounded field look, applied once for any field inside an .rjv-form. Replaces the
   per-component ::deep rounding rules previously copied into each form's scoped CSS. */
.rjv-form .rz-form-field-content {
    border: 1.5px solid rgba(65, 105, 160, 0.8);
    border-radius: 4px;
    background: #ffffff;
    min-height: 42px;
}

/* Focus treatment for both interactive forms (Radzen applies rz-state-focused via JS)
   and static-SSR forms like the login page (no interactivity, so drive it from
   :focus-within instead). */
.rjv-form .rjv-form-field.rz-form-field.rz-state-focused .rz-form-field-content,
.rjv-form .rjv-form-field:focus-within .rz-form-field-content {
    border-color: rgba(47, 110, 188, 1);
    box-shadow: 0 0 0 2px rgba(47, 110, 188, 0.16);
}

.app-update-fallback {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(28, 42, 58, 0.72);
}

.app-update-fallback__panel {
    width: min(100%, 30rem);
    padding: 1.5rem;
    border-radius: 8px;
    background: var(--rjv-white);
    color: var(--rjv-ink);
    box-shadow: 0 1rem 3rem rgba(28, 42, 58, 0.24);
    text-align: center;
}

.app-update-fallback__panel strong {
    display: block;
    color: var(--rjv-slate-deep);
    font-size: 1.25rem;
}

.app-update-fallback__panel p {
    margin: 0.75rem 0 1rem;
}

.app-update-fallback__panel button {
    min-width: 7rem;
    border: 0;
    border-radius: 8px;
    padding: 0.625rem 1rem;
    background: var(--rjv-slate-deep);
    color: var(--rjv-white);
    font-weight: 700;
}

.rjv-form .rz-form-field-content::before,
.rjv-form .rz-form-field-content::after {
    display: none;
}

/* Shared light navigation panel used by Settings and drawer-internal sidebars. */
.rjv-nav-sidebar {
    flex: 0 0 14rem;
    border: 1px solid var(--rz-border-color, #dee2e6);
    border-radius: var(--rz-border-radius, 4px);
    background-color: var(--rz-base-background-color, #fff);
    overflow: hidden;

    --rz-panel-menu-item-background-color: transparent;
    --rz-panel-menu-item-color: var(--rjv-ink);
    --rz-panel-menu-icon-color: var(--rjv-slate);
    --rz-panel-menu-item-hover-background-color: var(--rz-primary-lighter);
    --rz-panel-menu-item-active-background-color: var(--rz-primary-lighter);
    --rz-panel-menu-item-active-indicator: var(--rjv-coral);
}

/* The phone country-code dropdown (PhoneInput) opens a narrow popup because Radzen sizes the
   panel to match the closed trigger's width via inline style, which is too narrow for names
   like "United Kingdom (+44)". Radzen portals dropdown popups to <body>, outside any component's
   scoped CSS, so this override has to be global; it's scoped to just this popup — not every
   dropdown app-wide — by matching on the flag image unique to PhoneInput's item template, and
   needs !important to beat Radzen's inline width. */
.rz-dropdown-panel:has(.rjv-phone-input-flag) {
    width: 16rem !important;
    min-width: 16rem !important;
}

/* RadzenAutoComplete has no built-in trigger affordance, so select-style autocompletes read as
   plain text boxes. Draw the same down-chevron RadzenDropDown shows, on the right inside the field,
   so every dropdown-style control looks consistent. The leading-input padding keeps long values
   clear of the chevron. */
.rjv-form .rz-autocomplete {
    position: relative;
}

.rjv-form .rz-autocomplete::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 0.85rem;
    width: 0.5rem;
    height: 0.5rem;
    border-right: 2px solid var(--rz-text-secondary-color, #6c757d);
    border-bottom: 2px solid var(--rz-text-secondary-color, #6c757d);
    transform: translateY(-65%) rotate(45deg);
    pointer-events: none;
}

.rjv-form .rz-autocomplete .rz-inputtext {
    padding-right: 2rem;
}

/* Align Radzen info alerts with the Rejuvicon slate-blue theme. Keep body copy dark for
   readability, while the icon/title carry the blue information accent. */
.rz-alert.rz-info.rz-shade-lighter {
    background-color: rgba(55, 89, 138, 0.18);
    border-color: rgba(55, 89, 138, 0.32);
    color: var(--rjv-ink);
}

.rz-alert.rz-info.rz-shade-lighter .rz-alert-icon,
.rz-alert.rz-info.rz-shade-lighter .rz-alert-title {
    color: var(--rjv-slate-deep);
}

@media (max-width: 900px) {
    .rjv-form-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ==========================================================================
   Side-drawer chrome. Owned here (rather than in Drawer.razor.css) so both the
   shared Drawer component and hand-rolled read-only drawers — which can't use
   Drawer because it forces a Cancel/Save action row — share one consistent
   header/body look. Scoped CSS could not do this: a hand-rolled drawer's
   elements don't carry the Drawer component's scope id.
   ========================================================================== */
.rjv-drawer {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 100%;
    background: var(--rz-base-background-color);
}

/* Drawer.razor programmatically focuses its own root on open so a bubbled Escape keydown has
   somewhere to start from (Radzen does not autofocus anything inside the side dialog itself) -
   this isn't an interactive control, so suppress the focus ring that would otherwise draw. */
.rjv-drawer:focus {
    outline: none;
}

.rz-dialog-side.rz-dialog-side-position-right.rz-open {
    transform: translateX(0) !important;
}

.rz-dialog-side {
    top: 0;
    max-height: 100%;
}

.rz-dialog-side.rz-dialog-side-position-right,
.rz-dialog-side.rz-dialog-side-position-left {
    height: 100%;
}

/* A transformed .rz-body traps fixed descendants below side dialogs. Remove the transform
   only while a full-screen overlay (the common consent preview, or the drug book sign-in
   dialog) is open so its overlay can reach the app root. */
body:has(.cf-render-dialog-backdrop, .drug-book-signin-backdrop) .rz-body {
    transform: none !important;
}

body:has(.patient-photo-compare-backdrop) .rz-dialog-side.rz-dialog-side-position-right.rz-open {
    width: 100vw !important;
    max-width: 100vw !important;
}

.rz-dialog-side.rz-dialog-side-position-right .rz-dialog-side-content {
    height: 100%;
    overflow: hidden;
    padding: 0;
}

body:has(.patient-photo-compare-backdrop) .rz-dialog-side.rz-dialog-side-position-right .rz-dialog-side-content {
    overflow: visible;
}

.rjv-drawer-header {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.75rem;
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--rz-base-300);
    background: var(--rjv-workspace-surface);
}

.rjv-drawer-header h3 {
    margin: 0;
    color: var(--rjv-slate-deep);
    font-size: 1.15rem;
    font-weight: 700;
}

.rjv-drawer-header > .rjv-close-button-hover:last-child {
    margin-left: auto;
}

.rjv-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 1.5rem;
}

.rjv-drawer-body:has(.booking-drawer-layout) {
    min-height: 0;
    overflow: hidden;
}

.rjv-drawer-body:has(.booking-drawer-layout) > form {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

.rjv-drawer-loading {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* Fixed footer holding Close/Save: a flex sibling of the scrollable .rjv-drawer-body (not a
   child), so it stays reachable without scrolling on long forms, mirroring the header. */
.rjv-drawer-footer {
    flex-shrink: 0;
    padding: 1rem 1.5rem;
    border-top: 1px solid var(--rz-base-300);
    background: var(--rjv-workspace-surface);
}

.rjv-drawer-loading-content {
    height: 100%;
    min-height: 0;
}

.rjv-drawer-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.rjv-drawer-actions-leading,
.rjv-drawer-actions-primary {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.rjv-drawer-actions-primary {
    justify-content: flex-end;
    margin-left: auto;
}

.rjv-drawer-actions-busy {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
    white-space: nowrap;
}

/* Form-content helpers used inside drawer bodies: .rjv-drawer-row for an inline row (e.g. a
   toggle plus its label) and .rjv-drawer-row-list to stack such rows. */
.rjv-drawer-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.rjv-drawer-row-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.rjv-drawer-heading {
    margin-top: 0.5rem;
    margin-bottom: 1rem;
}

.rjv-drawer-empty {
    color: var(--rz-text-secondary-color);
}

.rjv-over-drawer-backdrop {
    position: fixed;
    top: 0;
    right: 0;
    bottom: auto;
    z-index: 1200;
    display: flex;
    justify-content: flex-end;
    width: var(--rjv-content-drawer-width);
    height: 100dvh;
    background: rgba(15, 23, 42, 0.28);
}

.rjv-over-drawer-panel {
    width: 50%;
    min-width: min(100%, 30rem);
    height: 100%;
    overflow: hidden;
    background: var(--rz-base-background-color);
    border-left: 1px solid var(--rz-base-300);
    box-shadow: -1rem 0 2.5rem rgba(15, 23, 42, 0.18);
}

/* PatientNoteDrawer/MedicalNoteEditorDrawer focus the panel on open so a bubbled Escape keydown
   has somewhere to start from - not an interactive control, so suppress the focus ring. */
.rjv-over-drawer-panel:focus {
    outline: none;
}

.rjv-over-drawer-body {
    max-height: calc(100vh - 5rem);
    overflow-y: auto;
    padding: 1.5rem;
}

.rjv-over-drawer-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
}

.rjv-over-drawer-action-spacer {
    flex: 1 1 auto;
}

@media (max-width: 760px) {
    .rjv-over-drawer-backdrop {
        width: 100vw;
    }

    .rjv-over-drawer-panel {
        width: 100%;
    }
}

/* Opt-in modifier: pins an over-drawer's Save/Cancel row in a fixed footer, mirroring
   Drawer.razor's footer-as-flex-sibling pattern. Scoped to consumers that add this class so
   other .rjv-over-drawer-panel consumers (which still keep their actions inside the scrollable
   body) are unaffected. */
.rjv-over-drawer-fixed-footer {
    display: flex;
    flex-direction: column;
}

.rjv-over-drawer-fixed-footer form {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.rjv-over-drawer-fixed-footer .rjv-over-drawer-body {
    flex: 1;
    max-height: none;
}

/* Radzen styles its own components, but the bare body (and the anonymous auth
   pages that hang off it) need the brand font set explicitly. */
body {
    font-family: var(--rjv-font);
}

/* Give content cards quiet definition against the pale app surface. Selected and focused
   controls carry the stronger brand colour; every passive card should not compete for it. */
.rz-card {
    border: 1px solid var(--rjv-workspace-border);
    border-radius: var(--rjv-workspace-radius);
    background: var(--rjv-workspace-surface);
    box-shadow: var(--rjv-workspace-shadow);
}

.rz-button {
    border-radius: 999px;
}

.rz-button.rz-light {
    border: 1.5px solid rgba(90, 143, 207, 0.8);
    color: var(--rjv-slate-deep);
}

.rz-button.rz-light .rz-button-icon,
.rz-button.rz-light i {
    color: var(--rjv-slate-deep);
}

.rz-button.rz-light.rz-variant-filled.rz-shade-default,
.rz-button.rz-light.rz-variant-flat.rz-shade-default,
.rz-button.rz-light.rz-variant-outlined.rz-shade-default,
.rz-button.rz-light.rz-variant-text.rz-shade-default {
    color: var(--rjv-slate-deep);
}

.rz-button.rz-light.rz-variant-filled.rz-shade-default .rz-button-icon,
.rz-button.rz-light.rz-variant-filled.rz-shade-default i,
.rz-button.rz-light.rz-variant-flat.rz-shade-default .rz-button-icon,
.rz-button.rz-light.rz-variant-flat.rz-shade-default i,
.rz-button.rz-light.rz-variant-outlined.rz-shade-default .rz-button-icon,
.rz-button.rz-light.rz-variant-outlined.rz-shade-default i,
.rz-button.rz-light.rz-variant-text.rz-shade-default .rz-button-icon,
.rz-button.rz-light.rz-variant-text.rz-shade-default i {
    color: var(--rjv-slate-deep);
}

h1:focus {
    outline: none;
}

/* Keep anonymous auth pages full-bleed even before scoped CSS finishes loading.
   Branded slate gradient backdrop for the unauthenticated card. */
.auth-shell {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    box-sizing: border-box;
    overflow-y: auto;
    color: var(--rjv-ink);
    background: linear-gradient(135deg, var(--rjv-slate-deep) 0%, var(--rjv-slate) 100%);
}

.rjv-auth-card {
    width: 100%;
    max-width: 420px;
    padding: 2.5rem 2.25rem;
    border-radius: var(--rjv-radius-lg);
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    box-shadow: 0 20px 60px rgba(45, 74, 115, 0.35);
    color: var(--rjv-ink);
    box-sizing: border-box;
}

.rjv-auth-card--wide {
    max-width: 680px;
}

.rjv-auth-header {
    margin-bottom: 1.75rem;
    text-align: center;
}

.rjv-auth-logo {
    display: block;
    width: 200px;
    max-width: 70%;
    height: auto;
    margin: 0 auto 1.25rem;
}

.rjv-auth-title {
    margin: 0 0 0.4rem;
    color: var(--rjv-slate-deep);
    font-size: 1.65rem;
    font-weight: 600;
    letter-spacing: 0;
}

.rjv-auth-field {
    margin-bottom: 1rem;
}

.rjv-auth-field .rz-textbox,
.rjv-auth-field input {
    color: var(--rjv-ink);
    font-family: inherit;
    background: transparent;
}

.rjv-auth-field .rz-textbox::placeholder,
.rjv-auth-field input::placeholder {
    color: var(--rjv-muted);
}

.rjv-auth-field input:-webkit-autofill,
.rjv-auth-field input:-webkit-autofill:hover,
.rjv-auth-field input:-webkit-autofill:focus,
.rjv-auth-field input:-webkit-autofill:active {
    -webkit-box-shadow: 0 0 0 1000px #ffffff inset;
    box-shadow: 0 0 0 1000px #ffffff inset;
    -webkit-text-fill-color: var(--rjv-ink);
    caret-color: var(--rjv-ink);
}

.rjv-auth-error {
    margin-bottom: 1rem;
    padding: 0.6rem 0.8rem;
    color: #5a0a0a;
    background: rgba(255, 220, 220, 0.7);
    border: 1px solid rgba(220, 80, 80, 0.4);
    border-radius: 10px;
    font-size: 0.85rem;
}

.rjv-auth-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.85rem 1rem;
    color: var(--rjv-white);
    background: var(--rjv-coral);
    border: 0;
    border-radius: 999px;
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 120ms ease, transform 120ms ease;
}

.rjv-auth-submit:disabled {
    cursor: wait;
    opacity: 0.82;
}

.rjv-auth-submit--busy {
    pointer-events: none;
}

.rjv-auth-submit--busy .rjv-auth-submit-icon {
    display: none;
}

.rjv-auth-submit-spinner {
    display: none;
    width: 1rem;
    height: 1rem;
    border: 2px solid rgba(255, 255, 255, 0.4);
    border-top-color: #ffffff;
    border-radius: 50%;
    box-sizing: border-box;
    animation: rjv-auth-submit-spin 800ms linear infinite;
}

.rjv-auth-submit--busy .rjv-auth-submit-spinner {
    display: inline-block;
}

@keyframes rjv-auth-submit-spin {
    to {
        transform: rotate(360deg);
    }
}

.rjv-auth-submit:hover {
    background: var(--rjv-coral-soft);
}

.rjv-auth-submit:active {
    transform: translateY(1px);
}

.rjv-auth-submit:focus-visible {
    outline: 3px solid rgba(255, 255, 255, 0.6);
    outline-offset: 2px;
}

.rjv-auth-footer {
    margin: 1.5rem 0 0;
    color: var(--rjv-muted);
    font-size: 0.85rem;
    text-align: center;
}

.rjv-auth-link {
    color: var(--rjv-slate-deep);
    font-weight: 500;
    text-decoration: none;
}

.rjv-auth-link:hover {
    text-decoration: underline;
}

@media (max-width: 480px) {
    .rjv-auth-card {
        padding: 2rem 1.5rem;
        border-radius: 20px;
    }

    .rjv-auth-title {
        font-size: 1.45rem;
    }
}

/* Lay the sidebar out as a column so the controls in .sidebar-footer
   can sit pinned to the bottom via margin-top: auto. */
.rz-sidebar.sidebar {
    display: flex;
    flex-direction: column;
}

/* When collapsed, keep a narrow rail visible (icons + the expand toggle) instead of
   Radzen's default of fully hiding the sidebar, which would make the toggle unreachable. */
.rz-sidebar.sidebar:not(.rz-sidebar-expanded) {
    width: 3.25rem;
    min-width: 3.25rem;
    overflow: hidden;
    opacity: 1;
}

/* In the collapsed rail, hide menu item labels and show only the icon. */
.rz-sidebar.sidebar:not(.rz-sidebar-expanded) .rz-navigation-item-text {
    display: none;
}

/* Pins administrative navigation and the collapse/expand toggle to the bottom. Expanded:
   one row — Settings on the left, toggle at the right edge. Collapsed rail: stacked
   (gear above, expand toggle below). */
.rz-sidebar.sidebar .sidebar-footer {
    margin-top: auto;
    display: flex;
    align-items: center;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}

/* Let the Settings menu take the row; the toggle keeps to the right edge even when the
   Settings item is absent (non-administrators). */
.rz-sidebar.sidebar .sidebar-footer .rz-panel-menu {
    flex: 1 1 auto;
    min-width: 0;
}

.rz-sidebar.sidebar .sidebar-toggle {
    display: flex;
    justify-content: flex-end;
    padding: 0.5rem;
    margin-inline-start: auto;
}

.rz-sidebar.sidebar:not(.rz-sidebar-expanded) .sidebar-footer {
    flex-direction: column;
    align-items: stretch;
}

.rz-sidebar.sidebar:not(.rz-sidebar-expanded) .sidebar-toggle {
    margin-inline-start: 0;
    justify-content: center;
}

/* Bare chevron glyph: drop the global Light-button pill outline inside the sidebar. */
.rz-sidebar.sidebar .sidebar-toggle .rz-button.rz-light {
    border: none;
}

.rz-sidebar.sidebar .sidebar-toggle .rz-button.rz-light.rz-variant-text.rz-shade-default,
.rz-sidebar.sidebar .sidebar-toggle .rz-button.rz-light.rz-variant-text.rz-shade-default .rz-button-icon,
.rz-sidebar.sidebar .sidebar-toggle .rz-button.rz-light.rz-variant-text.rz-shade-default i {
    color: var(--rz-panel-menu-item-color);
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

/* These forms surface validation through <ValidationMessage> text (and RadzenAlert), not the
   Blazor template's default green/red input outlines. Those outlines are rectangular and sit on
   the inner input, so they don't follow the rounded .rz-form-field-content border and read as a
   misaligned second border. Suppress them inside rjv-form. */
.rjv-form .valid.modified:not([type=checkbox]),
.rjv-form .invalid {
    outline: none;
}

.validation-message {
    color: #e50000;
}

.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: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}
/* ==========================================================================
   Loader animations â€” global so the RadzenDataGrid internal loader override
   below can reuse the same keyframe by name. The LoadingDots component's
   scoped CSS handles sizing and colour, but the animation property would be
   re-keyed by Blazor's CSS scoping, so it lives here instead.
   ========================================================================== */
.rjv-loading-dots__dot {
    animation: rjv-loading-dots-bounce 1.2s ease-in-out infinite;
}

/* Stagger so the dots ripple rather than blink in lockstep. 0.15s offsets
   look natural against the 1.2s cycle. */
.rjv-loading-dots__dot:nth-child(2) {
    animation-delay: 0.15s;
}

.rjv-loading-dots__dot:nth-child(3) {
    animation-delay: 0.3s;
}

@keyframes rjv-loading-dots-bounce {
    0%, 60%, 100% {
        opacity: 0.25;
        transform: translateY(0);
    }

    30% {
        opacity: 1;
        transform: translateY(-0.25em);
    }
}

@media (prefers-reduced-motion: reduce) {
    .rjv-loading-dots__dot {
        animation-duration: 1.8s;
    }
}

.rjv-skeleton-shimmer {
    background: linear-gradient(
        90deg,
        color-mix(in srgb, var(--rjv-workspace-border) 72%, #fff) 0%,
        color-mix(in srgb, var(--rjv-workspace-border) 36%, #fff) 42%,
        color-mix(in srgb, var(--rjv-workspace-border) 72%, #fff) 84%
    );
    background-size: 220% 100%;
    animation: rjv-skeleton-shimmer 1.35s ease-in-out infinite;
}

@keyframes rjv-skeleton-shimmer {
    0% {
        background-position: 120% 0;
    }

    100% {
        background-position: -120% 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .rjv-skeleton-shimmer {
        animation: none;
    }
}

.rz-button.rz-light:hover {
    background-color: var(--rz-base-400);
}

.help-toolbar .rz-button.rz-variant-outlined.rz-light:not(.rz-state-disabled):hover {
    background-color: var(--rz-base-300);
}

.rjv-dialog-over-side-drawer {
    z-index: 1300;
}

/* Radzen's Confirm dialog renders OK before Cancel and has no per-button ButtonStyle option.
   For destructive Cancel/Remove/Delete actions, show the safe option first and recolour OK to
   match the red used by RadzenButton ButtonStyle="ButtonStyle.Danger" throughout the app. */
.rjv-dialog-confirm-danger .rz-dialog-confirm-buttons {
    flex-direction: row-reverse;
}

.rjv-dialog-confirm-danger .rz-dialog-confirm-buttons .rz-button.rz-primary {
    background-color: var(--rz-danger);
    border-color: var(--rz-danger);
}

.rjv-dialog-confirm-danger .rz-dialog-confirm-buttons .rz-button.rz-primary:not(.rz-state-disabled):hover {
    background-color: var(--rz-danger-dark);
    border-color: var(--rz-danger-dark);
}

/* Radzen HTML editor prompts use the default dialog layer, which is the same layer as a side
   drawer and is therefore covered when the editor is inside one. Keep the prompt wrapper (which
   also contains its mask) on the established over-drawer layer. */
.rz-dialog-wrapper:has(.rz-html-editor-dialog-item) {
    z-index: 1300;
}

/* Header help button: dark icon (the Light button variant renders it white by
   default) and no pill outline (a bare question-mark glyph). The header layout
   owns spacing between all actions. */
.rz-button.rz-light.rjv-help-button {
    border: none;
    color: var(--rjv-slate-deep);
}

.rjv-help-button .rz-button-icon,
.rjv-help-button i {
    color: var(--rjv-slate-deep);
}

/* ==========================================================================
   Contextual help panel (HelpPanel.razor). The panel reuses the .rjv-drawer
   header/body chrome; the rules below style the Back / Help-home toolbar and
   the rendered Markdown content served by the help endpoints.
   ========================================================================== */
.help-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.help-toolbar-home {
    margin-left: auto;
}


.help-content {
    color: var(--rz-text-color);
    line-height: 1.55;
}

.help-content h1,
.help-content h2,
.help-content h3 {
    color: var(--rz-text-color);
    font-weight: 700;
    margin: 1.25rem 0 0.5rem;
}

.help-content h1 {
    font-size: 1.5rem;
    margin-top: 0;
}

.help-content h2 {
    font-size: 1.2rem;
}

.help-content h3 {
    font-size: 1.02rem;
}

.help-content p,
.help-content ul,
.help-content ol {
    margin-bottom: 0.75rem;
}

.help-content ul,
.help-content ol {
    padding-left: 1.4rem;
}

.help-content li {
    margin-bottom: 0.25rem;
}

.help-content a {
    color: var(--rjv-coral, var(--rz-primary));
    font-weight: 600;
}

.help-content code {
    background: var(--rz-base-200);
    border: 1px solid var(--rz-base-300);
    border-radius: 4px;
    padding: 0.05rem 0.3rem;
    font-size: 0.9em;
}

.help-content blockquote {
    border-left: 3px solid var(--rz-base-300);
    margin: 0.75rem 0;
    padding: 0.25rem 0 0.25rem 1rem;
    color: var(--rz-text-secondary-color);
}

.help-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 0.75rem 0;
    display: block;
    overflow-x: auto;
}

.help-content th,
.help-content td {
    border: 1px solid var(--rz-base-300);
    padding: 0.5rem;
    vertical-align: top;
    text-align: left;
}

.help-content th {
    background: var(--rz-base-200);
}

/* Appointments page busy overlay. Kept global because module isolated CSS is not
   currently included by the host shell. */
.appointments-board-panel {
    min-height: calc(100vh - 11rem);
}

.appointments-loading-panel {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: grid;
    place-items: center;
    padding: 1rem;
    background: rgba(248, 250, 252, 0.72);
}

.appointments-loading-card {
    display: grid;
    justify-items: center;
    gap: 0.75rem;
    min-width: min(24rem, 100%);
    padding: 1.5rem;
}

.appointments-loading-text {
    color: var(--rz-text-color);
    font-weight: 600;
    text-align: center;
}

/* ==========================================================================
   Appointments board chrome (day board + hourly week board). Shared here — not
   in a component's scoped CSS — so both AppointmentBoardDayView (columns = days'
   practitioners) and AppointmentBoardWeekView (columns = a practitioner's days)
   render the same gutter/columns/blocks. The create-drag band is styled inline
   by appointments-board.js (created outside Blazor's render tree).
   ========================================================================== */
.appt-board {
    display: flex;
    min-width: 720px;
    max-height: 100%;
    overflow: auto;
    background: var(--rz-base-background-color, #fff);
    border: 1px solid var(--rz-border-color, #dfe6ee);
    border-radius: var(--rjv-radius-md, 14px);
}

.appt-gutter { width: 56px; flex: none; }

.appt-gutter-head {
    height: 64px;
    border-bottom: 1px solid var(--rz-border-color, #dfe6ee);
    position: sticky;
    top: 0;
    background: var(--rz-base-background-color, #fff);
    z-index: 5;
}

.appt-hour {
    position: relative;
    font-size: 0.7rem;
    color: var(--rz-text-secondary-color, #5c6b7d);
    font-variant-numeric: tabular-nums;
}

.appt-hour span {
    position: absolute;
    top: -0.5rem;
    right: 0.6rem;
    background: var(--rz-base-background-color, #fff);
    padding: 0 0.15rem;
}

.appt-col {
    flex: 1;
    min-width: 300px;
    border-left: 1px solid var(--rz-border-color, #dfe6ee);
    display: flex;
    flex-direction: column;
}

.appt-col-head {
    height: 64px;
    border-bottom: 1px solid var(--rz-border-color, #dfe6ee);
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0 0.75rem;
    background: var(--rz-base-background-color, #fff);
    position: sticky;
    top: 0;
    z-index: 5;
}

.appt-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    flex: none;
    display: grid;
    place-items: center;
    color: #fff;
    font-weight: 600;
    font-size: 0.75rem;
    background: var(--rjv-slate, #5a8fcf);
}

.appt-col-who { line-height: 1.25; min-width: 0; display: flex; flex-direction: column; }
.appt-col-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.appt-col-shift { font-size: 0.7rem; color: var(--rz-text-secondary-color, #5c6b7d); font-variant-numeric: tabular-nums; }

.appt-col-load {
    margin-left: auto;
    font-size: 0.7rem;
    color: var(--rjv-slate-deep, #37598a);
    background: #eef4fb;
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.appt-col-body {
    position: relative;
    flex: none;
    cursor: cell;
    background:
        repeating-linear-gradient(to bottom,
            transparent 0, transparent 71px,
            var(--rz-border-color, #dfe6ee) 71px, var(--rz-border-color, #dfe6ee) 72px),
        repeating-linear-gradient(to bottom,
            transparent 0, transparent 17px,
            #eef1f6 17px, #eef1f6 18px);
    background-color: var(--rz-base-background-color, #fff);
}

.appt-offroster {
    position: absolute;
    left: 0;
    right: 0;
    z-index: 1;
    pointer-events: none;
    background: repeating-linear-gradient(-45deg, #f1f4f8 0 6px, #e9edf2 6px 12px);
}

.appt-block {
    position: absolute;
    z-index: 3;
    border-radius: var(--rjv-radius-sm, 8px);
    padding: 0.3rem 0.55rem;
    box-sizing: border-box;
    overflow: hidden;
    cursor: grab;
    touch-action: none;
    user-select: none;
    border-left: 3px solid var(--appt-edge, #8ca6c4);
    background: var(--appt-bg, #eef2f6);
    box-shadow: 0 1px 2px rgba(38, 50, 65, 0.08);
}

.appt-block--dragging {
    cursor: grabbing;
    z-index: 10;
    box-shadow: 0 6px 18px rgba(38, 50, 65, 0.25);
    opacity: 0.95;
}

.appt-resize-handle {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 8px;
    cursor: ns-resize;
    touch-action: none;
}

.appt-resize-handle::after {
    content: "";
    display: block;
    width: 28px;
    height: 3px;
    margin: 3px auto 0;
    border-radius: 2px;
    background: var(--appt-edge, #8ca6c4);
    opacity: 0;
}

.appt-block:hover .appt-resize-handle::after,
.appt-block--selected .appt-resize-handle::after { opacity: 0.55; }

@media (prefers-reduced-motion: no-preference) {
    .appt-block { transition: box-shadow 0.12s ease; }
}

.appt-block:hover { box-shadow: 0 2px 6px rgba(38, 50, 65, 0.18); }

.appt-block:focus-visible,
.appt-block--selected {
    outline: 2px solid var(--rjv-slate, #5a8fcf);
    outline-offset: 1px;
}

.appt-block--blocked {
    --appt-edge: #b7c1cc;
    --appt-bg: #e9edf1;
    color: var(--rz-text-secondary-color, #5c6b7d);
}

.appt-block--no-show {
    --appt-edge: var(--rz-danger, #d9534f) !important;
    --appt-bg: #edf0f3 !important;
    color: var(--rz-text-secondary-color, #5c6b7d);
    opacity: 0.68;
}

.appt-block--arrived {
    --appt-edge: var(--rz-success, #3aa76d) !important;
}

.appt-block-row1 {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-weight: 600;
    font-size: 0.75rem;
    line-height: 1.1;
    min-width: 0;
}

.appt-block-name {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.appt-block-time {
    margin-left: auto;
    font-weight: 400;
    font-size: 0.7rem;
    color: var(--rz-text-secondary-color, #5c6b7d);
    font-variant-numeric: tabular-nums;
}

.appt-arrived-indicator,
.appt-no-show-indicator,
.appt-blocked-indicator,
.appt-notes-indicator {
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    color: #fff;
}

.appt-notes-indicator {
    /* Fixed colour, not var(--appt-edge, ...) - that variable is overridden per-status
       (arrived/no-show) on the enclosing block and would inherit into this icon too. */
    background: #8ca6c4;
    cursor: help;
}

.appt-arrived-indicator {
    background: var(--rz-success, #3aa76d);
}

.appt-no-show-indicator {
    background: var(--rz-danger, #d9534f);
}

.appt-blocked-indicator {
    background: var(--rz-text-secondary-color, #5c6b7d);
}

.appt-arrived-indicator .rzi,
.appt-no-show-indicator .rzi,
.appt-blocked-indicator .rzi,
.appt-notes-indicator .rzi {
    font-size: 13px;
    line-height: 1;
}

.appt-block-treatment,
.appt-block-services {
    min-width: 0;
    font-size: 0.72rem;
    line-height: 1.15;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.appt-block-note {
    font-size: 0.68rem;
    color: var(--rz-text-secondary-color, #5c6b7d);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.appt-empty {
    flex: 1;
    display: grid;
    place-items: center;
    color: var(--rz-text-secondary-color, #5c6b7d);
    min-height: 12rem;
}
