/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* MainLayout — the app shell's own markup.

   The classes handed to MudBlazor components (.portal-main on MudMainContent, .portal-avatar on
   MudAvatar) are NOT here: Blazor's CSS isolation only stamps its scope attribute onto elements
   authored in this file, never onto a child component's root element, so a scoped rule for them
   would match nothing. They live in wwwroot/app.css under "App shell". */

/* The skip link itself IS authored directly in this file (a plain <a>, not a MudBlazor
   component), so a scoped rule does apply to it. Visually hidden off-screen until it receives
   keyboard focus, per the standard "skip to content" pattern. */
.portal-skip-link[b-p0kles7471] {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: var(--tv-space-2) var(--tv-space-4);
    background: var(--tv-surface);
    color: var(--tv-accent);
    border-radius: var(--tv-default-border-radius, 0.5rem);
    box-shadow: var(--tv-shadow-flyout);
}

.portal-skip-link:focus[b-p0kles7471] {
    left: var(--tv-space-2);
    top: var(--tv-space-2);
}

.portal-brand[b-p0kles7471] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-2);
    margin-inline-start: var(--tv-space-2);
    color: inherit;
    text-decoration: none;
    min-width: 0;
}

/* The identity surface: a rounded square in the brand gradient. This is the one place in the
   shell where the corporate palette is allowed — it says "TimeView", not "success" or "info". */
.portal-brand-mark[b-p0kles7471] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* A fixed 32px chip sized to the 28px favicon plus its inset — not a spacing step. */
    width: 32px;
    height: 32px;
    border-radius: var(--tv-default-border-radius, 0.5rem);
    background: var(--brand-gradient-deep, hotpink);
    flex: 0 0 auto;
}

.portal-brand-logo[b-p0kles7471] {
    width: 20px;
    height: 20px;
    display: block;
}

.portal-brand-text[b-p0kles7471] {
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
    letter-spacing: 0.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The app bar is narrow on a phone, and the brand mark already identifies the app there. */
@media (max-width: 599px) {
    .portal-brand-text[b-p0kles7471] {
        display: none;
    }
}

.portal-avatar-image[b-p0kles7471] {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.portal-user-name[b-p0kles7471] {
    font-size: var(--tv-text-body);
    margin-inline-end: var(--tv-space-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 16ch;
}

@media (max-width: 599px) {
    .portal-user-name[b-p0kles7471] {
        display: none;
    }
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* Nav links themselves are styled by MudBlazor; the glyph, the label and the version footer are
   ours. See the comment in NavMenu.razor for why the glyph is not MudNavLink's Icon parameter. */

.portal-nav-icon[b-5qpz1efjff] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Matches MudBlazor's own .mud-nav-link-icon box, so links with and without a glyph line up
       and the collapsed drawer centres it. */
    width: 24px;
    font-size: 1.25rem;
    color: var(--tv-nav-icon, hotpink);
    margin-inline-end: var(--tv-space-3);
    flex: 0 0 auto;
}

/* The active link recolours itself; the glyph follows the link rather than staying accent-blue
   on an accent-tinted row. */
.mud-nav-link.active .portal-nav-icon[b-5qpz1efjff] {
    color: inherit;
}

.portal-nav-label[b-5qpz1efjff] {
    font-size: var(--tv-text-body);
}

/* The mini drawer is only wide enough for glyphs. MudBlazor's own rule for this keys on a
   .mud-icon-root preceding the label, which our MDI glyph is not, so the label is hidden here
   instead.

   It is clipped rather than `display: none`: the glyph is aria-hidden, so `display: none` would
   strip the only text from the link and leave nine nav items with no accessible name at all
   (WCAG 2.4.4 / 4.1.2). Clipping keeps the name for assistive tech while freeing the space. */
.mud-drawer--closed.mud-drawer-mini .portal-nav-label[b-5qpz1efjff] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.mud-drawer--closed.mud-drawer-mini .portal-nav-icon[b-5qpz1efjff] {
    margin-inline-end: 0;
}

/* MudDrawer makes .mud-drawer-content a flex column, so margin-top:auto pushes the footer to the
   bottom of the drawer regardless of how many links the current role sees. */
.portal-nav-footer[b-5qpz1efjff] {
    margin-top: auto;
    padding: var(--tv-space-2) var(--tv-space-4);
    border-top: 1px solid var(--tv-border-color, hotpink);
    text-align: center;
}

.portal-nav-version[b-5qpz1efjff] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
    cursor: default;
    white-space: nowrap;
}

.mud-drawer--closed.mud-drawer-mini .portal-nav-footer[b-5qpz1efjff] {
    display: none;
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-6c8jkrxd30],
.components-reconnect-repeated-attempt-visible[b-6c8jkrxd30],
.components-reconnect-failed-visible[b-6c8jkrxd30],
.components-pause-visible[b-6c8jkrxd30],
.components-resume-failed-visible[b-6c8jkrxd30],
.components-rejoining-animation[b-6c8jkrxd30] {
    display: none;
}

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


#components-reconnect-modal[b-6c8jkrxd30] {
    background-color: var(--tv-surface, hotpink);
    color: var(--tv-body-fg, hotpink);
    font-size: var(--tv-text-body);
    /* A measured dialog width, not a spacing step. */
    width: 20rem;
    margin: 20vh auto;
    padding: var(--tv-space-6);
    border: 0;
    border-radius: var(--tv-default-border-radius, 0.5rem);
    box-shadow: var(--tv-shadow-flyout, hotpink);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-6c8jkrxd30 0.5s both;
    &[open]

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

}

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

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

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

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

    100% {
        opacity: 1;
    }
}

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

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-6c8jkrxd30] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--tv-space-4);
}

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

/* This dialog is rendered by the Blazor runtime outside the Mud component tree, so it cannot be
   a TvButton; the accent fill and its foreground are taken from the tokens directly. */
