h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

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

body {
    font-family: 'Vazirmatn', 'Segoe UI', sans-serif;
}

.app-bar-gradient {
    background: linear-gradient(120deg, #4B3FCF 0%, #6C5CE7 55%, #00B8A9 130%) !important;
    box-shadow: 0 4px 20px rgba(75, 63, 207, .25) !important;
}

.app-logo-badge {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: rgba(255, 255, 255, .18);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-left: 10px;
    backdrop-filter: blur(4px);
}

.user-chip-avatar {
    background: rgba(255, 255, 255, .22) !important;
    color: #fff !important;
    font-weight: 700;
}

.app-main-bg {
    background:
        radial-gradient(1200px 400px at 15% -10%, rgba(75, 63, 207, .07), transparent),
        radial-gradient(900px 400px at 100% 0%, rgba(0, 184, 169, .07), transparent),
        #F3F4FC;
    min-height: 100vh;
}

/* Sidebar "card" used by each role layout's nav menu — see HostLayout/AdminLayout/
   SuperAdminLayout/StudentLayout.razor. Sits alongside @Body in a MudGrid (MainLayout
   itself can't host a real MudDrawer here since the whole shell is static — see its
   own comment), styled to read as a proper app sidebar rather than a plain column. */
.app-sidebar {
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 4px 24px rgba(31, 30, 74, .06);
    padding: 12px;
    position: sticky;
    top: 88px;
}

.app-sidebar .mud-nav-link {
    border-radius: 10px;
    margin-bottom: 4px;
    transition: background-color .15s ease, color .15s ease;
}

.app-sidebar .mud-nav-link.active {
    background: linear-gradient(120deg, #4B3FCF, #6C5CE7);
    color: #fff !important;
}

.app-sidebar .mud-nav-link.active .mud-icon-root {
    color: #fff !important;
}

.app-sidebar .mud-nav-link:not(.active):hover {
    background: #F0EFFC;
}

/* Gradient stat cards — see Shared/StatCard.razor. Each Color maps to a distinct
   gradient so a row of cards reads as a coherent palette, not flat single-tone icons. */
.stat-card {
    border-radius: 16px;
    border: 1px solid rgba(31, 30, 74, .06);
    box-shadow: 0 6px 20px rgba(31, 30, 74, .05);
    transition: transform .15s ease, box-shadow .15s ease;
}

.stat-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 28px rgba(31, 30, 74, .10);
}

.stat-card-icon {
    width: 52px;
    height: 52px;
    border-radius: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
}

.stat-card-icon.mud-primary { background: linear-gradient(135deg, #4B3FCF, #6C5CE7); }
.stat-card-icon.mud-secondary { background: linear-gradient(135deg, #00B8A9, #06D6A0); }
.stat-card-icon.mud-tertiary { background: linear-gradient(135deg, #FF7F50, #FFA36C); }
.stat-card-icon.mud-success { background: linear-gradient(135deg, #2ECC71, #58D68D); }
.stat-card-icon.mud-warning { background: linear-gradient(135deg, #F5A623, #FBC02D); }
.stat-card-icon.mud-error { background: linear-gradient(135deg, #E74C3C, #FF7B7B); }
.stat-card-icon.mud-default { background: linear-gradient(135deg, #8A8FA3, #B0B4C4); }

/* Page header banner — see Shared/PageHeader.razor. */
.page-header {
    border-radius: 18px;
    padding: 22px 26px;
    background: linear-gradient(120deg, #EDEBFC 0%, #E4F8F6 100%);
    margin-bottom: 24px;
    display: flex;
    align-items: center;
    gap: 16px;
}

.page-header-icon {
    width: 48px;
    height: 48px;
    border-radius: 14px;
    background: linear-gradient(135deg, #4B3FCF, #00B8A9);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* Rounded, softly-elevated tables/cards app-wide for a less "boxy" default look. */
.mud-table-container {
    border-radius: 14px !important;
}

.mud-paper {
    border-radius: 14px;
}

/* Live classroom video grid — populated by wwwroot/js/livekitRoom.js, never by Blazor's
   own rendering, so these rules target plain DOM/class selectors, and livekitRoom.js
   itself toggles the "single-tile" class below (see updateGridMode) whenever a tile is
   added/removed, since CSS alone can't size a grid row to "100% of the container" off
   just a child count. One participant: #video-grid.single-tile below makes that one tile
   fill the whole pod, edge to edge. Two or more: the plain grid rule here divides the
   space between them via auto-fit + 1fr, so as a 3rd/4th tile joins, everyone's tile
   shrinks equally to keep fitting the same row instead of overflowing.
   min-height was previously a flat 320px, taller than this pod's body is by default — which
   forced a scrollbar to reach 320px of mostly-empty grid even with zero or one tile in it.
   100% instead: fill whatever height the pod actually has, no more, no less; align-content:
   start keeps a handful of tiles packed at the top instead of stretched across any leftover
   space; a scrollbar still appears, correctly, once there are truly more tiles than fit. */
/* Whiteboard — a plain white surface regardless of room skin, since strokes are near-black
   by default and would be invisible against a dark/translucent pod background. Drawing
   itself is owned entirely by wwwroot/js/whiteboard.js, same reasoning as #video-grid. */
#whiteboard-canvas {
    background: #fff;
    border-radius: 4px;
}

.wb-swatch {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, .4);
    padding: 0;
    cursor: pointer;
    flex-shrink: 0;
}

.wb-swatch-active {
    border-color: #fff;
    box-shadow: none;
    outline: 2px solid var(--pod-a, #8B5CF6);
    outline-offset: 1px;
}

#video-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    grid-auto-rows: min-content;
    align-content: start;
    gap: 12px;
    padding: 12px;
    background: #202124;
    border-radius: 8px;
    min-height: 100%;
    box-sizing: border-box;
}

/* Exactly one participant: fill the whole pod instead of staying boxed to a small
   16:9 tile. position:absolute + inset:0 (not a percentage width/height, which doesn't
   reliably resolve against a flex/grid container's cross size — tried first, computed to
   0 in testing) reliably fills #video-grid's own box, which has a definite size either
   way (min-height:100% above). */
#video-grid.single-tile {
    position: relative;
    padding: 0;
}
#video-grid.single-tile .lk-tile {
    position: absolute;
    inset: 0;
    aspect-ratio: auto;
}

#video-grid:empty {
    display: flex;
    align-items: center;
    justify-content: center;
}

#video-grid:empty::before {
    content: "دوربین کسی روشن نیست.";
    color: rgba(255, 255, 255, .45);
    font-size: .85rem;
}

.video-grid-start-cam-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.video-grid-start-cam-overlay .mud-button-root {
    pointer-events: auto;
}

.lk-tile {
    position: relative;
    background: #000;
    border-radius: 6px;
    overflow: hidden;
    aspect-ratio: 16 / 9;
}

.lk-tile-media {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.lk-video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.lk-audio {
    display: none;
}

.lk-tile-label {
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 8px;
    background: linear-gradient(transparent, rgba(0,0,0,.65));
    color: #fff;
    font-size: .8rem;
}

.lk-tile-hand {
    font-size: 1rem;
}

/* ---------------------------------------------------------------------------
   "Nebula Glass" room theme — a dark, immersive workspace ("room-stage") that
   frames the floating toolbar ("control-dock") and pod canvas together, so
   glassmorphism actually reads as glass: real blur, real depth, a living
   backdrop showing through every panel, instead of a light card that merely
   borrows an accent color. Each pod still carries a data-accent (violet/teal/
   rose/blue/amber/green/indigo/sky/orange) driving its icon chip, top bar and
   neon hover-glow via --pod-a/--pod-b. --------------------------------------- */
.room-stage {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100vh;
    padding: 18px;
    border-radius: 32px;
    overflow: hidden;
    box-sizing: border-box;
    background:
        radial-gradient(900px 560px at 6% -10%, rgba(139, 92, 246, .38), transparent 60%),
        radial-gradient(760px 520px at 100% 0%, rgba(20, 184, 166, .32), transparent 60%),
        radial-gradient(820px 560px at 45% 110%, rgba(244, 63, 94, .26), transparent 60%),
        radial-gradient(700px 480px at 85% 65%, rgba(249, 115, 22, .20), transparent 60%),
        linear-gradient(160deg, #17162E 0%, #0B0A1C 100%);
    background-size: 180% 180%, 180% 180%, 180% 180%, 180% 180%, 100% 100%;
    animation: aurora-drift 26s ease-in-out infinite alternate;
    box-shadow: none;
}

@keyframes aurora-drift {
    0%   { background-position: 0% 0%, 100% 0%, 50% 100%, 90% 60%, 0 0; }
    100% { background-position: 16% 12%, 84% 16%, 38% 92%, 72% 48%, 0 0; }
}

.room-stage::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image: radial-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px);
    background-size: 24px 24px;
    pointer-events: none;
}

/* The room must never scroll, in either direction. .room-stage is a column flexbox pinned
   to 100vh (above) with .control-dock sized to its own content, so this canvas — the flex
   item that takes "flex: 1" — always gets exactly whatever vertical space is actually left
   on screen, on any monitor and with a toolbar of any height (it wraps onto a second line
   on narrow screens), rather than guessing a fixed px budget that only happens to be right
   for one screen size. min-height: 0 overrides the flexbox default of never shrinking a
   flex item below its content size, which is what overflow: hidden here needs to actually
   clip instead of pushing .room-stage taller than the viewport.
   Every pod's default position (see ClassRoom.razor) is laid out to fit an ~800px-tall
   canvas as a reasonable common case, and podManager.js clamps drag/resize to this
   canvas's real bounds at runtime either way. A pod only ends up visually overlapping
   another, or (on a shorter screen than ~800px) having its default position run past the
   actual canvas bottom, if someone opens many of the optional pods at once (most are off
   by default) or works on an unusually short viewport — expected, same as any floating-
   window layout; the person drags/resizes pods to fit, nothing is ever hidden behind an
   unreachable scroll position instead. */
.pod-canvas {
    position: relative;
    z-index: 1;
    width: 100%;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

.pod[data-accent="violet"] { --pod-a: #8B5CF6; --pod-b: #C4B5FD; }
.pod[data-accent="teal"]   { --pod-a: #14B8A6; --pod-b: #5EEAD4; }
.pod[data-accent="rose"]   { --pod-a: #F43F5E; --pod-b: #FDA4AF; }
.pod[data-accent="blue"]   { --pod-a: #3B82F6; --pod-b: #93C5FD; }
.pod[data-accent="amber"]  { --pod-a: #F59E0B; --pod-b: #FCD34D; }
.pod[data-accent="green"]  { --pod-a: #10B981; --pod-b: #6EE7B7; }
.pod[data-accent="indigo"] { --pod-a: #6366F1; --pod-b: #A5B4FC; }
.pod[data-accent="sky"]    { --pod-a: #0EA5E9; --pod-b: #7DD3FC; }
.pod[data-accent="orange"] { --pod-a: #F97316; --pod-b: #FDBA74; }

.pod {
    position: absolute;
    z-index: 1;
    display: flex;
    flex-direction: column;
    background: rgba(255, 255, 255, .07);
    backdrop-filter: blur(26px) saturate(160%);
    -webkit-backdrop-filter: blur(26px) saturate(160%);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 20px;
    box-shadow: none;
    overflow: hidden;
    min-width: 240px;
    min-height: 160px;
    transition: box-shadow .25s ease, transform .15s ease;
    animation: pod-in .3s ease both;
}

@keyframes pod-in {
    from { opacity: 0; transform: translateY(6px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

.pod:hover {
    box-shadow: none;
}

.pod-accent-bar {
    height: 3px;
    flex-shrink: 0;
    background: linear-gradient(90deg, var(--pod-a), var(--pod-b));
    box-shadow: none;
}

.pod-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    cursor: move;
    user-select: none;
    flex-shrink: 0;
    border-bottom: 1px solid rgba(255, 255, 255, .06);
}

.pod-icon-chip {
    width: 28px;
    height: 28px;
    border-radius: 9px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--pod-a), var(--pod-b));
    color: #fff;
    box-shadow: none;
}

.pod-title {
    font-size: .85rem;
    font-weight: 700;
    color: #F4F4FF;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pod-drag-grip {
    color: rgba(255, 255, 255, .3);
    font-size: .8rem;
    letter-spacing: 1px;
}

.pod-header-spacer {
    flex: 1 1 auto;
}

.pod-btn {
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: rgba(255, 255, 255, .55);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease;
}

.pod-collapse {
    font-size: .75rem;
}

.pod-btn:hover {
    background: color-mix(in srgb, var(--pod-a) 30%, transparent);
    color: #fff;
}

/* Collapsed pod: only the header remains — the body/resize-handle stay in the DOM
   (see Pod.razor and .pod-hidden-while-collapsed below) but are hidden via CSS, and
   this override drops the container's own inline height (whatever it was expanded
   to) down to just that header's height. */
.pod.pod-collapsed {
    height: auto !important;
    min-height: 0;
    box-shadow: none;
}

/* Hides collapsed content without removing it from the DOM — see Pod.razor's own comment
   on why an @if there used to do this and broke JS-owned pod content (whiteboard, video,
   share, presentation) on every collapse/expand. */
.pod-hidden-while-collapsed {
    display: none;
}

.pod-body {
    flex: 1 1 auto;
    overflow: auto;
    padding: 10px 12px;
    min-height: 0;
    color: #E7E7F5;
    scrollbar-width: thin;
    scrollbar-color: var(--pod-a) transparent;
}

.pod-body, .pod-body .mud-typography, .pod-body p, .pod-body span, .pod-body strong {
    color: #E7E7F5;
}

.pod-body .mud-secondary-text, .pod-body .mud-typography-caption {
    color: #9A9BC0 !important;
}

.pod-body a, .pod-body .mud-link {
    color: #C4B5FD !important;
}

.pod-body .mud-input-outlined-border {
    border-color: rgba(255, 255, 255, .22) !important;
}

.pod-body .mud-input:hover .mud-input-outlined-border, .pod-body .mud-input-outlined-border:hover {
    border-color: rgba(255, 255, 255, .4) !important;
}

.pod-body .mud-input-outlined {
    background: rgba(255, 255, 255, .04);
    border-radius: 10px;
}

.pod-body .mud-input-slot, .pod-body input, .pod-body textarea {
    color: #F2F2FA !important;
    -webkit-text-fill-color: #F2F2FA;
}

.pod-body .mud-input-label {
    color: #9A9BC0 !important;
}

.pod-body::-webkit-scrollbar {
    width: 6px;
}

.pod-body::-webkit-scrollbar-thumb {
    background: var(--pod-a);
    opacity: .4;
    border-radius: 3px;
}

.pod-resize-handle {
    position: absolute;
    /* Physical "right", not inset-inline-end: podManager.js always grows a pod
       toward larger clientX/clientY (bottom-right), regardless of document
       direction, so the handle must stay visually on that same physical
       corner — inset-inline-end flips to the LEFT under RTL, putting the
       handle on the opposite corner from the one dragging actually resizes. */
    right: 5px;
    bottom: 5px;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
    background-image: radial-gradient(circle, var(--pod-a) 1.4px, transparent 1.4px);
    background-size: 5px 5px;
    background-position: bottom right;
    opacity: .5;
}

.pod:hover .pod-resize-handle {
    opacity: .9;
}

/* Floating glass "control dock" — the room's main toolbar (see ClassRoom.razor).
   A dark pill-shaped bar rather than a boxy top toolbar, with clusters of
   circular media/host controls separated by thin dividers. */
.control-dock {
    border-radius: 999px !important;
    background: rgba(22, 20, 42, .55) !important;
    backdrop-filter: blur(22px) saturate(180%);
    -webkit-backdrop-filter: blur(22px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, .12);
    box-shadow: none;
    padding: 9px 18px !important;
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
}

.control-dock, .control-dock .mud-typography, .control-dock .mud-switch-label {
    color: #EDEDF7 !important;
}

.control-dock .mud-icon-button .mud-icon-root.mud-default-text {
    color: #EDEDF7 !important;
}

.dock-divider {
    width: 1px;
    height: 26px;
    flex-shrink: 0;
    background: rgba(255, 255, 255, .14);
    margin: 0 2px;
}

.dock-btn.mud-button-root {
    border-radius: 999px !important;
    box-shadow: none;
    transition: transform .15s ease, box-shadow .15s ease;
}

.dock-btn.mud-button-root:hover {
    transform: translateY(-2px);
    box-shadow: none;
}

.dock-icon-btn.mud-icon-button-root {
    box-shadow: none;
    transition: transform .15s ease, box-shadow .15s ease;
}

.dock-icon-btn.mud-icon-button-root:hover {
    transform: translateY(-2px);
}

/* Pulsing red dot next to the "recording" state — a small, unmissable heartbeat
   rather than a static icon, so a live recording actually reads as "live". */
.rec-live-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #fff;
    margin-inline-end: 8px;
    animation: rec-pulse 1.2s ease-in-out infinite;
}

@keyframes rec-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: .35; transform: scale(1.5); }
}

/* Small status pills next to the theme toggle — visible proof that recording/
   streaming is live without needing to open the "more options" menu where the
   actual start/stop actions now live (see ClassRoom.razor). */
.rec-badge {
    display: flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 999px;
    background: rgba(244, 63, 94, .18);
    color: #FDA4AF;
    font-size: .72rem;
    font-weight: 700;
}

.rec-badge-live {
    background: rgba(20, 184, 166, .18);
    color: #5EEAD4;
}

.room-stage.theme-light .rec-badge {
    background: rgba(225, 29, 72, .12);
    color: #E11D48;
}

.room-stage.theme-light .rec-badge-live {
    background: rgba(13, 148, 136, .12);
    color: #0D9488;
}

/* Chat bubbles — own messages align opposite from everyone else's and pick up a
   gradient fill, instead of a flat "Name: text" line. */
.chat-bubble-row {
    display: flex;
    margin-bottom: 8px;
}

.chat-bubble-row.chat-self {
    justify-content: flex-end;
}

.chat-bubble {
    max-width: 82%;
    padding: 7px 12px;
    border-radius: 14px;
    font-size: .85rem;
    line-height: 1.5;
    box-shadow: none;
}

.chat-bubble .chat-bubble-name {
    display: block;
    font-size: .72rem;
    font-weight: 700;
    opacity: .8;
    margin-bottom: 2px;
}

.chat-bubble-row:not(.chat-self) .chat-bubble {
    background: rgba(255, 255, 255, .09);
    border: 1px solid rgba(255, 255, 255, .1);
    color: #F0F0FA;
    border-bottom-left-radius: 4px;
}

.chat-bubble-row.chat-self .chat-bubble {
    background: linear-gradient(135deg, #F43F5E, #FB7185);
    color: #fff;
    border-bottom-right-radius: 4px;
}

/* Participant rows — an avatar-initial chip + name/role, instead of a bare
   text line, so the list reads like a real roster. */
.participant-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border-radius: 12px;
    margin-bottom: 4px;
    transition: background-color .15s ease;
}

.participant-row:hover {
    background: rgba(255, 255, 255, .06);
}

.participant-avatar {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: .8rem;
    font-weight: 700;
    background: linear-gradient(135deg, #3B82F6, #93C5FD);
    box-shadow: none;
}

.participant-row .participant-hand {
    font-size: .95rem;
}

/* Poll options — colorful selectable cards instead of plain outlined buttons,
   with a glowing gradient result bar once votes are visible. */
.poll-option-btn.mud-button-root {
    border-radius: 12px !important;
    justify-content: flex-start !important;
    border-color: rgba(165, 180, 252, .4) !important;
    color: #C7D2FE !important;
    background: rgba(255, 255, 255, .04) !important;
    transition: transform .15s ease, background-color .15s ease;
}

.poll-option-btn.mud-button-root:hover {
    background: rgba(99, 102, 241, .18) !important;
    transform: translateX(-2px);
}

.poll-result-card {
    border-radius: 12px;
    padding: 8px 10px;
    margin-bottom: 8px;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .08);
}

.poll-result-bar {
    height: 8px;
    border-radius: 4px;
    margin-top: 6px;
    background: rgba(255, 255, 255, .1);
    overflow: hidden;
}

.poll-result-bar-fill {
    height: 100%;
    border-radius: 4px;
    background: linear-gradient(90deg, #6366F1, #A5B4FC);
    box-shadow: none;
    transition: width .3s ease;
}

/* Q&A cards — a glowing left accent bar marks answered (green) vs pending
   (amber) at a glance, instead of identical outlined boxes. */
.qa-card {
    border-radius: 12px;
    padding: 10px 12px;
    margin-bottom: 8px;
    background: rgba(255, 255, 255, .06);
    border: 1px solid rgba(255, 255, 255, .08);
    border-inline-start: 3px solid #FCD34D;
}

.qa-card.qa-answered {
    border-inline-start-color: #6EE7B7;
}

/* Presentation slide viewer */
.presentation-slide {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
}

/* Container PPTXjs renders the real .pptx into (see wwwroot/js/presentationViewer.js)
   — native transitions/animations included, not a flattened image. PPTXjs sizes its
   own slide div in pixels off the source file's dimensions, so this just gives it a
   dark stage to sit on and scrolls if a slide is scaled larger than the pod. */
.presentation-viewer-stage {
    flex: 1 1 auto;
    position: relative;
    overflow: auto;
    background: #111;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ---------------------------------------------------------------------------
   Light-mode variant of the room — toggled by adding "theme-light" to
   .room-stage (see ClassRoom.razor's theme toggle button + localStorage
   persistence). Every rule below only overrides colors/backgrounds; layout,
   blur amounts, and structure stay identical to the dark theme so the two
   feel like the same app, not two different pages. --------------------- */
.room-stage.theme-light {
    background:
        radial-gradient(900px 560px at 6% -10%, rgba(124, 58, 237, .14), transparent 60%),
        radial-gradient(760px 520px at 100% 0%, rgba(20, 184, 166, .13), transparent 60%),
        radial-gradient(820px 560px at 45% 110%, rgba(244, 63, 94, .10), transparent 60%),
        radial-gradient(700px 480px at 85% 65%, rgba(249, 115, 22, .08), transparent 60%),
        linear-gradient(160deg, #F6F5FD 0%, #EEEDFB 100%);
    box-shadow: none;
}

.room-stage.theme-light::before {
    background-image: radial-gradient(rgba(31, 30, 74, .07) 1px, transparent 1px);
}

.room-stage.theme-light .pod {
    background: rgba(255, 255, 255, .78);
    border-color: rgba(255, 255, 255, .65);
    box-shadow: none;
}

.room-stage.theme-light .pod:hover {
    box-shadow: none;
}

.room-stage.theme-light .pod.pod-collapsed {
    box-shadow: none;
}

.room-stage.theme-light .pod-header {
    border-bottom-color: rgba(31, 30, 74, .06);
}

.room-stage.theme-light .pod-title {
    color: #1F1E4A;
}

.room-stage.theme-light .pod-drag-grip {
    color: #C7C9DD;
}

.room-stage.theme-light .pod-btn {
    color: #8A8FA3;
}

.room-stage.theme-light .pod-btn:hover {
    color: var(--pod-a);
    background: color-mix(in srgb, var(--pod-a) 16%, transparent);
}

.room-stage.theme-light .pod-body,
.room-stage.theme-light .pod-body .mud-typography,
.room-stage.theme-light .pod-body p,
.room-stage.theme-light .pod-body span,
.room-stage.theme-light .pod-body strong {
    color: #332F63;
}

.room-stage.theme-light .pod-body .mud-secondary-text,
.room-stage.theme-light .pod-body .mud-typography-caption {
    color: #8A8FA3 !important;
}

.room-stage.theme-light .pod-body a, .room-stage.theme-light .pod-body .mud-link {
    color: #6D28D9 !important;
}

.room-stage.theme-light .pod-body .mud-input-outlined-border {
    border-color: rgba(31, 30, 74, .18) !important;
}

.room-stage.theme-light .pod-body .mud-input-outlined {
    background: rgba(255, 255, 255, .6);
}

.room-stage.theme-light .pod-body .mud-input-slot,
.room-stage.theme-light .pod-body input,
.room-stage.theme-light .pod-body textarea {
    color: #1F1E4A !important;
    -webkit-text-fill-color: #1F1E4A;
}

.room-stage.theme-light .pod-body .mud-input-label {
    color: #8A8FA3 !important;
}

.room-stage.theme-light .control-dock {
    background: rgba(255, 255, 255, .78) !important;
    border-color: rgba(255, 255, 255, .6);
    box-shadow: none;
}

.room-stage.theme-light .control-dock,
.room-stage.theme-light .control-dock .mud-typography,
.room-stage.theme-light .control-dock .mud-switch-label {
    color: #332F63 !important;
}

.room-stage.theme-light .dock-divider {
    background: rgba(31, 30, 74, .12);
}

.room-stage.theme-light .chat-bubble-row:not(.chat-self) .chat-bubble {
    background: rgba(124, 58, 237, .10);
    border-color: transparent;
    color: #1F1E4A;
}

.room-stage.theme-light .participant-row:hover {
    background: rgba(37, 99, 235, .07);
}

.room-stage.theme-light .poll-option-btn.mud-button-root {
    background: rgba(255, 255, 255, .5) !important;
    color: #4F46E5 !important;
    border-color: rgba(79, 70, 229, .35) !important;
}

.room-stage.theme-light .poll-result-card {
    background: rgba(79, 70, 229, .06);
    border-color: transparent;
}

.room-stage.theme-light .poll-result-bar {
    background: rgba(79, 70, 229, .12);
}

.room-stage.theme-light .qa-card {
    background: rgba(255, 255, 255, .65);
    border-color: transparent;
}
.impersonation-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 8px 16px;
    background: #b3261e;
    color: #fff;
    font-size: .9rem;
    font-weight: 600;
}

.impersonation-banner form { margin-inline-start: auto; }

.impersonation-exit {
    background: rgba(255, 255, 255, .18);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, .5);
    border-radius: 8px;
    padding: 4px 12px;
    cursor: pointer;
    font: inherit;
}

/* Global loader (BusyIndicator.razor + busy.js) */
.busy-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2100;
    pointer-events: none;
}

.busy-overlay {
    position: fixed;
    inset: 0;
    z-index: 1300; /* below MudBlazor dialogs (1400) so dialogs keep their own in-dialog loader */
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, .35);
    backdrop-filter: blur(1px);
    cursor: progress;
}

.busy-spinner {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: 5px solid rgba(75, 63, 207, .2);
    border-top-color: #4B3FCF;
    animation: busy-spin .8s linear infinite;
}

@keyframes busy-spin { to { transform: rotate(360deg); } }

.dialog-busy-slot {
    height: 4px;
    margin: -8px -8px 8px;
}

.dialog-busy {
    animation: dialog-busy-in 0s .15s forwards;
    opacity: 0;
}

@keyframes dialog-busy-in { to { opacity: 1; } }

.busy-link { pointer-events: none; opacity: .75; }

.busy-link-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    margin-inline-end: 8px;
    vertical-align: -2px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    animation: busy-spin .7s linear infinite;
}

/* Panel content placeholder until the page renders (PageBoot.razor) */
.page-boot {
    display: grid;
    place-items: center;
    min-height: 240px;
}

/* The page's own content is inserted as the next element sibling once it renders. */
.page-boot:has(+ *) { display: none; }

.busy-toast {
    position: fixed;
    top: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2200;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 18px;
    border-radius: 999px;
    background: #4B3FCF;
    color: #fff;
    font-weight: 600;
    box-shadow: 0 6px 24px rgba(75, 63, 207, .35);
    pointer-events: none;
}

.busy-toast .busy-link-spinner { margin: 0; }

/* ---------------------------------------------------------------------------
   Class-creation wizard (CreateClassDialog.razor): numbered step header and the
   searchable student checklist. -------------------------------------------- */
.wizard-steps {
    display: flex;
    gap: 6px;
    margin-bottom: 18px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.wizard-step {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    font-family: inherit;
    font-size: .8rem;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
    background: transparent;
    border: 0;
    border-bottom: 3px solid transparent;
    cursor: default;
    min-width: 0;
}

.wizard-step.done { cursor: pointer; color: var(--mud-palette-success); }
.wizard-step.active { color: var(--mud-palette-primary); border-bottom-color: var(--mud-palette-primary); }

.wizard-num {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: .75rem;
    border: 2px solid currentColor;
}

.wizard-step.active .wizard-num { background: var(--mud-palette-primary); color: #fff; border-color: var(--mud-palette-primary); }
.wizard-step.done .wizard-num { background: var(--mud-palette-success); color: #fff; border-color: var(--mud-palette-success); }
.wizard-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.wizard-student-list {
    max-height: 280px;
    overflow-y: auto;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 10px;
}

.wizard-student-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 0 8px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.wizard-student-row:last-child { border-bottom: 0; }
.wizard-student-row:hover { background: var(--mud-palette-action-default-hover); }
.wizard-student-email { font-size: .72rem; color: var(--mud-palette-text-secondary); direction: ltr; }

/* ---------- support tickets ---------- */
.support-nav-badge { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px; margin-inline-start: 6px; border-radius: 999px; background: #e5484d; color: #fff; font-size: .72rem; font-weight: 800; line-height: 1; }
.support-head { border: 1px solid var(--mud-palette-lines-default); border-radius: 14px; }
.support-thread { display: flex; flex-direction: column; gap: 14px; margin-bottom: 18px; }
.support-msg { max-width: min(760px, 92%); padding: 12px 16px; border-radius: 14px; border: 1px solid var(--mud-palette-lines-default); background: var(--mud-palette-surface); }
.support-msg-mine { align-self: flex-start; background: color-mix(in srgb, var(--mud-palette-primary) 10%, var(--mud-palette-surface)); border-color: color-mix(in srgb, var(--mud-palette-primary) 35%, transparent); }
.support-msg-theirs { align-self: flex-end; }
.support-msg-staff:not(.support-msg-mine) { border-inline-start: 4px solid var(--mud-palette-success); }
.support-msg-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: .8rem; color: var(--mud-palette-text-secondary); margin-bottom: 6px; }
.support-msg-meta strong { color: var(--mud-palette-text-primary); }
.support-msg-body { white-space: pre-wrap; word-break: break-word; line-height: 1.9; }
.support-reply { border: 1px solid var(--mud-palette-lines-default); border-radius: 14px; }

/* ---------- support attachments ---------- */
.support-attach-picker { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.support-attach-list { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; margin-top: 4px; }
.support-attach-size { opacity: .65; font-size: .75rem; margin-inline-start: 4px; }
.support-attachments { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.support-attach-file { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 10px; border: 1px solid var(--mud-palette-lines-default); text-decoration: none; color: inherit; max-width: 100%; }
.support-attach-file:hover { background: color-mix(in srgb, var(--mud-palette-primary) 8%, transparent); }
.support-attach-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 220px; }
.support-attach-thumb { display: flex; flex-direction: column; gap: 4px; width: 150px; text-decoration: none; color: inherit; font-size: .75rem; }
.support-attach-thumb img { width: 150px; height: 100px; object-fit: cover; border-radius: 10px; border: 1px solid var(--mud-palette-lines-default); background: #0001; }
.support-attach-thumb span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
