/* ===== AXIOMA ЛК — оформление кабинета ==================================
   Кабинет и публичный сайт — один продукт, поэтому здесь не «похожие» цвета,
   а те же самые токены, что в school-site/css/style.css: песочная страница,
   белые карточки, глубоко-изумрудный текст, зелёный акцент днём и медовый
   ночью. Шрифт тоже тот же — Onest, но со своего домена (css/onest.css).

   Что важно не сломать при правках: имена классов — это контракт с app.js,
   schedule.js и homework.js, которые собирают разметку через node(tag, class).
   Переименовать класс здесь значит молча убить кусок интерфейса.
   ======================================================================== */

/* --- токены: 1:1 с :root публичного сайта ------------------------------- */
:root {
  /* пять цветов фирменных полос, слева направо */
  --band-1: #C9E3B8;
  --band-2: #4FA37C;
  --band-3: #123B2E;
  --band-4: #F0B429;
  --band-5: #E4D8B4;

  --accent: #1F7A5A;
  --accent-hover: #17604A;
  --on-accent: #FFFFFF;

  --ink: #123B2E;
  --ink-soft: #4E7566;
  /* тёмная плоскость шапки, подвала и вводного экрана: в отличие от --ink
     никогда не светлеет, поэтому текст на ней всегда --on-surface */
  --ink-surface: #123B2E;
  --on-surface: #F1F6EC;
  --on-surface-soft: rgba(241, 246, 236, 0.72);
  --on-surface-line: rgba(241, 246, 236, 0.16);

  --paper: #F6F3EA;
  --paper-soft: #EFEADB;
  --paper-card: #FFFFFF;
  --header-bg: #FFFFFF;
  --line: rgba(18, 59, 46, 0.2);

  --danger: #A8332A;

  --shadow-soft: 0 16px 40px rgba(18, 59, 46, 0.10);
  --shadow-tight: 0 6px 16px rgba(18, 59, 46, 0.10);

  --radius-xl: 28px;
  --radius-lg: 22px;
  --radius-md: 14px;
  --radius-sm: 8px;

  --font: 'Onest', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --container: 1180px;
  --desk-width: 1440px;
  --transition: 200ms ease;
}

/* Финансовый экран: цифры читаются первым слоем, операции — вторым. */
.fin-summary{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px;margin:18px 0}.fin-stat,.fin-card{border:1px solid var(--line);background:var(--paper-card);border-radius:20px;padding:18px}.fin-stat{display:grid;gap:7px}.fin-stat span{color:var(--ink-soft);font-size:.82rem}.fin-stat strong{font-size:clamp(1.35rem,3vw,2rem)}.fin-card{margin-top:12px}.fin-card h3{margin:0 0 14px}.fin-chart{height:190px;display:flex;align-items:end;gap:10px;padding-top:28px}.fin-bar{height:100%;flex:1;min-width:38px;display:flex;flex-direction:column;justify-content:end;align-items:center;gap:6px}.fin-bar i{width:min(42px,80%);background:linear-gradient(180deg,var(--accent),color-mix(in srgb,var(--accent) 55%,#6657d8));border-radius:10px 10px 4px 4px;min-height:6px}.fin-bar span,.fin-bar small{font-size:.68rem;color:var(--ink-soft);white-space:nowrap}.fin-form{display:grid;grid-template-columns:2fr repeat(3,1fr);gap:9px}.fin-form input:nth-of-type(2),.fin-form .btn{grid-column:auto}.fin-list{display:grid;gap:8px}.fin-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;border-radius:14px;background:color-mix(in srgb,var(--ink) 5%,transparent)}.fin-row>div{display:grid;gap:3px}.fin-row span{color:var(--ink-soft);font-size:.8rem}.fin-status{border:0;border-radius:999px;padding:7px 11px;background:color-mix(in srgb,var(--accent) 13%,transparent);color:var(--accent);font:inherit;font-size:.78rem;font-weight:700;cursor:pointer}@media(max-width:700px){.fin-form{grid-template-columns:1fr}.fin-chart{overflow-x:auto}.fin-bar{min-width:56px}}
.tb-meta{display:grid;grid-template-columns:2fr 1fr 2fr repeat(4,.65fr);gap:8px;margin:16px 0}.tb-list{display:grid;gap:12px}.tb-q{border:1px solid var(--line);border-radius:20px;padding:16px;background:var(--paper-card)}.tb-q__head{display:grid;grid-template-columns:1fr minmax(180px,1fr) repeat(3,38px);align-items:center;gap:7px;margin-bottom:10px}.tb-icon{width:38px;height:38px;border:1px solid var(--line);border-radius:11px;background:transparent;color:var(--ink);font:inherit;cursor:pointer}.tb-q__opts{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;margin:8px 0}.tb-q__hint{margin:8px 2px;color:var(--ink-soft);font-size:.82rem}.tb-q__detail{font-family:ui-monospace,monospace}.tb-report{margin:12px 0;padding:14px;border-radius:15px}.tb-report p{margin:5px 0}.tb-report--bad{background:color-mix(in srgb,var(--danger) 12%,transparent)}.tb-report--ok{background:color-mix(in srgb,var(--accent) 12%,transparent)}@media(max-width:760px){.tb-meta,.tb-q__opts{grid-template-columns:1fr 1fr}.tb-meta>*:first-child,.tb-meta>*:nth-child(3){grid-column:1/-1}.tb-q__head{grid-template-columns:1fr repeat(3,38px)}.tb-q__head select{grid-column:1/-1;grid-row:2}.tb-q{padding:12px}}
.test-pick-card{display:grid;gap:6px;padding:16px;margin:10px 0;border:1px solid var(--line);border-radius:18px;background:var(--paper-card)}.test-pick-options{display:grid;grid-template-columns:110px 130px 1fr;gap:8px;align-items:center}.test-pick-difficulty{display:flex;gap:6px;flex-wrap:wrap}.test-pick-difficulty label{display:flex;gap:5px;align-items:center;padding:9px;border:1px solid var(--line);border-radius:12px;font-size:.82rem}@media(max-width:620px){.test-pick-options{grid-template-columns:1fr 1fr}.test-pick-difficulty{grid-column:1/-1}}
.streak-mini{margin-top:7px;border:0;border-radius:999px;padding:5px 9px;background:color-mix(in srgb,#f28c28 14%,transparent);color:var(--ink);font:inherit;font-weight:750;cursor:pointer}.streak-manage__hero{font-size:clamp(3rem,10vw,5rem);font-weight:800;color:#e77b20;margin:10px 0}

/* Тёмная тема — по атрибуту, как на сайте, а не по prefers-color-scheme:
   выбор человека должен переживать закрытие вкладки (js/shell.js), а ночью
   ребёнок делает домашку не при свете лампы. */
[data-theme='dark'] {
  --ink: #F1F6EC;
  --ink-soft: #9BBDA9;
  --paper: #0A2620;
  --paper-soft: #0D2E27;
  --paper-card: #0D2E27;
  --line: rgba(241, 246, 236, 0.22);
  --shadow-soft: 0 16px 40px rgba(0, 0, 0, 0.45);
  --shadow-tight: 0 6px 16px rgba(0, 0, 0, 0.4);

  /* мёд читается акцентом на глубокой зелени так же, как зелень на песке:
     роли меняются местами, иерархия — нет */
  --accent: #F0B429;
  --accent-hover: #D99C1F;
  --on-accent: #0A2620;

  --ink-surface: #061A16;
  --header-bg: #061A16;
  --band-3: #124A38;

  --danger: #F0857C;
}

/* Animate surfaces together. Transitions on every descendant's inherited
   color cascade through the tree and briefly make text unreadable. */
@media (prefers-reduced-motion: no-preference) {
  body, .site-header, .nav-row, .desk-card, .win__box, .profile-panel {
    transition: background-color 180ms ease, border-color 180ms ease;
  }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

/* Полоса прокрутки в палитре кабинета. Раньше она красилась приглушёнными
   чернилами и на тёмной теме выглядела светло-серой системной полосой —
   чужой заплаткой поверх зелени. Здесь она приглушённо-зелёная и темнеет
   под курсором, чтобы было видно, что её можно тащить. */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) transparent;
}
:root { --scroll-thumb: rgba(18, 59, 46, 0.28); }
[data-theme='dark'] { --scroll-thumb: rgba(47, 144, 104, 0.45); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border-radius: 999px; border: 2px solid transparent; background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--accent); background-clip: padding-box; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, .display {
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin: 0 0 0.5em;
  /* «конфиденциальности» шире телефона — иначе страница уезжает вбок */
  overflow-wrap: break-word;
}
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }
button { font-family: inherit; cursor: pointer; }

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}

/* ===== Шапка ============================================================ */

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: color-mix(in srgb, var(--header-bg) 90%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.header-inner {
  display: flex; align-items: center; gap: 16px;
  height: 76px;
}

/* Знак рисует библиотека комплекта (js/axioma-logo.js); ссылка — контейнер
   с защитным полем в половину ширины знака. */
.logo { display: flex; align-items: center; padding-right: 14px; flex: none; }

/* «личный кабинет» рядом со знаком: подпись к логотипу, а не заголовок */
.header-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
  padding-left: 16px;
  border-left: 1px solid var(--line);
  white-space: nowrap;
}

.header-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }

/* Тумблер темы перенесён из style.css без изменений: те же 56×28, тот же
   отскок ручки — чтобы в кабинете он ощущался ровно как на сайте. */
.theme-toggle {
  position: relative; width: 56px; height: 28px; border-radius: 999px;
  border: none; padding: 0; box-sizing: border-box;
  background: #1F7A5A;
  transition: background 0.45s cubic-bezier(0.4, 0, 0.2, 1);
  flex: none;
}
.theme-toggle:hover { filter: brightness(1.08); }
[data-theme='dark'] .theme-toggle { background: #0B1A15; }
.theme-toggle-icons {
  position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
  transition: left 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
[data-theme='dark'] .theme-toggle-icons { left: 31px; }
.theme-toggle-icons svg {
  position: absolute; top: 0; left: 0; display: block;
  transition: opacity 0.3s ease, transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.theme-toggle-sun { opacity: 1; transform: rotate(0deg) scale(1); }
.theme-toggle-moon { opacity: 0; transform: rotate(-60deg) scale(0.6); }
[data-theme='dark'] .theme-toggle-sun { opacity: 0; transform: rotate(60deg) scale(0.6); }
[data-theme='dark'] .theme-toggle-moon { opacity: 1; transform: rotate(0deg) scale(1); }
.theme-toggle-knob {
  position: absolute; top: 3px; left: 31px; width: 22px; height: 22px;
  border-radius: 999px; background: #FFFFFF;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
  transition: left 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
[data-theme='dark'] .theme-toggle-knob { left: 3px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35); }

@media (max-width: 560px) {
  .header-inner { height: 64px; gap: 10px; }
  .header-label { display: none; }
}

/* ===== Каркас страницы ================================================== */

/* app.js вешает на #card класс card--wide, когда человек вошёл: список людей
   и расписание шире формы входа. Класс остаётся контрактом с ним. */
.lk-main { flex: 1; display: flex; flex-direction: column; --lk-content: 980px; }
.lk-main.card--wide { --lk-content: 900px; }
.lk-main .container { max-width: var(--lk-content); }
/* Рабочий стол — на всю ширину, как рабочее место, а не лента по центру.
   Остальные разделы остаются в узкой колонке: список читается узким. */
.lk-main:has(#view-home:not([hidden])) { --lk-content: var(--desk-width); }

/* Шапка держится тех же краёв, что и стол. Иначе логотип и картинка профиля
   висят посреди пустого поля: стол шириной 1440, а шапка осталась 1180, и
   между их краями сотня пикселей, которую глаз читает как ошибку вёрстки. */
body:has(#view-home:not([hidden])) .site-header .container { max-width: var(--desk-width); }

/* ===== Вводный экран гостя ============================================== */

/* Фирменная диагональ: пять полос по тёмной плоскости, справа. Отдельными
   элементами, а не градиентом, — чтобы каждая въезжала со своей задержкой. */
.lk-hero {
  position: relative; overflow: hidden;
  background: var(--ink-surface);
  color: var(--on-surface);
  padding: 64px 0 72px;
}
.hero-bands {
  position: absolute; top: -20%; bottom: -20%; right: -10%; width: 34%;
  display: flex;
  transform: skewX(-12deg);
}
.hero-band { flex: 1; }
.hero-band:nth-child(1) { background: var(--band-1); }
.hero-band:nth-child(2) { background: var(--band-2); }
.hero-band:nth-child(3) { background: var(--band-3); }
.hero-band:nth-child(4) { background: var(--band-4); }
.hero-band:nth-child(5) { background: var(--band-5); }
@media (prefers-reduced-motion: no-preference) {
  .hero-band { animation: lk-band-in 420ms ease-out both; }
  .hero-band:nth-child(1) { animation-delay: 0ms; }
  .hero-band:nth-child(2) { animation-delay: 90ms; }
  .hero-band:nth-child(3) { animation-delay: 180ms; }
  .hero-band:nth-child(4) { animation-delay: 270ms; }
  .hero-band:nth-child(5) { animation-delay: 360ms; }
}
@keyframes lk-band-in { from { transform: translateX(140%); } to { transform: none; } }

/* Полосы позиционированы в процентах от всей ширины, а колонка текста —
   по --container: их зазор гуляет от ширины окна и масштаба. Заливка
   гарантирует, что светлый текст всегда лежит на тёмном. */
.hero-scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(90deg, var(--ink-surface) 0%, var(--ink-surface) 48%, transparent 78%);
}

.lk-hero__inner {
  position: relative; z-index: 2;
  display: grid;
  grid-template-columns: 1fr minmax(360px, 460px);
  gap: 48px;
  align-items: start;
}

.lk-hero__copy { padding-top: 8px; max-width: 520px; }
.lk-hero__copy .eyebrow { color: var(--band-4); }
.lk-hero__copy h1 {
  font-size: clamp(2rem, 4.4vw, 3.1rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--on-surface);
}
.lede { color: var(--on-surface-soft); font-size: 1.05rem; margin: 0 0 26px; }

/* Три коротких обещания под заголовком: что вообще внутри кабинета. */
.lk-facts { display: grid; gap: 10px; padding: 0; margin: 0; list-style: none; }
.lk-facts li {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 0.92rem; color: var(--on-surface-soft);
}
.lk-facts svg { flex: none; margin-top: 2px; color: var(--band-4); }

@media (max-width: 900px) {
  .lk-hero__inner { grid-template-columns: 1fr; gap: 32px; }
  .lk-hero { padding: 44px 0 52px; }
  .hero-bands { right: -18%; width: 26%; }
  .hero-scrim { background: linear-gradient(90deg, var(--ink-surface) 0%, var(--ink-surface) 62%, transparent 92%); }
}
@media (max-width: 640px) {
  /* на телефоне слева от полос не остаётся ширины, и диагональ читается не
     украшением, а мусором — убираем, цвет добирает полоса в подвале */
  .hero-bands { display: none; }
  .hero-scrim { background: var(--ink-surface); }
  .lk-hero__copy { display: none; }
  .lk-hero { padding: 28px 0 36px; }
}

/* ===== Панель формы ===================================================== */

.lk-panel {
  background: var(--paper-card);
  color: var(--ink);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-soft);
  padding: 30px 30px 34px;
}

.lk-panel h1 { font-size: 1.45rem; margin: 20px 0 6px; font-weight: 800; letter-spacing: -0.02em; }
.lk-panel .lead { color: var(--ink-soft); }

.lead { margin: 0 0 20px; color: var(--ink-soft); font-size: 0.95rem; }
.hint { margin: 6px 0 0; font-size: 0.82rem; color: var(--ink-soft); }

@media (max-width: 480px) {
  .lk-panel { padding: 24px 20px 28px; border-radius: var(--radius-lg); }
}

/* ===== Вкладки ========================================================== */

/* Тот же «пилюльный» переключатель, что в .tab-switch на сайте. */
.tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  background: var(--paper-soft);
  padding: 5px;
  border-radius: 999px;
}

.tabs button {
  border: 0;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-weight: 700;
  font-size: 0.9rem;
  padding: 10px 8px;
  border-radius: 999px;
  transition: background var(--transition), color var(--transition);
}

.tabs button[aria-selected='true'] {
  background: var(--paper-card);
  color: var(--ink);
  box-shadow: var(--shadow-tight);
}

/* Вкладок в кабинете то две, то три — в зависимости от роли, поэтому здесь
   не сетка, а ряд: третья не должна падать на новую строку. */
.tabs--nav { display: flex; max-width: 520px; margin: 24px 0 4px; }
.tabs--nav button { flex: 1; }

/* Тренажёры — ссылка на отдельную страницу, а не вкладка, но в ряду должна
   выглядеть ровно так же: человек не обязан знать, что там другая страница. */
.tabs--nav .tabs__link {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 8px;
  border-radius: 999px;
  color: var(--ink-soft);
  font-weight: 700;
  font-size: 0.9rem;
  text-decoration: none;
  transition: background var(--transition), color var(--transition);
}
.tabs--nav .tabs__link:hover {
  background: color-mix(in srgb, var(--paper-card) 70%, transparent);
  color: var(--ink);
}

/* ===== Поля ============================================================= */

label { display: block; margin-top: 16px; font-size: 0.85rem; font-weight: 700; }
.login-password-field { position: relative; }
.login-password-field input { padding-right: 54px; }
#form-login .login-password-toggle {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center; width: 44px; height: 44px;
  margin: 0; padding: 0; border: 0; border-radius: 10px;
  background: transparent; color: var(--ink-soft); cursor: pointer;
}
#form-login .login-password-toggle:hover { color: var(--accent); }
#form-login .login-password-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.login-password-slash { display: none; }
.login-shared-note { margin: 6px 0 0; color: var(--ink-soft); font-size: .78rem; line-height: 1.5; }
.login-password-toggle[aria-pressed='true'] .login-password-slash { display: block; }

input, select, textarea {
  width: 100%;
  margin-top: 6px;
  padding: 13px 16px;
  font: inherit;
  color: var(--ink);
  background: var(--paper);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-md);
  transition: border-color var(--transition), background var(--transition);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); }
/* дата и время в тёмной теме иначе рисуют чёрный системный значок календаря */
[data-theme='dark'] input[type='date'],
[data-theme='dark'] input[type='datetime-local'] { color-scheme: dark; }

/* Код приглашения — крупно и вразрядку: его переписывают с бумажки или
   диктуют по телефону, и каждый символ должен читаться однозначно. */
input.code {
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 1.25rem;
  font-weight: 800;
  text-align: center;
}

.checkbox {
  display: flex; gap: 10px; align-items: flex-start;
  margin-top: 18px; font-size: 0.88rem; font-weight: 500;
}
.checkbox input { width: auto; margin: 3px 0 0; flex: none; accent-color: var(--accent); }

/* ===== Кнопки =========================================================== */

/* Форма входа — один столбец, поэтому базовая .btn во всю ширину; узкие
   варианты (--small/--inline/--sm) сжимаются по содержимому. Имена классов
   те же, что в JS: node('button', 'btn btn--small btn--ghost', …). */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%;
  margin-top: 22px;
  padding: 13px 24px;
  font: inherit;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--on-accent);
  background: var(--accent);
  border: 2px solid transparent;
  border-radius: 999px;
  transition: transform var(--transition), background var(--transition),
              color var(--transition), border-color var(--transition);
}
.btn:hover:not(:disabled) { background: var(--accent-hover); transform: translateY(-2px); }
.btn:disabled { opacity: 0.55; cursor: default; transform: none; }

.btn--ghost {
  background: transparent;
  color: var(--ink-soft);
  border-color: var(--line);
  margin-top: 10px;
}
.btn--ghost:hover:not(:disabled) { background: transparent; border-color: var(--accent); color: var(--accent); }

.btn--inline, .btn--small, .btn--sm { width: auto; margin-top: 0; padding: 9px 18px; font-size: 0.85rem; }
.btn--small.btn--ghost, .btn--sm.btn--ghost { margin-top: 0; }

@media (max-width: 420px) {
  .btn { white-space: normal; text-align: center; }
}

/* ===== Сообщение ======================================================== */

/* Одно на весь кабинет: и «неверный пароль», и «урок поставлен». Раньше оно
   жило в конце карточки и на длинных экранах оказывалось за пределами
   видимого — теперь всплывает снизу и видно всегда. */