#components-reconnect-modal button[b-6c8jkrxd30] {
    border: 0;
    background-color: var(--tv-accent, hotpink);
    color: var(--tv-accent-fg, hotpink);
    padding: var(--tv-space-1) var(--tv-space-5);
    border-radius: var(--tv-default-border-radius, 0.5rem);
    font-size: var(--tv-text-body);
    font-weight: var(--tv-weight-medium);
    cursor: pointer;
}

    #components-reconnect-modal button:hover[b-6c8jkrxd30],
    #components-reconnect-modal button:active[b-6c8jkrxd30] {
        background-color: color-mix(in srgb, var(--tv-accent, hotpink) 85%, var(--brand-black, hotpink));
    }

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

    .components-rejoining-animation div[b-6c8jkrxd30] {
        position: absolute;
        border: 3px solid var(--tv-accent, hotpink);
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-6c8jkrxd30 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

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

@keyframes components-rejoining-animation-b-6c8jkrxd30 {
    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;
    }
}
/* /Components/Layout/TvButton.razor.rz.scp.css */
/* TvButton — layout only. The colour hierarchy (.tv-btn-primary / -secondary / -tertiary /
   -destructive) is unscoped in wwwroot/tv-theme.css, because it has to beat MudBlazor.min.css
   and a scoped attribute selector cannot reach MudBlazor's own rules. */

.tv-btn-icon[b-y6sztmhu6y] {
    /* Optically centres the glyph against the label's cap height. */
    display: inline-flex;
    align-items: center;
    line-height: 1;
}

.tv-btn-label[b-y6sztmhu6y] {
    line-height: var(--tv-leading-tight);
}
/* /Components/Layout/TvEmptyState.razor.rz.scp.css */
.tv-empty-state[b-ykjj6j52ur] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--tv-space-2);
    padding: var(--tv-space-6) var(--tv-space-4);
}

.tv-empty-state-icon[b-ykjj6j52ur] {
    font-size: var(--tv-text-metric);
    line-height: 1;
    color: var(--tv-color-text-secondary, hotpink);
}

/* "Nothing here yet" is an identity surface rather than a status, which is the design system's
   one sanctioned decorative use of the brand palette — so the glyph carries the brand gradient as
   a text fill. Not applied to the two variants below: an error painted in the corporate colours
   reads as a feature. */
.tv-empty-state-empty .tv-empty-state-icon[b-ykjj6j52ur] {
    background: var(--brand-gradient-cool, hotpink);
    background-clip: text;
    -webkit-background-clip: text;
    color: transparent;
}

.tv-empty-state-error .tv-empty-state-icon[b-ykjj6j52ur] {
    color: var(--palette-red, hotpink);
}

.tv-empty-state-title[b-ykjj6j52ur] {
    margin: 0;
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
    line-height: var(--tv-leading-tight);
}

.tv-empty-state-message[b-ykjj6j52ur] {
    margin: 0;
    font-size: var(--tv-text-body);
    color: var(--tv-color-text-secondary, hotpink);
    max-width: 40ch;
}

.tv-empty-state-actions[b-ykjj6j52ur] {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--tv-space-2);
    margin-top: var(--tv-space-2);
}
/* /Components/Layout/TvLoadingState.razor.rz.scp.css */
.tv-loading-state[b-oe6m9046b9] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--tv-space-2);
    padding: var(--tv-space-6) var(--tv-space-4);
}

.tv-loading-state-inline[b-oe6m9046b9] {
    display: inline-flex;
    justify-content: flex-start;
    padding: 0;
}

.tv-loading-state-label[b-oe6m9046b9] {
    font-size: var(--tv-text-body);
    color: var(--tv-color-text-secondary, hotpink);
}
/* /Components/Layout/TvPageHeader.razor.rz.scp.css */
/* TvPageHeader. Deliberately not sticky: the portal's pages are short and a sticky bar costs
   vertical space on the phone widths most of the traffic uses. */

.tv-page-header[b-1m16sihecq] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tv-space-3);
    margin-bottom: var(--tv-section-gap);
}

.tv-page-header-zone[b-1m16sihecq] {
    display: flex;
    align-items: center;
    gap: var(--tv-space-2);
    min-width: 0;
}

.tv-page-header-left[b-1m16sihecq] {
    flex: 1 1 auto;
}

.tv-page-header-center[b-1m16sihecq] {
    flex: 0 1 auto;
}

/* Pushed to the far edge on one line, and dropped to its own line when the title no longer
   leaves room — the actions wrap, the title never truncates. */
.tv-page-header-right[b-1m16sihecq] {
    flex: 0 0 auto;
    margin-left: auto;
    gap: var(--tv-space-2);
    flex-wrap: wrap;
}

.tv-page-header-icon[b-1m16sihecq] {
    font-size: var(--tv-text-page-title);
    color: var(--tv-accent, hotpink);
    line-height: 1;
}

.tv-page-header-title[b-1m16sihecq] {
    margin: 0;
    font-size: var(--tv-text-page-title);
    font-weight: var(--tv-weight-strong);
    line-height: var(--tv-leading-tight);
    min-width: 0;
    overflow-wrap: break-word;
}
/* /Components/Layout/TvStatusChip.razor.rz.scp.css */
/* TvStatusChip.

   Each status class only repoints two local variables; the paint itself is stated once. Those
   two are declared on the chip element (not at :root), so they are component-local — the token
   ownership rule that tv-tokens.css owns every :root token is intact. */

