/* Inter — variable subset woff2 files, served from this RCL. Two faces split by
   unicode-range let the browser fetch only the script(s) actually used on the page.
   Paths are RCL-relative (no leading slash); they resolve to
   /_content/Repetitum.Cabinet.Shared/fonts/… in both the WASM host and MAUI. */
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('fonts/Inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('fonts/Inter-cyrillic.woff2') format('woff2');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116; }

:root {
    /* --------------------------------------------------------------------
       Brand-blue tokens — derived from the РЕПЕТИТУМ logo wordmark, used by
       the rp-* rules in bp.css and the calendar/dashboard blocks below.
       Dark-mode flips live in `body.rp-dark` at the bottom of this file.
       -------------------------------------------------------------------- */
    --brand-primary:      #1D73B3;
    --brand-primary-tint: #E6F2FB;

    /* Slate neutrals (Tailwind palette) — the design system anchors everything
       on these so cabinet + landing visually agree. */
    --slate-50:   #F8FAFC;
    --slate-100:  #F1F5F9;
    --slate-200:  #E2E8F0;
    --slate-300:  #CBD5E1;
    --slate-400:  #94A3B8;
    --slate-500:  #64748B;
    --slate-700:  #334155;
    --slate-900:  #0F172A;

    --border-hairline: var(--slate-200);

    /* Validation state colors (used by .invalid / .valid.modified outlines
       and .validation-message — Blazor's own EditForm classes, not MudBlazor).
       Tokenized so the dark-mode block can brighten them for contrast on
       slate-900 backgrounds. */
    --state-error:    #E50000;
    --state-success:  #26B050;

    /* Alert tints, one triplet per severity (bg / ink / msg). `ink` drives
       the icon colour (via currentColor) and the 1px border (via color-mix);
       `msg` is the body-text ink. Each color appears in exactly one place —
       flip them once in the dark block below and every MudAlert tracks. */
    --alert-success-bg:  #E7F8EF;
    --alert-success-ink: #2BB673;
    --alert-success-msg: #0F5132;
    --alert-warning-bg:  #FEF6DA;
    --alert-warning-ink: #E89505;
    --alert-warning-msg: #6E430A;
    --alert-error-bg:    #FDEAEA;
    --alert-error-ink:   #DC2626;
    --alert-error-msg:   #8B1818;
    --alert-info-bg:     #E6F3FB;
    --alert-info-ink:    #2990DC;
    --alert-info-msg:    #14598E;

    /* Calendar group-lesson tone (purple) — the only calendar hue not already in the ramp above.
       1:1 lessons use --brand-*, slots/past use --slate-*, reservations reuse --alert-warning-*. */
    --cal-group-bg: #EEEDFE;
    --cal-group-fg: #534AB7;
}

/* Typography (font family, sizes, weights, tracking) comes from Blueprint's own base
   styles (blazorblueprint.css) plus the @font-face above, which stays in app.css because
   it has to be present at first paint. There is no separate theme object to configure —
   MudTheme/CabinetTheme.cs (and the MudThemeProvider runtime <style> tag that used to
   inject --mud-typography-* vars, which nothing here ever actually consumed) were
   removed in wave-9 T9. */

/* ------------------------------------------------------------------------
   Form validation (Blazor's built-in EditForm classes). The design system
   uses #e50000 for invalid and #26b050 for valid-modified to match the
   landing's existing colors. Kept verbatim — these classes are emitted by
   InputBase<T>, not by our markup.
   ------------------------------------------------------------------------ */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--state-success);
}

.invalid {
    outline: 1px solid var(--state-error);
}

.validation-message {
    color: var(--state-error);
}

h1:focus {
    outline: none;
}

/* ========================================================================
   Dark mode — token overrides triggered by the `rp-dark` class on <body>.
   ThemeController.SetAsync / InitializeAsync calls into theme.js's
   `repetitumTheme.apply()` which toggles the class — our own switch for our
   own --brand-* / --slate-* / --alert-* / --state-* tokens (tokens.css's
   shadcn-style vars flip on the parallel `.dark` class on <html> instead).

   The slate ramp inverts — slate-50 (lightest in light) maps to the
   darkest dark in this block — so any rule reading `var(--slate-50)` in
   dark mode renders the dark canvas, and so on up the ramp.
   ======================================================================== */