.message {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 200;
  max-width: min(520px, calc(100vw - 32px));
  padding: 13px 20px;
  /* не «пилюля»: сообщение бывает в две строки, и скруглённый по высоте
     прямоугольник тогда выглядит случайным */
  border-radius: var(--radius-lg);
  font-size: 0.9rem;
  font-weight: 600;
  text-align: center;
  background: var(--danger);
  color: #FFFFFF;
  box-shadow: var(--shadow-soft);
  /* Сообщение ничего не спрашивает — нажать в нём не на что. Без этого оно
     перехватывало касания у того, что оказалось под ним: на телефоне
     «Ответы приняты» ложилось ровно на варианты ответа. */
  pointer-events: none;
}
[data-theme='dark'] .message { color: #2A0C09; }
.message--ok { background: var(--accent); color: var(--on-accent); }
@media (prefers-reduced-motion: no-preference) {
  .message { animation: lk-toast-in 260ms cubic-bezier(.22,.61,.36,1) both; }
}
@keyframes lk-toast-in {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* ===== Кто вошёл ======================================================== */

/* Тот же блок используется и как карточка «ваш ребёнок в системе» при
   регистрации родителя (#register-child). */
.who {
  padding: 12px 18px;
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  font-size: 0.9rem;
  color: var(--ink-soft);
}
.who strong { display: block; font-size: 1.05rem; color: var(--ink); }
#register-child { margin-top: 16px; }

.lk-topbar { border-bottom: 1px solid var(--line); background: var(--paper-soft); }
.topline {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding-top: 16px; padding-bottom: 16px;
}
.topline .who { background: transparent; padding: 0; }

/* Внутренние экраны кабинета */
/* .container уже задал боковые поля; здесь только вертикальные — сокращённое
   padding обнулило бы отступы по бокам, и на телефоне текст лип к краю */
.lk-body { padding-top: 8px; padding-bottom: 64px; }
.lk-body h1 { font-size: 1.6rem; font-weight: 800; letter-spacing: -0.02em; margin: 26px 0 8px; }

.section-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.section-head h1 { margin: 26px 0 8px; }

/* ===== Панель школы ===================================================== */

.invite-bar { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 4px; }

/* Выданный код — крупно и с кнопкой копирования: его сейчас будут диктовать
   по телефону или пересылать в мессенджер. */
.issued {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin-top: 16px;
  padding: 14px 18px;
  border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.issued__label { font-size: 0.85rem; color: var(--ink-soft); }
.issued__code {
  font-size: 1.35rem; font-weight: 800; letter-spacing: 0.14em;
  color: var(--accent);
  max-width: 100%; overflow-wrap: anywhere;
}
.issued__code--link { font-size: 0.92rem; letter-spacing: 0; }

.group { margin-top: 28px; }
.group__title {
  font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-soft);
  margin-bottom: 10px;
}

.person {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  margin-bottom: 8px;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.person:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.person__main { flex: 1; min-width: 0; }
.person__name { font-weight: 700; }
.person__meta {
  font-size: 0.82rem; color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.person__actions { display: flex; gap: 6px; flex: none; }

.tag {
  font-size: 0.72rem; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}

.empty { color: var(--ink-soft); font-size: 0.92rem; padding: 8px 0; }

.pending { margin-top: 28px; }
.pending summary {
  cursor: pointer; font-weight: 700; font-size: 0.92rem; color: var(--ink-soft);
  padding: 10px 0;
}
.pending .person { margin-top: 10px; }

@media (max-width: 560px) {
  .person { flex-wrap: wrap; }
  .person__actions { width: 100%; }
  .person__actions .btn { flex: 1; }
}

/* ===== Расписание ======================================================= */

#form-lesson {
  margin-top: 16px;
  padding: 22px 24px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
}

.students-pick { margin-top: 18px; }
.picker { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }

/* Ученики выбираются нажатием на имя, а не галочками в списке: пять имён
   пальцем на телефоне выбрать проще, чем попасть в маленький квадратик. */
.chip {
  border: 1.5px solid var(--line);
  background: transparent;
  color: var(--ink);
  font: inherit; font-size: 0.85rem; font-weight: 700;
  padding: 8px 16px;
  border-radius: 999px;
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.chip[aria-pressed='true'] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

.day {
  margin-top: 28px;
  font-size: 0.72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--ink-soft);
}

.lesson {
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
  margin-top: 8px;
}
/* Прошедшие и отменённые приглушены: глаз должен цепляться за ближайшее
   занятие, а не за архив. */
.lesson--past { opacity: 0.62; }
.lesson--cancelled .lesson__title { text-decoration: line-through; }

/* Время и метка стоят на одной линии. По базовой линии крупная цифра и
   мелкий кружок статуса разъезжались по вертикали: цифра сидела ниже. */
.lesson__top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.lesson__time { font-weight: 800; font-size: 1.05rem; line-height: 1.2; }
.lesson__msk { font-size: 0.8rem; color: var(--ink-soft); }
.lesson__title { font-weight: 700; margin-top: 2px; }
.lesson__meta { font-size: 0.82rem; color: var(--ink-soft); margin-top: 4px; }
.lesson__actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }

.status {
  font-size: 0.72rem; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 10%, transparent);
  color: var(--ink-soft);
}
.status--done { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.status--cancelled { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.status--swap { background: color-mix(in srgb, #6F5AA8 18%, transparent); color: #6F5AA8; }

/* Флаг «списывать урок» — это деньги родителей, поэтому он всегда на виду
   и переключается одним нажатием. */
.charge {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 0.8rem; font-weight: 700;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background: transparent;
  color: var(--ink-soft);
  font-family: inherit;
}
.charge[aria-pressed='true'] { border-color: color-mix(in srgb, var(--accent) 55%, transparent); color: var(--accent); }

/* ===== Домашние задания ================================================= */

.hw {
  background: var(--paper-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  margin-top: 10px;
}
.hw__top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.hw__subject { font-weight: 800; }
.hw__due { font-size: 0.82rem; color: var(--ink-soft); }
.hw__count {
  font-size: 0.72rem; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 10%, transparent);
  color: var(--ink-soft);
}
.hw__count--full { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.hw__items { margin-top: 12px; }

/* Пункт задания — крупная строка, а не мелкая галочка: ребёнок отмечает
   её пальцем на телефоне, и промахиваться он не должен. */
.hw-item {
  display: flex; align-items: flex-start; gap: 12px;
  width: 100%;
  padding: 12px 16px;
  margin-top: 6px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ink);
  font: inherit;
  text-align: left;
  transition: border-color var(--transition), background var(--transition);
}
.hw-item[aria-pressed='true'] {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.hw-item__box {
  flex: none;
  width: 22px; height: 22px;
  border-radius: 7px;
  border: 2px solid var(--line);
  display: grid; place-items: center;
  font-size: 0.85rem; font-weight: 800;
  color: var(--on-accent);
}
.hw-item[aria-pressed='true'] .hw-item__box { background: var(--accent); border-color: var(--accent); }
.hw-item--readonly { cursor: default; }
.hw-item__mark {
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--ink-soft);
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
}
.hw-item__late { font-size: 0.72rem; font-weight: 700; color: var(--ink-soft); margin-left: auto; flex: none; }

.hw__review { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; align-items: center; }
.hw__student { font-size: 0.88rem; font-weight: 700; margin-right: 4px; }

.verdict { font-size: 0.72rem; font-weight: 700; padding: 4px 10px; border-radius: 999px; }
.verdict--accepted { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.verdict--rework { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }

/* Долг заметен, но не кричит: это напоминание, а не наказание. */
.debt {
  border: 1.5px solid color-mix(in srgb, var(--danger) 40%, var(--line));
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  border-radius: var(--radius-lg);
  padding: 16px 18px;
  margin-top: 10px;
}
.debt__title { font-weight: 800; margin-bottom: 4px; }
.debt__comment { font-size: 0.88rem; margin-top: 6px; }
.debt__items { font-size: 0.88rem; color: var(--ink-soft); margin-top: 6px; }

/* ===== Подвал =========================================================== */

.site-footer {
  background: var(--ink-surface);
  color: var(--on-surface);
  margin-top: auto;
  padding: 32px 0 0;
}
.footer-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding-bottom: 26px;
}
.site-footer p { margin: 0; font-size: 0.82rem; color: var(--on-surface-soft); max-width: 520px; }
.site-footer a { color: var(--on-surface-soft); font-size: 0.82rem; }
.site-footer a:hover { color: var(--on-surface); }
.footer-links { display: flex; gap: 18px; flex-wrap: wrap; }

/* Цветная полоса, закрывающая страницу: те же пять цветов, что в диагонали,
   переставленные 3-2-4-5-1 и неравной ширины — это подпись, а не повтор. */
.footer-strip { display: flex; height: 10px; }
.footer-strip span { display: block; }
.footer-strip span:nth-child(1) { flex: 2; background: var(--band-3); }
.footer-strip span:nth-child(2) { flex: 3; background: var(--band-2); }
.footer-strip span:nth-child(3) { flex: 2; background: var(--band-4); }
.footer-strip span:nth-child(4) { flex: 1.4; background: var(--band-5); }
.footer-strip span:nth-child(5) { flex: 1; background: var(--band-1); }

/* ===== Вход: сноски и живая проверка кода ==============================
   Вкладок «Войти / У меня есть код» больше нет. Код вводят один раз в жизни,
   вход — сотни раз, поэтому редкое действие ушло вниз сноской, как «Забыли
   пароль», а частое занимает весь экран. */

.footlinks {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 18px;
  font-size: 14px;
  color: var(--ink-soft);
}

.footlinks button {
  border: 0;
  background: none;
  padding: 2px 0;
  font: inherit;
  color: var(--ink-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: color 160ms ease;
}

.footlinks button:hover { color: var(--accent); }

/* Состояние кода: пока человек печатает — тишина, как только код набран
   целиком, поле само краснеет или зеленеет. Кнопки «Продолжить» нет:
   если код верный, подтверждать нечего. */
.codestate {
  margin: 10px 0 0;
  min-height: 20px;
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  color: var(--ink-soft);
}

.codestate--bad { color: var(--danger); }
.codestate--good { color: var(--accent); }

input.code--bad,
input.code--bad:focus { border-color: var(--danger); }

input.code--good,
input.code--good:focus { border-color: var(--accent); }

/* Проверка идёт полсекунды — за это время поле не должно выглядеть мёртвым */
input.code--checking { opacity: 0.7; }

.codeaccepted {
  margin: 0 0 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
}

/* На узком экране сноски переносятся, и разделительная точка повисает
   в конце строки. Прячем её и ставим ссылки в столбик. */
@media (max-width: 400px) {
  .footlinks { flex-direction: column; gap: 10px; }
  .footlinks span { display: none; }
}

/* ===== Состояние системы =================================================
   Открытые проблемы видны сразу и не спрятаны в свёрнутом блоке: тревога,
   которую надо разворачивать, чтобы увидеть, — не тревога. */

.health {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 22px;
  padding: 12px 16px;
  border-radius: var(--radius-md);
  font-size: 14px;
  font-weight: 600;
}

.health--ok {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}

.health--warning {
  background: color-mix(in srgb, #c98a1e 20%, transparent);
  color: #8a5c0f;
}

.health--critical {
  background: color-mix(in srgb, var(--danger) 14%, transparent);
  color: var(--danger);
}

@media (prefers-color-scheme: dark) {
  .health--warning { color: #e8b45a; }
}

.health__list { margin: 8px 0 0; padding-left: 18px; font-weight: 500; width: 100%; }
.health__list li { margin-top: 2px; }

/* Подсветка урока, к которому пришли с доски завершённого занятия. */
.lesson--focus {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  transition: outline-color 400ms ease;
}

/* ========================= РАБОЧИЙ СТОЛ ==================================
   Первое, что видит человек, войдя в кабинет. Плитками, а не списком: у
   каждой плитки один вопрос и один ответ, и глаз находит нужную сразу.
   Плитки разного веса — самая крупная та, ради которой кабинет и открыли. */

.desk {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  align-items: start;
  margin-top: 4px;
}
/* Место каждого блока задаёт скрипт: сколько из двенадцати колонок занять. */
.desk > * { grid-column: span 4; min-width: 0; }
/* Во всю ширину — от первой линии до последней: на узких экранах колонок
   шесть, а не двенадцать, и span 12 вылезал бы за сетку. */
.desk-w12 { grid-column: 1 / -1 !important; }
.desk-w8  { grid-column: span 8 !important; }
.desk-w7  { grid-column: span 7 !important; }
.desk-w6  { grid-column: span 6 !important; }
.desk-w5  { grid-column: span 5 !important; }
.desk-w4  { grid-column: span 4 !important; }
.desk-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

/* Ряд плиток одной высоты: ученики, классы, праздники. Растягиваются до
   самой высокой; полоска без классов не растёт — ей хватает строки. */
.desk-trio {
  display: grid;
  grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr));
  gap: 16px;
  align-items: stretch;
  min-width: 0;
}
.desk-trio > .desk-card { min-width: 0; }
.desk-trio > .desk-card--slim { align-self: start; }
.desk-slim { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.desk-slim__text { flex: 1 1 180px; color: var(--ink-soft); font-size: 0.93rem; }
.desk-slim .btn { flex: none; width: auto; }

/* Поздравления: текст на виду, три кнопки под ним. */
/* Список ограничен по высоте и прокручивается внутри: три дня рождения
   подряд не должны вытягивать соседние плитки в пустые колонны. */
.desk-greets { display: grid; gap: 10px; max-height: 430px; overflow: auto; padding-right: 2px; }
.desk-greet {
  display: grid; gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--paper);
}
.desk-greet__top { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.desk-greet__name { font-weight: 700; }
.desk-greet__meta { color: var(--ink-soft); font-size: 0.85rem; }
.desk-greet__text {
  margin: 0; padding: 8px 12px;
  border-left: 3px solid var(--accent); border-radius: 0 10px 10px 0;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  font-size: 0.9rem; line-height: 1.5;
}
.desk-greet__acts { display: flex; flex-wrap: wrap; gap: 6px; }
.desk-greet__acts .btn { flex: none; width: auto; padding: 5px 11px; font-size: 0.82rem; }

/* Стол собирается на глазах: блоки всплывают один за другим. */
@media (prefers-reduced-motion: no-preference) {
  .desk--fresh > *, .desk--fresh .desk-col > * { animation: desk-in 0.4s cubic-bezier(0.2, 0.7, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 55ms); }
  .desk--fresh .desk-col > * { --i: 2; }
  @keyframes desk-in { from { opacity: 0; transform: translateY(10px); } }
}

/* Приветствие во всю ширину: это шапка стола, а не одна из плиток. */
.desk-hello {
  grid-column: 1 / -1;
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  align-items: center;
  gap: clamp(18px, 2.4vw, 28px);
  min-height: 0;
  padding: 20px 28px;
  overflow: hidden;
  border-radius: 24px;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--accent) 18%, var(--paper-card)),
    var(--paper-card) 58%, color-mix(in srgb, var(--paper-card) 90%, #f0b429));
  border: 1px solid var(--line);
}
.desk-hello:not(:has(.desk-board-mini)) {
  grid-template-columns: minmax(0, 1fr);
  min-height: 0;
}
.desk-hello--greeting-only { padding-block: 22px; }
.desk-hello::before {
  content: '';
  position: absolute;
  z-index: -1;
  width: 360px;
  height: 360px;
  right: 18%;
  top: -250px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.desk-hello__title {
  margin: 0;
  font-size: clamp(1.75rem, 2.8vw, 2.6rem);
  line-height: 1.15;
}

.desk-hello__line {
  margin: 12px 0 0;
  color: var(--ink-soft);
  font-size: 1.04rem;
  line-height: 1.55;
}

.desk-board-mini {
  min-width: 0;
  width: 280px;
  max-width: 100%;
  padding: 8px;
  border: 1px solid color-mix(in srgb, var(--line) 75%, var(--accent));
  border-radius: 17px;
  background: color-mix(in srgb, var(--paper-card) 94%, transparent);
  box-shadow: 0 18px 42px rgba(10, 36, 27, .15);
  transform: rotate(-.6deg);
  color: var(--ink);
  text-decoration: none;
  transition: transform 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
.desk-board-mini:hover,
.desk-board-mini:focus-visible {
  transform: rotate(0) translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 20px 46px rgba(10, 36, 27, .2);
  outline: none;
}
.desk-board-mini__visual {
  aspect-ratio: 16 / 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  overflow: hidden;
  border: 1px solid rgba(18, 59, 46, .14);
  border-radius: 13px;
  background: #fff;
  color: #123b2e;
  text-align: center;
}
.desk-board-mini__visual--saved { display: block; }
.desk-board-mini__image { display: block; width: 100%; height: 100%; object-fit: cover; }
.desk-board-mini__brand { color: #c8a227; font-size: .6rem; font-weight: 850; letter-spacing: .18em; }
.desk-board-mini__subject { color: rgba(18,59,46,.6); font-size: .68rem; font-weight: 700; }
.desk-board-mini__topic { max-width: 82%; font-size: clamp(1rem, 1.5vw, 1.25rem); line-height: 1.15; }
.desk-board-mini__teacher { color: rgba(18,59,46,.55); font-size: .62rem; }
.desk-board-mini__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 3px 1px; }
.desk-board-mini__foot strong { font-size: .76rem; }
.desk-board-mini__open { color: var(--accent); font-size: .7rem; font-weight: 750; white-space: nowrap; }

/* Погода — хвост приветственной фразы: «Добрый день, Максим — сегодня в
   Москве ясно, +16°». Отдельным блоком в углу она занимала место, которого
   не заслуживает: в кабинет приходят не за ней. */
.desk-hello__dash { color: var(--ink-soft); }
.desk-sky {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0; border: 0; background: none;
  color: var(--ink-soft); font: inherit; cursor: pointer;
  border-bottom: 1px dashed transparent;
}
.desk-sky:hover { color: var(--accent); border-bottom-color: color-mix(in srgb, var(--accent) 50%, transparent); }
.desk-sky__icon { font-size: 1.05em; line-height: 1; }

/* Старый блок погоды. Оставлен на случай, если понадобится вернуть. */
.desk-weather {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex: none;
  min-width: 116px;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--paper-card);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
  transition: border-color 140ms ease, transform 140ms ease;
}

.desk-weather:hover { border-color: var(--accent); transform: translateY(-1px); }
.desk-weather__icon { font-size: 2.3rem; line-height: 1; }
.desk-weather__body { display: grid; text-align: center; }
.desk-weather__temp { font-size: 1.7rem; font-weight: 800; line-height: 1.05; }
.desk-weather__where { font-size: 0.8rem; color: var(--ink-soft); }

/* ------------------------------- плитки --------------------------------- */

.desk-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--paper-card);
}

.desk-card__title {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.desk-card__links { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.desk-empty { margin: 0; color: var(--ink-soft); font-size: 0.93rem; }
.desk-note { margin: 0; font-size: 0.9rem; color: var(--ink-soft); }
.desk-note--ok { color: var(--accent); font-weight: 600; }
.desk-warn { margin: 0; font-size: 0.9rem; font-weight: 600; color: var(--danger); }

.desk-link {
  align-self: flex-start;
  margin-top: 2px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  border-bottom: 1.5px solid transparent;
}

.desk-link:hover { border-bottom-color: var(--accent); }

/* --------------------------- ближайший урок ------------------------------
   Самая крупная плитка у ребёнка: ради неё кабинет и открывают. */

.desk-card--lesson {
  grid-column: span 2;
  gap: 4px;
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--accent) 10%, var(--paper-card)), var(--paper-card) 70%);
}

.desk-lesson__subject { font-size: 1.5rem; font-weight: 800; line-height: 1.15; }
.desk-lesson__when { font-size: 1rem; }
.desk-lesson__until { font-size: 0.92rem; color: var(--accent); font-weight: 700; }
.desk-lesson__topic { margin-top: 6px; color: var(--ink-soft); }
.desk-lesson__who { font-size: 0.88rem; color: var(--ink-soft); }
.desk-lesson__go { align-self: flex-start; margin-top: 12px; }
.desk-lesson__cal { align-self: flex-start; margin-top: 10px; text-decoration: none; }

/* Значок календаря в ленте дня: мелкий и молчаливый, но на своём месте. */
.desk-day__cal {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  color: var(--ink-soft);
  border: 1px solid var(--line);
}

.desk-day__cal:hover { color: var(--accent); border-color: var(--accent); }

/* Доска открывается за пятнадцать минут до урока. Кнопка до этого видна, но
   не нажимается: пусть будет понятно, что вход будет здесь. */
.desk-lesson__go--wait {
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
}

/* ------------------------------ числа ------------------------------------ */

.desk-figures { display: flex; flex-wrap: wrap; gap: 22px; }
.desk-figure { display: grid; }
.desk-figure__value { font-size: 1.7rem; font-weight: 800; line-height: 1; }
.desk-figure__label { font-size: 0.8rem; color: var(--ink-soft); margin-top: 3px; }
.desk-figure--warn .desk-figure__value { color: var(--danger); }

/* ------------------------------ полоска ---------------------------------- */

.desk-bar { display: flex; align-items: center; gap: 12px; }

.desk-bar__line {
  flex: 1;
  height: 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 10%, transparent);
  overflow: hidden;
}

.desk-bar__fill {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  transition: width 300ms ease;
}

.desk-bar__fill--warn { background: var(--danger); }
.desk-bar__label { font-size: 0.85rem; font-weight: 700; color: var(--ink-soft); }

/* ------------------------------ ребёнок ---------------------------------- */

.desk-card--child .desk-card__title {
  text-transform: none;
  font-size: 1.05rem;
  letter-spacing: 0;
  color: var(--ink);
}

.desk-child__lesson { font-size: 0.98rem; }
.desk-child__when { color: var(--ink-soft); }

.desk-child__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  font-size: 0.9rem;
}

.desk-child__label { color: var(--ink-soft); }
.desk-child__value { font-weight: 600; text-align: right; }
.desk-child__value--warn { color: var(--danger); }

/* ------------------------------- день ------------------------------------ */

.desk-card--day { grid-column: span 2; }

.desk-day__row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
}

.desk-day__row:first-of-type { border-top: 0; }
.desk-day__row--past { opacity: 0.5; }
.desk-day__time { font-weight: 800; font-variant-numeric: tabular-nums; }
.desk-day__body { display: grid; flex: 1; min-width: 0; }
.desk-day__who { font-size: 0.83rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.desk-day__go { flex: none; }

/* ------------------------------ проверить -------------------------------- */

.desk-check__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-top: 1px solid var(--line);
  font-size: 0.92rem;
}

.desk-check__row:first-of-type { border-top: 0; }
.desk-check__who { font-weight: 600; }
.desk-check__what { color: var(--ink-soft); text-align: right; overflow-wrap: anywhere; }

/* Итог под списком: сколько осталось и сколько уже сделано. */
.desk-check__foot {
  margin: 8px 0 0;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* ------------------------------ ученики ---------------------------------- */

.desk-students {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 2px 18px;
}

/* Кружок держится имени.
   Раньше здесь стояло space-between, и у того, у кого нет ни долгов, ни
   предупреждений, имя уезжало к правому краю столбца, а кружок оставался
   у левого: между ними была пустая полоса в полколонки. Теперь кружок и имя
   стоят рядом, а метки — если они есть — прижимаются вправо сами.
   Черты между строками тоже нет: в несколько столбцов она шла у одних
   строк и не шла у других, и читалась как случайная линия поперёк блока. */
.desk-student {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: 0.92rem;
}

.desk-student__marks {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
  margin-left: auto;
}

.desk-tag {
  padding: 2px 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
  font-size: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
}

.desk-tag--warn { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.desk-tag--quiet { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink-soft); }

/* -------------------------------- школа ---------------------------------- */

.desk-card--school {
  grid-column: 1 / -1;
  border-color: color-mix(in srgb, var(--accent) 35%, var(--line));
}

/* Непрочитанное. Обведено, чтобы не потеряться среди спокойных плиток, но
   без красного: это новость, а не авария. */
/* Уведомление должно выходить за рамки спокойного стиля, иначе его не
   замечают: жёлтая рамка в два пикселя и жёлтый заголовок. */
.desk-card--news,
.desk-card--ask {
  border: 2px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, var(--paper-card));
}
.desk-card--news .desk-card__title,
.desk-card--ask .desk-card__title { color: var(--accent); }

.desk-news__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  border-top: 1px solid var(--line);
  font-size: 0.93rem;
}

.desk-news__row:first-of-type { border-top: 0; }
.desk-news__text { font-weight: 600; }
.desk-news__when { color: var(--ink-soft); flex: none; }

.desk-card--system {
  grid-column: 1 / -1;
  border-style: dashed;
}

/* ------------------------------- выбор города ----------------------------- */

.city-sheet {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(10, 38, 32, 0.55);
}

.city-sheet__box {
  display: grid;
  /* Заголовок, поиск, список, кнопка. Строке со списком нужно и растянуться,
     и сжаться: без 1fr он выпирал за низ окна вместе с кнопкой «Закрыть». */
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  gap: 12px;
  width: min(520px, 100%);
  max-height: 80vh;
  padding: 20px;
  border-radius: 16px;
  background: var(--paper-card);
  border: 1px solid var(--line);
}

.city-sheet__title { font-weight: 800; font-size: 1.05rem; }

.city-sheet__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  align-content: start;
  gap: 6px;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}

.city-sheet__city {
  padding: 9px 12px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.9rem;
  text-align: left;
  cursor: pointer;
}

.city-sheet__city:hover { border-color: var(--accent); color: var(--accent); }

/* Поиск. Городов почти полсотни, и набрать три буквы быстрее, чем искать
   глазами по трём колонкам. Список при этом остаётся: кто не хочет
   набирать — выбирает мышью. */
.city-sheet__search {
  width: 100%;
  padding: 11px 14px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
}

.city-sheet__search:focus { outline: none; border-color: var(--accent); }

.city-sheet__name { pointer-events: none; }

/* Подсвечен ровно тот кусок, который набрали: видно, почему город в списке. */
.city-sheet__mark {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  color: inherit;
  border-radius: 3px;
  padding: 0 1px;
  font-weight: 700;
}

