html, body {
    margin: 0;
    height: 100%;
}

/* The Blazor app root needs an explicit height for the drawer chain to
   resolve `height: 100%` all the way down. Without this, every ancestor
   collapses to content height and the drawer ends partway down the page. */
#app {
    height: 100%;
}

:root {
    --header-h: 0px;
}

.contentFillViewPort {
    height: calc(100vh - var(--header-h) - 6px);
}

#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;
}

.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." }

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

.loading-progress circle {
    fill: none;
    stroke: #e0e0e0;
    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"); }

/* code { color: #c02d76; } */

/* ---------------------------------------------------------------------------
   Monaco Editor Error Decorations
   --------------------------------------------------------------------------- */

/* Line background highlight for error lines */
.errorLineDecoration {
    background-color: rgba(255, 0, 0, 0.1) !important;
}

/* Red circle glyph in the gutter */
.errorGlyph {
    background-color: #e51400;
    border-radius: 50%;
    width: 8px !important;
    height: 8px !important;
    margin-left: 5px;
    margin-top: 6px;
}

/* Inline error message shown after the line content */
.inlineErrorMessage {
    color: #e51400;
    font-style: italic;
    opacity: 0.9;
}

/* ---------------------------------------------------------------------------
   Script Editor Container (VSCode-style layout)
   --------------------------------------------------------------------------- */

.script-editor-container {
    display: flex;
    flex-direction: column;
    height: 600px;
    border: 1px solid #ccc;
}

.script-editor-wrapper {
    flex: 1;
    min-height: 100px;
    overflow: hidden;
}

.script-editor-wrapper #report-script-editor {
    height: 100% !important;
    width: 100% !important;
}

/* ---------------------------------------------------------------------------
   Script Output Panel (VSCode-style)
   --------------------------------------------------------------------------- */

.script-output-panel {
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 12px;
    display: flex;
    flex-direction: column;
    height: 150px;
    flex-shrink: 0;
}

.script-output-panel.collapsed {
    height: auto !important;
}

.script-output-panel.collapsed .script-output-resize-bar {
    display: none;
}

.script-output-resize-bar {
    height: 4px;
    background: #e0e0e0;
    cursor: ns-resize;
    flex-shrink: 0;
}

.script-output-resize-bar:hover {
    background: #0078d4;
}

.script-output-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 10px;
    background: #f3f3f3;
    border-bottom: 1px solid #ddd;
    flex-shrink: 0;
    user-select: none;
    cursor: pointer;
}

.script-output-header span {
    flex: 1;
}

.script-output-header:hover {
    background: #e8e8e8;
}

.script-output-clear {
    padding: 2px 8px;
    font-size: 11px;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 3px;
    cursor: pointer;
    margin-left: auto;
}

.script-output-clear:hover {
    background: #e8e8e8;
}

.script-output-content {
    flex: 1;
    overflow-y: auto;
    padding: 8px 10px;
    background: #1e1e1e;
    color: #d4d4d4;
}

.output-log {
    padding: 2px 0;
    white-space: pre-wrap;
    word-break: break-word;
}

.output-error {
    color: #f44336;
    padding: 2px 0;
    white-space: pre-wrap;
    word-break: break-word;
}

.output-empty {
    color: #666;
    font-style: italic;
}

/* =============================================================================
 * MainLayout navigation drawer (Pages/Layout/MainLayout.razor)
 *
 * Layout: a TelerikDrawer (chrome + push-mode width binding) wraps a custom
 * <Template> body that hosts a header bar (title + pin), a TelerikTreeView for
 * hierarchical navigation, and an absolute-positioned resize handle on the
 * right edge.
 *
 * Styles live here (global) instead of MainLayout.razor.css because Telerik
 * renders its own DOM wrappers around the Template content — those wrappers
 * don't carry our Blazor scope attribute, so ::deep selectors from a scoped
 * stylesheet can't reach .mp-drawer-shell. Global rules keyed on our distinct
 * `mp-drawer-*` class names sidestep the scoping problem entirely.
 * =============================================================================*/

/* Breathing room between the drawer/header chrome and the routed page content.
   Pages render straight into @Body so they have no padding of their own. */
.mp-body-pad {
    padding: 0.375rem 0 0 0.375rem;
}

/* Pin the drawer + its content area to fill the viewport below the AppBar.
   Telerik's default drawer height is content-driven so a short tree collapses
   the panel vertically. Reports' DockManager already uses the same
   `calc(100vh - var(--header-h))` formula (see .contentFillViewPort);
   re-using --header-h keeps drawer + page content vertically aligned.

   `!important` overrides Telerik's own height rule on the container; the
   inner .k-drawer + .k-drawer-content already use height: 100% so once
   the container has a real height they fill it. */