.tv-status-chip[b-n6zadem3uc] {
    --tv-status-chip-color: var(--palette-grey, hotpink);
    --tv-status-chip-fill: var(--palette-grey-deep, hotpink);

    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
    padding: var(--tv-space-1) var(--tv-space-2);
    border: 1px solid var(--tv-status-chip-color);
    border-radius: var(--tv-default-border-radius, 0.5rem);
    /* Design-system rule (upstream README, "text on a coloured wash"): the outline hues were
       chosen to work as a border and read as taxonomy, not as 12px text — measured as low as
       1.64:1 on a chip surface. Pulling the label 50 % toward --tv-body-fg clears 4.5:1 for every
       status in both themes (worst case measured: light amber 5.12:1, dark purple 5.01:1) while
       the border keeps the pure hue, since a border only needs 3:1 and the hue is what makes the
       chip identifiable at a glance. One percentage for every status — a per-status table is
       exactly the kind of thing that rots. */
    color: color-mix(in srgb, var(--tv-status-chip-color) 50%, var(--tv-body-fg, hotpink));
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-medium);
    line-height: var(--tv-leading-tight);
    white-space: nowrap;
}

/* The filled variant carries its own foreground: a fill cannot inherit a contrast guarantee from
   the theme, and the deep primitives were chosen precisely to hold white. */
.tv-status-chip-filled[b-n6zadem3uc] {
    background-color: var(--tv-status-chip-fill);
    border-color: var(--tv-status-chip-fill);
    color: var(--brand-white, hotpink);
}

/* ── Suggestion workflow ── */

.tv-status-chip-new[b-n6zadem3uc] {
    --tv-status-chip-color: var(--suggestion-status-new, hotpink);
    --tv-status-chip-fill: var(--suggestion-status-new-fill, hotpink);
}

.tv-status-chip-under-review[b-n6zadem3uc] {
    --tv-status-chip-color: var(--suggestion-status-under-review, hotpink);
    --tv-status-chip-fill: var(--suggestion-status-under-review-fill, hotpink);
}

.tv-status-chip-planned[b-n6zadem3uc] {
    --tv-status-chip-color: var(--suggestion-status-planned, hotpink);
    --tv-status-chip-fill: var(--suggestion-status-planned-fill, hotpink);
}

.tv-status-chip-in-progress[b-n6zadem3uc] {
    --tv-status-chip-color: var(--suggestion-status-in-progress, hotpink);
    --tv-status-chip-fill: var(--suggestion-status-in-progress-fill, hotpink);
}

.tv-status-chip-completed[b-n6zadem3uc] {
    --tv-status-chip-color: var(--suggestion-status-completed, hotpink);
    --tv-status-chip-fill: var(--suggestion-status-completed-fill, hotpink);
}

.tv-status-chip-declined[b-n6zadem3uc] {
    --tv-status-chip-color: var(--suggestion-status-declined, hotpink);
    --tv-status-chip-fill: var(--suggestion-status-declined-fill, hotpink);
}

/* ── Knowledge-base article lifecycle ── */

.tv-status-chip-draft[b-n6zadem3uc] {
    --tv-status-chip-color: var(--article-status-draft, hotpink);
    --tv-status-chip-fill: var(--article-status-draft-fill, hotpink);
}

.tv-status-chip-published[b-n6zadem3uc] {
    --tv-status-chip-color: var(--article-status-published, hotpink);
    --tv-status-chip-fill: var(--article-status-published-fill, hotpink);
}

.tv-status-chip-archived[b-n6zadem3uc] {
    --tv-status-chip-color: var(--article-status-archived, hotpink);
    --tv-status-chip-fill: var(--article-status-archived-fill, hotpink);
}
/* /Components/Pages/Admin/AuditLog.razor.rz.scp.css */
/* Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.audit-log-filters[b-c16ug6xppf] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    align-items: end;
    gap: var(--tv-space-3);
    margin-bottom: var(--tv-space-4);
}

.audit-log-table-card[b-c16ug6xppf] {
    border: 1px solid var(--tv-border-color);
    border-radius: var(--tv-default-border-radius);
    overflow: hidden;
}

.audit-log-table-card[b-c16ug6xppf]  .mud-table-head th {
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-strong);
}

.audit-log-table-card[b-c16ug6xppf]  .mud-table-body td {
    font-size: var(--tv-text-body);
}

.audit-log-details-icon[b-c16ug6xppf] {
    color: var(--tv-color-text-secondary);
}

.audit-log-action-badge[b-c16ug6xppf] {
    display: inline-flex;
    align-items: center;
    padding: 0 var(--tv-space-2);
    border-radius: var(--tv-default-border-radius);
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-medium);
    background: var(--tv-surface-alt);
}

.audit-log-action-created[b-c16ug6xppf] {
    color: var(--palette-green, hotpink);
}

.audit-log-action-updated[b-c16ug6xppf] {
    color: var(--palette-blue, hotpink);
}

.audit-log-action-deleted[b-c16ug6xppf] {
    color: var(--palette-red, hotpink);
}

.audit-log-action-status-changed[b-c16ug6xppf] {
    color: var(--palette-amber, hotpink);
}

.audit-log-action-role-changed[b-c16ug6xppf] {
    color: var(--palette-purple, hotpink);
}

.audit-log-action-default[b-c16ug6xppf] {
    color: var(--tv-color-text-secondary);
}
/* /Components/Pages/Admin/Index.razor.rz.scp.css */
/* Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.admin-index-grid[b-hwhyrmedul] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--tv-space-4);
}

.admin-index-card[b-hwhyrmedul] {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--tv-space-2);
    padding: var(--tv-space-4);
    border: 1px solid var(--tv-border-color);
    border-radius: var(--tv-default-border-radius);
    background: var(--tv-surface);
}

.admin-index-card-icon[b-hwhyrmedul] {
    font-size: var(--tv-text-metric);
    color: var(--tv-accent, hotpink);
    line-height: 1;
}

.admin-index-card-title[b-hwhyrmedul] {
    margin: 0;
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
}

.admin-index-card-description[b-hwhyrmedul] {
    margin: 0;
    font-size: var(--tv-text-body);
    color: var(--tv-color-text-secondary);
}
/* /Components/Pages/Admin/KnowledgeCategories.razor.rz.scp.css */
.kb-categories-card[b-289u101ddc] {
    padding: var(--tv-space-4);
    border: 1px solid var(--tv-border-color);
    border-radius: var(--tv-default-border-radius);
    background: var(--tv-surface);
}