body.rp-dark {
    --brand-primary:      #2990DC;
    --brand-primary-tint: rgba(41, 144, 220, 0.18);

    /* Dark canvas ramp — ported from the design bundle's `[data-reader="dim"]`
       block. Background #14181F is warmer/less blue than slate-900; the
       slate-* tokens flip so any `var(--slate-50)` in dark mode renders the
       dark canvas, and so on up the ramp to slate-900 ≈ body text colour. */
    --slate-50:   #14181F;  /* canvas / page bg — design's --read-bg */
    --slate-100:  #1B2029;  /* one step up — MudPaper surface in dark */
    --slate-200:  #232A35;  /* hairline — design's --read-rule */
    --slate-300:  #3A4250;  /* input border (LinesInputs) */
    --slate-400:  #64748B;
    --slate-500:  #94A3B8;  /* muted text — design's --read-fg-muted */
    --slate-700:  #CBD5E1;
    --slate-900:  #E8EAEC;  /* body text — design's --read-fg */

    --border-hairline: #232A35;

    --state-error:    #F87171;
    --state-success:  #5EE5A8;

    --alert-success-bg:  rgba(43, 182, 115, 0.18);
    --alert-success-ink: #5EE5A8;
    --alert-success-msg: #A7F3D0;
    --alert-warning-bg:  rgba(232, 149, 5, 0.18);
    --alert-warning-ink: #FBBF24;
    --alert-warning-msg: #FDE68A;
    --alert-error-bg:    rgba(220, 38, 38, 0.18);
    --alert-error-ink:   #F87171;
    --alert-error-msg:   #FECACA;
    --alert-info-bg:     rgba(41, 144, 220, 0.18);
    --alert-info-ink:    #60A5FA;
    --alert-info-msg:    #BFDBFE;

    --cal-group-bg: rgba(127, 119, 221, 0.20);
    --cal-group-fg: #AFA9EC;
}

/* The AppBar uses MudBlazor's `Color="Color.Surface"` which resolves to
   Palette.Surface — that flips automatically through PaletteDark.Surface.
   But the inline `border-bottom: 1px solid var(--border-hairline)` in
   MainLayout.razor reads the token directly and follows the block above. */

/* ------------------------------------------------------------------------
   Обратный флип: сцена видеокомнаты (доска + слайд) — единственная поверхность,
   которая НЕ темнеет (--wb-paper/--wb-ink, tokens.css), потому что палитра
   маркеров захардкожена под светлое. Значит внутри неё слейт-рампа должна
   вернуться к светлым значениям: разметка слайда рендерится как .rp-markdown,
   а та читает --slate-100 (фон code/pre), --slate-300 (линейка цитаты),
   --slate-500 (текст цитаты) и --brand-primary (ссылки) — с тёмными значениями
   это дало бы тёмный код-блок и светло-серую цитату на белом листе.

   Специфичность тут не спорит с `body.rp-dark`: это РАЗНЫЕ элементы, поэтому
   собственное объявление квадрата выигрывает для него и его поддерева, а не
   сравнивается с объявлением на <body>. Значения — копия светлого `:root`
   выше (литералы неизбежны: сослаться на затенённое значение переменной
   нельзя). Правишь рампу в `:root` — правь и здесь.
   ------------------------------------------------------------------------ */
.rp-room-square {
    --slate-100:     #F1F5F9;
    --slate-300:     #CBD5E1;
    --slate-500:     #64748B;
    --brand-primary: #1D73B3;
}

/* ------------------------------------------------------------------------
   Onboarding checklist — the "Начало работы" card on TutorHome. Done items
   stay tappable (the tutor may want to revisit the page) but their label
   reads as past-tense via line-through + muted opacity.
   ------------------------------------------------------------------------ */
.rp-onboarding-done {
    text-decoration: line-through;
    opacity: 0.65;
}

/* ------------------------------------------------------------------------
   Blazor error boundary — yellow exclamation-mark banner shown when an
   unhandled exception bubbles up. Stock styling kept; the embedded SVG is
   the standard ASP.NET Core "error" icon.
   ------------------------------------------------------------------------ */
.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: "Произошла ошибка."
}