/* Первый подходящий — тот, кого возьмёт ввод. */
.city-sheet__city--first {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.city-sheet__none {
  grid-column: 1 / -1;
  margin: 8px 2px;
  color: var(--ink-soft);
  font-size: 0.92rem;
}

.city-sheet__city[aria-current="true"] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

/* На телефоне плитки в одну колонку, и крупные перестают быть крупными. */
/* Планшет: шесть колонок. Широкие блоки во всю ширину, узкие — по два в ряд. */
@media (max-width: 1000px) {
  .desk { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .desk > *, .desk-w4, .desk-w5, .desk-w6 { grid-column: span 3 !important; }
  .desk-w7, .desk-w8, .desk-w12 { grid-column: span 6 !important; }
  .desk-trio { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Телефон: один столбец, порядок — по важности (--m ставит скрипт), а
   столбцы плиток рассыпаются, чтобы каждая встала на своё место. */
@media (max-width: 640px) {
  /* 1fr имеет скрытый минимум auto и расширял весь кабинет до ширины
     календаря (около 700 px). Нулевой минимум держит карточку в экране, а
     широкое содержимое прокручивается только в своей cal-wrap. */
  .desk { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .desk > * { grid-column: auto !important; order: var(--m, 50); }
  .desk-col { display: contents; }
  .desk-col > * { order: var(--m, 50); }
  .desk-trio { display: contents; }
  .desk-trio > * { order: var(--m, 50); }
  .desk-hello { padding: 18px; }
  /* На телефоне погода ложится в строку: квадрат в половину экрана ради
     двух цифр — расточительно. */
  .desk-weather { flex-direction: row; align-items: center; gap: 10px; padding: 10px 16px; }
  .desk-weather__icon { font-size: 1.7rem; }
  .desk-weather__temp { font-size: 1.25rem; }
  .desk-weather__body { text-align: left; }
  .desk-count { flex: 1 1 96px; }
}

/* ------------------------------- полоса статуса --------------------------- */

/* Приветствие. Было мелкими прописными — читалось как служебная пометка, а
   это первое, что человек видит, войдя. */
.desk-hello__hi { margin: 0 0 12px; font-size: clamp(1.02rem, 1.35vw, 1.28rem); font-weight: 700; color: var(--ink-soft); }
.desk-hello--greeting-only .desk-hello__hi { margin: 0; font-size: clamp(1.2rem, 2vw, 1.65rem); color: var(--ink); }
.desk-hello__text { flex: 1 1 340px; min-width: 0; }

/* Дела дня числами — в пустое место посередине полосы. Каждое нажимается. */
.desk-hello__counts { display: flex; flex-direction: row; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.desk-count {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 112px;
  padding: 10px 14px;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: color-mix(in srgb, var(--paper-card) 70%, transparent);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 140ms ease, transform 140ms ease;
}
.desk-count:hover { border-color: var(--accent); transform: translateY(-1px); }
.desk-count__value { font-size: 1.3rem; font-weight: 800; line-height: 1; }
.desk-count__label { font-size: .86rem; color: var(--ink-soft); max-width: 15em; }
@media (prefers-reduced-motion: no-preference) {
  /* Новое число всплывает: появление должно быть замечено, а не обнаружено. */
  .desk-count--in { animation: count-in 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  @keyframes count-in { from { opacity: 0; transform: translateY(8px) scale(0.94); } }
  /* Дело закрылось — число тает, а не пропадает рывком. */
  .desk-count--out { animation: count-out 0.5s ease forwards; pointer-events: none; }
  @keyframes count-out {
    30% { opacity: 1; }
    100% { opacity: 0; transform: translateY(-6px) scale(0.9); }
  }
}
.desk-count--warn { border-color: color-mix(in srgb, var(--accent) 60%, var(--line)); }
/* Без анимации ушедшее число просто не показываем. */
@media (prefers-reduced-motion: reduce) { .desk-count--out { display: none; } }
.desk-count--warn .desk-count__value { color: var(--accent); }
.desk-hello__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 14px; }
.desk-hello__actions .btn { width: auto; margin: 0; }
.desk-hello__go { padding: 12px 22px; font-size: 1.02rem; }
@media (prefers-reduced-motion: no-preference) {
  .desk-hello__go { animation: desk-pulse 2.2s ease-in-out infinite; }
  @keyframes desk-pulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
    50% { box-shadow: 0 0 0 9px color-mix(in srgb, var(--accent) 0%, transparent); }
  }
}
.desk-hello__side { width: auto; margin: 0; padding: 10px 16px; }
@media (max-width: 1120px) {
  .desk-hello { grid-template-columns: minmax(250px, 1fr) 260px; }
  .desk-board-mini { width: 260px; }
  .desk-hello__counts { grid-column: 1 / -1; flex-direction: row; }
}
@media (max-width: 720px) {
  .desk-hello { grid-template-columns: 1fr; min-height: 0; padding: 22px 18px; gap: 20px; }
  .desk-board-mini { transform: none; }
  .desk-hello__counts { grid-column: auto; }
}

@media (max-width: 620px) {
  .desk-hello { gap: 14px; }
  .desk-board-mini {
    width: 100%; padding: 0; transform: none; border: 0; box-shadow: none;
    background: transparent;
  }
  .desk-board-mini:hover, .desk-board-mini:focus-visible { transform: none; box-shadow: none; }
  .desk-board-mini__visual { display: none; }
  .desk-board-mini__foot {
    justify-content: center; min-height: 44px; padding: 10px 16px;
    border-radius: 13px; background: var(--accent); color: var(--ink-on-accent, #10251d);
  }
  .desk-board-mini__foot strong { display: none; }
  .desk-board-mini__open { color: inherit; font-size: .86rem; }
  .desk-hello__counts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .desk-count { min-width: 0; }
}

/* ----------------------- компактная повестка на Главном ---------------- */
.desk-card--agenda { gap: 16px; }
.agenda__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; }
.agenda__heading { min-width: 0; }
.agenda__heading .desk-card__title { margin: 0; }
.agenda__lead { margin: 5px 0 0; color: var(--ink-soft); font-size: .82rem; line-height: 1.45; }
.agenda__head-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.agenda__head-actions .btn { width: auto; margin: 0; white-space: nowrap; }
.agenda__body { display: grid; gap: 12px; }
.agenda__list { display: grid; gap: 15px; }
.agenda__day { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 7px 12px; align-items: start; }
.agenda__day-title {
  margin: 11px 0 0; color: var(--ink-soft);
  font-size: .76rem; font-weight: 750; text-transform: capitalize;
}
.agenda__lesson {
  grid-column: 2; display: grid; grid-template-columns: 54px minmax(0, 1fr) auto;
  align-items: center; gap: 12px; width: 100%; min-height: 54px; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 13px; background: var(--paper-soft);
  color: var(--ink); font: inherit; text-align: left; cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease, transform 140ms ease;
}
.agenda__lesson:hover { border-color: var(--accent); transform: translateY(-1px); }
.agenda__lesson--live { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, var(--paper-card)); }
.agenda__lesson--off { opacity: .58; }
.agenda__lesson--off .agenda__subject { text-decoration: line-through; }
.agenda__time { font-size: .86rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.agenda__copy { display: grid; gap: 2px; min-width: 0; }
.agenda__subject { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .93rem; }
.agenda__detail { overflow: hidden; color: var(--ink-soft); font-size: .76rem; text-overflow: ellipsis; white-space: nowrap; }
.agenda__state { color: var(--accent); font-size: .72rem; font-weight: 700; white-space: nowrap; }
.agenda__lesson--off .agenda__state { color: var(--ink-soft); }
.agenda__past { border-top: 1px solid var(--line); padding-top: 10px; color: var(--ink-soft); font-size: .8rem; }
.agenda__past summary { width: fit-content; cursor: pointer; }
.agenda__past-list { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; }
.agenda__past-lesson { padding: 7px 9px; border: 1px solid var(--line); border-radius: 10px; background: transparent; color: var(--ink-soft); font: inherit; font-size: .76rem; cursor: pointer; }

@media (max-width: 620px) {
  .agenda__head { display: grid; }
  .agenda__head-actions { justify-content: flex-start; }
  .agenda__day { grid-template-columns: 1fr; gap: 6px; }
  .agenda__day-title { grid-row: auto; margin: 3px 0; }
  .agenda__lesson { grid-column: 1; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 8px; }
  .agenda__state { grid-column: auto; }
}

/* ------------------------------- календарь по часам ----------------------
   Раньше уроки стояли в колонке дня друг за другом: загруженный день
   превращался в сжатый столбик, в котором не разобрать, что во сколько.
   Теперь слева часы, урок стоит на своём времени и занимает свою высоту —
   час занятия равен часу на сетке. Видно и когда урок, и сколько он идёт, и
   какие между ними окна. Все дни сохраняют одинаковую ширину. */

.desk-card--week .week__head { margin-top: -2px; }
/* Календарь не листается по вертикали.
   Сутки помещаются целиком: занятые часы полной высоты, пустые сжаты в
   узкие полосы. Вбок он ещё листается — на телефоне неделя шире экрана. */
.cal-wrap {
  overflow-x: auto;
  overflow-y: hidden;
  margin: 0 -4px;
  padding: 0 4px;
  overscroll-behavior-x: contain;
}
/* Шапка с днями не уезжает вверх при прокрутке: без неё непонятно, в
   каком дне стоит урок. */
.cal__corner, .cal__head {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--paper-card);
}
.cal {
  --cal-gutter: 52px;
  /* Высота всех суток разом — её считает js по шкале: занятый час держит
     свою высоту, а сутки сжимаются за счёт пустых часов, а не за счёт всех
     подряд. Здесь только запасное значение на случай пустой недели. */
  --cal-body: 560px;
  display: grid;
  grid-template-rows: auto auto;
  column-gap: 4px;
  min-width: 100%;
}
.cal--loading { opacity: 0.55; }

.cal__corner { grid-row: 1; }
.cal__head {
  grid-row: 1;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 5px;
  padding: 2px 0 8px;
  border-bottom: 1px solid var(--line);
}
.cal__dow { font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft); }
.cal__date { font-weight: 800; }
.cal__head--today { border-bottom-color: var(--accent); }
.cal__head--today .cal__date { color: var(--accent); }
.cal__head--empty { opacity: 0.5; }
.cal__head--empty { font-size: 0.9em; }

.cal__hours {
  grid-row: 2;
  display: flex;
  flex-direction: column;
  height: var(--cal-body);
}
/* Полоса шкалы: либо несколько часов подряд по строке на каждый, либо
   сжатый промежуток, подписанный одной строкой. */
.cal__seg { display: flex; flex-direction: column; flex-basis: 0; min-height: 0; }
.cal__seg-hour { flex: 1 1 0; min-height: 0; }
.cal__seg--idle {
  justify-content: center;
  align-items: flex-end;
  overflow: hidden;
}
.cal__hour {
  display: block;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  text-align: right;
  padding-right: 8px;
  transform: translateY(-0.55em);
}
/* Сжатые часы: подписаны промежутком и стоят по центру своей полосы —
   сдвигать их вверх, как часовые отметки, некуда. */
.cal__hour--idle {
  font-size: 0.62rem;
  opacity: 0.55;
  transform: none;
  letter-spacing: -0.01em;
}

/* Сетка — одним слоем поверх всей ширины, под колонками дней. Так линии
   идут через всю неделю, а не обрываются на границе каждой колонки. */
.cal__lines {
  grid-row: 2;
  grid-column: 2 / -1;
  position: relative;
  height: var(--cal-body);
  z-index: 0;
  pointer-events: none;
}
.cal__line {
  position: absolute;
  left: 0; right: 0;
  height: 1px;
  background: var(--line);
}
/* Граница сжатого промежутка — тем же цветом, но тоньше по смыслу: за ней
   не следующий час, а несколько часов сразу. */
.cal__line--soft { background: color-mix(in srgb, var(--line) 60%, transparent); }

.cal__col {
  grid-row: 2;
  position: relative;
  z-index: 1;
  height: var(--cal-body);
  border-left: 1px solid var(--line);
}
.cal__col--off { background-color: color-mix(in srgb, var(--ink) 3%, transparent); }
.cal__col--today { background-color: color-mix(in srgb, var(--accent) 6%, transparent); }

.cal__ev {
  position: absolute;
  left: 0;
  right: 3px;
  box-sizing: border-box;
  display: grid;
  gap: 1px;
  align-content: start;
  min-height: 38px;
  overflow: hidden;
  padding: 5px 8px;
  border: 0;
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 16%, var(--paper-card));
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  z-index: 1;
  transition: filter 140ms ease;
}
.cal__ev:hover { filter: brightness(1.06); }

/* Низкая плашка — только время и предмет. Вторая строка в ней всё равно
   обрезалась бы на полуслове, а «7Б» пополам хуже, чем «7Б» в подсказке. */
/* Несколько уроков в один час — одной плашкой. Список — при наведении. */
.cal__ev--many { border-left-style: double; border-left-width: 5px; }
.cal__ev--many:hover, .cal__ev--many:focus-visible { overflow: visible; z-index: 5; }
.cal__pop {
  display: none;
  position: absolute;
  left: 0;
  top: calc(100% + 4px);
  z-index: 6;
  min-width: 230px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--paper-card);
  box-shadow: var(--shadow-tight);
  color: var(--ink);
  font-weight: 400;
  text-align: left;
  white-space: nowrap;
}
.cal__ev--many:hover .cal__pop, .cal__ev--many:focus-visible .cal__pop { display: grid; gap: 4px; }
.cal__pop-title { font-size: 0.74rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); }
.cal__pop-row { font-size: 0.84rem; }
/* Последний день недели: список выезжал бы за правый край карточки. */
.cal__col:nth-last-child(-n+2) .cal__pop { left: auto; right: 0; }