.kb-categories-card-title[b-289u101ddc] {
    margin: 0 0 var(--tv-space-3);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
}

.kb-category-row[b-289u101ddc] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--tv-space-2);
    padding-block: var(--tv-space-1);
}

.kb-category-row-label[b-289u101ddc] {
    display: flex;
    align-items: center;
    gap: var(--tv-space-2);
    min-width: 0;
}

.kb-category-row-icon[b-289u101ddc] {
    color: var(--tv-color-text-secondary);
}

.kb-category-row-icon-inactive[b-289u101ddc] {
    color: var(--palette-red, hotpink);
}

.kb-category-row-name[b-289u101ddc] {
    font-size: var(--tv-text-body);
}

.kb-category-row-name-inactive[b-289u101ddc] {
    color: var(--tv-color-text-secondary);
}

.kb-category-row-count[b-289u101ddc] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary);
}

.kb-category-row-actions[b-289u101ddc] {
    display: flex;
    gap: var(--tv-space-1);
    flex: 0 0 auto;
}
/* /Components/Pages/Changelog/ByIssue.razor.rz.scp.css */
/* ByIssue redirects on load and, when the target entry is missing, renders nothing but
   TvPageHeader/TvEmptyState/TvButton — all of which own their own scoped styling. No
   page-specific rules are needed here; this file exists for symmetry with the other
   Changelog pages. */
/* /Components/Pages/Changelog/Detail.razor.rz.scp.css */
/* Changelog detail — description card, comment thread and the vote/subscribe side rail.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

/* Page layout — see Pages/Suggestions/Detail.razor.css for the rationale. Same three blocks,
   same two orders: on a phone the vote/subscribe rail sits between the description and the
   comments instead of below every comment. */
.changelog-detail-layout[b-ke53aj5dbt] {
    display: flex;
    flex-direction: column;
    gap: var(--tv-space-6);
}

.changelog-detail-primary[b-ke53aj5dbt] {
    order: 1;
}

.changelog-detail-aside[b-ke53aj5dbt] {
    order: 2;
}

.changelog-detail-comments[b-ke53aj5dbt] {
    order: 3;
}

.changelog-detail-comments .changelog-detail-section-title[b-ke53aj5dbt] {
    margin-top: 0;
}

@media (min-width: 960px) {
    .changelog-detail-layout[b-ke53aj5dbt] {
        display: grid;
        grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
        align-items: start;
    }

    .changelog-detail-primary[b-ke53aj5dbt] {
        grid-column: 1;
        grid-row: 1;
    }

    .changelog-detail-aside[b-ke53aj5dbt] {
        grid-column: 2;
        grid-row: 1 / span 2;
    }

    .changelog-detail-comments[b-ke53aj5dbt] {
        grid-column: 1;
        grid-row: 2;
    }
}

.changelog-detail-date[b-ke53aj5dbt] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
    font-weight: var(--tv-weight-regular);
}

.changelog-detail-description[b-ke53aj5dbt] {
    margin: 0 0 var(--tv-space-3);
    white-space: pre-wrap;
    font-size: var(--tv-text-body);
}

.changelog-detail-confirm-delete[b-ke53aj5dbt] {
    display: flex;
    align-items: center;
    gap: var(--tv-space-2);
    margin-top: var(--tv-space-3);
}

.changelog-detail-confirm-text[b-ke53aj5dbt] {
    font-size: var(--tv-text-body);
    color: var(--palette-red, hotpink);
}

.changelog-detail-section-title[b-ke53aj5dbt] {
    margin: var(--tv-section-gap) 0 var(--tv-space-3);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
    line-height: var(--tv-leading-tight);
}

.changelog-detail-reply-header[b-ke53aj5dbt] {
    display: flex;
    align-items: center;
    gap: var(--tv-space-1);
    font-size: var(--tv-text-meta);
    margin-bottom: var(--tv-space-2);
}

.changelog-detail-vote-icon[b-ke53aj5dbt] {
    font-size: var(--tv-text-metric);
    color: var(--tv-color-text-secondary, hotpink);
}

.changelog-detail-vote-count[b-ke53aj5dbt] {
    margin: 0;
    font-size: var(--tv-text-metric);
    font-weight: var(--tv-weight-strong);
    line-height: var(--tv-leading-tight);
}

.changelog-detail-vote-label[b-ke53aj5dbt] {
    margin: 0;
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}
/* /Components/Pages/Changelog/List.razor.rz.scp.css */
/* Changelog list — month sections of flat, clickable entry cards.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.changelog-list-month[b-yqgsuwbrox] {
    margin: var(--tv-section-gap) 0 var(--tv-space-3);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
    line-height: var(--tv-leading-tight);
}

.changelog-list-date[b-yqgsuwbrox] {
    margin: var(--tv-space-4) 0 var(--tv-space-2);
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-medium);
    color: var(--tv-color-text-secondary, hotpink);
}

.changelog-list-entry-title[b-yqgsuwbrox] {
    display: block;
    margin-bottom: var(--tv-space-2);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-medium);
    color: inherit;
    text-decoration: none;
}

.changelog-list-entry-title:hover[b-yqgsuwbrox],
.changelog-list-entry-title:focus-visible[b-yqgsuwbrox] {
    text-decoration: underline;
}

.changelog-list-entry-description[b-yqgsuwbrox] {
    margin: 0 0 var(--tv-space-2);
    white-space: pre-wrap;
    font-size: var(--tv-text-body);
}

.changelog-list-entry-meta[b-yqgsuwbrox] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tv-space-3);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
    margin-bottom: var(--tv-space-2);
}

.changelog-list-meta-item[b-yqgsuwbrox] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
}

.changelog-list-suggestion-tag[b-yqgsuwbrox] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
    padding: var(--tv-space-1) var(--tv-space-2);
    border: 1px solid var(--palette-green, hotpink);
    border-radius: var(--tv-default-border-radius, 0.5rem);
    color: var(--palette-green, hotpink);
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-medium);
}

[b-yqgsuwbrox] .mud-card-content {
    padding: var(--tv-space-4);
}
/* /Components/Pages/Error.razor.rz.scp.css */
/* The request id is machine output, so it gets the monospace stack — the one thing a user will
   be asked to read back character by character. */