/* ========================================================================
   Calendar (Components/Calendar/*) — shared time-grid surface used by the
   tutor schedule and the student "Мои уроки" page. All hues come from the
   design tokens above (--brand-*, --slate-*, --alert-warning-*, --cal-group-*)
   so the whole calendar flips with dark mode without a separate block.
   Kept global (not scoped .razor.css) because the calendar is split across
   several child components and Blazor scoped CSS does not cross component
   boundaries — matching the rp-tree / rp-block convention above.
   ======================================================================== */
.rp-cal { display: flex; flex-direction: column; gap: 12px; }

.rp-cal-header { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.rp-cal-nav { display: flex; align-items: center; gap: 4px; }
.rp-cal-title { font-size: 1.05rem; font-weight: 500; margin-left: 8px; }
.rp-cal-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ----- time grid (week / day) ----- */
.rp-cal-grid { border: 1px solid var(--border-hairline); border-radius: 12px; overflow: hidden; }
.rp-cal-grid-head { display: flex; border-bottom: 1px solid var(--border-hairline); }
.rp-cal-gutter-head { flex: 0 0 52px; }
.rp-cal-dayhead { flex: 1 1 0; text-align: center; padding: 6px 2px; border-left: 1px solid var(--border-hairline);
                  display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.rp-cal-dayhead--today { background: var(--brand-primary-tint); }
.rp-cal-dow { font-size: 11px; text-transform: uppercase; color: var(--slate-500); }
.rp-cal-daynum { font-size: 15px; font-weight: 500; }

/* No inner scroll: the page already scrolls, and an inner scrollbar would shrink the columns relative to
   the (unscrolled) header row, throwing the vertical gridlines out of alignment. The grid grows naturally. */
.rp-cal-grid-body { display: flex; }
.rp-cal-gutter { flex: 0 0 52px; position: relative; }
/* Hour labels sit just BELOW their own gridline (no vertical centring), so the top label isn't clipped
   above the grid and each number reads as the start of the hour block beneath it. */
.rp-cal-hour { position: absolute; right: 6px; margin-top: 2px; font-size: 10px; color: var(--slate-400); }
.rp-cal-cols { display: flex; flex: 1 1 0; }
.rp-cal-daycol { flex: 1 1 0; border-left: 1px solid var(--border-hairline); min-width: 0; }
.rp-cal-day-body { position: relative; width: 100%; }

.rp-cal-cell { position: absolute; left: 0; right: 0; cursor: pointer; }
.rp-cal-cell:hover { background: var(--brand-primary-tint); }

.rp-cal-now { position: absolute; left: 0; right: 0; height: 0; border-top: 2px solid var(--state-error); z-index: 5; }
.rp-cal-now::before { content: ''; position: absolute; left: 0; top: -4px; width: 7px; height: 7px;
                      border-radius: 50%; background: var(--state-error); }

/* ----- event blocks ----- */
.rp-cal-ev { position: absolute; border-radius: 6px; padding: 2px 6px; overflow: hidden; cursor: pointer;
             font-size: 12px; line-height: 1.25; box-sizing: border-box; z-index: 3; }
.rp-cal-ev[draggable="true"] { cursor: grab; }
.rp-cal-ev[draggable="true"]:active { cursor: grabbing; }
.rp-cal-ev-title { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rp-cal-ev-sub { font-size: 11px; opacity: 0.85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rp-cal-ev-badge { font-size: 11px; font-weight: 500; }

.rp-cal-ev--lesson { background: var(--brand-primary-tint); border-left: 3px solid var(--brand-primary); color: var(--brand-primary); }
.rp-cal-ev--group  { background: var(--cal-group-bg); border-left: 3px solid var(--cal-group-fg); color: var(--cal-group-fg); }
.rp-cal-ev--open   { background: transparent; border: 1px dashed var(--slate-300); color: var(--slate-500); }
.rp-cal-ev--past   { background: var(--slate-100); border-left: 3px solid var(--slate-300); color: var(--slate-500); }
/* Scheduled lesson running right now — green «идёт», so a live lesson reads apart from a plain upcoming
   one even before the now-line reaches it. */
.rp-cal-ev--live   { background: color-mix(in srgb, var(--state-success) 16%, transparent); border-left: 3px solid var(--state-success); color: var(--state-success); }

/* ----- tone dots (agenda / month) ----- */
.rp-cal-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.rp-cal-dot--lesson { background: var(--brand-primary); }
.rp-cal-dot--group { background: var(--cal-group-fg); }
.rp-cal-dot--open { background: var(--slate-400); }
.rp-cal-dot--past { background: var(--slate-300); }

/* ----- agenda (list) ----- */
.rp-cal-agenda-day { margin-bottom: 16px; }
.rp-cal-agenda-date { font-size: 13px; font-weight: 500; color: var(--slate-500); margin-bottom: 6px; text-transform: capitalize; }
.rp-cal-agenda-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border-hairline);
                     border-radius: 8px; margin-bottom: 6px; cursor: pointer; }
.rp-cal-agenda-row:hover { background: var(--brand-primary-tint); }
.rp-cal-agenda-time { font-weight: 500; font-size: 13px; flex: 0 0 42px; }
.rp-cal-agenda-main { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.rp-cal-agenda-title { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rp-cal-agenda-sub { font-size: 12px; color: var(--slate-500); }
.rp-cal-agenda-badge { flex: 0 0 auto; }

/* ----- month ----- */
.rp-cal-month { border: 1px solid var(--border-hairline); border-radius: 12px; overflow: hidden; }
.rp-cal-month-head { display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid var(--border-hairline); }
.rp-cal-month-dow { text-align: center; padding: 6px 0; font-size: 11px; text-transform: uppercase; color: var(--slate-500); }
.rp-cal-month-body { display: grid; grid-template-columns: repeat(7, 1fr); }
.rp-cal-month-cell { min-height: 94px; border-left: 1px solid var(--border-hairline); border-top: 1px solid var(--border-hairline);
                     padding: 4px; cursor: pointer; overflow: hidden; }
.rp-cal-month-cell--out { background: var(--slate-50); }
.rp-cal-month-cell--out .rp-cal-month-num { color: var(--slate-400); }
.rp-cal-month-num { font-size: 12px; font-weight: 500; display: inline-flex; align-items: center; justify-content: center;
                    min-width: 22px; height: 22px; }
.rp-cal-month-cell--today .rp-cal-month-num { background: var(--brand-primary); color: #fff; border-radius: 50%; }
.rp-cal-chip { display: flex; align-items: center; gap: 4px; font-size: 11px; padding: 1px 3px; border-radius: 4px;
               cursor: pointer; white-space: nowrap; overflow: hidden; }
.rp-cal-chip:hover { background: var(--brand-primary-tint); }
.rp-cal-chip-text { overflow: hidden; text-overflow: ellipsis; }
.rp-cal-month-more { font-size: 10px; color: var(--slate-500); padding-left: 3px; }

/* Mobile month cells are too narrow for the "HH:mm Title" chip — collapse each event to its tone dot
   (a wrapping row under the day number), so the day never clips its label to a single glyph. */
@media (max-width: 768px) {
  .rp-cal-month-cell { min-height: 52px; padding: 3px 2px; }
  .rp-cal-month-events { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; margin-top: 2px; }
  .rp-cal-chip { padding: 0; }
  .rp-cal-chip:hover { background: transparent; }
  .rp-cal-chip-text { display: none; }
  .rp-cal-month-more { padding-left: 0; line-height: 1; }
}

/* The old MudBlazor-era tests gradebook (.rp-matrix-*) was removed in wave 3 Task 11 — the /tests page
   was rebuilt on Blueprint (rp-tm-* in bp.css), and nothing else referenced these rules. */

/* ==================== Dashboard (home pages) ==================== */
/* Home page top-level rhythm: a flex column with the same 20px cadence as .rp-dash
   columns. Children carry their own legacy mb-* utilities (used on other pages too),
   so neutralize bottom margin on direct children — the gap owns vertical spacing. */
.rp-home { display: flex; flex-direction: column; gap: 20px; }
.rp-home > * { margin-bottom: 0 !important; }

.rp-dash { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
.rp-dash-main { flex: 3 1 520px; min-width: 0; display: flex; flex-direction: column; gap: 20px; }
.rp-dash-rail { flex: 1 1 300px; min-width: 280px; max-width: 360px; display: flex; flex-direction: column; gap: 20px; }

.rp-dash-stats { display: flex; gap: 12px; flex-wrap: wrap; }
.rp-dash-tile { flex: 1 1 170px; background: var(--card); border: 1px solid var(--border-hairline);
    border-radius: 12px; padding: 14px 16px; }
.rp-dash-tile--click { cursor: pointer; }
.rp-dash-tile--click:hover { border-color: var(--brand-primary); }
.rp-dash-tile-head { display: flex; align-items: center; gap: 8px; color: var(--slate-500); font-size: 12.5px; margin-bottom: 8px; }
.rp-dash-tile-value { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; }
.rp-dash-tile-note { font-size: 12px; color: var(--slate-500); }

.rp-dash-card { padding: 0; border: 1px solid var(--border-hairline); border-radius: 12px; overflow: hidden; }
.rp-dash-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 18px 12px; }
.rp-dash-card-title { font-size: 16px; font-weight: 600; }
.rp-dash-card-eyebrow { font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--slate-500); padding: 16px 18px 4px; }
.rp-dash-card-link { font-size: 13px; white-space: nowrap; flex-shrink: 0; }
.rp-dash-card-empty { padding: 14px 18px 18px; color: var(--slate-500); font-size: 13.5px; }
/* Body inset for free-form content inside .rp-dash-card (title + balance + button stacks
   in the rail cards). The eyebrow's own 16/18/4 padding owns the top inset, so this only
   adds horizontal + bottom. Not needed when the card body is a stack of .rp-dash-row's. */
.rp-dash-card-body { padding: 0 18px 16px; }

.rp-dash-row { display: flex; align-items: center; gap: 14px; padding: 13px 18px; border-top: 1px solid var(--border-hairline); }
.rp-dash-row--click { cursor: pointer; }
.rp-dash-row--click:hover { background: var(--secondary); }
.rp-dash-row-body { flex: 1; min-width: 0; }
.rp-dash-row-title { font-size: 14.5px; font-weight: 600; }
.rp-dash-row-sub { font-size: 12.5px; color: var(--slate-500); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.rp-dash-balance-exp { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; margin-top: 4px; }
.rp-dash-progress { padding: 6px 18px 14px; }
.rp-dash-progress-head { display: flex; justify-content: space-between; font-size: 13.5px; margin-bottom: 6px; }

/* The whole /room (video) chrome lives in bp.css; nothing rp-room remains here. */

/* ==================== Mobile (≤600px) ==================== */
@media (max-width: 600px) {
    /* Dashboard: single column, rail under main, on phones. */
    .rp-dash { flex-direction: column; }
    .rp-dash-main, .rp-dash-rail { flex: 1 1 100%; max-width: 100%; }
}

/* ==================== Whiteboard surface (wb-*) ====================
   wb-surface/wb-canvas back WhiteboardSurface.razor's canvas mount — width/height:100% of their
   `.rp-room-square` ancestor (bp.css) so the board always fills the stage in every rp-room-* layout
   (desktop, mobile/tablet portrait, phone landscape). Внутри комнаты фон тут перебивается на
   transparent (bp.css) — бумагу рисует сам квадрат; --wb-paper остаётся как фолбэк для монтирования
   вне .rp-room-square и держит один и тот же светлый лист в обеих темах. */
.wb-surface { position: relative; width: 100%; height: 100%; background: var(--wb-paper); }
.wb-canvas { width: 100%; height: 100%; touch-action: none; cursor: crosshair; display: block; }
/* Image blocks in lesson content (content page + reader). */
.rp-lesson-image { margin: 0 0 1rem; text-align: center; }
.rp-lesson-image img { max-width: 100%; height: auto; border-radius: 8px; display: block; margin: 0 auto; }
.rp-lesson-image figcaption { margin-top: 0.4rem; font-size: 0.85em; color: var(--muted-foreground); }
/* Lesson cover banners (content page + editor thumbnail + reader). */
.rp-lesson-cover { margin: 0 0 1rem; }
.rp-lesson-cover img { width: 100%; max-height: 220px; object-fit: cover; border-radius: 10px; display: block; }
.rp-lesson-cover-thumb { width: 32px; height: 32px; object-fit: cover; border-radius: 6px; margin-right: 8px; flex-shrink: 0; }
.rp-reader-cover { margin: 0 0 1.5rem; }
.rp-reader-cover img { width: 100%; max-height: 240px; object-fit: cover; border-radius: 10px; display: block; }

/* ==================== Blazor error UI ====================
   Moved from Layout/MainLayout.razor.css when the layout lost its scoped CSS
   (Blueprint shell rewrite): the default display:none is what keeps the
   reload bar hidden until blazor.web.js flips it on an unhandled exception. */
#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}