.k-drawer-container {
    height: calc(100vh - var(--header-h)) !important;
}

/* In Push mode Telerik renders:
     .k-drawer-container > .k-drawer-wrapper (sidebar)
                         > .k-drawer-content (page area)
   Force both to 100% so they inherit the container's viewport-minus-header
   height (per Drawer docs: "height is dynamic based on the height of the
   content — you can change it with CSS"). */
.k-drawer-wrapper,
.k-drawer-content {
    height: 100% !important;
}

/* AppBar carries a default elevation shadow that bleeds onto the drawer +
   content area. Flatten it so the header reads as a single calm strip. */
.k-appbar {
    box-shadow: none !important;
}

.mp-drawer-shell {
    display: flex;
    flex-direction: column;
    height: 100%;
    /* Resize handle is an absolute overlay on the right edge — needs a
       positioned ancestor. */
    position: relative;
    overflow: hidden;
}

/* ── Header (title + pin toggle) ───────────────────────────────────────── */

.mp-drawer-header {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 8px 8px 8px 10px;
    border-bottom: 1px solid var(--kendo-color-border, rgba(0, 0, 0, 0.08));
    min-height: 40px;
    flex: 0 0 auto;
    font-size: 0.95rem;
    font-weight: 500;
    background: var(--kendo-color-surface, #fafafa);
}

.mp-drawer-header .mp-drawer-pin {
    border: none;
    background: transparent;
    padding: 4px;
    border-radius: 4px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: inherit;
    line-height: 1;
}

.mp-drawer-header .mp-drawer-pin:hover {
    background: var(--kendo-color-base-hover, rgba(0, 0, 0, 0.06));
}

.mp-drawer-header .mp-drawer-title {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mp-drawer-header .mp-drawer-pin.is-pinned {
    color: var(--kendo-color-primary, #1a6ea6);
}

/* ── Tree container ────────────────────────────────────────────────────── */

.mp-drawer-items {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 4px 0;
}

/* Let the TelerikTreeView use the full panel width and not clip its own
   chevrons against the resize handle (which sits on the right edge with 6px
   of reserved hit area). */
.mp-drawer-items .k-treeview {
    width: 100%;
    padding-right: 6px;
}

/* ── Resize handle on the right edge ───────────────────────────────────── */

.mp-drawer-resize-handle {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 6px;
    cursor: ew-resize;
    z-index: 2;
    background: transparent;
    transition: background 120ms ease-out;
}
.mp-drawer-resize-handle:hover {
    background: var(--kendo-color-primary, #1a6ea6);
    opacity: 0.4;
}

/* Body-level cursor lock during a drag (set by drawer.js). Keeps the
   ew-resize cursor visible even when the pointer briefly leaves the handle. */
body.mp-drawer-resizing,
body.mp-drawer-resizing * {
    cursor: ew-resize !important;
    user-select: none !important;
}

/* ---------------------------------------------------------------------------
   Update-available sticky toast (UpdateAvailableNotification.razor)
   --------------------------------------------------------------------------- */
.mpTelerikUpdateNotification .k-notification {
    min-width: 320px;
    padding: 12px 14px;
}

.mp-update-toast {
    display: flex;
    align-items: center;
    gap: 12px;
}

.mp-update-toast__msg {
    font-weight: 600;
}

.mp-update-toast__sub {
    font-weight: 400;
    font-size: 0.85em;
    opacity: 0.85;
}

/* ---------------------------------------------------------------------------
   Avatar dropdown (AvatarMenu.razor)
   Teams-style profile menu anchored to the avatar button in the top AppBar.
   Telerik components don't accept attribute splatting, so styling lives here
   keyed on .mp-avatar-* class names assigned via the components' `Class` prop
   (or on plain HTML inside the popup).
   --------------------------------------------------------------------------- */
.mp-avatar-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
    margin: 0;
    background: transparent;
    border: 0;
    border-radius: 999px;
    cursor: pointer;
    line-height: 0;
}

.mp-avatar-button:hover {
    background: rgba(0, 0, 0, 0.06);
}

.mp-avatar-button:focus-visible {
    outline: 2px solid var(--kendo-color-primary, #1a6ea6);
    outline-offset: 2px;
}

.mp-avatar-menu {
    display: flex;
    flex-direction: column;
    background: var(--kendo-color-surface, #fff);
    color: var(--kendo-color-on-app-surface, #1f1f1f);
    border: 1px solid var(--kendo-color-border, rgba(0, 0, 0, 0.08));
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    padding: 12px 0 6px;
    overflow: hidden;
}

.mp-avatar-menu-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 16px 12px;
}

.mp-avatar-menu-identity {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.mp-avatar-menu-name {
    font-weight: 600;
    font-size: 0.95rem;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mp-avatar-menu-institution {
    font-size: 0.82rem;
    opacity: 0.75;
    line-height: 1.2;
    margin-top: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mp-avatar-menu-separator {
    height: 1px;
    background: var(--kendo-color-border, rgba(0, 0, 0, 0.08));
    margin: 0 0 4px;
}

.mp-avatar-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 16px;
    background: transparent;
    border: 0;
    text-align: left;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.mp-avatar-menu-item:hover,
.mp-avatar-menu-item:focus-visible {
    background: var(--kendo-color-base-hover, rgba(0, 0, 0, 0.04));
    outline: none;
}

/* Sign-out item — same chrome as the others, but the icon + label turn
   destructive on hover/focus so an accidental click reads as a stop sign. */
.mp-avatar-menu-item--danger:hover,
.mp-avatar-menu-item--danger:focus-visible {
    color: var(--kendo-color-error, #d9534f);
}
.mp-avatar-menu-item--danger:hover .k-svg-icon,
.mp-avatar-menu-item--danger:focus-visible .k-svg-icon {
    color: var(--kendo-color-error, #d9534f);
}
.mp-avatar-menu-item[disabled] {
    opacity: 0.6;
    cursor: default;
    pointer-events: none;
}

/* Trailing chevron on items that open further UI (Switch institution). */
.mp-avatar-menu-chevron {
    margin-left: auto;
    opacity: 0.55;
    font-size: 1.1em;
    line-height: 1;
}

/* About dialog --------------------------------------------------------------- */
.mp-about-dialog {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 4px 2px;
}

.mp-about-product {
    font-size: 1.1rem;
    font-weight: 600;
}

.mp-about-version,
.mp-about-copyright {
    font-size: 0.9rem;
    opacity: 0.85;
}

/* ---------------------------------------------------------------------------
   Switch Institution page (Pages/Institution/Switch.razor)
   --------------------------------------------------------------------------- */
.mp-switch-inst-page {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-width: 980px;
    padding: 12px 4px 4px;
}

.mp-switch-inst-page > h1 {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 600;
}

.mp-switch-inst-context {
    margin: 0;
    font-size: 0.95rem;
    color: var(--kendo-color-on-app-surface, #1f1f1f);
    opacity: 0.85;
}

.mp-switch-inst-toolbar {
    display: flex;
    align-items: center;
    gap: 16px;
}

.mp-switch-inst-filter {
    flex: 1 1 auto;
    min-width: 0;
}

.mp-switch-inst-refresh {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    color: var(--kendo-color-primary, #1a6ea6);
    text-decoration: none;
    font-size: 0.9rem;
    line-height: 1;
    cursor: pointer;
}
.mp-switch-inst-refresh:hover {
    text-decoration: underline;
}
.mp-switch-inst-refresh.is-busy {
    opacity: 0.55;
    pointer-events: none;
    cursor: default;
}

/* Current-institution capsule rendered next to the active row's name. */
.mp-current-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--kendo-color-base-hover, rgba(0, 0, 0, 0.08));
    color: inherit;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.85;
    vertical-align: middle;
}

/* Inline error block — same look used for both load + switch failures. */
.mp-switch-inst-error {
    padding: 8px 12px;
    border-radius: 4px;
    background: rgba(217, 83, 79, 0.08);
    color: var(--kendo-color-error, #b94a48);
    font-size: 0.9rem;
}

/* Small "Institutions cache refreshed." note that appears after a refresh. */
.mp-switch-inst-toast {
    font-size: 0.85rem;
    color: var(--kendo-color-on-app-surface, #1f1f1f);
    opacity: 0.75;
}

/* Footer button row (Cancel + Switch) under the grid. */
.mp-switch-inst-buttons {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding-top: 8px;
}

/* Inline text-button used inside error blocks (the [Retry] link). */
.mp-link-button {
    background: none;
    border: 0;
    padding: 0 4px;
    color: var(--kendo-color-primary, #1a6ea6);
    text-decoration: underline;
    cursor: pointer;
    font: inherit;
}