.error-request-id[b-ksi1vzq1d2] {
    margin: 0;
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}

.error-request-id code[b-ksi1vzq1d2] {
    font-family: var(--tv-font-mono);
    font-size: var(--tv-text-meta);
}
/* /Components/Pages/Knowledgebase/Article.razor.rz.scp.css */
/* Knowledgebase article detail — draft banner, meta line, feedback and threaded comments.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.kb-article-draft-banner-text[b-f37ne51zyo] {
    margin: 0;
    font-size: var(--tv-text-body);
}

.kb-article-draft-banner-actions[b-f37ne51zyo] {
    display: flex;
    gap: var(--tv-space-2);
    margin-top: var(--tv-space-2);
}

.kb-article-meta[b-f37ne51zyo] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tv-space-4);
    margin-bottom: var(--tv-space-4);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}

.kb-article-meta span[b-f37ne51zyo] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
}

.kb-article-tags[b-f37ne51zyo] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tv-space-2);
}

.kb-article-feedback[b-f37ne51zyo] {
    display: flex;
    align-items: center;
    gap: var(--tv-space-4);
}

.kb-article-feedback-label[b-f37ne51zyo] {
    font-size: var(--tv-text-body);
    font-weight: var(--tv-weight-medium);
}

.kb-article-feedback-static[b-f37ne51zyo] {
    font-size: var(--tv-text-section);
    color: var(--tv-color-text-secondary, hotpink);
}

.kb-article-feedback-counts[b-f37ne51zyo] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}

.kb-article-comments-title[b-f37ne51zyo] {
    margin: 0 0 var(--tv-space-2);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
}

.kb-article-comment-body[b-f37ne51zyo] {
    margin: 0;
    font-size: var(--tv-text-body);
}

.kb-article-comment-deleted[b-f37ne51zyo] {
    color: var(--tv-color-text-secondary, hotpink);
    font-style: italic;
}

.kb-article-comment-meta[b-f37ne51zyo] {
    display: flex;
    gap: var(--tv-space-4);
    margin-top: var(--tv-space-1);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}
/* /Components/Pages/Knowledgebase/Category.razor.rz.scp.css */
/* Knowledgebase category listing.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.kb-category-description[b-xxmvnq7vtc] {
    margin: 0 0 var(--tv-space-4);
    font-size: var(--tv-text-body);
}

.kb-category-article-summary[b-xxmvnq7vtc] {
    margin: var(--tv-space-1) 0 0;
    font-size: var(--tv-text-body);
}

.kb-category-article-meta[b-xxmvnq7vtc] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tv-space-4);
    margin-top: var(--tv-space-2);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}

.kb-category-article-meta span[b-xxmvnq7vtc] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
}

.kb-category-pagination[b-xxmvnq7vtc] {
    display: flex;
    justify-content: center;
    margin-top: var(--tv-space-4);
}
/* /Components/Pages/Knowledgebase/Editor.razor.rz.scp.css */
/* Knowledgebase editor — form grid, markdown tabs and publish/draft actions.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.kb-editor-form[b-gti92zjgvq] {
    display: grid;
    gap: var(--tv-space-4);
    margin-bottom: var(--tv-space-4);
}

.kb-editor-content-label[b-gti92zjgvq] {
    margin: 0 0 var(--tv-space-1);
    font-size: var(--tv-text-body);
    font-weight: var(--tv-weight-medium);
}

.kb-editor-upload-label[b-gti92zjgvq] {
    margin: var(--tv-space-1) 0;
    font-size: var(--tv-text-meta);
    color: var(--tv-accent, hotpink);
}

.kb-editor-markdown-wrapper[b-gti92zjgvq] {
    margin-top: var(--tv-space-2);
}

.kb-editor-preview-empty[b-gti92zjgvq] {
    margin: 0;
    font-size: var(--tv-text-body);
    color: var(--tv-color-text-secondary, hotpink);
}

.kb-editor-actions[b-gti92zjgvq] {
    display: flex;
    flex-direction: column;
    gap: var(--tv-space-2);
}

.kb-editor-actions[b-gti92zjgvq]  .tv-btn {
    width: 100%;
}

.kb-editor-discard-confirm-text[b-gti92zjgvq] {
    margin: 0 0 var(--tv-space-2);
    font-size: var(--tv-text-body);
}

.kb-editor-discard-confirm-actions[b-gti92zjgvq] {
    display: flex;
    gap: var(--tv-space-2);
}
/* /Components/Pages/Knowledgebase/History.razor.rz.scp.css */
/* Knowledgebase revision history — selected revision panel and revision table.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.kb-history-article-title[b-rxq7pzqmdm] {
    font-size: var(--tv-text-body);
    color: var(--tv-color-text-secondary, hotpink);
}

.kb-history-revision-header[b-rxq7pzqmdm] {
    margin-bottom: var(--tv-space-2);
}

.kb-history-revision-title[b-rxq7pzqmdm] {
    margin: 0;
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
}

.kb-history-revision-actions[b-rxq7pzqmdm] {
    display: flex;
    gap: var(--tv-space-2);
}

.kb-history-revision-summary[b-rxq7pzqmdm] {
    margin: 0 0 var(--tv-space-2);
    font-size: var(--tv-text-meta);
}

.kb-history-revision-meta[b-rxq7pzqmdm] {
    margin: 0 0 var(--tv-space-4);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}
/* /Components/Pages/Knowledgebase/Index.razor.rz.scp.css */
/* Knowledgebase index — category sidebar + article stream.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.kb-index-sidebar-title[b-3cvypgihlx] {
    margin: 0 0 var(--tv-space-2);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
}

.kb-index-category-icon[b-3cvypgihlx] {
    font-size: var(--tv-text-body);
    color: var(--tv-nav-icon, hotpink);
    flex: 0 0 auto;
}

.kb-index-category-label[b-3cvypgihlx] {
    font-size: var(--tv-text-body);
}

/* Label + trailing glyph, matching .suggestion-list-search: a placeholder alone is not an
   accessible name, and a leading glyph would collide with the floating label. */
