/* /Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-3msmt04gsn] {
    position: relative;
    display: flex;
    flex-direction: column;
}

main[b-3msmt04gsn] {
    flex: 1;
    background-color: var(--ra-bg);
}

.sidebar[b-3msmt04gsn] {
    background-color: var(--ra-bg-raised);
    background-image:
        linear-gradient(180deg, var(--ra-bg-raised) 0%, var(--ra-bg) 45%, var(--ra-bg) 100%),
        repeating-linear-gradient(135deg, rgba(255, 106, 26, 0.05) 0px, rgba(255, 106, 26, 0.05) 2px, transparent 2px, transparent 22px);
    border-right: 2px solid var(--ra-rust-dim);
    box-shadow: 4px 0 24px rgba(255, 106, 26, 0.08);
}

.top-row[b-3msmt04gsn] {
    background-color: var(--ra-bg-raised);
    border-bottom: 1px solid var(--ra-rust-dim);
    justify-content: flex-end;
    height: 3.5rem;
    display: flex;
    align-items: center;
}

    .top-row[b-3msmt04gsn]  a, .top-row[b-3msmt04gsn]  .btn-link {
        white-space: nowrap;
        margin-left: 1.5rem;
        text-decoration: none;
        color: var(--ra-text-muted);
    }

        .top-row[b-3msmt04gsn]  a:hover, .top-row[b-3msmt04gsn]  .btn-link:hover {
            color: var(--ra-cyan);
            text-decoration: none;
            text-shadow: var(--ra-glow-cyan);
        }

    .top-row[b-3msmt04gsn]  a:first-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

@media (max-width: 640.98px) {
    .top-row[b-3msmt04gsn] {
        justify-content: space-between;
    }

    .top-row[b-3msmt04gsn]  a, .top-row[b-3msmt04gsn]  .btn-link {
        margin-left: 0;
    }
}

@media (min-width: 641px) {
    .page[b-3msmt04gsn] {
        flex-direction: row;
    }

    .sidebar[b-3msmt04gsn] {
        width: 250px;
        height: 100vh;
        position: sticky;
        top: 0;
        /* Without an explicit value here, NavMenu's own hover flyouts (position: fixed, z-index: 1000
           - see NavMenu.razor.css) lose to this layout's .top-row below despite that one being z-index:
           1, a hundred times smaller. Confirmed empirically, the hard way: a positioned sibling branch
           with z-index left at its default "auto" apparently loses to a sibling branch that has ANY
           explicit z-index at all, regardless of what a z-index deep inside the "auto" branch says -
           the explicit z-index has to be up here, on the branch's own root, not just on the element
           that visually needs to win. Comfortably below Bootstrap's own elevated components (dropdowns
           start at 1020) so it never fights a modal/dropdown/toast if one is ever added to this layout. */
        z-index: 10;
    }

    .top-row[b-3msmt04gsn] {
        position: sticky;
        top: 0;
        z-index: 1;
    }

    .top-row.auth[b-3msmt04gsn]  a:first-child {
        flex: 1;
        text-align: right;
        width: 0;
    }

    .top-row[b-3msmt04gsn], article[b-3msmt04gsn] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}

#blazor-error-ui[b-3msmt04gsn] {
    color-scheme: dark only;
}

    #blazor-error-ui .dismiss[b-3msmt04gsn] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* /Components/Layout/NavMenu.razor.rz.scp.css */
.navbar-toggler[b-roqz6cltce] {
    appearance: none;
    cursor: pointer;
    width: 3.5rem;
    height: 2.5rem;
    color: white;
    position: absolute;
    top: 0.5rem;
    right: 1rem;
    border: 1px solid var(--ra-rust-dim);
    background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 106, 26, 0.85%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 106, 26, 0.08);
}

.navbar-toggler:checked[b-roqz6cltce] {
    background-color: rgba(255, 106, 26, 0.25);
    box-shadow: var(--ra-glow-rust);
}

.top-row[b-roqz6cltce] {
    /* Fixed height (not min-height) and the same border color as MainLayout.razor.css's own
       .top-row - these are two separate elements (sidebar's brand+toggle bar vs. the main content's
       header bar) that sit side by side at the same vertical position, and any mismatch between them
       - a few px of height, or two different border colors meeting at the seam - reads as a visibly
       jagged, misaligned corner right where the sidebar meets the main content. background-color was
       also a flat rgba(0,0,0,0.5) dark overlay regardless of theme, which is exactly the kind of
       hardcoded-dark leftover that made the sidebar area look wrong in light mode even after the
       sidebar background itself became theme-aware. */
    height: 3.5rem;
    background-color: var(--ra-bg-raised);
    border-bottom: 1px solid var(--ra-rust-dim);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.navbar-brand[b-roqz6cltce] {
    font-family: var(--ra-font-display);
    font-size: 1.4rem;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ra-rust-bright) !important;
    text-shadow: var(--ra-glow-rust);
}

    .navbar-brand:hover[b-roqz6cltce] {
        color: var(--ra-cyan) !important;
        text-shadow: var(--ra-glow-cyan);
    }