/* Низкая плашка: время и предмет встают рядом — второй строки в ней нет. */
.cal__ev--short {
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  column-gap: 6px;
  gap: 0;
  padding: 3px 8px;
}
.cal__ev--short .cal__ev-what {
  display: block;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.cal__ev--short .cal__ev-who,
.cal__ev--short .cal__ev-topic,
.cal__ev--short .cal__ev-mark { display: none; }
/* Три строки, каждая во всю ширину плашки. Раньше время и предмет делили
   одну, и на предмет в колонке дня оставалось полтора сантиметра:
   «Английский язык» читался как «Англи…». */
.cal__ev-time {
  font-size: 0.7rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  opacity: 0.8;
  line-height: 1.15;
}
/* Предмет — до двух строк, но только целыми словами. Слово шире плашки
   переносить некуда: раньше оно ломалось посреди буквы — «Мате / мат».
   Такое js помечает классом --one, и слово обрезается многоточием. */
.cal__ev-what {
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.18;
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow-wrap: normal;
  word-break: normal;
}
.cal__ev-what--one {
  display: block;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.cal__ev-who { font-size: 0.76rem; font-weight: 600; line-height: 1.15; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: 10px; }
.cal__ev-topic { font-size: 0.76rem; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal__ev-mark { font-size: 0.72rem; font-weight: 700; }
.cal__ev-mark--ask { color: var(--danger); }
.cal__ev-mark--todo { color: var(--ink-soft); }

/* Пометка у короткого урока — точка в углу и цвет полосы слева. Словами она
   не помещается: в часовой ячейке три строки, и они заняты временем,
   предметом и именем ученика. Имя важнее. */
.cal__ev--ask { border-left-color: var(--danger); }
.cal__ev--todo { border-left-color: var(--ink-soft); }
.cal__ev-dot {
  position: absolute;
  top: 5px; right: 5px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ink-soft);
}
.cal__ev--ask .cal__ev-dot { background: var(--danger); }
@media (prefers-reduced-motion: no-preference) {
  .cal__ev--ask .cal__ev-dot { animation: ev-dot 2s ease-in-out infinite; }
  @keyframes ev-dot {
    0%, 100% { box-shadow: 0 0 0 0 rgba(193, 18, 31, 0.5); }
    50% { box-shadow: 0 0 0 5px rgba(193, 18, 31, 0); }
  }
}
.cal__ev--done { border-left-color: var(--ink-soft); background: color-mix(in srgb, var(--ink) 7%, var(--paper-card)); }
/* Замена. «Математика в 15:00» ничем не отличается от обычной, а идёт к ней
   другой человек — и узнать об этом на пороге худший способ узнать. */
.cal__ev--swap {
  border-left-color: #6F5AA8;
  background: color-mix(in srgb, #6F5AA8 16%, var(--paper-card));
}
.cal__ev--off { border-left-color: var(--line); opacity: 0.55; }
.cal__ev--off .cal__ev-what { text-decoration: line-through; }
.cal__ev--live { box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent); }
/* Дети родителя — своим цветом каждый. */
.cal__ev--k1 { border-left-color: #d98e04; background: color-mix(in srgb, #d98e04 14%, var(--paper-card)); }
.cal__ev--k2 { border-left-color: #2f6fed; background: color-mix(in srgb, #2f6fed 14%, var(--paper-card)); }
.cal__ev--k3 { border-left-color: #b23a8f; background: color-mix(in srgb, #b23a8f 14%, var(--paper-card)); }

/* Отчёты прошлых уроков — под стрелкой, раскрываются на месте. */
.hist__toggle {
  justify-self: start;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0; border: 0; background: none;
  color: var(--accent); font: inherit; font-size: 0.88rem; font-weight: 600; cursor: pointer;
}
.hist__chevron { font-size: 1.1em; line-height: 1; transition: transform 180ms ease; }
.hist__toggle[aria-expanded='true'] .hist__chevron { transform: rotate(180deg); }
@media (prefers-reduced-motion: no-preference) {
  .hist__report:not([hidden]) { animation: desk-in 0.28s ease both; }
}
.hist__board { justify-self: start; width: auto; margin-top: 8px; text-decoration: none; white-space: nowrap; }

/* Названное, но не принятое время. Пока обе стороны ждут ответа, этого часа
   в календаре не было вовсе: человек смотрел на пустую неделю и ставил туда
   другой урок, забыв, что сам же предложил это окно. */
.cal__hatch {
  position: absolute;
  left: 2px;
  right: 3px;
  z-index: 0;
  border-radius: 8px;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 60%, transparent);
  background: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, var(--accent) 14%, transparent) 0 6px,
    transparent 6px 12px
  );
  pointer-events: none;
}

.cal__now { position: absolute; left: 0; right: 0; height: 2px; background: #e5484d; z-index: 2; pointer-events: none; }
.cal__now::before {
  content: ''; position: absolute; left: -4px; top: -3px;
  width: 8px; height: 8px; border-radius: 50%; background: #e5484d;
}

@media (max-width: 900px) {
  .cal { --cal-gutter: 44px; min-width: 660px; }
}

/* ------------------------------- лента дня -------------------------------- */

.tl { display: grid; }
.tl__row {
  display: grid;
  grid-template-columns: 4.2em 18px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  position: relative;
}
.tl__row::before {
  content: ''; position: absolute; left: calc(4.2em + 10px + 8px); top: 0; bottom: 0;
  width: 2px; background: var(--line);
}
.tl__row:first-child::before { top: 50%; }
.tl__row:last-child::before { bottom: 50%; }
.tl__row--past { opacity: 0.5; }
.tl__time { display: grid; font-variant-numeric: tabular-nums; line-height: 1.15; }
.tl__time-end { font-size: 0.75rem; color: var(--ink-soft); }
.tl__dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--paper-card); border: 2.5px solid var(--ink-soft);
  position: relative; z-index: 1; justify-self: center;
}
.tl__row--next .tl__dot { border-color: var(--accent); }
.tl__row--live .tl__dot { background: var(--accent); border-color: var(--accent); }
@media (prefers-reduced-motion: no-preference) {
  .tl__row--live .tl__dot { animation: tl-blink 1.6s ease-in-out infinite; }
  @keyframes tl-blink {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent); }
    50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 0%, transparent); }
  }
}
.tl__body {
  display: grid; gap: 2px; min-width: 0;
  padding: 8px 12px; border: 0; border-radius: 10px;
  background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer;
}
.tl__body:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); }
.tl__row--live .tl__body { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.tl__what { font-size: 1rem; }
.tl__who { font-size: 0.85rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.tl__state { font-size: 0.8rem; color: var(--ink-soft); }
.tl__state--live { color: var(--accent); font-weight: 700; }
.tl__acts { display: flex; align-items: center; gap: 8px; }
.tl__acts .btn { width: auto; margin: 0; }
.tl__gap {
  display: grid; grid-template-columns: 4.2em 18px 1fr; gap: 10px; align-items: center;
  padding: 2px 0; position: relative;
}
.tl__gap::before {
  content: ''; position: absolute; left: calc(4.2em + 10px + 8px); top: 0; bottom: 0;
  width: 2px; background: repeating-linear-gradient(180deg, var(--line) 0 4px, transparent 4px 8px);
}
.tl__gap-text { grid-column: 3; font-size: 0.8rem; color: var(--ink-soft); padding-left: 12px; font-style: italic; }
/* В узкой колонке справа кнопки не помещаются рядом — уходят под урок. */
.desk-w4 .tl__row { grid-template-columns: 3.4em 14px minmax(0, 1fr) auto; }
.desk-w4 .tl__row::before, .desk-w4 .tl__gap::before { left: calc(3.4em + 10px + 6px); }
.desk-w4 .tl__acts { display: contents; }
.desk-w4 .tl__go { grid-column: 3; grid-row: 2; justify-self: start; margin: 0 0 0 12px !important; }
.desk-w4 .desk-day__cal { grid-column: 4; grid-row: 1; }
.desk-w4 .tl__gap { grid-template-columns: 3.4em 14px 1fr; }

@media (max-width: 560px) {
  .tl__row { grid-template-columns: 3.4em 14px minmax(0, 1fr) auto; }
  .tl__row::before, .tl__gap::before { left: calc(3.4em + 10px + 6px); }
  .tl__acts { display: contents; }
  .tl__go { grid-column: 3; grid-row: 2; justify-self: start; margin: 0 0 0 12px !important; }
  .desk-day__cal { grid-column: 4; grid-row: 1; }
  .tl__gap { grid-template-columns: 3.4em 14px 1fr; }
}

/* ------------------------------- домашка на столе ------------------------- */

.desk-hw { display: grid; gap: 8px; padding-top: 12px; border-top: 1px solid var(--line); }
.desk-hw:first-of-type { border-top: 0; padding-top: 0; }
/* Заголовок задания — кнопка: пункты под ним раскрываются и сворачиваются.
   Развёрнутыми три задания по четыре пункта занимали весь стол, и неделя с
   конспектами уезжали под них. */
.desk-hw__head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.desk-hw__head::after {
  content: '';
  width: 6px;
  height: 6px;
  margin-left: auto;
  border-right: 2px solid var(--ink-soft);
  border-bottom: 2px solid var(--ink-soft);
  transform: rotate(45deg);
  transition: transform 160ms ease;
}
.desk-hw__head[aria-expanded='true']::after { transform: rotate(-135deg); }
.desk-hw--folded .desk-hw__items { display: none; }
.desk-hw__title { font-size: 1rem; }
.desk-hw__due { font-size: 0.82rem; color: var(--ink-soft); }
.desk-hw__due--late { color: var(--danger); font-weight: 700; }
.desk-hw__items { display: grid; gap: 4px; }
.desk-hw .hw-item { width: 100%; }
.desk-hw__done { margin-top: 4px; }
@media (prefers-reduced-motion: no-preference) {
  .hw-item__box--pop { animation: hw-pop 0.35s cubic-bezier(0.34, 1.56, 0.64, 1); }
  @keyframes hw-pop { 0% { transform: scale(0.6); } 100% { transform: scale(1); } }
}

/* ------------------------------- лента отчётов ---------------------------- */

.feed { display: grid; gap: 6px; padding: 12px 0; border-top: 1px solid var(--line); }
.feed:first-of-type { border-top: 0; padding-top: 0; }
.feed__head { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.feed__who { font-weight: 700; }
.feed__when { font-size: 0.82rem; color: var(--ink-soft); flex: none; }
.feed__topic { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
.feed__prose { margin: 0; line-height: 1.5; }
.feed__more {
  justify-self: start; padding: 0; border: 0; background: none;
  color: var(--accent); font: inherit; font-size: 0.85rem; font-weight: 600; cursor: pointer;
  border-bottom: 1px dashed color-mix(in srgb, var(--accent) 50%, transparent);
}
.feed__points { margin-top: 4px; }
@media (prefers-reduced-motion: no-preference) {
  .feed__points:not([hidden]) { animation: desk-in 0.3s ease both; }
}

/* ------------------------------- оплата, цифры ---------------------------- */

.desk-pay { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; padding: 8px 0; border-top: 1px solid var(--line); }
.desk-pay:first-of-type { border-top: 0; padding-top: 0; }
.desk-pay__left { font-weight: 700; text-align: right; }
.desk-pay__until { grid-column: 1 / -1; font-size: 0.85rem; color: var(--ink-soft); }

/* Школа целиком — строкой под приветствием. Не крупно: Максим прежде всего
   преподаватель, а директор он между уроками. */
.desk-card--numbers { padding: 10px 18px; border-style: dashed; }
.desk-numbers { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 18px; }
.desk-numbers__label {
  font-size: 0.74rem; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-soft);
}
.desk-num {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 2px 0; border: 0; background: none;
  color: var(--ink-soft); font: inherit; font-size: 0.88rem; cursor: pointer;
}
.desk-num b { font-size: 1.05rem; font-weight: 800; color: var(--ink); }
.desk-num:hover b, .desk-num:hover { color: var(--accent); }
.desk-num--warn b { color: var(--danger); }
.desk-card--school, .desk-card--news, .desk-card--system { grid-column: auto; }
.desk-child__row .desk-bar { flex: 1; margin-left: 12px; }

/* ============================ ПРОФИЛЬ =====================================
   Наверху была строка из трёх вещей: имя, должность и «Выйти». Имя с
   должностью человек и так про себя знает, а «Выйти» нажимают раз в месяц —
   втроём они занимали всю верхнюю полосу. Осталась одна картинка, и за ней
   всё про самого человека. */

/* Песочной полосы под шапкой больше нет: она держала одну кнопку профиля и
   съедала целую линию экрана. Кнопка переехала в шапку сайта, к названию
   школы. */

.avatar-button {
  padding: 0;
  border: 0;
  background: none;
  border-radius: 50%;
  cursor: pointer;
  line-height: 0;
  transition: transform 140ms ease;
}

.avatar-button:hover { transform: scale(1.06); }

.avatar-button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* Рамка вокруг своей картинки — косметика, купленная за кубики в «Практике».
   Только своей: в списках людей кружков много, и обводка там означала бы
   что-то другое. Поэтому селекторы перечислены поимённо — шапка, профиль и
   строка «Ваш профиль» в настройках. */
html[data-practice-frame] #who-avatar,
html[data-practice-frame] .profile-head .avatar--big,
html[data-practice-frame] .settings-identity__avatar {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22), 0 0 0 3px var(--frame, #f0b429);
}
html[data-practice-frame='frame-wood'] { --frame: #b9650f; }
html[data-practice-frame='frame-sea'] { --frame: #4f86c0; }
html[data-practice-frame='frame-leaf'] { --frame: #227354; }
html[data-practice-frame='frame-gold'] { --frame: #f0b429; }

/* Картинка профиля. Пока это цвет с инициалами: настоящие знаки ещё будут
   нарисованы, и встанут они сюда же, под теми же именами. */
.avatar {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--tint, #1F7A5A);
  color: #fff;
  font-size: 0.86rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22);
}

.avatar--big {
  width: 60px;
  height: 60px;
  font-size: 1.25rem;
}

.avatar-art {
  display: block;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  object-fit: contain;
  border-radius: 50%;
  pointer-events: none;
}

/* ------------------------------- панель ---------------------------------- */

.drawer {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: flex;
  justify-content: flex-end;
  background: rgba(10, 38, 32, 0.5);
}

.drawer__box {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  width: min(420px, 100%);
  height: 100%;
  background: var(--paper-card);
  border-left: 1px solid var(--line);
  box-shadow: -18px 0 44px rgba(10, 38, 32, 0.22);
  animation: drawer-in 200ms ease-out;
}

@keyframes drawer-in {
  from { transform: translateX(28px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .drawer__box { animation: none; }
}

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  font-weight: 800;
}

.drawer__body {
  display: grid;
  gap: 22px;
  align-content: start;
  padding: 20px;
  overflow-y: auto;
}

.drawer__foot {
  padding: 14px 20px;
  border-top: 1px solid var(--line);
}

.profile-out { width: 100%; transition: background 140ms ease, border-color 140ms ease; }

/* Переспрашиваем в самой кнопке: нажал не туда — она спросила, а не вышла. */
.profile-out--sure {
  border-color: var(--danger);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: var(--danger);
  font-weight: 700;
}

/* ------------------------------- содержимое ------------------------------ */

.profile-head { display: flex; align-items: center; gap: 14px; }

/* По своей картинке нажимают, чтобы раскрыть набор — значит она должна
   выглядеть нажимаемой. */
.profile-head--pick .avatar--big { cursor: pointer; }
.profile-head--pick .avatar--big:hover { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent); }
.profile-head--pick .avatar--big:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.profile-head__name { display: block; font-size: 1.1rem; }
.profile-head__role { font-size: 0.85rem; color: var(--ink-soft); }

.profile-block { display: grid; gap: 8px; }

.profile-block__title {
  margin: 0;
  font-size: 0.76rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.profile-value { margin: 0; font-weight: 600; }
.profile-note { margin: 0; color: var(--ink-soft); font-size: 0.92rem; }

.profile-hint {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.82rem;
  line-height: 1.4;
}

.profile-form { display: grid; gap: 10px; }

.profile-field { display: grid; gap: 4px; margin: 0; }

.profile-field span {
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.profile-field input {
  width: 100%;
  padding: 9px 12px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
}

.profile-field input:focus { outline: none; border-color: var(--accent); }

.profile-form .btn { justify-self: start; }

.profile-buttons { display: flex; gap: 8px; flex-wrap: wrap; }

/* Ссылка на бота. Появляется под включённым каналом: пока канал выключен,
   идти никуда не надо. */
.profile-bot {
  display: block;
  margin: -2px 0 4px;
  padding: 7px 11px;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 45%, var(--line));
  border-radius: 10px;
  color: var(--accent);
  font-size: 0.83rem;
  font-weight: 600;
  text-decoration: none;
}

.profile-bot:hover { border-style: solid; background: color-mix(in srgb, var(--accent) 8%, transparent); }

.profile-feed { display: grid; gap: 5px; }

.profile-feed__label {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink-soft);
}

.profile-feed__line { display: flex; gap: 8px; align-items: center; }
.profile-feed__line .profile-link { flex: 1; min-width: 0; }
.profile-feed__line .btn { flex: none; }

/* Ссылка на подписку. Читать её не надо, надо скопировать — поэтому поле
   мелкое, моноширинное и выделяется одним нажатием. */
.profile-link {
  width: 100%;
  padding: 8px 10px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  color: var(--ink-soft);
  font-family: "JetBrains Mono", Consolas, monospace;
  font-size: 0.76rem;
}

/* --------------------------------- цвета --------------------------------- */

.profile-tints {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: color-mix(in srgb, var(--ink) 3%, transparent);
  animation: tints-in 160ms ease-out;
}

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

@media (prefers-reduced-motion: reduce) {
  .profile-tints { animation: none; }
}

.profile-tint {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 50%;
  background: var(--tint);
  color: #fff;
  font: inherit;
  font-size: 0.72rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22);
  transition: transform 120ms ease;
}

.profile-tint:hover { transform: scale(1.1); }

.profile-tint[aria-pressed="true"] {
  border-color: var(--paper-card);
  box-shadow: 0 0 0 2px var(--tint), inset 0 0 0 1px rgba(255, 255, 255, 0.22);
}

.profile-tint:has(.avatar-art) { background: transparent; box-shadow: none; }
.profile-tint:has(.avatar-art)[aria-pressed="true"] { box-shadow: 0 0 0 2px #F0B429; }

/* ----------------------------- переключатели ------------------------------ */

.profile-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-top: 1px solid var(--line);
  font-size: 0.95rem;
}

.profile-toggle:first-of-type { border-top: 0; }

.switch {
  position: relative;
  flex: none;
  width: 44px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 18%, transparent);
  cursor: pointer;
  transition: background 160ms ease;
}

.switch::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
  transition: transform 160ms ease;
}

.switch[aria-checked="true"] { background: var(--accent); }
.switch[aria-checked="true"]::after { transform: translateX(18px); }

.switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

@media (max-width: 520px) {
  .drawer__box { width: 100%; }
  .profile-tints { grid-template-columns: repeat(4, 1fr); }
}

/* ============================ ТЕЛЕФОН =====================================
   Кабинет писался под ноутбук, а открывают его с телефона: ребёнок смотрит
   домашку по дороге, родитель — расписание из очереди. Здесь то, что на
   узком экране ломалось: обрезанные вкладки, кнопка поверх названия урока,
   поля, от которых iPhone сам увеличивал страницу. */

/* Вкладок четыре, и на 375 px они не помещаются: ряд прокручивается вбок,
   а выбранная сама подъезжает в кадр (js/schedule.js). Полоса прокрутки
   спрятана: это пилюля, а не таблица. */
.tabs--nav {
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
.tabs--nav::-webkit-scrollbar { display: none; }
.tabs--nav button { flex: 1 0 auto; scroll-snap-align: center; }

@media (max-width: 560px) {
  .tabs--nav { max-width: none; margin: 16px 0 4px; }
  .tabs--nav button { font-size: 0.85rem; padding: 9px 12px; }
  .container { padding: 0 16px; }
}

/* Строка урока на столе: название сжималось до нуля, и кнопка «Открыть
   доску» ложилась прямо на слово «Математика». Название переносится,
   а на совсем узком экране кнопка уходит под строку — во всю ширину,
   под большой палец. */
.desk-day__body > * { min-width: 0; overflow-wrap: anywhere; }

@media (max-width: 480px) {
  .desk-day__row { flex-wrap: wrap; gap: 10px 14px; }
  .desk-day__go { flex: 1 1 100%; text-align: center; }
  .desk-hello { padding: 16px; }
  .desk-hello__text { min-width: 0; }
  .desk-hello__title { overflow-wrap: anywhere; }
}

/* Поле ввода мельче 16 px iPhone считает нечитаемым и увеличивает всю
   страницу при нажатии — а обратно не уменьшает. Логин и пароль вводят
   с телефона чаще всего, поэтому на нём поля ровно 16 px. */
@media (max-width: 760px) {
  input, select, textarea { font-size: 16px; }
}

/* Вырезы и «чёлки»: у телефона с закруглённым экраном края экрана заняты, и
   без этих отступов кнопка выхода внизу ящика попадает под полосу жестов. */
.drawer__foot { padding-bottom: max(14px, env(safe-area-inset-bottom)); }
.site-header .header-inner {
  padding-left: max(24px, env(safe-area-inset-left));
  padding-right: max(24px, env(safe-area-inset-right));
}
@media (max-width: 560px) {
  .site-header .header-inner {
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
  }
}

/* Канал уведомлений: не переключатель, а состояние — «подключён как …»
   или кнопка «подключить». Telegram подключается рукопожатием через бота,
   и переключатель тут врал бы: включить его можно, а писать всё равно
   некуда. */
.profile-channel {
  display: grid;
  gap: 8px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.profile-channel:first-of-type { border-top: 0; }
.profile-channel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-weight: 600;
}
.profile-channel__state { font-size: 0.82rem; font-weight: 600; color: var(--ink-soft); }
.profile-channel__state--on { color: var(--accent); }
.profile-code { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
.profile-code code {
  padding: 2px 7px;
  border-radius: 6px;
  background: var(--paper-soft);
  color: var(--ink);
  font-weight: 700;
  letter-spacing: 0.06em;
  user-select: all;
}

/* ============================ ИТОГ УРОКА ==================================
   Две фразы преподавателя после урока — то, что родитель спросил бы сам. */
.lesson__summary {
  margin: 8px 0 0;
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  border-radius: 0 8px 8px 0;
  font-size: 0.92rem;
  line-height: 1.45;
}
.lesson__summary-edit {
  margin-top: 6px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  border-bottom: 1px dashed color-mix(in srgb, var(--accent) 50%, transparent);
}
.summary-form { display: grid; gap: 8px; margin-top: 8px; }
.summary-form textarea { margin: 0; resize: vertical; }
.summary-form__row { display: flex; gap: 8px; flex-wrap: wrap; }

/* ============================ ПУТЬ И КОНСПЕКТЫ ============================ */
.desk-note-row {
  display: flex;
  gap: 12px;
  align-items: baseline;
  padding: 8px 0;
  border-top: 1px solid var(--line);
  color: var(--ink);
  text-decoration: none;
}
.desk-note-row:first-of-type { border-top: 0; }
.desk-note-row:hover .desk-note-row__what { color: var(--accent); }
.desk-note-row__when { flex: none; font-size: 0.82rem; color: var(--ink-soft); min-width: 5.5em; }
.desk-note-row__what { font-weight: 600; }

/* Конспекты по предметам: ищут здесь всегда по предмету — «где у меня было
   про причастия», — а дата нужна уже внутри. */
.desk-notes__group { margin-top: 12px; }
.desk-notes__group:first-of-type { margin-top: 2px; }
.desk-notes__subject {
  display: block;
  margin-bottom: 2px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.desk-notes__group .desk-note-row:first-of-type { border-top: 0; }

/* ---------------------------- архив домашек ------------------------------ */

.desk-arch {
  display: grid;
  gap: 6px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.desk-arch:first-of-type { border-top: 0; padding-top: 2px; }
.desk-arch__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.desk-arch__what { font-size: 0.95rem; }
.desk-arch__when { font-size: 0.8rem; color: var(--ink-soft); white-space: nowrap; }
.desk-arch__marks { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.desk-arch__note { margin: 0; font-size: 0.86rem; color: var(--ink-soft); }

/* -------------------------------- серия ---------------------------------- */

/* Смысл здесь один: не оборвать цепочку. Цепочку и показываем — точками, по
   одной на домашку, чтобы пробел было видно взглядом. */
.streak { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.streak__flame { font-size: 1.4rem; line-height: 1; }
.streak__count { font-size: 1.8rem; font-weight: 800; line-height: 1; }
.streak__word { font-size: 0.86rem; color: var(--ink-soft); }
.streak__beads { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 10px; }
.streak__bead {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 14%, transparent);
}
.streak__bead--on { background: var(--accent); }
.streak__foot { margin: 10px 0 0; font-size: 0.8rem; color: var(--ink-soft); }

/* Строка ученика на столе преподавателя — кнопка: ведёт на его страницу. */
button.desk-student {
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
button.desk-student:hover .desk-student__name { color: var(--accent); }

.person__name--link {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
.person__name--link:hover { color: var(--accent); }

/* ============================ СТРАНИЦА УЧЕНИКА ============================
   История, а не карточка: уроки с темами и итогами, домашка, путь. */
.student-page { display: grid; gap: 18px; margin-top: 8px; }
.student-page__back {
  justify-self: start;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}
.student-page__back:hover { color: var(--accent); }
.student-head { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.student-head h1 { margin: 0; font-size: clamp(1.4rem, 3vw, 1.9rem); }
.student-head__meta { color: var(--ink-soft); font-size: 0.92rem; }
.student-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  align-items: start;
}
.student-grid .desk-card--history { grid-column: 1 / -1; }
.hist { display: grid; gap: 0; }
.hist__row {
  display: grid;
  grid-template-columns: 6.5em 1fr auto;
  gap: 6px 14px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
  align-items: baseline;
}
.hist__row:first-child { border-top: 0; }
.hist__row--off { opacity: 0.55; }
.hist__when { font-size: 0.85rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.hist__what { font-weight: 600; }
.hist__status { font-size: 0.8rem; color: var(--ink-soft); white-space: nowrap; }
.hist__status--done { color: var(--accent); }
.hist__status--warn { color: var(--danger); }
.hist__summary {
  grid-column: 2 / -1;
  margin: 0;
  font-size: 0.9rem;
  color: var(--ink);
  padding-left: 10px;
  border-left: 2px solid color-mix(in srgb, var(--accent) 50%, transparent);
}
.hw-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}
.hw-row:first-child { border-top: 0; }
.hw-row__title { font-weight: 600; }
.hw-row__mark { font-size: 0.82rem; color: var(--ink-soft); white-space: nowrap; }
.hw-row__mark--ok { color: var(--accent); }
.hw-row__mark--warn { color: var(--danger); }
.hw-row__note { grid-column: 1 / -1; margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
@media (max-width: 480px) {
  .hist__row { grid-template-columns: 1fr auto; }
  .hist__when { grid-column: 1 / -1; }
  .hist__summary, .hist__board { grid-column: 1 / -1; }
}

/* ============================ ПРОСЬБЫ И СЕРИИ ============================= */
.ask-form { display: grid; gap: 8px; margin-top: 8px; }
.ask-form__kinds { display: flex; gap: 8px; flex-wrap: wrap; }
.ask-form textarea { margin: 0; resize: vertical; }
.ask-form__row { display: flex; gap: 8px; flex-wrap: wrap; }
.lesson__asked {
  margin: 8px 0 0;
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.desk-ask__row {
  display: grid;
  gap: 4px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
}
.desk-ask__row:first-of-type { border-top: 0; }
.desk-ask__head { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.desk-ask__who { font-weight: 600; }
.desk-ask__what { font-size: 0.85rem; color: var(--ink-soft); }
.desk-ask__note { margin: 0; font-size: 0.92rem; }
.desk-ask__row .desk-link { justify-self: start; }
.lesson__series { font-size: 0.8rem; color: var(--ink-soft); margin-left: 6px; }

/* ============================ НИЖНЯЯ НАВИГАЦИЯ ============================
   На ноутбуке вкладки — пилюля под шапкой, значки спрятаны. На телефоне
   та же пилюля уезжает вниз, под большой палец, и значки появляются:
   так устроено каждое приложение, к которому привыкла рука. */
.tabs--nav button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.tabs--nav button svg { display: none; flex: none; }

/* Точка на вкладке: есть непроверенные работы. Сколько именно — знать
   незачем, как и у колокольчика: важно только «туда стоит зайти». */
.tabs--nav button { position: relative; }
.tabs__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--danger, #c0392b);
  flex: none;
}

@media (max-width: 640px) {
  .tabs--nav {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 60;
    margin: 0;
    max-width: none;
    padding: 6px max(10px, env(safe-area-inset-left)) max(6px, env(safe-area-inset-bottom)) max(10px, env(safe-area-inset-right));
    border-radius: 0;
    border-top: 1px solid var(--line);
    background: var(--paper-card);
    box-shadow: 0 -8px 24px rgba(10, 38, 32, 0.10);
    overflow: visible;
    gap: 4px;
  }
  .tabs--nav button {
    flex: 1 1 0;
    flex-direction: column;
    gap: 2px;
    padding: 6px 4px 4px;
    font-size: 0.72rem;
    font-weight: 600;
    border-radius: 12px;
    min-height: 52px;
  }
  .tabs--nav button svg { display: block; }
  .tabs--nav button[aria-selected='true'] { box-shadow: none; background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); }

  /* Место под полосу — иначе она накрывает последнюю карточку и кнопку
     выхода в ящике профиля. */
  #signed-in:not([hidden]) ~ .site-footer,
  .lk-main:has(#signed-in:not([hidden])) { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
  .drawer__foot { padding-bottom: max(14px, calc(env(safe-area-inset-bottom) + 6px)); }
}

/* ============================ НЕДЕЛЯ СЕТКОЙ =============================== */
.section-head__tools { display: flex; align-items: center; gap: 10px; }
.week-toggle {
  display: none;
  height: 34px;
  padding: 0 12px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
}
.week-toggle[aria-pressed='true'] { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
@media (min-width: 900px) { .week-toggle { display: inline-flex; align-items: center; } }

.week { display: grid; gap: 12px; margin-top: 12px; }
.week__head { display: flex; align-items: center; gap: 10px; }
.week__title { font-weight: 700; }
.week__nav {
  width: 32px; height: 32px;
  border: 1.5px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  font: inherit; font-size: 1.1rem; line-height: 1;
  cursor: pointer;
}
.week__nav:hover { border-color: var(--accent); color: var(--accent); }
.week__today {
  margin-left: auto;
  padding: 0; border: 0; background: none;
  color: var(--accent); font: inherit; font-size: 0.85rem; font-weight: 600; cursor: pointer;
  border-bottom: 1px dashed color-mix(in srgb, var(--accent) 50%, transparent);
}
.week__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px;
  align-items: start;
}
.week__day {
  display: grid;
  gap: 6px;
  align-content: start;
  min-height: 160px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--paper-card);
}
.week__day--off { background: color-mix(in srgb, var(--paper-soft) 60%, var(--paper-card)); }
.week__day--today { border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 18%, transparent); }
.week__label { display: flex; align-items: baseline; gap: 6px; padding-bottom: 4px; border-bottom: 1px solid var(--line); }
.week__dow { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft); }
.week__date { font-weight: 800; }
.week__day--today .week__date { color: var(--accent); }
.week__chip {
  display: grid;
  gap: 1px;
  padding: 6px 8px;
  border: 0;
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  min-width: 0;
}
.week__chip:hover { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.week__chip--done { border-left-color: var(--ink-soft); background: color-mix(in srgb, var(--ink) 6%, transparent); }
.week__chip--off { border-left-color: var(--line); opacity: 0.55; text-decoration: line-through; }
.week__chip-time { font-size: 0.8rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.week__chip-what { font-size: 0.82rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.week__chip-who { font-size: 0.76rem; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.week__chip-ask { font-size: 0.72rem; color: var(--danger); font-weight: 600; }
.week__free { color: var(--ink-soft); font-size: 0.85rem; text-align: center; padding-top: 12px; }

/* ============================ ОТЧЁТ ПОСЛЕ УРОКА ===========================
   Экран, который открывается, когда урок уже завершён. Всё в нём нажимается:
   набор текста — одно поле в самом конце, спрятанное под кнопку. */

.rep {
  position: fixed;
  inset: 0;
  /* Выше шапки сайта (100): отчёт на телефоне занимает весь экран, и
     прилипшая сверху шапка резала бы ему заголовок. */
  z-index: 120;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(10, 38, 32, 0.55);
  overflow-y: auto;
}

.rep__box {
  display: flex;
  flex-direction: column;
  width: min(680px, 100%);
  max-height: calc(100dvh - 32px);
  border-radius: 18px;
  background: var(--paper-card);
  border: 1px solid var(--line);
  box-shadow: 0 24px 60px rgba(10, 38, 32, 0.3);
  overflow: hidden;
}

.rep__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px 14px;
  border-bottom: 1px solid var(--line);
}
.rep__head h2 { margin: 0; font-size: 1.25rem; }
.rep__lesson { margin: 4px 0 0; color: var(--ink-soft); font-size: 0.9rem; }
.rep__close {
  flex: none;
  width: 32px; height: 32px;
  border: 0; border-radius: 50%;
  background: transparent;
  color: var(--ink-soft);
  font-size: 1.5rem; line-height: 1;
  cursor: pointer;
}
.rep__close:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }

.rep__list { overflow-y: auto; padding: 4px 20px; }

.rep-card { padding: 14px 0; border-top: 1px solid var(--line); }
.rep-card:first-child { border-top: 0; }
.rep-card__name { margin: 0 0 10px; font-size: 1.05rem; }
.rep-card__body { display: grid; gap: 12px; }

.rep-group { display: grid; gap: 6px; }
.rep-group__title { font-size: 0.82rem; font-weight: 700; color: var(--ink-soft); }
.rep-group__hint { font-weight: 500; white-space: pre; }

.rep-chips { display: flex; gap: 6px; flex-wrap: wrap; }

.rep-chip {
  padding: 9px 14px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease, color 140ms ease;
}
.rep-chip:hover { border-color: var(--accent); }
.rep-chip[aria-pressed='true'] {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent, #fff);
}
.rep-chip--small { padding: 6px 11px; font-size: 0.82rem; }

.rep-late { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rep-late__label { font-size: 0.82rem; color: var(--ink-soft); }
/* Минуты опоздания пишут числом: четыре готовые кнопки — 5, 10, 15, 30+ —
   заставляли округлять семь минут до одной из них. */
.rep-late__input {
  width: 3.6em;
  padding: 6px 8px;
  border: 1.5px solid var(--line);
  border-radius: 9px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.rep-late__input:focus { outline: none; border-color: var(--accent); }
.rep-rest { display: grid; gap: 12px; }

.rep-note { margin-top: 2px; }
.rep-note__open {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  border-bottom: 1px dashed color-mix(in srgb, var(--accent) 50%, transparent);
}
.rep-note__area { margin: 0; resize: vertical; }

.rep__foot {
  display: flex;
  gap: 10px;
  padding: 14px 20px 6px;
  border-top: 1px solid var(--line);
}
/* Кнопки кабинета по умолчанию во всю ширину формы и с отступом сверху —
   здесь они стоят в ряд, и то и другое лишнее. */
.rep__foot .btn {
  flex: 1 1 0;
  width: auto;
  margin-top: 0;
  padding: 11px 16px;
  font-size: 0.9rem;
  white-space: nowrap;
}
.rep__hint {
  margin: 0;
  padding: 0 20px max(16px, env(safe-area-inset-bottom));
  font-size: 0.8rem;
  color: var(--ink-soft);
}

@media (max-width: 560px) {
  .rep { padding: 0; }
  .rep__box { width: 100%; max-height: 100dvh; height: 100dvh; border-radius: 0; }
  .rep-chip { padding: 10px 14px; }
  /* Две кнопки в ряд на 375 px переносят слова и выглядят тесно. Главная —
     во всю ширину, «позже» под ней: так же, как везде на телефоне. */
  .rep__foot { flex-direction: column; gap: 8px; }
}

/* Отчёт в истории ученика — теми же словами, что пришли родителю. */
.hist__report {
  grid-column: 2 / -1;
  margin: 2px 0 0;
  padding-left: 10px;
  border-left: 2px solid color-mix(in srgb, var(--accent) 40%, transparent);
  font-size: 0.88rem;
  color: var(--ink-soft);
  white-space: pre-line;
}
@media (max-width: 480px) { .hist__report { grid-column: 1 / -1; } }

/* Строка незаполненного отчёта — кнопка во всю ширину карточки. */
button.desk-report__row {
  width: 100%;
  border: 0;
  border-top: 1px solid var(--line);
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
button.desk-report__row:first-of-type { border-top: 0; }
button.desk-report__row:hover .desk-ask__who { color: var(--accent); }


/* ============================== ОКНО ====================================
   Урок, карточка ученика, быстрое действие — поверх страницы, а не переходом.
   Раньше нажатие на урок в календаре уводило вниз, в расписание: экран
   уезжал, и человек искал глазами, куда попал. */

.win {
  position: fixed;
  inset: 0;
  z-index: 130;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(10, 38, 32, 0.55);
  overflow-y: auto;
}
@media (prefers-reduced-motion: no-preference) {
  .win { animation: win-back 160ms ease-out; }
  .win__box { animation: win-in 220ms cubic-bezier(0.2, 0.8, 0.2, 1); }
  @keyframes win-back { from { opacity: 0; } }
  @keyframes win-in { from { opacity: 0; transform: translateY(12px) scale(0.98); } }
}
.win__box {
  display: flex;
  flex-direction: column;
  width: min(580px, 100%);
  max-height: calc(100dvh - 32px);
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--paper-card);
  box-shadow: 0 24px 60px rgba(10, 38, 32, 0.32);
  overflow: hidden;
}
.win__box--wide { width: min(880px, 100%); }
.win__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 15px 20px;
  border-bottom: 1px solid var(--line);
}
.win__title { margin: 0; font-size: 1.15rem; }
.win__close {
  flex: none;
  width: 32px; height: 32px;
  border: 0; border-radius: 50%;
  background: transparent;
  color: var(--ink-soft);
  font-size: 1.5rem; line-height: 1;
  cursor: pointer;
}
.win__close:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }
.win__body { padding: 4px 20px 20px; overflow-y: auto; }
/* Карточка урока внутри окна — без второй рамки вокруг первой. */
.win__body .lesson { border: 0; padding: 0; margin-top: 12px; background: none; }

/* ======================= ЖИВЫЕ УВЕДОМЛЕНИЯ ================================
   Пока человек на странице, новости приходят сразу — плашкой сверху, как на
   iPhone: плавно выезжает из-за верхнего края, висит восемь секунд и уезжает
   обратно. Важное ждёт, пока его уберут. Свайп вверх тоже убирает. */

.bell {
  position: fixed;
  top: calc(64px + env(safe-area-inset-top));
  left: 50%;
  transform: translateX(-50%);
  z-index: 400;
  display: grid;
  gap: 8px;
  width: min(420px, calc(100vw - 20px));
  pointer-events: none;
}
.bell__note {
  position: relative;
  display: grid;
  grid-template-columns: 38px 1fr;
  gap: 2px 12px;
  align-items: center;
  pointer-events: auto;
  padding: 11px 40px 12px 12px;
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-radius: 20px;
  background: color-mix(in srgb, var(--paper-card) 86%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(1.6);
  backdrop-filter: blur(18px) saturate(1.6);
  box-shadow: 0 18px 40px rgba(10, 38, 32, 0.24), 0 2px 6px rgba(10, 38, 32, 0.08);
  cursor: pointer;
  touch-action: pan-x;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.bell__icon {
  grid-row: span 2;
  display: grid; place-items: center;
  width: 38px; height: 38px;
  border-radius: 11px;
  background: var(--accent);
  color: #fff;
  font-size: 1.15rem; line-height: 1;
}
.bell__title { margin: 0; font-size: 0.8rem; font-weight: 700; letter-spacing: 0.01em; color: var(--ink-soft); }
.bell__note--urgent { border: 2px solid var(--accent); }
.bell__text { margin: 0; font-size: 0.92rem; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.bell__close {
  position: absolute; top: 8px; right: 8px;
  width: 24px; height: 24px;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-soft);
  font-size: 1.2rem; line-height: 1; cursor: pointer;
}
.bell__close:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }

@media (prefers-reduced-motion: no-preference) {
  .bell__note { animation: bell-in 0.55s cubic-bezier(0.22, 1.25, 0.36, 1); }
  .bell__note--out { animation: bell-out 0.28s cubic-bezier(0.4, 0, 1, 1) forwards; }
  @keyframes bell-in { from { opacity: 0; transform: translateY(-120%) scale(0.96); } }
  @keyframes bell-out { to { opacity: 0; transform: translateY(-130%) scale(0.96); } }
}
@media (prefers-reduced-motion: reduce) {
  .bell__note--out { opacity: 0; }
}

/* ========================== РЕЖИМ ДИРЕКТОРА ===============================
   У Максима две роли сразу: преподаватель с четырьмя уроками сегодня и
   школа с двенадцатью учениками. На одном экране их мешать нельзя — рабочий
   день утонет в отчётности. Школа лежит ниже, за чертой. */

.desk-director {
  display: flex; align-items: center; gap: 14px;
  margin: 18px 0 2px;
}
.desk-director__line { flex: 1; height: 1px; background: var(--line); }
.desk-director__title {
  display: flex; align-items: center; flex: none;
  font-size: 0.76rem; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-soft);
}
.desk-card--teachers, .desk-card--money { border-style: dashed; }
/* Строка преподавателя не нажимается — у неё нет своей страницы. */
.desk-student--flat { cursor: default; }
.desk-student--flat:hover .desk-student__name { color: inherit; }
.desk-student__name .desk-tag { margin-left: 8px; }

/* ============================== КЛАССЫ ====================================
   Групповые занятия. Класс — постоянный состав, а не «урок на пятерых»:
   у него своё название, свои преподаватели и своя оплата. */

.cls-list { display: grid; gap: 8px; margin-top: 12px; }
.cls-row {
  display: grid; gap: 3px;
  padding: 12px 14px;
  border: 1.5px solid var(--line); border-radius: 14px;
  background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
  transition: border-color 140ms ease, transform 140ms ease;
}
.cls-row:hover { border-color: var(--accent); transform: translateY(-1px); }
.cls-row__top { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.cls-row__name { font-weight: 800; font-size: 1.05rem; }
.cls-row__count { font-size: 0.82rem; color: var(--ink-soft); }
.cls-row__meta { font-size: 0.88rem; color: var(--ink-soft); }
.cls-row__next { font-size: 0.85rem; color: var(--accent); font-weight: 600; }

.cls-head { margin: 14px 0 4px; }
.cls-head__meta { color: var(--ink-soft); font-size: 0.92rem; }
.cls-head__note { margin: 8px 0 0; font-size: 0.92rem; }

.cls-student { padding-right: 6px; }
.cls-student__name {
  border: 0; background: none; padding: 0;
  color: inherit; font: inherit; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cls-student__name:hover { color: var(--accent); }
.cls-student__out {
  flex: none; width: 22px; height: 22px;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-soft);
  font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.cls-student__out:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }

.cls-lessons { display: grid; }
.cls-lesson {
  display: grid; grid-template-columns: 9em 1fr auto; gap: 4px 12px; align-items: baseline;
  padding: 9px 0; border-top: 1px solid var(--line);
  border-left: 0; border-right: 0; border-bottom: 0;
  background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.cls-lesson:first-child { border-top: 0; }
.cls-lesson:hover .cls-lesson__what { color: var(--accent); }
.cls-lesson__when { font-size: 0.85rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.cls-lesson__what { font-weight: 600; }
.cls-lesson__mark { font-size: 0.78rem; color: var(--accent); }

/* Уроки, которые идут прямо сейчас, — у главы школы. «4 урока сегодня» не
   говорит, кто из них уже за доской. */
.desk-live {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.desk-live:first-of-type { border-top: 0; }
.desk-live__words { display: grid; gap: 2px; min-width: 0; margin-right: auto; }
.desk-live__what { font-size: 0.95rem; }
.desk-live__who { font-size: 0.84rem; color: var(--ink-soft); }

/* Цвет предмета: у преподавателя с тремя предметами лента заданий читалась
   как один длинный список, в котором математика и английский различались
   только словом в заголовке. */
.hw { border-left: 4px solid var(--subject-tint, var(--line)); }

.hw-filter { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 14px; }
.hw-filter__one {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 0.86rem;
  cursor: pointer;
}
.hw-filter__one::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--subject-tint, var(--ink-soft));
}
.hw-filter__one:hover { border-color: var(--accent); }
.hw-filter__one[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  font-weight: 700;
}

/* ============================== БИБЛИОТЕКА ===============================
   Тесты, учебники и разборы, которые задают не в первый раз. */

.lib-group { margin-bottom: 16px; }
.lib-group__name {
  margin-bottom: 4px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.lib-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  margin-bottom: 6px;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
}
button.lib-row { cursor: pointer; }
button.lib-row:hover { border-color: var(--accent); }
.lib-row[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.lib-row__words { display: grid; gap: 2px; min-width: 0; margin-right: auto; }
.lib-row__title { font-size: 0.95rem; overflow-wrap: anywhere; }
.lib-row__meta { font-size: 0.8rem; color: var(--ink-soft); }
.lib-row__note { font-size: 0.82rem; color: var(--ink-soft); }
.lib-row__tags { display: block; color: var(--accent); font-size: 0.78rem; }
.lib-row__acts { display: flex; align-items: center; gap: 6px; flex: none; }
.lib-search { margin: 4px 0 14px; }
.lib-type-filters { display: flex; gap: 7px; overflow-x: auto; padding: 0 0 14px; scrollbar-width: thin; }
.lib-sections { display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:10px; margin:0 0 16px; }
.lib-section { min-width:0; padding:13px 15px; border:1px solid var(--line); border-radius:16px; background:var(--paper); color:var(--ink); text-align:left; font:inherit; cursor:pointer; transition:border-color 180ms ease,background 180ms ease,transform 180ms ease; }
.lib-section:hover { transform:translateY(-1px); border-color:color-mix(in srgb,var(--accent) 45%,var(--line)); }
.lib-section strong,.lib-section span { display:block; }
.lib-section strong { font-size:.9rem; }
.lib-section span { margin-top:3px; color:var(--ink-soft); font-size:.74rem; line-height:1.3; }
.lib-section[aria-pressed='true'] { border-color:var(--accent); background:color-mix(in srgb,var(--accent) 10%,var(--paper)); box-shadow:inset 0 0 0 1px var(--accent); }
.lib-type-filter { flex: none; min-height: 36px; padding: 7px 13px; border: 1px solid var(--line); border-radius: 999px; background: var(--paper); color: var(--ink-soft); font: inherit; font-size: .8rem; cursor: pointer; }
.lib-type-filter[aria-pressed='true'] { background: color-mix(in srgb,var(--accent) 12%,var(--paper)); border-color: color-mix(in srgb,var(--accent) 55%,var(--line)); color: var(--accent); font-weight: 700; }
.lib-group--books { display: grid; grid-template-columns: repeat(auto-fill,minmax(176px,1fr)); gap: 18px 16px; }
.lib-group--books>.lib-group__name { grid-column: 1/-1; margin-bottom: -2px; }
.lib-row--book { min-width: 0; display: flex; flex-direction: column; align-items: stretch; gap: 10px; padding: 10px; border: 0; background: transparent; text-align: left; transition: transform 180ms ease,background 180ms ease; }
.lib-row--book:hover { transform: translateY(-3px); background: color-mix(in srgb,var(--accent) 5%,transparent); }
.lib-row--book[aria-pressed='true'] { background: color-mix(in srgb,var(--accent) 12%,transparent); box-shadow: inset 0 0 0 2px var(--accent); }
.lib-book-cover { position: relative; display: block; width: 100%; aspect-ratio: 3/4.2; overflow: hidden; padding: 17px 14px; border-radius: 8px 14px 14px 8px; background: linear-gradient(145deg,#dcefcf,#2f9063); color: #103a2b; box-shadow: 0 13px 25px #10271d22, inset 5px 0 0 #ffffff55; }
.lib-book-cover::after { content:''; position:absolute; inset:0; pointer-events:none; background:linear-gradient(90deg,#00000016,transparent 13%,transparent 82%,#fff3); }
.lib-book-cover[data-subject*='англ'] { background:linear-gradient(145deg,#cbdcf7,#4d6fbb); color:#14254e; }
.lib-book-cover[data-subject*='матем'] { background:linear-gradient(145deg,#f4df9a,#d69632); color:#503509; }
.lib-book-cover[data-subject*='рус'] { background:linear-gradient(145deg,#f0d6d0,#bd6658); color:#4d1b17; }
.lib-book-cover[data-palette='band-1'] { background:linear-gradient(145deg,#e3f2d7,#83bd71); color:#183c2c; }
.lib-book-cover[data-palette='band-2'] { background:linear-gradient(145deg,#a7d9bd,#318665); color:#0d3527; }
.lib-book-cover[data-palette='band-3'] { background:linear-gradient(145deg,#397862,#173f33); color:#f1f6ec; }
.lib-book-cover[data-palette='band-4'] { background:linear-gradient(145deg,#f9dfa0,#e3a82e); color:#503509; }
.lib-book-cover[data-palette='band-5'] { background:linear-gradient(145deg,#f2e8c8,#cdbf92); color:#473917; }
.lib-book-cover[data-palette='accent'] { background:linear-gradient(145deg,color-mix(in srgb,var(--accent) 55%,white),var(--accent)); color:white; }
.lib-book-cover img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:center; }
.lib-book-cover__type,.lib-book-cover__author { position:relative; z-index:1; display:block; font-size:.68rem; font-weight:700; opacity:.78; }
.lib-book-cover__title { position:relative; z-index:1; display:block; margin-top:24%; font-size:clamp(.92rem,2vw,1.18rem); line-height:1.15; overflow-wrap:anywhere; }
.lib-book-cover__author { position:absolute; z-index:1; left:14px; right:14px; bottom:16px; }
.lib-row--book .lib-row__words { width:100%; margin:0; }
.lib-row--book .lib-row__title { font-size:.92rem; line-height:1.25; }
.lib-row--book .lib-row__note { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.lib-row--book .lib-row__acts { width:100%; flex-wrap:wrap; align-items:stretch; }
.lib-row--book .lib-row__acts .btn { flex:1 1 auto; }
.lib-upload { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.lib-upload .nl__label:first-child,
.lib-upload .nl__label:nth-child(2),
.lib-upload .nl__label:nth-child(7) { grid-column: 1 / -1; }
.lib-upload__file { align-self: center; color: var(--ink-soft); font-size: 0.84rem; }
@media (max-width: 640px) {
  .lib-upload { grid-template-columns: 1fr; }
  .lib-upload .nl__label { grid-column: 1 !important; }
  .lib-group--books { grid-template-columns: repeat(2,minmax(0,1fr)); gap:14px 8px; }
  .lib-row--book { padding:7px; }
  .lib-row--book .lib-row__acts { display:grid; grid-template-columns:1fr; }
  .lib-sections { grid-template-columns:1fr; gap:7px; }
}
@media (max-width: 370px) { .lib-group--books { grid-template-columns:1fr; } }
@media (prefers-reduced-motion:reduce) { .lib-row--book { transition:none; } }
.lib-row__drop {
  min-width: 26px;
  height: 26px;
  padding: 0 8px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--ink-soft);
  font: inherit;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
}
.lib-row__drop:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.lib-row__drop--sure {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  color: var(--danger);
  font-size: 0.78rem;
  font-weight: 700;
}

/* Прикреплённое в окне «Задать домашку» и в карточке задания. */
.hw-materials { display: grid; gap: 8px; justify-items: start; margin: 6px 0 10px; }
.hw-materials__list { display: flex; flex-wrap: wrap; gap: 6px; }
.hw-material {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 6px 5px 12px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  font-size: 0.84rem;
}
.hw-material__drop {
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink-soft);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.hw-material__drop:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }

.hw__materials { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.hw__material {
  padding: 5px 12px;
  border: 1.5px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 999px;
  color: var(--accent);
  font-size: 0.84rem;
  font-weight: 600;
  text-decoration: none;
}
a.hw__material:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }

/* ========================= ПОПОЛНИТЬ ЗАНЯТИЯ =============================
   Денег на сайте нет: родитель переводит на карту, а кабинет ведёт учёт
   занятий. Здесь только реквизиты, число занятий и слова. */

/* «6 + 3 неподтверждённых»: сложить их в одно число нельзя — оплаченное это
   оплаченное, а обещанное может и не дойти. */
.desk-pay__pending {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--accent);
  white-space: nowrap;
}

.pay-pick { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.pay-pick__one {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 0.88rem;
  cursor: pointer;
}
.pay-pick__one:hover { border-color: var(--accent); }
.pay-pick__one[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  font-weight: 700;
}
.pay-count { max-width: 140px; }

.pay-details { display: grid; gap: 10px; margin: 4px 0 14px; }
.pay-details__wait { margin: 0; color: var(--ink-soft); font-size: 0.9rem; line-height: 1.5; }
.pay-details__one {
  display: grid;
  gap: 6px;
  justify-items: start;
  padding: 12px 14px;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}
.pay-details__who { font-size: 0.76rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); }
.pay-details__text { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.5; overflow-wrap: anywhere; }

.pay-claim {
  display: grid;
  gap: 6px;
  padding: 12px 0;
  border-top: 1px solid var(--line);
}
.pay-claim:first-of-type { border-top: 0; }
.pay-claim__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.pay-claim__count { font-weight: 800; color: var(--accent); white-space: nowrap; }
.pay-claim__meta { margin: 0; font-size: 0.86rem; color: var(--ink-soft); }
.pay-claim__note { margin: 0; font-size: 0.9rem; }
.pay-claim__acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }

/* ============================ СТРАНИЦА КЛАССА ============================
   В окне помещался список имён и ничего больше: занятия, состав и настройки
   в него уже не влезали, а класс — это ровно они. */

/* Кружок класса в плитке на столе — то же лицо, что на его странице. */
.desk-class__face {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--tint, #1F7A5A);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 800;
}

.class-page { display: grid; gap: 22px; max-width: 900px; }
.cls-back { justify-self: start; margin-top: 18px; }

.cls-page__head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  flex-wrap: wrap;
}
.cls-page__words { flex: 1 1 240px; min-width: 0; }
.cls-page__name { margin: 0; font-size: 1.5rem; }
.cls-page__meta { margin: 4px 0 0; color: var(--ink-soft); font-size: 0.92rem; }
.cls-page__note { margin: 8px 0 0; font-size: 0.92rem; }

/* Лицо класса — тот же набор цветов, что у людей. Десяток классов в списке
   отличался только названием одним шрифтом: глаз по ним скользил. */
.cls-face {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: 16px;
  background: var(--tint, #1F7A5A);
  color: #fff;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}

.cls-page__block { display: grid; gap: 10px; justify-items: start; }
.cls-page__title {
  margin: 0;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Имена целиком: в чипе фиксированной ширины «Константин Ф…» — это не имя,
   а обещание имени. */
.cls-who {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
  width: 100%;
}
.cls-who__one {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
}
.cls-who__name {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.cls-who__name:hover { color: var(--accent); }
.cls-who__grade { margin-left: auto; font-size: 0.76rem; color: var(--ink-soft); white-space: nowrap; }
.cls-who__out {
  flex: none;
  margin-left: auto;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
}
.cls-who__grade + .cls-who__out { margin-left: 6px; }
.cls-who__out:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
/* Переспрос: одно случайное нажатие крестика выкидывало ребёнка из группы
   вместе с доступом к её занятиям и домашке. */
.cls-who__out--sure {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  color: var(--danger);
  font-size: 0.78rem;
  font-weight: 700;
}

/* Параллель и цвет в настройках класса. */
.cls-grades { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 4px; }
.cls-grade {
  width: 36px;
  height: 34px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.cls-grade:hover { border-color: var(--accent); }
.cls-grade[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  font-weight: 800;
}
.cls-tints { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
.cls-tint {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 50%;
  background: var(--tint, #1F7A5A);
  cursor: pointer;
}
.cls-tint[aria-pressed='true'] { border-color: var(--ink); }

/* Поле домашки в окне. */
.hw-area { resize: vertical; line-height: 1.5; }
.hw-area__count { margin: 6px 0 0; font-size: 0.82rem; color: var(--ink-soft); }

@media (max-width: 560px) {
  .cls-lesson { grid-template-columns: 1fr; }
}

/* Страница класса: одна собранная рабочая область вместо разрозненных строк. */
.class-page { width: 100%; max-width: 1120px; min-height: 72vh; gap: 18px; padding: 10px 0 56px; }
.cls-page__toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cls-page__toolbar .cls-back { margin: 0; }
.cls-page__hero {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 20px; padding: clamp(22px, 4vw, 38px);
  border: 1px solid var(--line); border-radius: 26px;
  background:
    radial-gradient(circle at 92% 12%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 34%),
    linear-gradient(145deg, var(--paper-card), color-mix(in srgb, var(--paper-soft) 74%, var(--paper-card)));
  box-shadow: var(--shadow-soft);
}
.cls-page__hero .cls-face { width: 72px; height: 72px; border-radius: 20px; font-size: 1.15rem; }
.cls-page__hero .cls-page__name { font-size: clamp(1.8rem, 4vw, 2.7rem); line-height: 1.04; letter-spacing: -0.045em; }
.cls-page__quick { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; max-width: 340px; }
.cls-page__quick .btn { width: auto; margin: 0; }
.cls-page__block {
  gap: 16px; padding: clamp(20px, 3vw, 28px); justify-items: stretch;
  border: 1px solid var(--line); border-radius: 22px; background: var(--paper-card);
}
.cls-page__section-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.cls-page__section-head .btn { width: auto; margin: 0; }
.cls-page__title { font-size: 1rem; letter-spacing: -0.015em; text-transform: none; color: var(--ink); }
.cls-page__section-note { margin: 3px 0 0; color: var(--ink-soft); font-size: 0.84rem; }
.cls-who { grid-template-columns: repeat(auto-fill, minmax(235px, 1fr)); gap: 10px; }
.cls-who__one { min-height: 58px; padding: 10px 12px; background: var(--paper-soft); border-width: 1px; }
.cls-next-lesson {
  display: grid; gap: 7px; width: 100%; padding: 22px;
  border: 1px solid color-mix(in srgb, var(--accent) 58%, var(--line)); border-radius: 18px;
  background: color-mix(in srgb, var(--accent) 9%, var(--paper-card)); color: var(--ink);
  font: inherit; text-align: left; cursor: pointer;
}
.cls-next-lesson:hover { background: color-mix(in srgb, var(--accent) 14%, var(--paper-card)); }
.cls-next-lesson__eyebrow, .cls-lessons__caption, .cls-archive__label {
  color: var(--accent); font-size: 0.72rem; font-weight: 800; letter-spacing: 0.07em; text-transform: uppercase;
}
.cls-next-lesson__title { font-size: 1.25rem; }
.cls-next-lesson__time { color: var(--ink-soft); font-size: 0.88rem; }
.cls-lessons { gap: 0; }
.cls-lessons__caption { padding: 12px 0 8px; color: var(--ink-soft); }
.cls-lesson { grid-template-columns: 9em minmax(0, 1fr) auto auto; min-height: 54px; padding: 12px 4px; align-items: center; }
.cls-lesson__status { width: max-content; padding: 5px 8px; border-radius: 999px; background: var(--paper-soft); color: var(--ink-soft); font-size: 0.72rem; font-weight: 700; }
.cls-lesson__status--done { color: #287052; background: color-mix(in srgb, #45a67b 14%, var(--paper-card)); }
.cls-lesson__status--cancelled_teacher,
.cls-lesson__status--cancelled_early,
.cls-lesson__status--cancelled_late,
.cls-lesson__status--no_show { color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, var(--paper-card)); }
.cls-archive__top { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.cls-archive__date, .cls-archive__muted { color: var(--ink-soft); font-size: 0.88rem; }
.cls-archive__summary { margin-top: 18px; padding: 18px; border-radius: 16px; background: var(--paper-soft); }
.cls-archive__summary p { margin: 8px 0 0; line-height: 1.65; }
.cls-archive__facts { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.cls-archive__facts .btn, .cls-archive__personal { width: auto; margin: 0; }
.cls-archive__personal { margin-top: 16px; }
.cls-report-list { display: grid; gap: 12px; }
.cls-report { padding: 16px; border: 1px solid var(--line); border-radius: 14px; background: var(--paper-soft); }
.cls-report p { margin: 7px 0 0; line-height: 1.65; white-space: pre-wrap; }
.cls-remove__lead { margin: 0; font-size: 1.05rem; font-weight: 700; }
.cls-remove__note { margin: 8px 0 0; color: var(--ink-soft); line-height: 1.65; }
.cls-remove__actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.cls-remove__actions .btn { width: auto; margin: 0; }
.btn--danger {
  border-color: color-mix(in srgb, var(--danger) 72%, var(--line));
  background: color-mix(in srgb, var(--danger) 18%, var(--paper-card));
  color: var(--danger);
}
.btn--danger:hover { background: color-mix(in srgb, var(--danger) 27%, var(--paper-card)); }
@media (max-width: 760px) {
  .cls-page__hero { grid-template-columns: auto minmax(0, 1fr); }
  .cls-page__quick { grid-column: 1 / -1; justify-content: stretch; max-width: none; }
  .cls-page__quick .btn { flex: 1 1 180px; }
  .cls-lesson { grid-template-columns: 1fr auto; }
  .cls-lesson__when { grid-column: 1 / -1; }
  .cls-lesson__mark { grid-column: 1 / -1; }
}

/* ========================= ПОСТАВИТЬ УРОК =================================
   Окно поверх стола. Время выбирается двумя способами сразу: протянуть по
   неделе, где видно занятое, или вписать цифрами. Оба связаны.

   На компьютере окно в два столбца: слева календарь, справа всё остальное.
   Календарь нужен всё время, пока заполняешь форму, — выбрал ученика, увидел
   его занятость, — и когда он стоял над полями, к нему приходилось
   прокручивать обратно. У каждого столбца своя прокрутка, а кнопка
   «Поставить урок» стоит под ними и видна всегда. На телефоне столбцы
   складываются в ленту: сначала время, потом всё остальное. */

.nl__lead { margin-top: 14px; }
.nl__left { margin-top: 14px; }
.nl__cal { --hour: 42px; }

@media (min-width: 900px) {
  /* Час в сетке подстраивается под высоту окна: неделя должна помещаться в
     столбец целиком, а не уезжать под его край. Окно не выше 880px и не выше
     экрана; из его высоты вычитаем шапку, кнопки и всё, что в столбце стоит
     над сеткой и под ней, — остаток делим на тринадцать часов дня. */
  /* Меньше тридцати пикселей на час не опускаемся: в такой ячейке не
     помещаются даже время с предметом. В невысоком окне неделю лучше чуть
     прокрутить — столбец и так прокручивается, — чем гадать по обрывкам. */
  .nl__cal { --hour: clamp(30px, calc((min(880px, 100dvh - 48px) - 456px) / 13), 44px); }
  .win__body.win__body--cols {
    flex: 1; min-height: 0;
    display: flex; flex-direction: column;
    overflow: hidden;
  }
  .nl__cols {
    flex: 1; min-height: 0;
    display: grid;
    grid-template-columns: minmax(420px, 1.15fr) minmax(340px, 1fr);
    /* «Кому урок» стоит над правым столбцом и не уезжает при прокрутке полей.
       В разметке он первый — на телефоне с него начинается лента. */
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: 'left lead' 'left right';
    column-gap: 28px;
  }
  .nl__lead { grid-area: lead; margin-top: 0; padding-bottom: 16px; }
  .nl__left { grid-area: left; }
  .nl__right { grid-area: right; }
  .nl__left, .nl__right { min-height: 0; overflow-y: auto; padding-right: 6px; }
  .nl__left { margin-top: 0; }
  .nl__right .nl__rest { margin-top: 0; padding-top: 0; border-top: 0; }
  /* Кнопки стоят под столбцами, прилипать им не к чему. */
  .win__body--cols .nl__footrow { position: static; margin-top: 14px; padding-top: 0; background: none; }
  .win__body--cols .nl__warn { margin-top: 12px; }
}

.nl__fields { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; margin-bottom: 14px; }
.nl__label { display: grid; gap: 4px; margin: 0; font-size: 0.78rem; color: var(--ink-soft); }
.nl__field {
  margin: 0;
  padding: 9px 12px;
  border: 1.5px solid var(--line); border-radius: 12px;
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: 16px;
}
.nl__field:focus { outline: none; border-color: var(--accent); }
.nl__field--wide { width: 100%; box-sizing: border-box; }
.nl__len { font-size: 0.85rem; font-weight: 700; color: var(--accent); padding-bottom: 10px; }
.nl__hint { margin-left: auto; font-size: 0.8rem; color: var(--ink-soft); }
.nl__cal { margin-bottom: 4px; }
.nl__pick { background: color-mix(in srgb, var(--accent) 45%, var(--paper-card)); z-index: 2; }
.nl__pick-time { line-height: 1.15; }

/* Подпись не влезла в блок (небольшое окно, узкий столбец): время выносим
   ярлычком над блоком — целиком и крупно, а блок остаётся цветной меткой.
   У самого утра ярлычок уходит вниз, чтобы не лечь на шапку дней, в выходные
   прижимается к правому краю, чтобы не уйти за окно. Меряет newlesson.js. */
.nl__pick.is-tight { overflow: visible; }
.nl__pick.is-tight .rs__busy-who { display: none; }
.nl__pick.is-tight .nl__pick-time {
  position: absolute; left: -2px; bottom: calc(100% + 4px);
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.76rem; font-weight: 800;
  white-space: nowrap;
  box-shadow: 0 2px 8px color-mix(in srgb, #000 30%, transparent);
  pointer-events: none;
}
.nl__pick.is-tight.is-top .nl__pick-time { bottom: auto; top: calc(100% + 4px); }
.nl__pick.is-tight.is-end .nl__pick-time { left: auto; right: -2px; }

/* Чужой урок в тесном блоке: время и предмет мелко, каждое одной строкой с
   многоточием, имя убираем. Совсем тесно (полчаса) — только время. Строка,
   обрезанная пополам по высоте, читается как поломка; целиком — в подсказке. */
.nl__cal .rs__busy-at { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Строки блока держат свою высоту. Иначе сетка ужимала их под низкий блок —
   до семи пикселей на строку, — текст резался пополам, а замер «не влезло»
   ничего не замечал: переполнения формально не было. */
.nl__cal .rs__busy, .nl__cal .nl__pick { grid-auto-rows: max-content; }
.nl__cal .rs__busy.is-tight { padding: 2px 4px; gap: 0; font-size: 0.66rem; }
.nl__cal .rs__busy.is-tight .rs__busy-at,
.nl__cal .rs__busy.is-tight .rs__busy-what { line-height: 1.1; }
.nl__cal .rs__busy.is-tight .rs__busy-who,
.nl__cal .rs__busy.is-tiny .rs__busy-what { display: none; }
/* Самый тесный случай — телефон, столбец в три десятка пикселей: остаётся
   одно время, мельче и почти без отступов, но целиком. */
.nl__cal .rs__busy.is-tiny { padding: 2px 1px 2px 2px; font-size: 0.6rem; letter-spacing: -0.02em; }

/* Нерабочее время преподавателя: затенено, но не закрыто — это подсказка, и
   протянуть по нему урок можно (pointer-events выключены). */
.nl__off {
  position: absolute; left: 0; right: 0;
  background: repeating-linear-gradient(135deg,
    color-mix(in srgb, var(--ink) 9%, transparent) 0 5px, transparent 5px 10px);
  pointer-events: none;
}
/* Ребёнок занят у другого преподавателя: штриховка и красная кромка — окно у
   преподавателя свободно, а урок сюда всё равно не встанет. */
.rs__busy.nl__kid {
  background: repeating-linear-gradient(135deg,
    color-mix(in srgb, var(--danger) 18%, var(--paper-card)) 0 6px, var(--paper-card) 6px 12px);
  border-left-color: var(--danger);
  color: var(--ink);
}
.nl__legend { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 8px 0 2px; font-size: 0.76rem; color: var(--ink-soft); }
.nl__legend-item { display: inline-flex; align-items: center; gap: 6px; }
.nl__legend-item i { width: 14px; height: 10px; border-radius: 3px; flex: none; }
.nl__legend-busy { background: color-mix(in srgb, var(--ink) 12%, var(--paper-card)); border-left: 3px solid var(--ink-soft); }
.nl__legend-kid { background: color-mix(in srgb, var(--danger) 22%, var(--paper-card)); border-left: 3px solid var(--danger); }
.nl__legend-off { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--ink) 16%, transparent) 0 3px, transparent 3px 6px); }

.nl__rest { display: grid; gap: 16px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.nl__group { display: grid; gap: 8px; }
.nl__group-name {
  font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-soft);
}

/* Ученики — с лицами: имя в списке из тридцати ищут глазами по картинке.
   Список у менеджера — вся школа, поэтому у него своя прокрутка: иначе форма
   под ним уезжала бы за экран. */
.nl__wholist { display: grid; gap: 8px; max-height: 250px; overflow-y: auto; padding-right: 2px; }
.nl__whohead { font-size: 0.74rem; font-weight: 700; color: var(--ink-soft); margin-top: 2px; }
.nl__who { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 8px; }
.nl__student {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 12px 7px 7px;
  border: 1.5px solid var(--line); border-radius: 999px;
  background: none; color: var(--ink); font: inherit; text-align: left; cursor: pointer;
  min-width: 0;
}
.nl__student:hover { border-color: var(--accent); }
.nl__student[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  font-weight: 700;
}
.nl__student-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.avatar--mini { width: 30px; height: 30px; font-size: 0.72rem; flex: none; }

/* Как часто: четыре способа задать расписание и список того, что выйдет. */
.nl__modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; }
.nl__mode {
  display: grid; gap: 2px; padding: 9px 12px;
  border: 1.5px solid var(--line); border-radius: 14px;
  background: none; color: var(--ink); font: inherit; text-align: left; cursor: pointer;
}
.nl__mode:hover { border-color: var(--accent); }
.nl__mode[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.nl__mode b { font-size: 0.92rem; }
.nl__mode span { font-size: 0.76rem; color: var(--ink-soft); }
.nl__modebody { display: grid; gap: 12px; margin-top: 4px; }
.nl__modehint { margin: 0; font-size: 0.82rem; color: var(--ink-soft); line-height: 1.5; }

.nl__days { display: flex; flex-wrap: wrap; gap: 6px; }
.nl__day {
  min-width: 46px; padding: 9px 10px;
  border: 1.5px solid var(--line); border-radius: 12px;
  background: none; color: var(--ink); font: inherit; cursor: pointer;
}
.nl__day:hover { border-color: var(--accent); }
.nl__day[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  font-weight: 700;
}
.nl__daytimes { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; }
.nl__daytimes .nl__modehint { flex: 1 0 100%; }
.nl__end { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; }

.nl__monthhead { display: flex; align-items: center; gap: 10px; }
.nl__monthhead strong { min-width: 150px; }
.nl__month { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; max-width: 360px; }
.nl__monthdow { font-size: 0.7rem; color: var(--ink-soft); text-align: center; }
.nl__date {
  padding: 8px 0;
  border: 1.5px solid var(--line); border-radius: 10px;
  background: none; color: var(--ink); font: inherit; cursor: pointer;
}
.nl__date:hover:not(:disabled) { border-color: var(--accent); }
.nl__date:disabled { opacity: 0.35; cursor: default; }
.nl__date--outside { opacity: 0.45; }
.nl__date[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  font-weight: 700;
}

.nl__plan-note { margin: 0; font-size: 0.85rem; color: var(--ink-soft); line-height: 1.5; }
.nl__plan { display: grid; gap: 4px; max-height: 260px; overflow: auto; }
.nl__planrow {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  font-size: 0.88rem; cursor: pointer;
}
.nl__planrow--busy {
  background: color-mix(in srgb, var(--danger) 9%, transparent);
  cursor: default;
}
.nl__planwhen { font-variant-numeric: tabular-nums; }
.nl__planclock { padding: 4px 8px; font-size: 0.85rem; }
.nl__planwhy { margin-left: auto; font-size: 0.78rem; color: var(--danger); text-align: right; }
/* «Вне рабочих часов» — не отказ, а вопрос: спокойнее красного. */
.nl__planwhy--soft { color: var(--ink-soft); }
.nl__anyway { display: flex; align-items: center; gap: 8px; font-size: 0.83rem; color: var(--ink-soft); }

/* Итог после постановки: что получилось и что дальше. */
.nl__done { display: grid; gap: 16px; padding-top: 6px; }
.nl__done-title { font-size: 1.25rem; }

.nl__warn {
  margin: 14px 0 0; padding: 10px 14px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  color: var(--danger); font-size: 0.88rem; font-weight: 600; line-height: 1.45;
}

@media (max-width: 700px) {
  .nl__cal { --hour: 34px; }
  .nl__fields { gap: 8px; }
  .nl__label { flex: 1 1 30%; }
  /* Семь дней обязаны поместиться в экран телефона: сетку тянут пальцем, и
     горизонтальная прокрутка под пальцем спорила бы с протягиванием. */
  .rs__cal.nl__cal { grid-template-columns: 30px repeat(7, minmax(0, 1fr)); column-gap: 2px; }
  .nl__cal .rs__busy-who { display: none; }
  .nl__cal .cal__hour { font-size: 0.62rem; }
  .nl__who { grid-template-columns: 1fr; }
}

/* ===================== КАРТОЧКА УРОКА: ПАНЕЛИ ПО СМЫСЛУ ===================
   Десяток кнопок стоял в одну строку, и они читались как десять равных
   возможностей. Теперь их две группы с подписями: «как прошёл» — про
   случившееся и про деньги, «дальше» — про то, что делать сейчас. */

.lesson__groups { display: grid; gap: 14px; margin-top: 14px; }
.lesson__group { display: grid; gap: 6px; }
.lesson__group-name {
  font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-soft);
}
.lesson__row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lesson__row .btn { width: auto; margin: 0; }
.status--live {
  color: #0d6b4d;
  background: color-mix(in srgb, #35b982 18%, var(--paper-card));
}
.lesson__presence {
  display: grid; gap: 4px; margin-top: 12px; padding: 12px 14px;
  border-left: 3px solid #35b982; border-radius: 10px;
  background: color-mix(in srgb, #35b982 8%, transparent);
  font-size: 0.84rem; color: var(--ink-soft);
}
.lesson__presence strong { color: var(--ink); }
.lesson__live-actions {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line);
}
.lesson__live-note { margin: 0; color: var(--ink-soft); font-size: 0.88rem; }
.lesson__homework-view { margin-top: 12px; }
.lesson__homework-note { color: var(--ink-soft); }
.lesson__homework-list { display: grid; gap: 8px; margin: 8px 0 0; padding-left: 22px; }
.hw__class-progress {
  display: grid; gap: 5px; margin-top: 12px; padding: 12px 14px;
  border-radius: 12px; background: color-mix(in srgb, var(--accent) 7%, transparent);
  color: var(--ink-soft); font-size: 0.84rem;
}
.hw__class-progress strong { color: var(--ink); }
.hw__focus {
  outline: 3px solid color-mix(in srgb, #4d83bd 58%, transparent);
  outline-offset: 4px;
  animation: homework-focus 900ms ease-out;
}
@keyframes homework-focus {
  from { background: color-mix(in srgb, #4d83bd 22%, var(--paper-card)); }
  to { background: inherit; }
}

/* Тема правится карандашом прямо в заголовке. */
.lesson__title { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.lesson__pencil {
  flex: none;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-soft); cursor: pointer;
}
.lesson__pencil:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--accent); }
.lesson__subject-fixed { font-weight: inherit; }
.lesson__topic-input {
  flex: 1 1 12em; min-width: 0; margin: 0;
  padding: 4px 10px;
  border: 1.5px solid var(--accent); border-radius: 10px;
  background: var(--paper); color: var(--ink);
  font: inherit; font-size: 1rem;
}
.lesson__topic-input:focus { outline: none; }

/* Просьба семьи — в самой карточке урока, с кнопками и своим цветом. */
.lesson__ask {
  display: grid; gap: 6px;
  margin-top: 12px; padding: 12px 14px;
  border: 2px solid var(--accent); border-radius: 14px;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}
.lesson__ask-title { font-weight: 700; }
.lesson__ask-note { margin: 0; font-size: 0.92rem; }
.lesson__ask-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 2px; }
.lesson__ask-acts .btn { width: auto; margin: 0; }

/* ===================== СПИСОК ОТЧЁТОВ, КОТОРЫЕ ЖДУТ ======================
   Нажатие на «3 отчёта» открывало первый попавшийся. Начинают обычно с того
   урока, который лучше помнят, — поэтому сначала список. */

.rep-list { display: grid; gap: 8px; margin-top: 12px; }
.rep-list__row {
  display: grid; gap: 3px;
  padding: 12px 14px;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: none;
  color: inherit; font: inherit; text-align: left; cursor: pointer;
  transition: border-color 140ms ease, transform 140ms ease;
}
.rep-list__row:hover { border-color: var(--accent); transform: translateY(-1px); }
.rep-list__top { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.rep-list__who { font-weight: 700; }
.rep-list__when { font-size: 0.82rem; color: var(--ink-soft); }
.rep-list__what { font-size: 0.9rem; color: var(--ink-soft); }
.rep-list__late { font-size: 0.8rem; font-weight: 700; color: var(--danger); }
.rep-list__go { justify-self: start; margin-top: 4px; font-size: 0.85rem; font-weight: 700; color: var(--accent); }
.rep-list__done { margin: 16px 0; font-size: 0.95rem; color: var(--ink-soft); }

/* Подтверждение после отправки: окно не закрывается само. */
.rep-done__acts { display: flex; gap: 10px; justify-content: center; margin-top: 18px; }
.rep-done__acts .btn { width: auto; margin: 0; padding: 10px 20px; }

/* Просроченный отчёт подписан словами: «ждёт четыре дня» бьёт сильнее даты. */
.desk-ask__late { margin: 0; font-size: 0.82rem; font-weight: 700; color: var(--danger); }

/* ========================= КАРТОЧКА УЧЕНИКА ===============================
   Коротко и с кнопками — то, что нужно между уроками. Целая страница
   открывается из неё же, когда надо разбираться. */

.card-top { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.card-top__name { font-size: 1.2rem; font-weight: 800; }
.card-top__meta { font-size: 0.88rem; color: var(--ink-soft); margin-top: 2px; }

.card-facts {
  display: grid; grid-template-columns: auto 1fr; gap: 6px 16px;
  margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: 0.93rem;
}
.card-facts dt { color: var(--ink-soft); }
.card-facts dd { margin: 0; font-weight: 600; }
.card-facts__warn { color: var(--danger); }

.card-last { margin-top: 16px; padding: 12px 14px; border-radius: 12px; background: color-mix(in srgb, var(--accent) 7%, transparent); }
.card-last__title { font-size: 0.78rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); }
.card-last__text { margin: 6px 0 0; font-size: 0.92rem; line-height: 1.5; }

.card-acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.card-acts .btn { flex: 1 1 auto; width: auto; margin: 0; padding: 11px 16px; }

/* Строка проверки домашки стала кнопкой — ведёт к карточке ученика. */
button.desk-check__row { width: 100%; border: 0; border-top: 1px solid var(--line); background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
button.desk-check__row:first-of-type { border-top: 0; }
button.desk-check__row:hover .desk-check__who { color: var(--accent); }

/* ============================= ПЕРЕНОС УРОКА ==============================
   Окно, в котором преподаватель отмечает, когда свободен. Неделя по часам:
   занятое нарисовано, свободное отмечается протягиванием. */

.rs__lead { margin: 12px 0 4px; color: var(--ink-soft); font-size: 0.92rem; line-height: 1.5; }
.rs__quote { margin: 0 0 10px; font-size: 0.92rem; }
.rs__list { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.rs__empty { margin: 12px 0; color: var(--ink-soft); font-size: 0.9rem; }
.rs__chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 10px 7px 14px;
  border: 1.5px solid var(--accent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--ink); font: inherit; font-size: 0.88rem; cursor: pointer;
}
.rs__chip-x { font-size: 1.1rem; line-height: 1; color: var(--ink-soft); }
.rs__chip:hover .rs__chip-x { color: var(--danger); }

.rs__weekhead { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.rs__weekhead .week__title { font-weight: 700; }

.rs__cal {
  display: grid;
  grid-template-columns: 46px repeat(7, minmax(0, 1fr));
  grid-template-rows: auto auto;
  column-gap: 3px;
  user-select: none;
  touch-action: none;
}
.rs__corner { grid-row: 1; }
.rs__dayhead {
  grid-row: 1;
  display: flex; align-items: baseline; justify-content: center; gap: 4px;
  padding: 2px 0 6px;
  border-bottom: 1px solid var(--line);
}
.rs__dayhead--today { border-bottom-color: var(--accent); }
.rs__dayhead--today .cal__date { color: var(--accent); }
.rs__cal .cal__hours {
  grid-row: 2;
  /* Календарь переноса — своя, ровная шкала: там выбирают время, а не
     смотрят неделю, и сжимать в нём нечего. */
  display: grid;
  grid-template-rows: repeat(var(--rows, 13), 1fr);
  height: calc(var(--rows, 13) * var(--hour, 44px));
}
.rs__col {
  grid-row: 2;
  position: relative;
  height: calc(var(--rows, 13) * var(--hour, 44px));
  border-left: 1px solid var(--line);
  background-image: repeating-linear-gradient(180deg, var(--line) 0 1px, transparent 1px var(--hour, 44px));
  cursor: crosshair;
}
.rs__busy, .rs__pick {
  position: absolute; left: 0; right: 0;
  box-sizing: border-box;
  display: grid; align-content: start; gap: 1px;
  padding: 3px 5px;
  border-radius: 6px;
  font-size: 0.72rem;
  overflow: hidden;
}
.rs__busy {
  background: color-mix(in srgb, var(--ink) 12%, var(--paper-card));
  color: var(--ink-soft);
  border-left: 3px solid var(--ink-soft);
}
/* Часовая ячейка низкая, и длинное название в неё не влезает. Режем
   многоточием, а целиком показываем подсказкой: обрезанное пополам слово
   читается как поломка, а многоточие — как «здесь ещё есть текст». */
.rs__busy-at { font-weight: 700; line-height: 1.1; }
.rs__busy-what,
.rs__busy-who {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.15;
}
.rs__busy-who { opacity: 0.8; }
.rs__pick {
  background: color-mix(in srgb, var(--accent) 34%, var(--paper-card));
  border: 1.5px solid var(--accent);
  color: var(--ink);
  font-weight: 700;
}
.rs__pick--draft { opacity: 0.6; border-style: dashed; }
.rs__pick-x {
  position: absolute; top: 2px; right: 3px;
  width: 18px; height: 18px;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--ink);
  font-size: 1rem; line-height: 1; cursor: pointer;
}
.rs__pick-x:hover { background: color-mix(in srgb, var(--ink) 14%, transparent); }

.rs__note {
  width: 100%; box-sizing: border-box;
  margin: 14px 0 0;
  padding: 11px 14px;
  border: 1.5px solid var(--line); border-radius: 12px;
  background: var(--paper); color: var(--ink); font: inherit; font-size: 16px;
}
.rs__note:focus { outline: none; border-color: var(--accent); }

/* Кнопки не уезжают под календарь.
   В окне «Когда вам удобно» сначала идёт неделя по часам, и «Отправить»
   оказывалось ниже неё: человек отмечал окна, смотрел на экран и не
   понимал, чем закончить, — кнопки просто не было видно. Теперь ряд
   прилипает ко дну окна и виден всегда. */
.rs__foot {
  position: sticky;
  bottom: 0;
  z-index: 4;
  display: flex;
  gap: 10px;
  margin-top: 16px;
  padding: 12px 0 2px;
  background: linear-gradient(to top,
    var(--paper-card) 70%,
    color-mix(in srgb, var(--paper-card) 0%, transparent));
}
.rs__foot .btn { flex: 1 1 0; width: auto; margin: 0; padding: 11px 16px; }

.rs__sure {
  margin-top: 16px; padding: 14px 16px;
  border: 1.5px solid var(--accent); border-radius: 14px;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.rs__sure-title { margin: 0 0 8px; font-weight: 800; }
.rs__sure-list { margin: 0; padding-left: 20px; display: grid; gap: 4px; font-size: 0.92rem; }
.rs__sure-note { margin: 10px 0 0; font-size: 0.85rem; color: var(--ink-soft); line-height: 1.45; }

.rs__day { margin-top: 14px; }
.rs__day-title { font-weight: 700; margin-bottom: 8px; }

/* Кнопки ответа на просьбу — в ряд, не ссылками: это действия, а не навигация. */
.desk-ask__acts { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 4px; }
.desk-ask__acts .btn { width: auto; margin: 0; }

@media (max-width: 700px) {
  .rs__cal { grid-template-columns: 38px repeat(7, minmax(44px, 1fr)); font-size: 0.9em; }
  .rs__foot { flex-wrap: wrap; }
}

/* ============================ ПОДСКАЗКИ ⓘ ===============================
   Пояснение живёт за кружком и появляется по нажатию. Правило на весь
   кабинет: длинный серый текст под каждым полем читают один раз, а место он
   занимает всегда.

   Класс .tip, а не .hint: .hint уже занят серыми пояснениями под полями
   формы регистрации — их видят один раз в жизни, и там текст на месте.
   Два разных правила под одним именем ломали ту форму. */
.tip { position: relative; display: inline-block; margin-left: 6px; vertical-align: middle; }
.tip__button {
  width: 18px; height: 18px;
  padding: 0;
  border: 1.5px solid color-mix(in srgb, var(--ink-soft) 60%, transparent);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-soft);
  font: inherit;
  font-size: 11px;
  font-weight: 800;
  font-style: italic;
  line-height: 1;
  text-transform: none;
  letter-spacing: 0;
  cursor: pointer;
}
.tip__button:hover { border-color: var(--accent); color: var(--accent); }
.tip__bubble {
  position: absolute;
  left: 0;
  top: calc(100% + 8px);
  /* Куда раскрыться, решает placeBubble в app.js: у правого края экрана
     вправо места нет, и подсказка уезжала за страницу. */
  z-index: 5;
  width: min(300px, 78vw);
  padding: 10px 12px;
  border-radius: 12px;
  background: #18342a;
  color: #f5fbf7;
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: 0;
  text-transform: none;
  box-shadow: 0 10px 28px rgba(10, 38, 32, 0.28);
  animation: tip-in 140ms ease-out;
}
.desk-card--week .tip__bubble {
  width: min(250px, 72vw);
  border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent);
  box-shadow: 0 14px 32px rgb(4 20 13 / 32%);
}
@keyframes tip-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
/* Внизу экрана подсказка раскрывается вверх, а не за нижний край. */
.tip__bubble--up { top: auto; bottom: calc(100% + 8px); }
/* Заголовок блока в профиле — в ряд с кружком. */
.profile-block__title { display: flex; align-items: center; }

/* Крестик в шапке панели: раньше стиль был только у доски. */
.drawer__head .modal__close {
  width: 32px; height: 32px;
  border: 0; border-radius: 50%;
  background: transparent;
  color: var(--ink-soft);
  font-size: 1.5rem; line-height: 1;
  cursor: pointer;
}
.drawer__head .modal__close:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }

/* ============================ ОТЧЁТ v2: ШАГИ ==============================
   По одному вопросу на экран, полоска прогресса сверху, внизу — строка, в
   которой текст родителю собирается по мере нажатий. */

/* ============================ ЗАМЕНЫ ===================================== */
.sub-center { display: grid; gap: 12px; margin-bottom: 18px; }
.sub-create { justify-self: start; }
/* Карточка появляется, а не оказывается на месте.
   Запрос на замену приходит, пока человек смотрит на стол: без движения он
   просто обнаруживает поверх работы новый блок и не понимает, откуда тот
   взялся. Уходит она тем же путём — классом sub-card--leaving. */
.sub-card {
  padding: 18px; border: 1px solid var(--line); border-left: 5px solid var(--accent);
  border-radius: var(--radius-md); background: var(--paper-card); box-shadow: var(--shadow-tight);
  overflow: hidden;
  transition: opacity 260ms ease, transform 260ms ease, max-height 320ms ease,
    margin 320ms ease, padding 320ms ease;
}
@media (prefers-reduced-motion: no-preference) {
  .sub-card { animation: sub-card-in 280ms ease-out; }
}
@keyframes sub-card-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
.sub-card__head, .sub-family, .sub-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sub-card__head { justify-content: space-between; }
.sub-card__head h3 { margin: 0; font-size: 1.05rem; }
.sub-tag, .sub-decision { padding: 3px 8px; border-radius: 999px; background: var(--paper-soft); font-size: .78rem; }
.sub-decision--approve { color: var(--accent); font-weight: 700; }
.sub-decision--decline { color: var(--danger); font-weight: 700; }
.sub-private { margin: 9px 0; color: var(--ink-soft); font-size: .86rem; }
.sub-lessons { display: grid; gap: 8px; margin-top: 12px; }
.sub-lesson { display: grid; gap: 4px; padding-top: 9px; border-top: 1px solid var(--line); font-size: .9rem; }
.sub-family { justify-content: space-between; }
.sub-actions { margin-top: 10px; }
/* ===================== СООБЩИТЬ ОБ ОТСУТСТВИИ ============================
   Была форма из пяти выпадающих списков подряд. Системные селекты в зелёном
   кабинете выглядели чужими, на телефоне открывались во весь экран, а
   главное — из них не видно того, что выбираешь: «Ольга Учитель» в списке
   ничем не отличается от «Ольги Учитель», которая не ведёт этот предмет. */

.sub-form { display: grid; gap: 10px; }
.sub-label {
  margin-top: 6px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.sub-hint { margin: 0; font-size: 0.88rem; color: var(--ink-soft); line-height: 1.5; }

.sub-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.sub-chip {
  padding: 7px 14px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 0.88rem;
  cursor: pointer;
}
.sub-chip:hover { border-color: var(--accent); }
.sub-chip[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  font-weight: 700;
}

.sub-dates { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.sub-dates__word { font-size: 0.86rem; color: var(--ink-soft); }
/* Дальше года вперёд уроков не ставят, и календарь, позволяющий выбрать
   2031 год, — это способ ошибиться, а не свобода. */
.sub-date { margin: 0; width: auto; min-width: 9.5em; }

/* Уроки плитками: видно день, предмет и кто на них. Строка с галочкой
   говорила то же самое, но прочесть её можно было только целиком.
   Имя не «sub-lesson»: так уже называется строка урока в карточке замены,
   и один селектор на две разные вещи — способ однажды покрасить не то. */
.sub-picks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 8px;
  max-height: 320px;
  overflow-y: auto;
  padding: 2px;
}
.sub-pick {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.sub-pick:hover { border-color: var(--accent); }
.sub-pick[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.sub-pick__when { font-size: 0.78rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.sub-pick__what { font-size: 0.95rem; }
.sub-pick__who { font-size: 0.8rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.sub-picks__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.sub-picks__count { font-size: 0.84rem; color: var(--ink-soft); }

/* Заменяющий — карточкой с лицом и предметами. */
.sub-people {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 8px;
}
.sub-person {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.sub-person:hover { border-color: var(--accent); }
.sub-person[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.sub-person__words { display: grid; gap: 1px; min-width: 0; }
.sub-person__subjects { font-size: 0.78rem; color: var(--ink-soft); overflow-wrap: anywhere; }
.sub-board { display: flex; justify-content: space-between; gap: 16px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.sub-board span { color: var(--ink-soft); font-size: .86rem; }
@media (max-width: 620px) {
  .sub-board { display: grid; gap: 2px; }
}

.rep__box { max-height: calc(100dvh - 32px); }
.rep__head { display: block; padding: 0; border-bottom: 1px solid var(--line); }
.rep__bar { height: 4px; background: color-mix(in srgb, var(--accent) 16%, transparent); }
.rep__bar-fill { height: 100%; width: 0; background: var(--accent); transition: width 260ms ease; }
.rep__head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 14px 20px 12px; }
.rep__crumbs { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-soft); }
.rep__title { margin: 2px 0 0; font-size: 1.25rem; }
.rep__body { flex: 1; overflow-y: auto; padding: 16px 20px; min-height: 240px; }

.rep-step { display: grid; gap: 12px; }
@media (prefers-reduced-motion: no-preference) {
  .rep-step--in { animation: rep-in 220ms cubic-bezier(.22,.61,.36,1) both; }
  .rep-step--back { animation: rep-back 220ms cubic-bezier(.22,.61,.36,1) both; }
  .rep-chip--pop { animation: rep-pop 260ms cubic-bezier(.34,1.56,.64,1); }
  .rep-mood__face--pop { animation: rep-pop 320ms cubic-bezier(.34,1.56,.64,1); }
  .rep__live--bump .rep__live-text { animation: rep-fade 260ms ease; }
  .rep--out { animation: rep-out 200ms ease forwards; }
}
@keyframes rep-in { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes rep-back { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
@keyframes rep-pop { 0% { transform: scale(0.92); } 60% { transform: scale(1.06); } 100% { transform: scale(1); } }
@keyframes rep-fade { from { opacity: 0.3; } to { opacity: 1; } }
@keyframes rep-out { to { opacity: 0; } }

.rep-sub { margin-top: 6px; font-size: 0.82rem; font-weight: 700; color: var(--ink-soft); }
.rep-hint { margin: 0; font-size: 0.82rem; color: var(--ink-soft); line-height: 1.45; }
.rep-area { margin: 0; resize: vertical; font-size: 0.95rem; }

.rep-chip--add { border-style: dashed; color: var(--ink-soft); }
.rep-chip-input {
  width: 180px; margin: 0; padding: 8px 12px;
  border: 1.5px solid var(--accent); border-radius: 999px;
  font: inherit; font-size: 0.88rem; background: var(--paper); color: var(--ink);
}

.rep-again {
  margin-top: 8px;
  padding: 10px 14px;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 55%, var(--line));
  border-radius: 12px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  color: var(--accent);
  font: inherit; font-size: 0.9rem; font-weight: 700;
  cursor: pointer;
  text-align: left;
}
.rep-again:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }

/* Ползунок включённости. */
.rep-mood { display: grid; justify-items: center; gap: 4px; padding: 6px 0 2px; }
.rep-mood__face { font-size: 3rem; line-height: 1; }
.rep-mood__label { font-weight: 800; font-size: 1.05rem; }
/* Заливка доходит ровно до кружка.
   Браузер держит кружок внутри дорожки: при нуле его центр стоит не у
   самого края, а на половину своей ширины правее. Полоса же красилась
   ровно по проценту, и у краёв между заливкой и кружком зиял просвет —
   выглядело как два несвязанных элемента. Поправку считает js. */
.rep-slider {
  --fill: 65%;
  width: 100%;
  margin: 10px 0 4px;
  height: 28px;
  padding: 0;
  border: 0;
  box-sizing: border-box;
  appearance: none;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent) var(--fill), color-mix(in srgb, var(--ink) 12%, transparent) var(--fill));
  background-size: 100% 10px;
  background-position: center;
  background-repeat: no-repeat;
  outline: none;
}
.rep-slider::-webkit-slider-thumb {
  appearance: none;
  width: 28px; height: 28px;
  box-sizing: border-box;
  border-radius: 50%;
  background: var(--paper-card);
  border: 3px solid var(--accent);
  box-shadow: 0 4px 12px rgba(10, 38, 32, 0.25);
  cursor: pointer;
}
.rep-slider::-moz-range-thumb {
  box-sizing: border-box;
  width: 28px; height: 28px; border-radius: 50%;
  background: var(--paper-card); border: 3px solid var(--accent); cursor: pointer;
}
.rep-mood__scale { display: flex; justify-content: space-between; width: 100%; font-size: 0.72rem; color: var(--ink-soft); }

/* Живая строка внизу. Её нет у отчёта класса: письмо там одно на всех, и
   собирать его по одному ребёнку не из чего — оставалась пустая полоса. */
.rep__live[hidden] { display: none; }
.rep__live {
  padding: 10px 20px;
  border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  font-size: 0.85rem;
  line-height: 1.45;
  max-height: 5.2em;
  overflow: hidden;
}
.rep__live-label { font-weight: 800; color: var(--accent); }
.rep__live-text { color: var(--ink); }

/* Последний шаг: текст, который уйдёт, и пункты под ним. */
.rep-final { display: grid; gap: 8px; padding-bottom: 12px; }
.rep-final + .rep-final { border-top: 1px solid var(--line); padding-top: 12px; }
.rep-final__name { margin: 0; font-size: 1rem; }
.rep-final__text { margin: 0; resize: vertical; font-size: 0.95rem; line-height: 1.5; }
.rep-final__points, .hist__points {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 12px;
  margin: 0;
  font-size: 0.85rem;
}
.rep-final__points dt, .hist__points dt { color: var(--ink-soft); }
.rep-final__points dd, .hist__points dd { margin: 0; }
.hist__prose { margin: 0 0 8px; font-size: 0.9rem; line-height: 1.5; color: var(--ink); }
.hist__report { white-space: normal; }

/* Готово. */
.rep-done { display: grid; place-items: center; gap: 10px; padding: 40px 0; }
.rep-done__mark {
  width: 72px; height: 72px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--accent); color: var(--on-accent);
  font-size: 2.2rem; font-weight: 800;
  animation: rep-pop 420ms cubic-bezier(.34,1.56,.64,1);
}
.rep-done__text { font-weight: 800; font-size: 1.1rem; }

/* Во весь экран на доске: не окно поверх, а страница на том же зелёном. */
.rep--page { padding: 0; background: var(--paper); place-items: stretch; }
.rep--page .rep__box {
  width: 100%; max-width: none; height: 100dvh; max-height: none;
  border: 0; border-radius: 0; box-shadow: none;
  background: var(--paper);
}
.rep--page .rep__head-row, .rep--page .rep__body, .rep--page .rep__live, .rep--page .rep__foot {
  width: min(720px, 100%); margin: 0 auto;
}
.rep--page .rep__body { padding-top: 24px; }
.rep--page .rep__head { background: var(--paper); }
@media (prefers-reduced-motion: no-preference) {
  .rep--page { animation: rep-page-in 420ms ease both; }
}
@keyframes rep-page-in { from { opacity: 0; } to { opacity: 1; } }

/* ======================== ДОМАШКА НА ДОСКЕ ================================
   Задание, которое можно решить прямо на доске: своя доска у каждого,
   отдельная от урочной. */

.hw-onboard {
  display: flex; align-items: center; gap: 8px;
  margin: 14px 0 0; font-size: 0.92rem; cursor: pointer;
}
.hw-onboard input { width: 18px; height: 18px; margin: 0; accent-color: var(--accent); }

.hw-board { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-top: 0; }
.hw-board .btn { width: auto; margin: 0; }
.hw-board__state { font-size: 0.85rem; color: var(--ink-soft); }
.hw-board__state--warn { color: var(--danger); font-weight: 600; }
.hw-board-slot { display: none; }

/* ===================== ОТЧЁТ О ЗАНЯТИИ КЛАССА ============================
   Про десятерых нельзя спрашивать по отдельности: это десять одинаковых
   наборов экранов подряд. Про занятие спрашиваем один раз, про каждого —
   только присутствие и строчку лично ему. */

.rep-class { display: grid; gap: 10px; margin-top: 12px; }
.rep-class__row {
  display: grid;
  grid-template-columns: 6.5em auto;
  gap: 8px 12px;
  align-items: center;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.rep-class__row:first-child { border-top: 0; }
.rep-class__name { font-weight: 700; }
.rep-class__note {
  grid-column: 1 / -1;
  margin: 0;
  padding: 9px 12px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
}
.rep-class__note:focus { outline: none; border-color: var(--accent); }
/* «на ___ минут» — под кнопками присутствия, в их же колонке: с краю
   строки это читалось как отдельный вопрос, не связанный с «Опоздал». */
.rep-class__row .rep-late { grid-column: 2; margin-top: -2px; }
.rep-class__row--absent { opacity: 0.55; }
.rep-class__row--absent .rep-class__note { display: none; }

/* Личная приписка ребёнку — под своей кнопкой.
   Раньше письма второго и дальше сворачивались стрелкой-невидимкой у имени:
   две точки высотой, по которым нельзя было догадаться, что строка вообще
   раскрывается. Теперь это честная кнопка с подписью, что она сделает. */
.rep-kid {
  display: grid;
  gap: 8px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}
.rep-kid__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 4px 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}
.rep-kid__name { font-weight: 700; }
.rep-kid__sign { font-size: 0.82rem; font-weight: 700; color: var(--accent); white-space: nowrap; }
.rep-kid__head:hover .rep-kid__sign { text-decoration: underline; }
.rep-kid--absent .rep-kid__name { opacity: 0.6; }

@media (max-width: 560px) {
  .rep-class__row { grid-template-columns: 1fr; }
}

/* ------------------------------ колокольчик ------------------------------ */

/* Новости переехали из карточки на столе в шапку. На столе они отодвигали
   собой работу: десять строк «поставлен урок» выше расписания — это лента,
   а не новость, и читать её переставали. */

.header-actions { position: relative; }

.bellbtn {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink);
  cursor: pointer;
  transition: background 140ms ease, transform 140ms ease;
}
.bellbtn:hover { background: color-mix(in srgb, var(--ink) 8%, transparent); }
.bellbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.bellbtn[aria-expanded='true'] { background: color-mix(in srgb, var(--accent) 16%, transparent); }

/* Точка, а не число: важно, есть ли непрочитанное, а не сколько его. */
.bellbtn__dot {
  position: absolute;
  top: 8px; right: 9px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--danger, #c0392b);
  box-shadow: 0 0 0 2px var(--paper-card, #fff);
}

/* Профиль крупнее прежнего: рядом с колокольчиком мелкий кружок выглядел
   приложением к нему, а не человеком. */
.avatar--head { width: 44px; height: 44px; font-size: 0.95rem; }

.bellbox {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 60;
  width: min(420px, calc(100vw - 24px));
  max-height: min(70vh, 560px);
  display: flex;
  flex-direction: column;
  background: var(--paper-card, #fff);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg, 16px);
  box-shadow: 0 18px 48px rgba(18, 59, 46, 0.18);
  overflow: hidden;
  animation: bellbox-in 160ms ease-out;
}
@keyframes bellbox-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}

.bellbox__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.bellbox__title {
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.bellbox__list { overflow-y: auto; padding: 6px; }

/* Строка — оболочка, внутри неё текст-кнопка и, где есть куда идти, кнопка
   перехода. Вложить кнопку в кнопку нельзя, поэтому оболочка нейтральная. */
.bellrow {
  display: grid;
  gap: 8px;
  padding: 10px 12px;
  border-left: 3px solid transparent;
  border-radius: 10px;
  transition: background 120ms ease, opacity 240ms ease, transform 240ms ease;
}
.bellrow__body {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 12px;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
}
.bellrow:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); }
.bellrow__acts { display: flex; flex-wrap: wrap; gap: 6px; }
.bellrow__go { justify-self: start; }
.bellrow__text { font-size: 0.92rem; line-height: 1.45; }
.bellrow__when { font-size: 0.78rem; color: var(--ink-soft); white-space: nowrap; }

/* Срочное — то, из-за чего день планируют заново. */
.bellrow--urgent { border-left-color: var(--danger, #c0392b); }
.bellrow--urgent .bellrow__text { font-weight: 600; }

/* Чужое: пришло по должности, а не по своим ученикам. Голова школы видит и
   то и другое, и без этой метки одно от другого не отличить. */
.bellrow--foreign {
  background: color-mix(in srgb, #f0b429 12%, transparent);
  border-left-color: #f0b429;
}
.bellrow--foreign:hover { background: color-mix(in srgb, #f0b429 20%, transparent); }
.bellrow__who {
  grid-column: 1 / -1;
  font-size: 0.76rem;
  color: var(--ink-soft);
}

/* Сданная работа — дело, а не новость: её открывают и читают. Зелёная
   отметка отличает «есть что посмотреть» от «планы поменялись». */
.bellrow--work {
  background: color-mix(in srgb, #2E9E74 12%, transparent);
  border-left-color: #2E9E74;
}
.bellrow--work:hover { background: color-mix(in srgb, #2E9E74 20%, transparent); }

/* Активные запросы не являются прочитанными новостями: это закреплённые
   состояния рабочего процесса, поэтому у них собственные цвета и действия. */
.bellbox__section {
  padding: 8px 12px 5px;
  color: var(--ink-soft);
  font-size: 0.7rem;
  font-weight: 750;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.bellbox__section--news { margin-top: 5px; border-top: 1px solid var(--line); padding-top: 11px; }
.bellrow--request-sent {
  margin: 2px;
  border-left-color: #2f6fb3;
  background: color-mix(in srgb, #2f6fb3 11%, transparent);
}
.bellrow--request-sent:hover { background: color-mix(in srgb, #2f6fb3 17%, transparent); }
.bellrow--request-incoming {
  margin: 2px;
  border-left-color: #d38b12;
  background: color-mix(in srgb, #f0b429 16%, transparent);
}
.bellrow--request-incoming:hover { background: color-mix(in srgb, #f0b429 23%, transparent); }
.bellrow__request-status {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 0 9px;
  border-radius: 8px;
  background: color-mix(in srgb, #2f6fb3 12%, transparent);
  color: #2f6fb3;
  font-size: 0.75rem;
  font-weight: 700;
}
.bellrow__request-cancel { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, var(--line)); }

/* Появление и уход. Новость, прилетевшая при открытом списке, должна
   появиться на глазах, а не оказаться там молча. */
.bellrow--fresh { animation: bellrow-in 260ms ease-out; }
@keyframes bellrow-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
.bellrow--gone { opacity: 0; transform: translateX(28px); }

.bellbox__empty {
  padding: 26px 18px;
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.92rem;
}

@media (max-width: 560px) {
  .bellbox { right: -8px; width: calc(100vw - 20px); }
}

/* --------------------------- «замена найдена» ---------------------------- */

/* Пока идёт поиск, карточка замены стоит наверху стола и отодвигает работу:
   вопрос не решён. Как только нашли, подробности не нужны — нужно одно
   слово. Зелёным, крупно, и потом карточка уходит, а стол поднимается. */

.sub-card--done {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--accent, #1F7A5A);
  border-color: var(--accent, #1F7A5A);
  color: #fff;
  animation: sub-done-in 320ms ease-out;
  transition: opacity 420ms ease, transform 420ms ease, margin 420ms ease, padding 420ms ease, max-height 420ms ease;
  max-height: 160px;
  overflow: hidden;
}
@keyframes sub-done-in {
  from { opacity: 0; transform: scale(0.985); }
  to { opacity: 1; transform: none; }
}

/* Уходит вверх и схлопывается по высоте, чтобы стол поднялся плавно, а не
   прыгнул на её место. */
.sub-card--leaving {
  opacity: 0;
  transform: translateY(-10px);
  max-height: 0;
  margin-top: 0;
  margin-bottom: 0;
  padding-top: 0;
  padding-bottom: 0;
}

.sub-done__tick {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
  font-size: 1.05rem;
  font-weight: 700;
}
.sub-done__words { display: grid; gap: 2px; }
.sub-done__title { font-size: 1.06rem; }
.sub-done__who { font-size: 0.88rem; opacity: 0.86; }

@media (prefers-reduced-motion: reduce) {
  .sub-card--done { animation: none; transition: opacity 200ms linear; }
  .sub-card--leaving { transform: none; }
}

/* ------------------------------- ученики --------------------------------- */

/* Раньше на каждого ребёнка была своя карточка, и они стояли в столбик разной
   высоты: у одного пусто, у другого густо, между ними дыра. Читались как
   разные разделы кабинета, хотя вопрос один — как идут дела у детей. */

.desk-card--kids { gap: 0; }

.desk-kid {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) minmax(0, 1.1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 14px 2px;
  border-top: 1px solid var(--line);
}
.desk-kid:first-of-type { border-top: 0; padding-top: 6px; }

.desk-kid__face {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--tint, #1F7A5A);
  color: #fff;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.desk-kid__face[data-tint='mint'] { --tint: #1F7A5A; }
.desk-kid__face[data-tint='gold'] { --tint: #C8961E; }
.desk-kid__face[data-tint='sky']  { --tint: #2E6F8E; }
.desk-kid__face[data-tint='plum'] { --tint: #79427A; }
.desk-kid__face[data-tint='clay'] { --tint: #A9553C; }
.desk-kid__face[data-tint='moss'] { --tint: #4B7038; }

.desk-kid__who { display: grid; gap: 2px; min-width: 0; }
.desk-kid__name { font-size: 0.98rem; }
.desk-kid__next {
  font-size: 0.84rem;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.desk-kid__task { min-width: 0; }
.desk-kid__value { font-size: 0.9rem; color: var(--ink-soft); }
.desk-kid__more { justify-self: end; }

/* На телефоне четыре столбца не встают: имя сверху, полоса под ним. */
@media (max-width: 620px) {
  .desk-kid {
    grid-template-columns: auto minmax(0, 1fr) auto;
    row-gap: 8px;
  }
  .desk-kid__task { grid-column: 2 / -1; }
  .desk-kid__more { grid-column: 2 / -1; justify-self: start; }
}

/* --------------------------- тревога в приветствии ----------------------- */

/* Кончившийся абонемент — не «число, на которое можно посмотреть потом»:
   пока он не продлён, уроки списывать нечем. Поэтому строка, а не счётчик,
   и в самой заметной части кабинета. */

.desk-hello__alerts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.desk-alert {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 13px;
  border: 1px solid color-mix(in srgb, var(--danger, #c0392b) 42%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--danger, #c0392b) 10%, var(--paper-card));
  color: var(--danger, #c0392b);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 140ms ease;
}
.desk-alert:hover { background: color-mix(in srgb, var(--danger, #c0392b) 18%, var(--paper-card)); }
.desk-alert__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  flex: 0 0 auto;
}

/* ===== правка вида: значок подсказки, лица, классы, отчёты ============== */

/* Знак вместо буквы «i» курсивом. Буква зависела от шрифта, съезжала с
   середины кружка, а в заголовке из прописных читалась как опечатка. */
.tip {
  display: inline-grid;
  place-items: center;
  vertical-align: middle;
  margin-left: 7px;
  /* Заголовок плитки набран прописными с разрядкой и приподнят по базовой
     линии. Знак выравниваем по середине строки, а не по буквам. */
  translate: 0 -1px;
}
.tip__button {
  display: grid;
  place-items: center;
  width: 17px;
  height: 17px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: color-mix(in srgb, var(--ink-soft) 85%, transparent);
  cursor: pointer;
  transition: color 140ms ease, background 140ms ease;
}
.tip__button svg { width: 17px; height: 17px; display: block; }
.tip__button:hover {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
.tip__button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Кружок человека в строках стола. Тот же, что в шапке и в профиле. */
.desk-face {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--tint, #1F7A5A);
  color: #fff;
  font-size: 0.74rem;
  font-weight: 700;
}

.desk-student__name { min-width: 0; }

/* Главное действие плитки — кнопкой, а не строкой текста. */
.desk-card__do { align-self: flex-start; margin-top: 4px; }

/* ------------------------------- классы ---------------------------------- */

.desk-classes { display: grid; gap: 8px; }
/* Строка класса переносится по содержимому, а не по ширине экрана.
   Три жёсткие колонки не влезали в половину стола: метки и кнопка ширину не
   отдают, и на название класса оставалось ноль пикселей — оно исчезало, а
   соседи выглядели наехавшими друг на друга. Ширина плитки зависит от места
   на столе, а не от экрана, поэтому медиазапрос тут не помогал. */
.desk-class {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
}
.desk-class__who {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  /* Без переносов: «7Б ·» с обрывком «английский» на второй строке читалось
     как поломка вёрстки, а не как название класса. */
  white-space: nowrap;
  overflow: hidden;
}
.desk-class__name { font-size: 1rem; flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; }
.desk-class__subject {
  font-size: 0.86rem;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Название получает не меньше 150 px и растёт первым: оно и есть ответ на
   вопрос «какой это класс». Метки и кнопка уходят на вторую строку. */
.desk-class__who { flex: 1 1 150px; }
.desk-class__marks { display: flex; flex-wrap: wrap; gap: 6px; flex: 0 1 auto; }
.desk-class > .btn { flex: 0 0 auto; margin-left: auto; }

/* ------------------------------- отчёты ---------------------------------- */

/* Сначала лица, потом текст: три развёрнутых отчёта подряд — стена слов, и
   писать их один за другим никто не станет. */
.desk-owed { display: grid; gap: 6px; }
.desk-owed__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: none;
  text-align: left;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease;
}
.desk-owed__row:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}
.desk-owed__words { display: grid; gap: 2px; min-width: 0; }
.desk-owed__who { font-size: 0.95rem; }
.desk-owed__what {
  font-size: 0.82rem;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Ряд разделов и действия справа. Раньше «Сообщить об отсутствии» стояло
   отдельной строкой под вкладками: одно действие занимало целую линию
   каждый день ради случая раз в месяц. */
.nav-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.nav-row .tabs--nav { margin-right: auto; }
.nav-row__acts { display: flex; align-items: center; gap: 8px; }
.sub-create { justify-self: auto; }

@media (max-width: 620px) {
  .nav-row { gap: 8px; }
  .nav-row__acts { width: 100%; }
  .nav-row__acts .btn { width: 100%; }
}

/* ===== расписание: свёрнутое управление ================================= */

/* Девять кнопок под каждой строкой расписания — это не управление, а шум:
   на неделю вперёд их читают девять раз и ни разу не нажимают. Пока урок
   далеко, они свёрнуты; открыть можно всегда. */
.lesson__groups--folded { display: none; }

.lesson__unfold {
  align-self: flex-start;
  margin-top: 4px;
  padding: 5px 12px 5px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.84rem;
  cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease;
}
/* Стрелка раскрытия — нарисованная, а не знак «⌄» из шрифта.
   Знак сидел на своей строке, болтался по вертикали и в разных шрифтах
   выглядел по-разному: то галочкой, то запятой. Здесь это два ребра
   квадрата, которые поворачиваются при раскрытии. */
.lesson__unfold::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  margin: -3px 8px 0 2px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  border-radius: 1px;
  transform: rotate(45deg);
  transition: transform 160ms ease;
  vertical-align: middle;
}
.lesson__unfold[aria-expanded='true']::before { transform: rotate(-135deg); margin-top: 2px; }

.lesson__unfold:hover { border-color: var(--accent); color: var(--accent); }

/* Ссылка на созвон: доска в кабинете своя, а разговаривают в Телемосте.
   Живёт на уроке, а не в переписке, — значит, видна тем, кто на уроке, и
   остаётся в архиве, когда урок пройдёт. */
.lesson__meet {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-top: 8px;
}
.lesson__meet-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
  margin-top: 4px;
}
.lesson__meet-form .nl__field { flex: 1 1 260px; margin: 0; }

/* «Заполнить отчёт» — действие, а не примечание. */
.lesson__report { align-self: flex-start; margin-top: 2px; }

/* Списано занятие или нет — это про урок, поэтому стоит в его шапке, рядом
   со статусом. В ряду кнопок эта строка читалась как ещё одна кнопка,
   только почему-то не нажимающаяся. */
.charge-note {
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--ink-soft);
}
.charge-note--free { color: var(--accent); }

/* Разговор о переносе, который уже был: в архиве от него остаётся память,
   а не кнопки. */
.lesson__ask-past {
  margin: 6px 0 0;
  font-size: 0.86rem;
  color: var(--ink-soft);
}

/* Отмена: причина и переспрос. */
.lesson__why {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
  margin-top: 8px;
  padding: 9px 12px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--ink) 5%, transparent);
}
.lesson__why--wide { display: grid; gap: 8px; justify-items: start; }
.lesson__why-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lesson__why-field { margin: 0; width: min(240px, 100%); }
.lesson__why-text { font-size: 0.88rem; font-weight: 600; }

/* «Неделя» и «Поставить урок» — одного роста: рядом они читаются как пара. */
.week-toggle[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

/* ===== домашка ========================================================== */

/* Преподавателю пункты свёрнуты: он их только что сам и написал, а закрывают
   они собой то, ради чего он сюда пришёл — кто сдал и что с этим делать. */
.hw__items--folded { display: none; }

.hw__unfold {
  align-self: flex-start;
  margin: 2px 0 6px;
  padding: 5px 12px 5px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.84rem;
  cursor: pointer;
}
/* Стрелка раскрытия — нарисованная, а не знак «⌄» из шрифта.
   Знак сидел на своей строке, болтался по вертикали и в разных шрифтах
   выглядел по-разному: то галочкой, то запятой. Здесь это два ребра
   квадрата, которые поворачиваются при раскрытии. */
.hw__unfold::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  margin: -3px 8px 0 2px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  border-radius: 1px;
  transform: rotate(45deg);
  transition: transform 160ms ease;
  vertical-align: middle;
}
.hw__unfold[aria-expanded='true']::before { transform: rotate(-135deg); margin-top: 2px; }

.hw__unfold:hover { border-color: var(--accent); color: var(--accent); }

/* Строка ученика: сначала человек, потом действия. Имя без лица в ряду из
   пяти кнопок терялось, и строка читалась как набор кнопок ни о ком. */
.hw__review {
  display: grid;
  gap: 8px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.hw__who {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  margin-right: auto;
}
.hw__student { font-weight: 700; }

/* Два ряда действий, у каждого своя подпись: «работа» — это её открыть и
   отметить прочитанной, «решение» — это принять или вернуть. Вперемешку в
   одну строку они читались как четыре равные кнопки, между которыми
   зачем-то вставлен текст «сдано, не проверено». */
.hw__verdict-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding-left: 42px;
  width: 100%;
}
.hw__verdict-name {
  flex: 0 0 5.2em;
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Состояние работы — меткой у имени, а не строчкой между кнопками. */
.hw__state {
  padding: 2px 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  color: var(--ink-soft);
  font-size: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
}
.hw__state--warn {
  background: color-mix(in srgb, var(--danger) 14%, transparent);
  color: var(--danger);
}
.hw__state--ok {
  background: color-mix(in srgb, #2E9E74 16%, transparent);
  color: #2E9E74;
}

@media (max-width: 620px) {
  .hw__verdict-row { padding-left: 0; }
  .hw__verdict-name { flex-basis: 100%; }
}

/* ===== «Задать домашку»: каждый пункт своей строкой =================== */

/* Одним полем «каждый пункт с новой строки» пункты сливались в стену текста:
   не видно, сколько их, нельзя поменять местами и негде ошибиться заметно.
   Отдельные строки — это ровно то, что ребёнок увидит у себя списком. */

.hw-lines { display: grid; gap: 8px; margin-bottom: 10px; }

/* Пункт: строка с полем и ряд отметок под ней. */
.hw-line {
  display: grid;
  gap: 6px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}
.hw-line:first-child { border-top: 0; padding-top: 0; }
.hw-line__top {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 10px;
}
.hw-line__top .hw-line__num { margin-top: 0; align-self:center; }
.hw-line__num {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  color: var(--ink-soft);
  font-size: 0.78rem;
  font-weight: 700;
}
/* Поле растёт вниз по тексту. Раньше это была строка ввода: длинный пункт
   уезжал за правый край, и увидеть его целиком было нельзя ни при наборе,
   ни при правке. */
.hw-line__field {
  margin: 0;
  resize: none;
  overflow: hidden;
  min-height: 42px;
  line-height: 1.45;
}

/* Отметки пункта: где его делают и к какому занятию. */
.hw-line__marks { display: flex; flex-wrap: wrap; gap: 6px; padding-left: 34px; }
.hw-mark {
  padding: 5px 12px;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  background: none;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}
.hw-mark:hover { border-color: var(--accent); color: var(--accent); }
.hw-mark[aria-pressed='true'] {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--ink);
  font-weight: 700;
}

/* Выбор занятия — блоками, а не выпадающим списком: занятий три-четыре, и
   каждое надо узнать по дню и времени, а не по строчке мелким шрифтом. */
.hw-when {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 6px;
  margin: 2px 0 2px 34px;
  padding: 8px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: color-mix(in srgb, var(--ink) 3%, transparent);
}
.hw-when__one {
  display: grid;
  gap: 1px;
  padding: 8px 10px;
  border: 1.5px solid transparent;
  border-radius: 10px;
  background: var(--paper-card);
  color: var(--ink);
  font: inherit;
  font-size: 0.82rem;
  text-align: left;
  cursor: pointer;
}
.hw-when__one:hover { border-color: var(--accent); }
.hw-when__one[aria-pressed='true'] { border-color: var(--accent); font-weight: 700; }
.hw-when__day { font-weight: 700; }
.hw-when__what { color: var(--ink-soft); font-size: 0.78rem; }
.hw-line__drop {
  align-self: center;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--ink-soft);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}
.hw-line__drop:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); color: var(--danger); }

.hw-lines__add {
  align-self: flex-start;
  padding: 6px 14px;
  border: 1px dashed var(--line);
  border-radius: 999px;
  background: none;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.86rem;
  cursor: pointer;
}
.hw-lines__add:hover { border-color: var(--accent); color: var(--accent); }

/* Подсказка у «можно сделать на доске» вылезала за окно и закрывала кнопки.
   Поднимаем её над строкой и не даём быть шире окна. */
.hw-onboard { display: flex; align-items: center; gap: 8px; margin: 10px 0 4px; }
.hw-onboard .tip__bubble { width: min(320px, calc(100% + 240px)); }

/* Черта «сейчас» в остальных днях — бледная: видно и который час, и какой
   день сегодня, а пустой день перестал выглядеть промежутком между днями. */
.cal__now--pale { background: color-mix(in srgb, #e5484d 32%, transparent); height: 1px; }
.cal__now--pale::before { display: none; }

/* Закрытый урок: менять нечего, и кнопок здесь нет. */
.lesson__closed {
  margin: 6px 0 0;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

/* Подтверждение домашки одной кнопкой. Раньше каждое нажатие уходило на
   сервер и перерисовывало раздел: страница дёргалась под рукой. */
.hw-confirm {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  animation: hw-confirm-in 160ms ease-out;
}
@keyframes hw-confirm-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}

/* ===== единый центр домашней работы ==================================== */
.homework-page { padding-bottom: 52px; }
.homework-page__head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;
  margin-bottom: 22px;
}
.homework-page__head h1 { margin: 2px 0 0; font-size: clamp(2rem, 4vw, 3rem); letter-spacing: -.045em; }
.homework-page__eyebrow { margin: 0; color: var(--accent); font-size: .72rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; }
.homework-page__intro { max-width: 620px; margin: 8px 0 0; color: var(--ink-soft); }
.homework-page__head-actions { display: flex; gap: 8px; }
.homework-page__create { width: auto; margin: 0; white-space: nowrap; }
.homework-page__guide { display: inline-block; margin-top: 18px; }

.hw-tabs {
  display: flex; gap: 4px; margin-bottom: 14px; padding: 4px; overflow-x: auto;
  border: 1px solid var(--line); border-radius: 15px; background: var(--paper-card);
  scrollbar-width: none;
}
.hw-tabs::-webkit-scrollbar { display: none; }
.hw-tabs__one {
  flex: none; min-height: 38px; padding: 7px 13px; border: 0; border-radius: 11px;
  background: transparent; color: var(--ink-soft); font: inherit; font-size: .84rem;
  font-weight: 700; cursor: pointer;
}
.hw-tabs__one:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 5%, transparent); }
.hw-tabs__one[aria-pressed='true'] { background: var(--ink); color: var(--paper-card); }

.hw-toolbar {
  display: grid; grid-template-columns: minmax(220px, 1fr) auto auto auto;
  align-items: center; gap: 8px; margin-bottom: 12px;
}
.hw-toolbar__search, .hw-toolbar__select {
  min-height: 42px; margin: 0; padding: 9px 12px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--paper-card); color: var(--ink); font: inherit; font-size: .86rem;
}
.hw-toolbar__search:focus, .hw-toolbar__select:focus { outline: 2px solid color-mix(in srgb, var(--accent) 35%, transparent); border-color: var(--accent); }
.hw-toolbar__found { padding-inline: 7px; color: var(--ink-soft); font-size: .8rem; white-space: nowrap; }

.hw-workspace {
  display: grid; grid-template-columns: minmax(310px, 390px) minmax(0, 1fr);
  min-height: 620px; overflow: hidden; border: 1px solid var(--line);
  border-radius: 22px; background: var(--paper-card); box-shadow: var(--shadow-soft);
}
.hw-queue { min-width: 0; padding: 8px; overflow-y: auto; border-right: 1px solid var(--line); background: var(--paper-soft); }
.hw-work {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px 12px;
  width: 100%; margin: 0; padding: 12px; border: 1px solid transparent;
  border-radius: 14px; background: transparent; color: var(--ink); font: inherit; text-align: left; cursor: pointer;
}
.hw-work + .hw-work { margin-top: 3px; }
.hw-work:hover { background: var(--paper-card); }
.hw-work--selected { border-color: color-mix(in srgb, var(--accent) 36%, var(--line)); background: var(--paper-card); box-shadow: 0 7px 20px rgb(12 45 33 / 7%); }
.hw-work__face { grid-row: 1 / 3; width: 36px; height: 36px; font-size: .7rem; }
.hw-work__words { display: grid; min-width: 0; gap: 2px; }
.hw-work__who, .hw-work__title, .hw-work__meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-work__who { font-size: .88rem; }
.hw-work__title { color: var(--ink); font-size: .82rem; }
.hw-work__meta { color: var(--ink-soft); font-size: .72rem; }
.hw-status {
  grid-column: 2; justify-self: start; padding: 3px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 7%, transparent); color: var(--ink-soft);
  font-size: .67rem; font-weight: 750;
}
.hw-status--review { background: #E8EFFF; color: #284D9B; }
[data-theme='dark'] .hw-status--review { background: #24364B; color: #BED5FF; }
.hw-status--rework, .hw-status--late, .hw-status--missed, .hw-status--not_reworked { background: color-mix(in srgb, var(--danger) 11%, transparent); color: var(--danger); }
.hw-status--accepted { background: color-mix(in srgb, #2e9e74 14%, transparent); color: #287052; }
.hw-status--discuss { background: color-mix(in srgb, #2f6fb0 12%, transparent); color: #2f6fb0; }

.hw-stage { min-width: 0; overflow-y: auto; }
.hw-stage__empty, .hw-empty { display: grid; min-height: 240px; place-items: center; padding: 30px; color: var(--ink-soft); text-align: center; }
.hw-detail { max-width: 860px; margin-inline: auto; padding: clamp(22px, 4vw, 38px); }
.hw-detail__head { padding-bottom: 20px; border-bottom: 1px solid var(--line); }
.hw-detail__eyebrow { color: var(--accent); font-size: .74rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.hw-detail__head h2 { margin: 5px 0 0; font-size: clamp(1.35rem, 2.4vw, 2rem); letter-spacing: -.035em; }
.hw-detail__meta { margin: 7px 0 0; color: var(--ink-soft); font-size: .85rem; }
.hw-detail__section { padding: 22px 0; border-bottom: 1px solid var(--line); }
.hw-detail__section h3, .hw-decision h3 { margin: 0 0 12px; font-size: .78rem; letter-spacing: .075em; text-transform: uppercase; color: var(--ink-soft); }
.hw-detail__items { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 320px)); gap: 10px; align-items: stretch; }
.hw-task {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px;
  align-content: start; justify-items: start; width: 100%; padding: 14px 16px; border: 1px solid var(--line);
  border-radius: 12px; background: transparent; color: var(--ink); font: inherit; text-align: left;
}
button.hw-task { cursor: pointer; }
button.hw-task:hover { border-color: var(--accent); }
.hw-task__state { color: var(--danger); background: color-mix(in srgb, var(--danger) 9%, transparent); border-radius: 7px; padding: 4px 7px; font-size: .7rem; font-weight: 750; }
.hw-task--done .hw-task__state { color: var(--ink); background: color-mix(in srgb, #287052 18%, var(--paper-card)); }
.hw-task__body { min-width: 0; line-height: 1.45; overflow-wrap: anywhere; }
.hw-task__due { color: var(--ink-soft); font-size: .72rem; }
.hw-detail__materials, .hw-detail__work-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.hw-detail__material {
  display: inline-flex; width: auto; margin: 0; padding: 7px 11px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--paper-soft); color: var(--ink); font: inherit; font-size: .8rem; text-decoration: none; cursor: pointer;
}
.hw-detail__material:hover { border-color: var(--accent); }
.hw-detail__muted { margin: 0; color: var(--ink-soft); font-size: .86rem; line-height: 1.5; }
.hw-detail__work-actions .btn { width: auto; margin: 0; }

.hw-detail__tests { display: grid; gap: 7px; margin-top: 12px; }
.hw-test-line { display: grid; grid-template-columns: 112px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 12px; background: var(--paper-soft); }
.hw-test-line__state { color: var(--ink-soft); font-size: .72rem; font-weight: 750; }
.hw-test-line .hw-detail__material { background: var(--paper-card); }
.hw-decision { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 20px 0; border-bottom: 1px solid var(--line); }
.hw-decision h3 { flex-basis: 100%; }
.hw-decision .btn { width: auto; margin: 0; }
.hw-decision .btn--quiet { border-color: var(--line); background: var(--paper-card); color: var(--ink); }
.hw-decision .btn--quiet:hover, .hw-decision .btn--quiet:focus-visible { border-color: var(--ink-soft); color: var(--ink); background: var(--paper-soft); }
.hw-decision .hw-decision__missed{border-color:color-mix(in srgb,var(--danger) 30%,var(--line));background:color-mix(in srgb,var(--danger) 10%,var(--paper-card));color:var(--danger)}
.hw-decision .hw-decision__missed:hover:not(:disabled){border-color:color-mix(in srgb,var(--danger) 48%,var(--line));background:color-mix(in srgb,var(--danger) 17%,var(--paper-card));color:var(--danger)}
.hw-feedback { margin-top: 18px; padding: 16px 18px; border-left: 3px solid var(--accent); border-radius: 12px; background: color-mix(in srgb, var(--accent) 8%, transparent); }
.hw-feedback p { margin: 6px 0 0; line-height: 1.55; }
.hw-timeline__event { position: relative; display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; gap: 5px 9px; padding: 4px 0 15px; font-size: .82rem; }
.hw-timeline__event::before { content: ''; position: absolute; left: 5px; top: 15px; bottom: -3px; width: 1px; background: var(--line); }
.hw-timeline__event:last-child::before { display: none; }
.hw-timeline__dot { z-index: 1; width: 11px; height: 11px; margin-top: 3px; border: 2px solid var(--paper-card); border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.hw-timeline__event time { color: var(--ink-soft); font-size: .72rem; }
.hw-timeline__event p { grid-column: 2 / -1; margin: 0; color: var(--ink-soft); }
.hw-class-grid { display: grid; grid-template-columns: repeat(auto-fill,minmax(190px,1fr)); gap: 7px; }
.hw-class-person, .hw-lesson-picker__one { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--paper-soft); color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.hw-class-person span, .hw-lesson-picker__one span { color: var(--ink-soft); font-size: .78rem; }
.hw-lesson-picker { display: grid; gap: 7px; }
.hw-lesson-picker__one:hover, .hw-class-person:hover { border-color: var(--accent); }
.hw-delivery { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 16px 0; }
.hw-delivery__one { display: grid; gap: 3px; padding: 13px 14px; border: 1.5px solid var(--line); border-radius: 13px; background: var(--paper-card); color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.hw-delivery__one span { color: var(--ink-soft); font-size: .78rem; line-height: 1.4; }
.hw-delivery__one[aria-pressed='true'] { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, var(--paper-card)); }

@media (max-width: 900px) {
  .hw-workspace { grid-template-columns: minmax(270px, 330px) minmax(0, 1fr); }
  .hw-toolbar { grid-template-columns: minmax(180px, 1fr) auto; }
  .hw-toolbar__found { display: none; }
}
@media (max-width: 700px) {
  .homework-page__head { align-items: flex-start; flex-direction: column; gap: 14px; }
  .homework-page__create { width: 100%; }
  .homework-page__head-actions { width: 100%; }
  .hw-toolbar { grid-template-columns: 1fr 1fr; }
  .hw-toolbar__search { grid-column: 1 / -1; }
  .hw-workspace { display: block; min-height: 0; overflow: visible; border: 0; border-radius: 0; box-shadow: none; background: transparent; }
  .hw-queue { max-height: 320px; border: 1px solid var(--line); border-radius: 16px; background: var(--paper-card); }
  .hw-stage { margin-top: 12px; border: 1px solid var(--line); border-radius: 18px; background: var(--paper-card); }
  .hw-detail { padding: 20px 16px; }
  .hw-task { grid-template-columns: minmax(0,1fr); }
  .hw-task__due { grid-column: 1; }
  .hw-test-line { grid-template-columns: 1fr auto; }
  .hw-test-line__state { grid-column: 1 / -1; }
  .hw-delivery { grid-template-columns: 1fr; }
}

/* «Подробнее» в списке детей стояло вплотную к полосе домашки: два разных
   по смыслу элемента читались как один. */
.desk-kid__task { padding-right: 14px; }
.desk-kid__more { margin-left: 8px; }

/* ===== импорт встроенного теста ======================================= */
.test-import { display: grid; gap: 12px; }
.test-import__tools { display: flex; flex-wrap: wrap; gap: 8px; }
.test-import__choose { position: relative; }
.test-import__filename { color: var(--ink-soft); font-size: .84rem; }
.test-import__source {
  width: 100%; min-height: 280px; resize: vertical;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: .86rem; line-height: 1.45;
}
.test-import__report { display: grid; gap: 5px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 14px; }
.test-import__report--ok { border-color: color-mix(in srgb, #2e9e74 55%, var(--line)); background: color-mix(in srgb, #2e9e74 8%, transparent); }
.test-import__report--error { border-color: color-mix(in srgb, var(--danger) 55%, var(--line)); background: color-mix(in srgb, var(--danger) 8%, transparent); }
.test-import__report ul { margin: 6px 0 0; padding-left: 20px; }
.test-import__questions { max-height: 220px; overflow: auto; margin: 10px 0 0; padding-left: 24px; }
.test-import__questions li { padding: 4px 0; }
.tb-field{display:grid;gap:5px;color:var(--ink-soft);font-size:.72rem}.tb-field .nl__field{width:100%;min-width:0}
.hw-lesson-picker__row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:stretch}.hw-lesson-picker__row+.hw-lesson-picker__row{margin-top:8px}.hw-lesson-picker__prep{white-space:nowrap}
@media(max-width:600px){.hw-lesson-picker__row{grid-template-columns:1fr}.hw-lesson-picker__prep{width:100%}}

/* Домашка раскрывается как аккордеон. Так компактная очередь не держит
   рядом пустую колонку высотой с подробную карточку: выбранная работа
   занимает всю доступную ширину, остальные остаются короткими строками. */
.hw-accordion{display:grid;gap:10px}.hw-fold{overflow:hidden;border:1px solid var(--line);border-radius:18px;background:var(--paper)}.hw-fold>.hw-work{width:100%;min-height:76px;border:0;border-radius:0;background:transparent;grid-template-columns:auto minmax(0,1fr) auto;padding:14px 18px;text-align:left}.hw-fold>.hw-work:hover{background:color-mix(in srgb,var(--accent) 5%,transparent)}.hw-fold--open{border-color:color-mix(in srgb,var(--accent) 32%,var(--line));box-shadow:0 14px 34px color-mix(in srgb,var(--ink) 7%,transparent)}.hw-fold--open>.hw-work{background:color-mix(in srgb,var(--accent) 7%,var(--paper));border-bottom:1px solid var(--line)}.hw-fold--open>.hw-work>.hw-status{display:none}.hw-fold__toggle{display:inline-flex;align-items:center;gap:7px;align-self:center;padding:8px 12px;border:1px solid color-mix(in srgb,var(--ink-soft) 42%,var(--line));border-radius:10px;background:color-mix(in srgb,var(--paper-card) 86%,transparent);color:var(--ink);font-size:.75rem;font-weight:750;line-height:1;box-shadow:0 2px 7px color-mix(in srgb,var(--ink) 6%,transparent)}.hw-fold__toggle::before{content:'⌃';font-size:.9rem;line-height:.7;color:var(--accent)}.hw-fold>.hw-work:hover .hw-fold__toggle{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 9%,var(--paper-card))}.hw-fold>.hw-detail{border:0;border-radius:0;background:transparent;padding:22px 28px 26px}.hw-fold>.hw-detail>.hw-detail__head{display:none}.hw-fold__back{margin:14px 18px 0;border:0;background:none;color:var(--accent);font:inherit;font-weight:750;cursor:pointer}.hw-fold--exception>.hw-detail>.hw-detail__head{display:block}
@media(max-width:700px){.hw-fold>.hw-work{grid-template-columns:auto minmax(0,1fr);padding:13px 14px}.hw-fold>.hw-work>.hw-status{display:none}.hw-fold__toggle{grid-column:2;justify-self:end;padding:7px 10px}.hw-fold>.hw-detail{padding:18px 16px 22px}}
.hw-composer__heading{margin:20px 0 10px;font-size:.86rem;color:var(--ink);font-weight:800}.hw-line__fragments{display:flex;flex-wrap:wrap;gap:7px;padding-left:34px}.hw-fragment{position:relative;display:grid;gap:3px;max-width:100%;padding:9px 34px 9px 12px;border:1px solid var(--line);border-radius:11px;background:color-mix(in srgb,var(--accent) 5%,var(--paper-card));font-size:.75rem}.hw-fragment>span{color:var(--ink-soft);font-size:.68rem}.hw-fragment>.hw-material__drop{position:absolute;right:7px;top:50%;transform:translateY(-50%)}.lib-pick-tools{display:grid;grid-template-columns:minmax(0,1fr) 190px;gap:10px;margin-bottom:14px}.lib-fragment-list{display:grid;gap:8px}.lib-fragment-list .lib-row--book{display:flex;align-items:center;gap:14px;width:100%;text-align:left}.lib-fragment-list .lib-book-cover{flex:0 0 64px;width:64px;height:88px}.hw-lesson-picker__heading{margin:18px 0 9px;font-size:.78rem;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.05em}
@media(max-width:600px){.lib-pick-tools{grid-template-columns:1fr}.hw-line__fragments{padding-left:0}}

/* Report workspace and archive */
.rep-section { padding: 16px 0; border-top: 1px solid var(--line); }
.rep-section > summary { font-size: 1rem; font-weight: 700; cursor: pointer; padding: 10px 0; }
.rep-section[open] { display: block; }
.rep-section .rep-chips { margin: 8px 0 14px; }
.rep-field { display: grid; gap: 8px; margin: 14px 0; }
.rep-field.rep-checkbox { display:flex; align-items:center; gap:10px; cursor:pointer; }
.rep-checkbox input[type='checkbox'] { width:18px; height:18px; padding:0; margin:0; flex:0 0 18px; accent-color:var(--accent); }
.rep-checkbox span { line-height:1.5; }
.rep-field .rep-sub { margin: 0; }
.rep-select,.rep-search { width: 100%; box-sizing: border-box; padding: 12px; color: var(--ink); background: var(--paper); border: 1px solid var(--line); border-radius: 10px; font: inherit; }
.rep-area,.rep-final__text { width: 100%; box-sizing: border-box; resize: vertical; }
.rep-save-status { flex: 1; margin: 0; font-size: .82rem; color: var(--ink-soft); }
.rep__foot { flex-wrap: wrap; }
.rep-countdown { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.rep-archive-item { padding: 16px 0; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.rep-archive-item h3 { margin: 0 0 8px; }
.rep-archive-prose { white-space: pre-wrap; line-height: 1.65; }
/* Homework folds retain their DOM so opening and closing can both animate. */
.hw-fold { transition: border-color 280ms ease, box-shadow 280ms ease; }
.hw-fold > .hw-work { grid-template-columns: 48px minmax(0,1fr) auto 120px; align-items: center; gap: 16px; min-height: 116px; padding: 20px 24px; transition: background 280ms ease; }
.hw-fold > .hw-work > .hw-work__face { grid-column: 1; grid-row: 1; width: 48px; height: 48px; font-size: .85rem; }
.hw-fold > .hw-work > .hw-work__words { grid-column: 2; grid-row: 1; gap: 6px; }
.hw-fold .hw-work__who { font-size: 1.05rem; }
.hw-fold .hw-work__title { font-size: 1.3rem; font-weight: 750; white-space: normal; line-height: 1.3; }
.hw-fold .hw-work__meta { font-size: .85rem; white-space: normal; line-height: 1.4; }
.hw-fold > .hw-work > .hw-status { display: inline-flex; grid-column: 3; grid-row: 1; align-items: center; justify-content: center; align-self: center; min-height: 34px; margin: 0; padding: 7px 12px; line-height: 1.2; text-align: center; }
.hw-fold > .hw-work > .hw-fold__toggle { grid-column: 4; grid-row: 1; width: 120px; box-sizing: border-box; justify-self: end; }
.hw-fold__toggle { display: inline-grid; min-width: 100px; justify-items: center; transition: background 280ms ease, border-color 280ms ease; }
.hw-fold__toggle::before { content: none; }
.hw-fold__label { grid-area: 1 / 1; transition: opacity 180ms ease, transform 240ms ease; }
.hw-fold__label--collapse { opacity: 0; transform: translateY(4px); }
.hw-fold--open .hw-fold__label--expand { opacity: 0; transform: translateY(-4px); }
.hw-fold--open .hw-fold__label--collapse { opacity: 1; transform: translateY(0); }
.hw-fold__panel { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows 320ms cubic-bezier(.22,.61,.36,1), opacity 220ms ease; }
.hw-fold--open > .hw-fold__panel { grid-template-rows: 1fr; opacity: 1; }
.hw-fold__content { min-height: 0; overflow: hidden; }
.hw-fold__content > .hw-detail { border: 0; border-radius: 0; background: transparent; padding: 22px 28px 26px; }
.hw-fold__content > .hw-detail > .hw-detail__head { display: none; }
@media (max-width: 620px) {
  .hw-fold > .hw-work { grid-template-columns: 40px minmax(0,1fr) 104px; gap: 10px; padding: 16px; }
  .hw-fold > .hw-work > .hw-work__face { width: 40px; height: 40px; }
  .hw-fold .hw-work__title { font-size: 1.1rem; }
  .hw-fold > .hw-work > .hw-status { grid-column: 2; grid-row: 2; justify-self: start; }
  .hw-fold > .hw-work > .hw-fold__toggle { grid-column: 3; grid-row: 1 / span 2; width: 104px; min-width: 0; }
  .hw-fold__content > .hw-detail { padding: 18px; }
}
@media (prefers-reduced-motion: reduce) {
  .hw-fold, .hw-fold > .hw-work, .hw-fold__toggle, .hw-fold__label, .hw-fold__panel { transition: none; }
}
.rep-preview-points { margin: 12px 0; }
.rep-preview-points > summary { cursor: pointer; color: var(--ink-soft); font-weight: 600; }
.rep-point { font-size: .88rem; line-height: 1.5; }
.rep-archive-nav { display: flex; gap: 10px; width: 100%; justify-content: space-between; }
.rep__box button:focus-visible,.rep__box summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@media(max-width:620px) { .rep__foot .rep__send { width: 100%; } .rep-save-status { flex-basis: 100%; } }
/* Dedicated report archive and writing queue. */
#view-reports { padding: clamp(16px,3vw,32px); }
.reports-page-head h1 { margin: 0 0 10px; }
.reports-page-head { margin-bottom: 24px; max-width: 760px; }
.reports-page-tools { display:flex; flex-wrap:wrap; gap:16px; align-items:center; margin-bottom:24px; }
.reports-page-tabs { display:flex; flex-wrap:wrap; gap:8px; }
.reports-page-tabs [aria-pressed="true"] { outline:2px solid currentColor; outline-offset:2px; }
.reports-page-tools .rep-search { flex:1; min-width:180px; margin:0; }
#view-reports .reports-card-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,280px),1fr)); gap:20px; }
.reports-card.rep-archive-item { display:flex; flex-direction:column; align-items:stretch; text-align:left; min-width:0; margin:0; padding:24px; border:1px solid var(--line,#dce2e8); border-radius:20px; background:var(--paper-card,#fff); color:inherit; font:inherit; cursor:pointer; overflow-wrap:anywhere; }
.reports-card:hover { border-color:currentColor; }
.reports-card:focus-visible { outline:3px solid currentColor; outline-offset:3px; }
.reports-card h3 { margin:12px 0 8px; }
.reports-card-name { margin:0 0 8px; font-weight:600; }
.reports-card-status { font-size:12px; font-weight:600; }
.reports-card-excerpt { display:-webkit-box; -webkit-line-clamp:4; -webkit-box-orient:vertical; overflow:hidden; line-height:1.6; }
.reports-card-action { margin-top:auto; padding-top:20px; font-weight:600; }
.reports-empty { grid-column:1/-1; padding:32px; border:1px dashed var(--line,#dce2e8); border-radius:20px; }

/* Dismiss the issued notice without revoking invitations. */
.issued { position: relative; padding-right: 58px; flex-wrap: wrap; }
.issued__close { position: absolute; top: 8px; right: 8px; width: 36px; height: 36px; display: grid; place-items: center; border: 0; border-radius: 50%; background: transparent; color: var(--ink-soft); font-size: 26px; cursor: pointer; }
.issued__close:hover { background: rgba(128,128,128,.15); color: var(--ink); }
.issued__close:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

.issued { flex-direction: column; align-items: stretch; gap: 12px; }
.issued__row { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; min-width: 0; }
.issued__family { display: flex; flex-direction: column; gap: 12px; }
.issued__note { margin: 0; font-size: .85rem; color: var(--ink-soft); }

.family-add-form { margin-top: 16px; }
.family-add-form label { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.family-add-form input { max-width: 360px; width: 100%; box-sizing: border-box; }

#desk .desk-card--family { border: 1px solid var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface, transparent)); }
.family-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; }
.family-parents { margin: 8px 0; font-size: .9rem; }
.family-partner-invite { margin-top: 16px; }
@media(max-width: 600px) { .family-actions > button { width: 100%; } }

.invite-help { font-size: .85rem; line-height: 1.5; color: var(--ink-soft); margin: 12px 0; }

.person--pay-open { flex-wrap: wrap; }
.person > .pay-form { flex: 0 0 100%; width: 100%; min-width: 0; margin: 8px 0 0; padding-top: 12px; border-top: 1px solid var(--line); box-sizing: border-box; }
.person > .pay-form > .btn { width: 100%; }

.lesson-balances { display:flex; flex-direction:column; gap:6px; flex-shrink:0; }
.lesson-balance__button { border:1px solid var(--line); border-radius:10px; padding:7px 10px; background:rgba(130,185,151,.10); color:var(--text); font:inherit; font-size:12px; font-weight:700; cursor:pointer; }
.lesson-balance__button--low { background:rgba(245,183,35,.15); }
.lesson-balance__button--empty { background:rgba(210,110,90,.12); }
.lesson-balance__button:focus-visible { outline:2px solid #f7b723; outline-offset:3px; }
.invitation-card { align-items:flex-start; }
.invitation-code { display:flex; align-items:center; flex-wrap:wrap; gap:10px; margin-top:12px; }
.invitation-code strong { color:#f7b723; letter-spacing:.06em; }
.invitation-card .person__meta { margin-top:8px; }
@media(max-width:700px) { .lesson-balances { flex-direction:row; flex-wrap:wrap; } }

/* Let readable balances and actions wrap without shrinking the pupil name. */
.person { flex-wrap:wrap; }
.person > .person__main { flex:1 1 240px; min-width:min(240px,100%); }
.person__actions { flex-wrap:wrap; max-width:100%; }
.invitation-card > .person__main { min-width:0; }

/* Consistent, readable close icons throughout the cabinet. */
button[aria-label^="Закрыть"],button[aria-label^="Close"],button[data-close],button[data-anno-close]{min-width:42px!important;min-height:42px!important;font-size:28px;line-height:1}button[aria-label^="Закрыть"] svg,button[aria-label^="Close"] svg,button[data-close] svg,button[data-anno-close] svg{width:24px;height:24px}

button[aria-label^="\0417\0430\043a\0440\044b\0442\044c"],button[aria-label^="Close"],button[data-close],button[data-anno-close]{background:var(--paper,#1b2c24);color:var(--ink,#edf3eb);border:1px solid var(--line,#35473d)}
button[aria-label^="\0417\0430\043a\0440\044b\0442\044c"]:hover,button[aria-label^="Close"]:hover,button[data-close]:hover,button[data-anno-close]:hover{background:#8e3030!important;color:#fff!important;border-color:#b94545!important}