.kb-index-search[b-3cvypgihlx] {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    margin-bottom: var(--tv-space-4);
}

.kb-index-search[b-3cvypgihlx]  .mud-input-root {
    flex: 1 1 auto;
}

.kb-index-search[b-3cvypgihlx]  .mud-input-slot {
    padding-right: var(--tv-space-5);
}

.kb-index-search-icon[b-3cvypgihlx] {
    position: absolute;
    right: var(--tv-space-2);
    bottom: var(--tv-space-2);
    color: var(--tv-color-text-secondary, hotpink);
    pointer-events: none;
    font-size: var(--tv-text-body);
}

.kb-index-section-title[b-3cvypgihlx] {
    margin: 0 0 var(--tv-space-2);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
    display: flex;
    align-items: center;
    gap: var(--tv-space-1);
}

.kb-index-section-title-spaced[b-3cvypgihlx] {
    margin-top: var(--tv-space-4);
}

.kb-index-article-summary[b-3cvypgihlx] {
    margin: var(--tv-space-1) 0 0;
    font-size: var(--tv-text-body);
}

.kb-index-article-meta[b-3cvypgihlx] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tv-space-4);
    margin-top: var(--tv-space-2);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}

.kb-index-article-meta span[b-3cvypgihlx] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
}

.kb-index-article-tags[b-3cvypgihlx] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--tv-space-1);
    margin-top: var(--tv-space-1);
}

.kb-index-category-tag[b-3cvypgihlx] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
    background: var(--tv-surface-alt, hotpink);
    border-radius: var(--tv-default-border-radius, 0.5rem);
    padding: var(--tv-space-1) var(--tv-space-2);
}
/* /Components/Pages/Suggestions/Create.razor.rz.scp.css */
/* New / edit suggestion form.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.suggestion-create-warning-icon[b-u41hc9mh8d] {
    font-size: var(--tv-text-body);
    margin-top: var(--tv-space-1);
}
/* /Components/Pages/Suggestions/Detail.razor.rz.scp.css */
/* Suggestion detail: content card, comment threads, vote/sidebar widgets.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

/* Page layout.

   This deliberately isn't a MudGrid. The page has three blocks — description, vote/action aside,
   comments — and they need two different orders:

     phone   description → aside → comments   (the vote button must be reachable without
                                               scrolling past every comment)
     desktop description + aside side by side, comments beneath the description

   A MudGrid can't express that: the aside is a single column child, so on a phone it would stack
   after the entire main column, i.e. below the last comment. Explicit grid placement gives the
   desktop shape, and the mobile fallback is a plain flex column reordered with `order`. */
.suggestion-detail-layout[b-lef6z2935z] {
    display: flex;
    flex-direction: column;
    gap: var(--tv-space-6);
}

.suggestion-detail-primary[b-lef6z2935z] {
    order: 1;
}

.suggestion-detail-aside[b-lef6z2935z] {
    order: 2;
}

.suggestion-detail-comments[b-lef6z2935z] {
    order: 3;
}

/* The layout gap already separates the comments block; the heading's own top margin is only
   needed when it follows content inside the same block. */
.suggestion-detail-comments .suggestion-detail-section-title[b-lef6z2935z] {
    margin-top: 0;
}

@media (min-width: 960px) {
    .suggestion-detail-layout[b-lef6z2935z] {
        display: grid;
        /* 3fr/1fr reproduces the md="9" / md="3" split this page used before.
           minmax(0, …) stops long words and <pre> blocks from blowing the column out. */
        grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
        align-items: start;
    }

    .suggestion-detail-primary[b-lef6z2935z] {
        grid-column: 1;
        grid-row: 1;
    }

    .suggestion-detail-aside[b-lef6z2935z] {
        grid-column: 2;
        grid-row: 1 / span 2;
    }

    .suggestion-detail-comments[b-lef6z2935z] {
        grid-column: 1;
        grid-row: 2;
    }
}

.suggestion-detail-meta[b-lef6z2935z] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tv-space-2);
    margin-bottom: var(--tv-space-3);
}

.suggestion-detail-meta-text[b-lef6z2935z] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary);
}

.suggestion-detail-meta-edited[b-lef6z2935z] {
    font-style: italic;
}

.suggestion-detail-section-title[b-lef6z2935z] {
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
    margin: var(--tv-space-6) 0 var(--tv-space-3);
}

.suggestion-detail-comment-form[b-lef6z2935z] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--tv-space-2);
    padding: var(--tv-space-3);
    margin-bottom: var(--tv-space-4);
    background-color: var(--tv-surface);
    border: 1px solid var(--tv-border-color);
    border-radius: var(--tv-default-border-radius);
}

.suggestion-detail-comment-form[b-lef6z2935z]  .mud-input-control,
.suggestion-detail-reply-form[b-lef6z2935z]  .mud-input-control {
    width: 100%;
}

.suggestion-detail-reply-form[b-lef6z2935z] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--tv-space-2);
    padding: var(--tv-space-3);
    margin: 0 0 var(--tv-space-3) var(--tv-space-6);
    background-color: var(--tv-surface);
    border: 1px solid var(--tv-border-color);
    border-left: 2px solid var(--tv-border-color-strong);
    border-radius: var(--tv-default-border-radius);
}