.bi[b-roqz6cltce] {
    /* Real Bootstrap Icons webfont glyphs (this app already loads the font globally - see every
       plain .bi-xxx icon elsewhere, e.g. ServerDetail.razor's bi-terminal/bi-chat-dots), not custom
       inline-SVG images - a font glyph is just colored text, so it already follows the surrounding
       .nav-link's own color (muted/hover/active, either theme) with zero extra CSS.
       Previously this rendered a hand-copied SVG per icon via mask-image + background-color, which
       had two real bugs: three nav items (Servers/Invitation Codes/Platform Settings) used class
       names that were never actually given an icon definition at all, so they rendered as a solid
       painted square instead of the intended shape; and the shared .bi rule's background-color/mask
       properties also applied to bi-github below (a real webfont glyph, not a masked image), painting
       a solid block behind its character. Using the real font class for every icon - the same one
       already used everywhere else in this app - sidesteps both problems rather than patching them. */
    margin-right: 0.75rem;
}

.nav-item[b-roqz6cltce] {
    font-family: var(--ra-font-display);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding-bottom: 0.5rem;
}

.nav-group[b-roqz6cltce] {
    /* Section labels for the two audiences the nav serves - see NavMenu.razor. Deliberately quieter
       than the links they head: dimmer, smaller and not interactive, so they read as signposts
       rather than as another row you could click. An <h2> rather than a <div> on purpose - it gives
       screen readers the same structure sighted users get from the rule above it, and it keeps the
       .nav-item:first-of-type/:last-of-type padding rules below working, since those match by tag
       and a heading div would have quietly stolen "first div". */
    font-family: var(--ra-font-display);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--ra-text-muted);
    opacity: 0.75;
    margin: 0.5rem 0 0.25rem;
    padding: 0.75rem 1rem 0;
    border-top: 1px solid var(--ra-border);
}

    /* The first group heading sits right under Home, which already has the list's top padding - a
       second rule above it there would read as a stray line rather than a divider. */
    .nav-group:first-of-type[b-roqz6cltce] {
        border-top: none;
        padding-top: 0;
    }

.nav-flyout-group[b-roqz6cltce] {
    /* The positioning context .nav-flyout-menu's "drop down from here" anchors against - see that
       rule's own remarks for why down rather than sideways. */
    position: relative;
}

.nav-subgroup-toggle[b-roqz6cltce] {
    /* A hover-revealing variant of .nav-group above - same type treatment (font, size, tracking), but
       a real <button> (so it's a natural keyboard-focusable element :focus-within can key off, even
       though nothing happens on click - see .nav-flyout-menu). Deliberately not driven by Bootstrap's
       data-bs-toggle - this app never loads Bootstrap's JS bundle (see App.razor), so unlike a
       Bootstrap dropdown this is pure CSS :hover/:focus-within, no JS of any kind. */
    font-family: var(--ra-font-display);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--ra-text-muted);
    background: none;
    border: none;
    border-top: 1px solid var(--ra-border);
    width: 100%;
    text-align: left;
    cursor: default;
    margin: 0.5rem 0 0.25rem;
    padding: 0.75rem 1rem 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    transition: color 0.15s ease;
}

    /* Highlights the group the current page actually lives in (see IsInGroup) - the one thing this
       still needs Blazor for, since with visibility now pure CSS there's no expanded state left to
       imply it. */
    .nav-subgroup-toggle.active[b-roqz6cltce],
    .nav-flyout-group:hover .nav-subgroup-toggle[b-roqz6cltce],
    .nav-flyout-group:focus-within .nav-subgroup-toggle[b-roqz6cltce] {
        color: var(--ra-cyan);
    }

    .nav-subgroup-toggle .bi[b-roqz6cltce] {
        /* Stays pointing right, unrotated - it's already pointing where the flyout actually appears
           (to the right, over the content), unlike an accordion's chevron there'd be no reason to
           rotate it open/closed for. */
        margin-right: 0;
        font-size: 0.75rem;
    }

.nav-subgroup-caret[b-roqz6cltce] {
    /* The trailing chevron on a subitem link that's ALSO a flyout trigger (an area's Reports entry,
       opening a third level listing that area's individual reports) - pushed to the row's far right
       via the flex layout .nav-item ::deep .nav-link already sets up, rather than leading like
       .nav-subgroup-toggle's own chevron above. It has to trail here: this trigger, unlike that one,
       is a real link you can also just click, and leading with an icon that reads as "opens a menu"
       on something you'd otherwise click straight through would say the wrong thing first. */
    margin-left: auto;
    margin-right: 0;
    font-size: 0.7rem;
    opacity: 0.65;
}

.nav-flyout-menu[b-roqz6cltce] {
    /* Hidden by default everywhere - the two media blocks below decide how it becomes visible,
       differently per screen size. */
    display: none;
}

@media (min-width: 641px) {
    .nav-flyout-menu[b-roqz6cltce] {
        /* Flies out to the right, over the main content - not a dropdown under the trigger, which
           would sit on top of (and block hovering into) whichever group's row comes next.
           position: fixed, with top/left set by navFlyout.js from the trigger's own
           getBoundingClientRect() - not position: absolute. .nav-scrollable (this menu's nearest
           scrolling ancestor) sets overflow-y: auto, and per the CSS overflow spec a non-visible
           value on one axis forces the other axis to compute as auto too rather than staying
           visible - so an absolutely-positioned flyout escaping sideways (left: 100%) would be
           silently clipped at the sidebar's own edge instead of floating over the page. Only
           position: fixed escapes an ancestor's overflow clipping outright, which is what costs the
           small amount of JS - a fixed element's offsets are relative to the viewport, not to
           whichever row happens to be hovered, so nothing but script can supply the right coordinates
           for three triggers that each sit at a different height in a scrollable list. */
        position: fixed;
        z-index: 1000;
        min-width: 14rem;
        background-color: var(--ra-bg-raised);
        border: 1px solid var(--ra-border);
        border-radius: 4px;
        box-shadow: 0 8px 16px rgba(0, 0, 0, 0.35);
    }

    /* The direct-child combinator matters once a Reports group nests a further flyout of its own
       (see NavMenu.razor's own remarks) - a plain descendant selector here would reveal a group's
       whole subtree, chevron flyout included, the instant its ancestor group was hovered, rather
       than waiting for that nested trigger to be hovered on its own. Scoping to > keeps every level
       answerable only to its own hover/focus-within, so they can nest arbitrarily deep. */
    .nav-flyout-group:hover > .nav-flyout-menu[b-roqz6cltce],
    .nav-flyout-group:focus-within > .nav-flyout-menu[b-roqz6cltce] {
        display: block;
    }

    /* Set by navFlyout.js the instant a flyout link is clicked - see its own remarks for why
       hover/focus-within alone cannot be trusted to close the menu once Blazor's post-navigation
       DOM patch strands it at an unset position. Walks every ancestor flyout group the click was
       nested inside, adding this class to each - so the > here matters the same way the reveal
       rule's does above, each group only ever hiding its own menu. !important because it has to win
       over the :hover rule above while the pointer is still physically resting on the (about to
       move) menu. */
    .nav-flyout-group.nav-flyout-force-closed > .nav-flyout-menu[b-roqz6cltce] {
        display: none !important;
    }
}

@media (max-width: 640px) {
    .nav-flyout-menu[b-roqz6cltce] {
        /* No :hover on a touch screen, and the mobile nav is already a full-screen overlay once
           opened (plenty of room) - so on narrow screens this simply stays part of the flat list
           instead of trying to be a popup nothing could reveal. */
        display: block;
    }

    .nav-subsubitem[b-roqz6cltce]  .nav-link {
        /* One indent level deeper than .nav-subitem's own, only needed here on mobile: both flyout
           levels render inline in the same flat list with no floating panel to draw the grouping
           for you, so without this a report link would sit flush with its own area's Reports
           trigger instead of visibly nested under it. */
        padding-left: 2rem;
    }
}

.nav-subitem[b-roqz6cltce]  .nav-link {
    /* On mobile (where .nav-flyout-menu renders inline under its trigger, not as a flyout - see that
       rule's own max-width block), this indent is what actually shows the grouping; on desktop it's
       just breathing room inside the floating panel, since the panel itself is the grouping cue there. */
    padding-left: 1rem;
}

.nav-session[b-roqz6cltce] {
    /* Account and Logout are the session, not a section of the product, so they get a rule but no
       heading - the same treatment .nav-source below gets, and for the same reason. */
    border-top: 1px solid var(--ra-border);
    margin-top: 0.5rem;
    padding-top: 0.75rem;
}