.suggestion-detail-reply-header[b-lef6z2935z] {
    display: flex;
    align-items: center;
    gap: var(--tv-space-2);
    width: 100%;
    color: var(--tv-color-text-secondary);
    font-size: var(--tv-text-meta);
}

.suggestion-detail-reply-target[b-lef6z2935z] {
    flex: 1 1 auto;
}

.suggestion-detail-vote-icon[b-lef6z2935z] {
    font-size: var(--tv-text-page-title);
    color: var(--tv-color-text-secondary);
}

.suggestion-detail-vote-count[b-lef6z2935z] {
    font-size: var(--tv-text-metric);
    font-weight: var(--tv-weight-strong);
    line-height: var(--tv-leading-tight);
}

.suggestion-detail-vote-label[b-lef6z2935z] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary);
}

.suggestion-detail-sidebar-label[b-lef6z2935z] {
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-medium);
    color: var(--tv-color-text-secondary);
    margin: 0 0 var(--tv-space-2);
}
/* /Components/Pages/Suggestions/List.razor.rz.scp.css */
/* Suggestions list — filter toolbar and flat, hoverable suggestion cards.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

/* The row this sits in also holds two labelled MudSelects. A MudBlazor field only reserves space
   for its floating label when it has one, so an unlabelled search box rides visibly higher than
   its neighbours — hence Label="Søg" on the field rather than a placeholder alone (which also
   left it with no accessible name). The glyph is trailing: leading would collide with the label
   in its resting position. */
.suggestion-list-search[b-y60o8vu5gn] {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
}

.suggestion-list-search-icon[b-y60o8vu5gn] {
    position: absolute;
    right: var(--tv-space-2);
    bottom: var(--tv-space-2);
    color: var(--tv-color-text-secondary);
    pointer-events: none;
    font-size: var(--tv-text-body);
}

/* Keep the typed text clear of the trailing glyph. The wrapper is authored here, so ::deep has
   the scoped ancestor it needs. */
.suggestion-list-search[b-y60o8vu5gn]  .mud-input-slot {
    padding-right: var(--tv-space-5);
}

.suggestion-list[b-y60o8vu5gn] {
    display: flex;
    flex-direction: column;
    gap: var(--tv-space-3);
    margin-bottom: var(--tv-space-4);
}

.suggestion-list-card[b-y60o8vu5gn] {
    display: flex;
    align-items: flex-start;
    gap: var(--tv-space-4);
    padding: var(--tv-space-4);
    background-color: var(--tv-surface);
    border: 1px solid var(--tv-border-color);
    border-radius: var(--tv-default-border-radius);
    cursor: pointer;
    transition: box-shadow 0.15s ease;
}

.suggestion-list-card:hover[b-y60o8vu5gn],
.suggestion-list-card:focus-visible[b-y60o8vu5gn] {
    box-shadow: var(--tv-shadow-flyout);
}

.suggestion-list-card-vote[b-y60o8vu5gn] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--tv-space-1);
    min-width: 3rem;
    color: var(--tv-color-text-secondary);
}

.suggestion-list-vote-count[b-y60o8vu5gn] {
    font-size: var(--tv-text-metric);
    font-weight: var(--tv-weight-strong);
    color: var(--tv-body-fg);
    line-height: var(--tv-leading-tight);
}

.suggestion-list-card-body[b-y60o8vu5gn] {
    flex: 1 1 auto;
    min-width: 0;
}

.suggestion-list-card-title[b-y60o8vu5gn] {
    margin: 0 0 var(--tv-space-2);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-medium);
    line-height: var(--tv-leading-tight);
}

.suggestion-list-card-meta[b-y60o8vu5gn] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--tv-space-3);
}

.suggestion-list-meta-text[b-y60o8vu5gn] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary);
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
}

.suggestion-list-comment-count i[b-y60o8vu5gn] {
    font-size: var(--tv-text-body);
}

.suggestion-list-changelog-badge[b-y60o8vu5gn] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
    font-size: var(--tv-text-meta);
    color: var(--suggestion-status-completed, hotpink);
}
/* /Components/Pages/Users/Detail.razor.rz.scp.css */
.user-detail-card[b-yg0vyovbib] {
    padding: var(--tv-space-4);
    border: 1px solid var(--tv-border-color);
    border-radius: var(--tv-default-border-radius);
    background: var(--tv-surface);
}

.user-detail-card-actions[b-yg0vyovbib] {
    display: flex;
    justify-content: flex-end;
    margin-top: var(--tv-space-4);
}

.user-detail-field-label[b-yg0vyovbib] {
    margin: 0 0 var(--tv-space-2);
    font-size: var(--tv-text-body);
    font-weight: var(--tv-weight-medium);
}

.user-detail-section-title[b-yg0vyovbib] {
    margin: var(--tv-section-gap) 0 var(--tv-space-3);
    font-size: var(--tv-text-section);
    font-weight: var(--tv-weight-strong);
}

.user-detail-table-card[b-yg0vyovbib] {
    border: 1px solid var(--tv-border-color);
    border-radius: var(--tv-default-border-radius);
    overflow: hidden;
}

.user-detail-table-card[b-yg0vyovbib]  .mud-table-head th {
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-strong);
}

.user-detail-table-card[b-yg0vyovbib]  .mud-table-body td {
    font-size: var(--tv-text-body);
}

/* Categorical role colours — taxonomy, not status. Mirrors Users/List.razor.css; the two
   stylesheets are scoped separately by Blazor CSS isolation so the rules cannot be shared. */
.user-role-badge[b-yg0vyovbib] {
    display: inline-flex;
    align-items: center;
    padding: 0 var(--tv-space-2);
    border-radius: var(--tv-default-border-radius);
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-medium);
    background: var(--tv-surface-alt);
}

.user-role-badge-admin[b-yg0vyovbib] {
    color: var(--palette-purple, hotpink);
}