.nav-source[b-roqz6cltce] {
    /* Separated visually from the app's own nav items - it's a licensing link (AGPL-3.0 source
       offer, see NOTICE.md), not part of the product's navigation, and shows regardless of
       sign-in state. */
    border-top: 1px solid var(--ra-border);
    margin-top: 0.5rem;
    padding-top: 0.75rem;
}

    .nav-item:first-of-type[b-roqz6cltce] {
        padding-top: 1rem;
    }

    .nav-item:last-of-type[b-roqz6cltce] {
        padding-bottom: 1rem;
    }

    .nav-item[b-roqz6cltce]  .nav-link {
        color: var(--ra-text-muted);
        background: none;
        border: none;
        border-left: 3px solid transparent;
        border-radius: 0 4px 4px 0;
        height: 3rem;
        display: flex;
        align-items: center;
        line-height: 3rem;
        width: 100%;
        transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
    }

.nav-item[b-roqz6cltce]  a.active {
    background-color: rgba(255, 106, 26, 0.12);
    border-left-color: var(--ra-rust);
    color: var(--ra-rust-bright);
    text-shadow: var(--ra-glow-rust);
}

.nav-item[b-roqz6cltce]  .nav-link:hover {
    background-color: rgba(22, 242, 255, 0.08);
    border-left-color: var(--ra-cyan);
    color: var(--ra-cyan);
}

.nav-scrollable[b-roqz6cltce] {
    display: none;
}

.navbar-toggler:checked ~ .nav-scrollable[b-roqz6cltce] {
    display: block;
}

@media (min-width: 641px) {
    .navbar-toggler[b-roqz6cltce] {
        display: none;
    }

    .nav-scrollable[b-roqz6cltce] {
        /* Never collapse the sidebar for wide screens */
        display: block;

        /* Allow sidebar to scroll for tall menus */
        height: calc(100vh - 3.5rem);
        overflow-y: auto;
    }
}
/* /Components/Layout/ProfileMenu.razor.rz.scp.css */
.profile-menu[b-mxngkk6wmg] {
    position: relative;
    display: inline-flex;
    align-items: center;
    height: 100%;
}

.profile-trigger[b-mxngkk6wmg] {
    display: inline-flex !important;
    align-items: center;
    gap: 0.5rem;
    height: 100%;
}

.profile-trigger i[b-mxngkk6wmg] {
    font-size: 1.25rem;
}

.profile-dropdown[b-mxngkk6wmg] {
    display: none;
    position: absolute;
    top: 100%;
    right: 0;
    flex-direction: column;
    min-width: 11rem;
    padding: 0.35rem;
    margin-top: -1px;
    background-color: var(--ra-bg-raised);
    border: 1px solid var(--ra-rust-dim);
    border-radius: 0.25rem;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    z-index: 10;
}

.profile-menu:hover .profile-dropdown[b-mxngkk6wmg],
.profile-menu:focus-within .profile-dropdown[b-mxngkk6wmg] {
    display: flex;
}

.profile-dropdown-form[b-mxngkk6wmg] {
    display: contents;
}

.profile-dropdown-item[b-mxngkk6wmg] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: none;
    border: none;
    border-radius: 0.2rem;
    font: inherit;
    text-align: left;
    color: var(--ra-text);
    text-decoration: none;
    cursor: pointer;
}

    .profile-dropdown-item:hover:not(.disabled)[b-mxngkk6wmg] {
        background-color: var(--ra-bg);
        color: var(--ra-cyan);
    }

    .profile-dropdown-item.disabled[b-mxngkk6wmg] {
        color: var(--ra-text-muted);
        cursor: not-allowed;
        opacity: 0.6;
    }
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-zhiq5gevsu],
.components-reconnect-repeated-attempt-visible[b-zhiq5gevsu],
.components-reconnect-failed-visible[b-zhiq5gevsu],
.components-pause-visible[b-zhiq5gevsu],
.components-resume-failed-visible[b-zhiq5gevsu],
.components-rejoining-animation[b-zhiq5gevsu] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-zhiq5gevsu],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-zhiq5gevsu],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-zhiq5gevsu],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-zhiq5gevsu],
#components-reconnect-modal.components-reconnect-retrying[b-zhiq5gevsu],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-zhiq5gevsu],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-zhiq5gevsu],
#components-reconnect-modal.components-reconnect-failed[b-zhiq5gevsu],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-zhiq5gevsu] {
    display: block;
}


#components-reconnect-modal[b-zhiq5gevsu] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-zhiq5gevsu 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-zhiq5gevsu 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-zhiq5gevsu 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-zhiq5gevsu]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-zhiq5gevsu 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-zhiq5gevsu {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-zhiq5gevsu {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-zhiq5gevsu {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-zhiq5gevsu] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-zhiq5gevsu] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-zhiq5gevsu] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-zhiq5gevsu] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-zhiq5gevsu] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-zhiq5gevsu] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-zhiq5gevsu] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-zhiq5gevsu 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-zhiq5gevsu] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-zhiq5gevsu {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