.user-role-badge-moderator[b-yg0vyovbib] {
    color: var(--palette-teal, hotpink);
}

.user-role-badge-user[b-yg0vyovbib] {
    color: var(--palette-grey, hotpink);
}

.user-role-badge-changelog[b-yg0vyovbib] {
    color: var(--palette-blue, hotpink);
}

.user-role-badge-issue[b-yg0vyovbib] {
    color: var(--palette-accent, hotpink);
}
/* /Components/Pages/Users/List.razor.rz.scp.css */
/* Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

/* Label + trailing glyph, matching .suggestion-list-search and .kb-index-search. */
.user-list-search-bar[b-m0488hwbnp] {
    position: relative;
    display: flex;
    align-items: center;
    max-width: 24rem;
    margin-bottom: var(--tv-space-4);
}

.user-list-search-bar[b-m0488hwbnp]  .mud-input-root {
    flex: 1 1 auto;
}

.user-list-search-bar[b-m0488hwbnp]  .mud-input-slot {
    padding-right: var(--tv-space-5);
}

.user-list-search-icon[b-m0488hwbnp] {
    position: absolute;
    right: var(--tv-space-2);
    bottom: var(--tv-space-2);
    color: var(--tv-color-text-secondary, hotpink);
    pointer-events: none;
    font-size: var(--tv-text-body);
}

.user-list-table-card[b-m0488hwbnp] {
    border: 1px solid var(--tv-border-color);
    border-radius: var(--tv-default-border-radius);
    overflow: hidden;
}

.user-list-table-card[b-m0488hwbnp]  .mud-table-head th {
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-strong);
}

.user-list-table-card[b-m0488hwbnp]  .mud-table-body td {
    font-size: var(--tv-text-body);
}

/* Categorical role colours — taxonomy, not status. Text is mixed toward body colour rather than
   using the wash colour at full strength, so the badge reads as a label, not an alert. */
.user-role-badge[b-m0488hwbnp] {
    display: inline-flex;
    align-items: center;
    padding: 0 var(--tv-space-2);
    border-radius: var(--tv-default-border-radius);
    font-size: var(--tv-text-meta);
    font-weight: var(--tv-weight-medium);
    background: var(--tv-surface-alt);
}

.user-role-badge-admin[b-m0488hwbnp] {
    color: var(--palette-purple, hotpink);
}

.user-role-badge-moderator[b-m0488hwbnp] {
    color: var(--palette-teal, hotpink);
}

.user-role-badge-user[b-m0488hwbnp] {
    color: var(--palette-grey, hotpink);
}

.user-role-badge-changelog[b-m0488hwbnp] {
    color: var(--palette-blue, hotpink);
}

.user-role-badge-issue[b-m0488hwbnp] {
    color: var(--palette-accent, hotpink);
}
/* /Components/Shared/ChangelogCommentCard.razor.rz.scp.css */
/* Changelog comment card, recursively nested for one level of replies.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.changelog-comment-deleted[b-a47hhk4rb2] {
    margin: 0;
    font-style: italic;
    font-size: var(--tv-text-body);
    color: var(--tv-color-text-secondary, hotpink);
}

.changelog-comment-meta[b-a47hhk4rb2] {
    margin: 0 0 var(--tv-space-1);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}

.changelog-comment-body[b-a47hhk4rb2] {
    margin: 0 0 var(--tv-space-2);
    white-space: pre-wrap;
    font-size: var(--tv-text-body);
}

.changelog-comment-actions[b-a47hhk4rb2] {
    display: flex;
    align-items: center;
    gap: var(--tv-space-1);
}

.changelog-comment-vote-readonly[b-a47hhk4rb2] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}
/* /Components/Shared/CommentCard.razor.rz.scp.css */
/* Comment thread card. Replies are indented and rule off with a neutral border, not brand. */

.comment-card[b-053emm05wc] {
    padding: var(--tv-space-2) 0 var(--tv-space-2) var(--tv-space-3);
    margin-bottom: var(--tv-space-2);
    border-left: 2px solid var(--tv-border-color);
}

.comment-card-reply[b-053emm05wc] {
    margin-left: var(--tv-space-6);
}

.comment-card-deleted[b-053emm05wc] {
    margin: 0;
    font-style: italic;
    font-size: var(--tv-text-body);
    color: var(--tv-color-text-secondary);
}

.comment-card-header[b-053emm05wc] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--tv-space-1);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary);
}

.comment-card-author[b-053emm05wc] {
    font-weight: var(--tv-weight-strong);
    color: var(--tv-body-fg);
}

.comment-card-content[b-053emm05wc] {
    margin: var(--tv-space-1) 0;
    font-size: var(--tv-text-body);
    white-space: pre-wrap;
    overflow-wrap: break-word;
}

.comment-card-actions[b-053emm05wc] {
    display: flex;
    align-items: center;
    gap: var(--tv-space-1);
}

.comment-card-vote-readonly[b-053emm05wc] {
    display: inline-flex;
    align-items: center;
    gap: var(--tv-space-1);
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary);
}
/* /Components/Shared/QuillEditor.razor.rz.scp.css */
/* QuillEditor — footer meta line (character count / upload state) below the WYSIWYG surface.
   Classes handed to Mud/Tv components via Class="…" live in wwwroot/app.css instead, because
   CSS isolation can't scope them here. */

.quill-editor-footer[b-tc1fcykbhp] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: var(--tv-space-1);
}

.quill-editor-count[b-tc1fcykbhp] {
    font-size: var(--tv-text-meta);
    color: var(--tv-color-text-secondary, hotpink);
}

.quill-editor-count-error[b-tc1fcykbhp] {
    color: var(--palette-red, hotpink);
}

.quill-editor-error[b-tc1fcykbhp] {
    font-size: var(--tv-text-meta);
    color: var(--palette-red, hotpink);
}
