/* Коммерческие списки: таблица на компьютере, компактная карточка на телефоне. */
.commerce-list .commerce-description { display: none; }
@media (max-width: 580px) {
  .admin-body .commerce-list .page-head .commerce-description-desktop { display: none; }
  .commerce-list .commerce-description { display: block; }
  .commerce-list .commerce-description summary { min-height: 44px; display: flex; align-items: center; gap: 8px; color: var(--slate); cursor: pointer; font-size: 14px; }
  .commerce-list .commerce-description summary::after { content: "+"; }
  .commerce-list .commerce-description[open] summary::after { content: "−"; }
  .commerce-list .commerce-description .lead { margin-block: 0 8px; font-size: 14px; }
  .admin-body .commerce-list .commerce-cards tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 5px 12px; padding: 12px; }
  .admin-body .commerce-list .commerce-cards tbody td { display: block; min-width: 0; width: auto; padding: 0; border: 0; white-space: normal; overflow-wrap: anywhere; font-size: 14px; }
  .admin-body .commerce-list .commerce-cards tbody td::before { display: none; }
  .admin-body .commerce-list .commerce-cards .commerce-name { grid-column: 1; grid-row: 1; font-size: 16px; align-self: center; }
  .admin-body .commerce-list .commerce-cards .commerce-name a { display: flex; align-items: center; min-height: 44px; }
  .admin-body .commerce-list .commerce-cards .commerce-amount { grid-column: 2; grid-row: 1; align-self: center; font-size: 16px; font-weight: 600; text-align: right; }
  .admin-body .commerce-list .commerce-cards .commerce-status { grid-column: 2; grid-row: 2; text-align: right; }
  .admin-body .commerce-list .commerce-cards .commerce-context { grid-column: 1; grid-row: 2; color: var(--slate); }
  .admin-body .commerce-list .commerce-cards .commerce-context .sub { display: inline; margin: 0; }
  .admin-body .commerce-list .commerce-cards .commerce-context .sub:not(:empty)::before { content: " · "; }
  .admin-body .commerce-list .commerce-cards .commerce-address { grid-column: 1 / -1; grid-row: 3; color: var(--slate); font-size: 13px; }
  .admin-body .commerce-list .commerce-cards code { white-space: normal; overflow-wrap: anywhere; }
  .admin-body .commerce-list .commerce-cards .commerce-limit { grid-column: 1 / -1; grid-row: 3; color: var(--slate); }
  .admin-body .commerce-list .commerce-cards .commerce-scope { grid-column: 1 / -1; grid-row: 4; color: var(--slate); font-size: 13px; }
  .admin-body .commerce-list .commerce-cards .commerce-refunded { grid-column: 1 / -1; grid-row: 3; color: var(--slate); }
  .admin-body .commerce-list .commerce-cards :is(.commerce-limit, .commerce-scope, .commerce-refunded)::before { display: inline; content: attr(data-th) ": "; font-size: inherit; font-weight: 400; }
}
/* Конец адаптации коммерческих списков. */
/* Mobile learning/editor: bounded choices and compact actions, 2026-09-19.
   Local specificity keeps these rules independent of the shared desktop styles. */
@media (max-width: 899px) {
  .lesson-nav .lesson-nav-mobile > ul {
    max-block-size: 50vh;
    max-block-size: 50dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .course-jumps { display: flex; flex-wrap: wrap; gap: 8px; }
  .course-section-title { scroll-margin-block-start: 100px; }
}
@media (max-width: 580px) {
  body .savebar-head {
    flex-wrap: nowrap; gap: 8px; padding: 10px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  }
  body .savebar-head .hint {
    position: absolute; inline-size: 1px; block-size: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  body .savebar-head :is(.button, .button-secondary) {
    flex: 1 1 0; min-inline-size: 0; min-block-size: 44px;
    padding: 8px 12px; white-space: nowrap;
  }
  html body:has(.savebar-head:not([hidden])) .site-footer {
    padding-block-end: calc(32px + var(--savebar-h, 66px) + 16px + env(safe-area-inset-bottom, 0px));
  }
}
@media (max-width: 899px), (hover: none) {
  .blocks .blk .blk-more { width: 44px; height: 44px; }
  .blocks .blk > .blk-title[contenteditable] { margin-inline-end: 44px; }
  .blocks .sub:has(> .sub-acts) { padding-inline-end: 52px; min-block-size: 44px; }
  .blocks .sub > .sub-acts {
    position: absolute; inset-block-start: 0; inset-inline-end: 0;
    inline-size: 44px; block-size: 44px;
  }
  .blocks .sub .sub-more { position: static; opacity: 1; width: 44px; height: 44px; }
}

/* LMS R1 · версия dock. Референс: refero.design, Dock («Sunlit cream paper, cobalt pulse»).
   Кремовый бумажный холст #faf9f7, три ступени поверхностей (canvas → ivory → white),
   один электрический кобальт #0068f9 на все интерактивные элементы, фиолетовый #6736eb
   только как декоративная метка, hairline #efefef, почти невидимые трёхслойные тени,
   капсулы 48px у кнопок и навигации, карточки 16px, плотный лидинг заголовков.
   Roobert нет на Google Fonts – по рекомендации референса стоит Inter с ss01.
   Имена классов совпадают с макетами r1, HTML не менялся. */

:root {
  --canvas: #faf9f7;
  --ivory: #fbfaf7;
  --white: #ffffff;
  --lavender: #f4f0ff;
  --powder: #d6e4f1;
  --sky: #d5ecff;
  --ink: #121722;
  --deep-ink: #1d1d1d;
  --graphite: #2d2d2d;
  --slate: #666b75;   /* 5.35:1 на белом – подписи и мелкий текст ≤14px */
  --steel: #8a8a8a;   /* 3.3:1 – только рамки, точки, шевроны; для текста не использовать */
  --hairline: #efefef;
  --faint: #cccccc;
  --cobalt: #0068f9;
  --cobalt-deep: #024bb1;
  --cerulean: #0074dd;
  --violet: #6736eb;
  --forest: #046645;
  --rust: #b42318;
  --amber: #8a5a00;
  --max: 1200px;
  --narrow: 760px;
  --r-badge: 8px;
  --r-card: 16px;
  --r-button: 48px;
  --r-pill: 100px;
  --shadow-subtle: rgba(0,0,0,.07) 0 1px 1px 0, rgba(0,0,0,.04) 0 -1px 1px 0 inset, rgba(0,0,0,.14) 0 0 0 .5px inset;
  --shadow-lg: rgba(0,0,0,.04) 0 20px 20px -8px;
  --sans: "Inter", "Roobert", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* совместимость с inline-стилями макетов r1 */
  --aicjm-space-8: 8px;
  --aicjm-space-12: 12px;
  --aicjm-space-16: 16px;
  --aicjm-text-primary: var(--ink);
  --aicjm-border-subtle: var(--hairline);
  --aicjm-type-size-lead: 18px;
  --aicjm-type-size-body-small: 14px;
  --aicjm-action-primary: var(--cobalt);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100vh; display: flex; flex-direction: column;
  color: var(--ink); background: var(--canvas);
  font-family: var(--sans); font-size: 16px; line-height: 1.56;
  font-feature-settings: "ss01", "kern", "cv11";
  -webkit-font-smoothing: antialiased;
}
a { color: var(--cobalt); text-decoration: none; font-weight: 500; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 2px; }
button, input, select, textarea { font: inherit; }
h1, h2, h3 { margin: 0; color: var(--ink); font-weight: 600; text-wrap: balance; }
h1 { font-size: clamp(34px, 5vw, 48px); line-height: 1.09; letter-spacing: -.028em; }
h2 { font-size: 24px; line-height: 1.33; letter-spacing: -.02em; }
h3 { font-size: 20px; line-height: 1.38; letter-spacing: -.014em; }
p { margin: 0; text-wrap: pretty; }
p + p { margin-block-start: 10px; }

/* Оболочка */
.shell { width: min(calc(100% - 32px), var(--max)); margin-inline: auto; }
.shell-narrow { width: min(calc(100% - 32px), var(--narrow)); margin-inline: auto; }
main { flex: 1; padding-block: 24px 80px; }
.stack { display: grid; gap: 12px; }
.stack-lg { display: grid; gap: 24px; }
.row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.row-between { justify-content: space-between; }

/* Шапка: белая полоса с hairline снизу, логотип – кобальтовая капсула-«док» с белым штрихом,
   пункты навигации – капсулы 48px, активный на ivory */
.site-header { position: sticky; top: 0; z-index: 20; background: var(--white); border-bottom: 1px solid var(--hairline); }
.header-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 64px; }
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); font-size: 16px; font-weight: 600; letter-spacing: -.012em; }
.brand:hover { text-decoration: none; }
.brand::before { content: ""; display: block; flex: none; width: 30px; height: 20px; border-radius: var(--r-pill); background: var(--cobalt) linear-gradient(90deg, transparent 0 8px, #fff 8px 14px, transparent 14px); }
.brand small { color: var(--slate); font-size: 13px; font-weight: 500; letter-spacing: .01em; margin-inline-start: 4px; }
.primary-nav ul { display: flex; flex-wrap: wrap; gap: 2px; margin: 0; padding: 0; list-style: none; }
.primary-nav a { display: inline-flex; align-items: center; min-height: 36px; padding: 0 16px; border-radius: var(--r-button); color: var(--ink); font-size: 15px; font-weight: 500; transition: background .15s ease; }
.primary-nav a:hover { text-decoration: none; background: var(--canvas); }
.primary-nav a[aria-current="page"] { background: var(--ivory); box-shadow: var(--shadow-subtle); }

/* Заголовок страницы: как hero Dock – плотный заголовок, лид 18px по ширине колонки (до 900px),
   чтобы описание занимало одну-две строки и в кабинете, и в админке */
.page-head { display: grid; gap: 12px; padding-block: 24px 8px; }
.eyebrow { margin: 0; color: var(--slate); font-size: 13px; font-weight: 500; letter-spacing: .077em; text-transform: uppercase; }
.lead { max-width: 900px; color: var(--ink); font-size: 18px; line-height: 1.5; font-weight: 400; }
.crumbs { display: flex; flex-wrap: wrap; gap: 8px; font-size: 14px; color: var(--slate); }
.crumbs a { color: var(--slate); font-weight: 400; }
.crumbs a:hover { color: var(--cobalt); }
.crumbs span:last-child { color: var(--ink); font-weight: 500; }

/* Кнопки: капсулы 48px. Primary – кобальт без рамки, secondary – белый ghost с hairline */
.button, .button-secondary { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 24px; border-radius: var(--r-button); font-size: 15px; font-weight: 500; line-height: 1.3; text-decoration: none; cursor: pointer; transition: background .15s ease, color .15s ease, border-color .15s ease; }
.button { border: 1px solid var(--cobalt); background: var(--cobalt); color: #fff; }
.button:hover { background: var(--cobalt-deep); border-color: var(--cobalt-deep); text-decoration: none; }
.button-secondary { border: 1px solid var(--hairline); background: var(--white); color: var(--ink); box-shadow: var(--shadow-subtle); }
.button-secondary:hover { border-color: var(--faint); background: var(--ivory); text-decoration: none; }
.button-block { width: 100%; }
.button[aria-disabled="true"], .button-secondary[aria-disabled="true"] { opacity: .4; cursor: default; box-shadow: none; }
.button[disabled]{background:var(--ivory);border-color:var(--hairline);color:var(--graphite);box-shadow:none;cursor:default;transform:none}
.button-secondary[disabled]{opacity:.5;cursor:default;box-shadow:none}
.button-danger { color: var(--rust); border-color: var(--hairline); background: var(--white); }
.button-danger:hover { background: #fff5f4; border-color: #f2c4bf; }
.button-sm { min-height: 36px; padding: 6px 16px; font-size: 14px; }
.link-button { background: none; border: 0; padding: 0; color: var(--cobalt); font-weight: 500; cursor: pointer; }
.link-button:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Карточка: белая, hairline, 16px, трёхслойная микротень как у Dock */
.card { display: grid; gap: 16px; padding: 20px; border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--white); color: var(--ink); box-shadow: var(--shadow-subtle); }
.card-link { color: inherit; font-weight: 400; transition: border-color .15s ease, box-shadow .15s ease; }
.card-link:hover { text-decoration: none; border-color: var(--powder); box-shadow: var(--shadow-subtle), var(--shadow-lg); }
.muted { color: var(--slate); }
.small { font-size: 14px; }
/* Строка, где элементы стоят вплотную друг к другу: бейдж и число занятий в шапке карточки
   курса, ссылка на чат и подсказка ⓘ в её нижней строке (приёмка 2026-09-10) */
.row-tight { gap: 8px; }
/* Карточка курса в «Моих курсах»: название – единственный переход внутрь курса */
.course-card h3 > a { color: inherit; }
.course-card h3 > a:hover { color: var(--cobalt); }
.course-chat { font-size: 14px; }
/* Ключевая карточка «ближайшее занятие»: единственное место с градиентом – cream → sky → lavender,
   как hero-фон Dock. Без тяжёлых теней: только hairline powder-blue. */
.card-deep { position: relative; overflow: hidden; border-color: var(--powder); background: linear-gradient(160deg, var(--white) 0%, var(--sky) 62%, var(--lavender) 100%); color: var(--ink); }
.card-deep::after { content: ""; position: absolute; right: -80px; bottom: -110px; width: 260px; height: 260px; border-radius: 50%; background: radial-gradient(circle, rgba(0,104,249,.28), transparent 68%); pointer-events: none; }
.card-deep > * { position: relative; z-index: 1; }
.card-deep .eyebrow { color: var(--cobalt); }
.card-deep .muted { color: var(--graphite); }
.card-deep .tag { background: var(--white); }

/* Метки: капсулы 8px на ivory, состояние читается точкой и текстом; violet – декоративный акцент */
.tag { display: inline-flex; align-items: center; gap: 7px; min-height: 26px; padding: 0 10px; border: 1px solid var(--hairline); border-radius: var(--r-badge); background: var(--ivory); color: var(--ink); font-size: 13px; font-weight: 500; white-space: nowrap; line-height: 1; }
.tag::before { content: ""; width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid var(--steel); background: transparent; flex: none; }
.tag-live { border-color: #bfd8ff; background: #e8f1ff; color: var(--cobalt-deep); }
.tag-live::before { border-color: var(--cobalt); background: var(--cobalt); box-shadow: 0 0 0 3px rgba(0,104,249,.18); }
.tag-live .dot { display: none; }
.tag-deep { border-color: var(--deep-ink); background: var(--deep-ink); color: #fff; }
.tag-deep::before { border-color: #fff; background: #fff; }
.tag-strong { border-color: #ddd3ff; background: var(--lavender); color: #4a22b8; }
.tag-strong::before { border-color: var(--violet); background: var(--violet); }
.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* Список занятий: белая карточка, hairline-строки, дата в ivory-плашке 8px,
   выполненные – с зелёной галочкой в духе checklist Dock */
.list { display: grid; margin: 0; padding: 4px; list-style: none; border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--white); box-shadow: var(--shadow-subtle); }
.list > li + li { border-top: 1px solid var(--hairline); }
.list a { display: grid; grid-template-columns: auto 1fr auto; gap: 8px 14px; align-items: center; padding: 14px 12px; border-radius: 12px; color: inherit; font-weight: 400; transition: background .15s ease; }
.list a:hover { background: var(--canvas); text-decoration: none; }
.list .when { display: grid; grid-template-columns: minmax(0, 1fr); place-items: center; flex: none; width: 52px; height: 52px; overflow: hidden; white-space: nowrap; border-radius: var(--r-badge); border: 1px solid var(--hairline); background: var(--ivory); color: var(--slate); font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: .077em; line-height: 1.1; }
.list .when strong { display: block; font-size: 18px; letter-spacing: -.03em; color: var(--ink); font-weight: 600; }
.list .title { display: grid; gap: 2px; }
.list .title strong { font-weight: 500; color: var(--ink); letter-spacing: -.01em; }
.list .title .muted { font-size: 14px; }
.list li[aria-current="true"] a { background: #eef5ff; }
.list li[aria-current="true"] .when { background: var(--cobalt); border-color: var(--cobalt); color: #dbe9ff; }
.list li[aria-current="true"] .when strong { color: #fff; }
.list li.past .when strong, .list li.past .title strong { color: var(--slate); }
.list li.past .tag::before { border-color: var(--forest); background: var(--forest); }

/* Формы: белые поля, hairline, 12px; фокус – кобальтовое кольцо */
.field { display: grid; gap: 6px; }
label, legend { font-weight: 500; font-size: 15px; color: var(--ink); }
.hint { color: var(--slate); font-size: 14px; line-height: 1.5; }
input:not([type="checkbox"]):not([type="radio"]), textarea, select { width: 100%; min-height: 44px; padding-inline: 14px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--white); color: var(--ink); box-shadow: rgba(0,0,0,.04) 0 1px 1px 0; transition: border-color .15s ease, box-shadow .15s ease; }
textarea { padding-block: 10px; resize: vertical; }
input:focus, textarea:focus, select:focus { border-color: var(--cobalt); box-shadow: 0 0 0 3px rgba(0,104,249,.16); outline: none; }
input::placeholder, textarea::placeholder { color: var(--slate); }
/* Нативный select: тот же шеврон, что у .dd-btn (слэйт 1.5px, 16px от правого края),
   справа 40px воздуха под него. Календарь и время: иконка отодвинута от текста и рамки. */
select { appearance: none; -webkit-appearance: none; padding-inline-end: 40px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23666b75' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 4.5 6 8.5l4-4'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; background-size: 12px 12px; cursor: pointer; text-overflow: ellipsis; }
select:hover { border-color: var(--faint); }
select:disabled { background-color: var(--ivory); color: var(--slate); cursor: default; }
input:is([type="date"], [type="time"], [type="datetime-local"]) { padding-inline-end: 12px; font-variant-numeric: tabular-nums; }
input:is([type="date"], [type="time"], [type="datetime-local"])::-webkit-calendar-picker-indicator { margin-inline-start: 12px; padding: 6px; border-radius: 8px; opacity: .65; cursor: pointer; transition: opacity .15s ease, background-color .15s ease; }
input:is([type="date"], [type="time"], [type="datetime-local"])::-webkit-calendar-picker-indicator:hover { opacity: 1; background-color: var(--canvas); }
input[readonly] { background: var(--ivory); color: var(--graphite); }
.check { display: flex; gap: 10px; align-items: flex-start; font-weight: 400; font-size: 15px; }
.check input { width: 18px; height: 18px; margin: 3px 0 0; flex: none; accent-color: var(--cobalt); }
.form-grid { display: grid; gap: 16px; }
@media (min-width: 768px) { .form-grid { grid-template-columns: 1fr 1fr; } .form-grid .span-2 { grid-column: 1 / -1; } }
fieldset { margin: 0; padding: 0; border: 0; display: grid; gap: 10px; }
.choices { display: flex; flex-wrap: wrap; gap: 6px; }
/* Чипы – tab bar Dock: текст без рамки, активный – ivory-капсула, единственный индикатор */
.chip { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding-inline: 16px; border: 1px solid transparent; border-radius: var(--r-button); background: transparent; color: var(--ink); font-size: 15px; font-weight: 500; cursor: pointer; transition: background .15s ease, border-color .15s ease; }
.chip:hover { background: var(--white); border-color: var(--hairline); text-decoration: none; }
.chip[aria-pressed="true"], .chip[aria-current="true"], .chip[data-check][data-checked="true"] { background: var(--ivory); border-color: var(--hairline); box-shadow: var(--shadow-subtle); }
.chip[aria-pressed="true"]::before, .chip[aria-current="true"]::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--cobalt); flex: none; }

/* Уведомление: лавандовая подложка 12px с кобальтовой точкой; warn – тёплый персик,
   точка-кольцо и «!» перед заголовком, чтобы состояние читалось не только цветом */
.notice { display: grid; gap: 6px; padding: 14px 16px; border: 1px solid #e3dcff; border-radius: 12px; background: var(--lavender); }
.notice > strong { display: flex; align-items: center; gap: 8px; color: var(--ink); font-weight: 600; }
.notice > strong::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--cobalt); flex: none; }
.notice-warn { background: #fff7ed; border-color: #fbe2c2; }
.notice-warn > strong { color: var(--amber); }
.notice-warn > strong::before { content: "!"; width: 18px; height: 18px; border-radius: 50%; background: var(--amber); color: #fff; font-size: 12px; font-weight: 700; line-height: 18px; text-align: center; }

/* Определения */
.dl { display: grid; gap: 10px; margin: 0; }
.dl > div { display: grid; grid-template-columns: minmax(7em, 32%) 1fr; gap: 10px; align-items: start; padding-bottom: 10px; border-bottom: 1px solid var(--hairline); min-width: 0; }
.dl > div:last-child { border: 0; padding-bottom: 0; }
.dl dt { color: var(--slate); font-size: 14px; font-weight: 500; padding-top: 2px; }
.dl dd { margin: 0; display: grid; gap: 4px; min-width: 0; font-size: 15px; }
.dl dd > * { min-width: 0; max-width: 100%; }
@media (max-width: 767px) { .dl > div { grid-template-columns: 1fr; gap: 4px; } }

/* Таблицы: pricing-row Dock – белая карточка, заголовки 14px/500 slate, hairline-строки */
.table-wrap { overflow-x: auto; border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--white); box-shadow: var(--shadow-subtle); }
table { width: 100%; border-collapse: collapse; font-size: 15px; }
th, td { padding: 12px 16px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--hairline); white-space: nowrap; }
th { color: var(--slate); font-size: 14px; font-weight: 500; background: var(--ivory); }
tbody tr:hover td { background: var(--canvas); }
tr:last-child td { border: 0; }
td a { font-weight: 500; color: var(--ink); }
td a:hover { color: var(--cobalt); }
.td-wrap { white-space: normal; }

/* Плеер: «продуктовый скриншот» – контейнер 16px с мягкой 20px тенью на лавандовой подложке */
.player { aspect-ratio: 16 / 9; display: grid; place-items: center; border-radius: var(--r-card); background: var(--deep-ink); color: #b8bcc4; font-size: 14px; box-shadow: var(--shadow-lg); }
.player-placeholder { aspect-ratio: 16 / 9; display: grid; place-items: center; min-width: 0; padding: 24px; text-align: center; border: 1px solid var(--powder); border-radius: var(--r-card); background: linear-gradient(180deg, var(--lavender), var(--white)); color: var(--graphite); box-shadow: var(--shadow-lg); }
.player-placeholder > * { width: 100%; min-width: 0; }

/* Экран входа: cream → sky → lavender, как hero Dock; карточка белая, тень 20px */
.auth-page { background: linear-gradient(180deg, var(--canvas) 0%, var(--sky) 55%, var(--lavender) 100%); }
.auth-page main { display: grid; place-items: center; }
.auth-card { width: min(100%, 440px); padding: 28px; border-radius: 20px; box-shadow: var(--shadow-subtle), var(--shadow-lg); }
.auth-card h1 { font-size: clamp(28px, 4.5vw, 36px); }

/* Десктоп */
@media (min-width: 768px) {
  .card { padding: 24px; }
  .header-row { min-height: 72px; }
  .page-head { padding-block: 40px 16px; }
  .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; }
  .side-layout { display: grid; grid-template-columns: 2fr 1fr; gap: 24px; align-items: start; }
  .shell, .shell-narrow { width: min(calc(100% - 48px), var(--max)); }
  .shell-narrow { max-width: var(--narrow); }
  .list a { padding: 14px 16px; }
}
@media (max-width: 580px) {
  .brand > small { display: none; }
  .primary-nav ul { justify-content: flex-end; row-gap: 0; }
  .primary-nav a { padding: 0 10px; font-size: 14px; min-height: 34px; }
  .header-row { gap: 8px; }
  /* Строка списка занятий: метка статуса уходит под подпись, название получает всю ширину */
  .list a { grid-template-columns: auto minmax(0, 1fr); gap: 6px 12px; }
  .list a > .tag { grid-column: 2; justify-self: start; }
  .card-deep::after { width: 180px; height: 180px; right: -60px; bottom: -80px; }
}

/* Подвал: белый, hairline сверху, ссылки slate */
.site-footer { background: var(--white); border-top: 1px solid var(--hairline); padding-block: 24px 32px; color: var(--slate); font-size: 13px; }
.site-footer .shell { display: flex; flex-wrap: wrap; gap: 8px 32px; justify-content: space-between; }
.site-footer a { color: var(--slate); font-weight: 400; }
.site-footer a:hover { color: var(--cobalt); }

/* Плашка макета: белая капсула с hairline, кобальт при наведении */
.mock-note { position: fixed; bottom: 12px; right: 12px; z-index: 60; padding: 8px 16px; border: 1px solid var(--hairline); border-radius: var(--r-button); background: var(--white); color: var(--ink); font-size: 13px; font-weight: 500; box-shadow: var(--shadow-subtle), var(--shadow-lg); }
.mock-note:hover { text-decoration: none; background: var(--cobalt); border-color: var(--cobalt); color: #fff; }
/* Отступ снизу нужен только когда плашка реально висит на экране: она fixed и
   на узком экране закрывает нижнюю полосу. Ни один шаблон её не выводит, а
   безусловный `body { padding-block-end: 44px }` давал пустую полосу под
   подвалом на каждой странице ≤640px. `:has()` привязывает отступ к плашке. */
@media (max-width: 640px) { .mock-note { left: 0; right: 0; bottom: 0; border-radius: 0; text-align: center; box-shadow: none; } body:has(.mock-note) { padding-block-end: 44px; } }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* Общие компоненты состояний · добавлены 2026-09-04 для полного покрытия пути */
.notice-ok { background: #edf9f1; border-color: #c6ecd3; }
.notice .hint strong { font-weight: 600; color: var(--ink); }
.notice-ok > strong { color: #046645; }
.notice-ok > strong::before { content: "✓"; width: 18px; height: 18px; border-radius: 50%; background: #046645; color: #fff; font-size: 11px; font-weight: 700; display: grid; place-items: center; }
.notice-error { background: #fff4f3; border-color: #f5cfcb; }
.notice-error > strong { color: var(--rust, #b3261e); }
.notice-error > strong::before { content: "!"; width: 18px; height: 18px; border-radius: 50%; background: var(--rust, #b3261e); color: #fff; font-size: 12px; font-weight: 700; display: grid; place-items: center; }
.field-error input, .field-error select, .field-error textarea { border-color: var(--rust, #b3261e); }
.field-error .hint { color: var(--rust, #b3261e); }
.confirm { display: grid; gap: 12px; padding: 18px 20px; border: 1px solid var(--hairline); border-left: 4px solid var(--amber, #b45309); border-radius: 12px; background: var(--white); box-shadow: var(--shadow-lg, 0 20px 40px rgba(0,0,0,.06)); }
.confirm h3 { font-size: 16px; }
.confirm ul { margin: 0; padding-inline-start: 1.2em; color: var(--graphite, #4b5563); font-size: 14px; display: grid; gap: 4px; }
.htmx-indicator { display: inline-flex; align-items: center; gap: 8px; color: var(--graphite, #4b5563); font-size: 13px; }
.htmx-indicator::before { content: ""; width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--hairline); border-top-color: var(--cobalt); animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.empty { display: grid; gap: 8px; padding: 28px 20px; text-align: center; border: 1px dashed var(--hairline); border-radius: var(--r-card); color: var(--graphite, #4b5563); background: var(--ivory, #fbfaf7); }
.empty strong { color: var(--ink); }
.state-switch { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 10px; border-radius: 12px; background: var(--ivory, #fbfaf7); border: 1px dashed var(--hairline); font-size: 12px; color: var(--graphite, #4b5563); align-items: center; }
.state-switch a { font-weight: 500; }
.error-page main { display: grid; place-items: center; text-align: center; }
.error-page .code { font-size: 64px; font-weight: 600; letter-spacing: -.05em; color: var(--cobalt); line-height: 1; }
@media (max-width: 580px) {
  .header-row { flex-wrap: wrap; }
  .primary-nav { flex-basis: 100%; overflow-x: auto; }
  .primary-nav ul { flex-wrap: nowrap; }
  .table-wrap table { font-size: 13px; }
  th, td { padding: 10px 12px; }
}

/* ── Экран занятия · добавлено 2026-09-04 ────────────────────────────────────
   Двухколоночный макет: слева список всех занятий потока, справа контент.
   На узких экранах колонка сворачивается в details над заголовком. */

.lesson-layout { display: grid; gap: 24px; align-items: start; }
.lesson-body { min-width: 0; }
.lesson-layout .page-head { padding-block: 0 4px; }

/* Боковая навигация */
.lesson-nav { display: grid; gap: 10px; min-width: 0; }
.lesson-nav-stream {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--ink); font-size: 15px; font-weight: 600; letter-spacing: -.012em;
}
.lesson-nav-stream::before { content: "‹"; color: var(--slate); font-weight: 500; }
@media (min-width: 900px) { .lesson-nav-stream { padding-inline-start: 12px; } }
.lesson-nav-stream:hover { color: var(--cobalt); text-decoration: none; }

.lesson-nav ul { display: grid; gap: 1px; margin: 0; padding: 0; list-style: none; }
.lesson-nav li a {
  display: grid; gap: 2px; padding: 8px 12px;
  border-radius: 10px; border-inline-start: 2px solid transparent;
  color: var(--ink); font-weight: 400; transition: background .15s ease;
}
.lesson-nav li a:hover { background: var(--white); text-decoration: none; }
.lesson-nav li.now a:hover { background: #dbe8ff; }
.lesson-nav .n { color: var(--slate); font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: .077em; }
.lesson-nav .t { font-size: 14px; line-height: 1.36; letter-spacing: -.006em; text-wrap: pretty; }
.lesson-nav li.now a { background: #e6efff; border-inline-start-color: var(--cobalt); box-shadow: inset 0 0 0 1px #cddffd; }
.lesson-nav li.now .t { font-weight: 600; color: var(--cobalt-deep, #0a3f96); }
.lesson-nav li.now .n { color: var(--cobalt); }
.lesson-nav li.past .t, .lesson-nav li.past .n { color: var(--steel); }

/* Мобильный переключатель: details вместо колонки */
.lesson-nav-mobile { border: 1px solid var(--hairline); border-radius: 12px; background: var(--white); box-shadow: var(--shadow-subtle); }
.lesson-nav-mobile > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 11px 14px; cursor: pointer; list-style: none;
  font-size: 14px; font-weight: 500; color: var(--ink);
}
.lesson-nav-mobile > summary::-webkit-details-marker { display: none; }
.lesson-nav-mobile > summary::after { content: "▾"; color: var(--ink); font-size: 16px; }
.lesson-nav-mobile[open] > summary { border-bottom: 1px solid var(--hairline); }
.lesson-nav-mobile[open] > summary::after { content: "▴"; }
.lesson-nav-mobile ul { padding: 4px; }

/* Плеер-ссылка: сам блок ведёт на запись, подписей нет */
a.player { position: relative; text-decoration: none; transition: box-shadow .15s ease; }
a.player:hover { text-decoration: none; box-shadow: var(--shadow-lg), 0 0 0 1px var(--powder); }
a.player .play {
  width: 68px; height: 68px; border-radius: 50%;
  background: rgba(255,255,255,.94); box-shadow: 0 6px 24px rgba(0,0,0,.35);
  display: grid; place-items: center; transition: transform .15s ease, background .15s ease;
}
a.player .play::before {
  content: ""; width: 0; height: 0; margin-inline-start: 5px;
  border-block: 12px solid transparent; border-inline-start: 20px solid var(--deep-ink);
}
a.player:hover .play { transform: scale(1.06); background: #fff; }
a.player .len {
  position: absolute; right: 12px; bottom: 12px;
  padding: 3px 8px; border-radius: 6px;
  background: rgba(0,0,0,.72); color: #fff; font-size: 13px; font-weight: 500;
}

/* Блок «О занятии» */
.lesson-about p { color: var(--graphite); }
.lesson-about .ticks { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.lesson-about .ticks li { position: relative; padding-inline-start: 26px; color: var(--graphite); font-size: 15px; }
.lesson-about .ticks li::before {
  content: ""; position: absolute; inset-block-start: 7px; inset-inline-start: 4px;
  width: 10px; height: 6px; border-inline-start: 2px solid var(--cobalt); border-block-end: 2px solid var(--cobalt);
  transform: rotate(-45deg);
}

/* Переход к соседним занятиям */
.lesson-pager { display: grid; gap: 8px; margin-block-start: 8px; }
.lesson-pager a {
  display: grid; gap: 2px; padding: 14px 16px;
  border: 1px solid var(--hairline); border-radius: 12px; background: var(--white);
  color: var(--ink); font-weight: 400; box-shadow: var(--shadow-subtle);
  transition: border-color .15s ease;
}
.lesson-pager a:hover { text-decoration: none; border-color: var(--powder); }
.lesson-pager .dir { color: var(--slate); font-size: 12px; font-weight: 500; }
.lesson-pager .next { text-align: end; }
.lesson-pager .t { font-size: 15px; font-weight: 500; letter-spacing: -.008em; text-wrap: pretty; }

@media (min-width: 900px) {
  .lesson-layout { grid-template-columns: 280px minmax(0, 1fr); gap: 40px; }
  .lesson-nav { position: sticky; top: 88px; }
  .lesson-nav-mobile { display: none; }
  .lesson-pager { grid-template-columns: 1fr 1fr; }
  .lesson-pager a.prev:only-child { grid-column: 1; }
  .lesson-pager a.next:only-child { grid-column: 2; }
}
@media (max-width: 899px) {
  /* специфичность .lesson-nav ul выше, чем у одиночного класса, поэтому квалифицируем */
  .lesson-nav ul.lesson-nav-list { display: none; }
  .lesson-layout { gap: 16px; }
}

/* Чекбокс согласия на странице входа: не даёт карточке разъехаться шире экрана,
   потому что .auth-page main центрирует контент грид-раскладкой (place-items: center). */
.auth-page main > * { min-width: 0; max-width: 100%; }
/* .check – flex-контейнер: текст согласия должен течь одним абзацем и переноситься
   по словам, поэтому он лежит в собственном блоке, а не отдельными flex-элементами. */
.check { min-width: 0; }
.check > .check-text { min-width: 0; display: block; }

/* ── Домашка, таймкоды, ширина колонки, прошедшие занятия · 2026-09-04 ───────
   Три правки поверх блока «Экран занятия» выше. */

/* Прошедшее занятие читается основным цветом: состояние несёт метка справа,
   а не приглушённый текст. Серой остаётся только подпись под названием. */
.lesson-nav li.past .t { color: var(--ink); }
.lesson-nav li.past .n { color: var(--slate); }
.list li.past .when strong, .list li.past .title strong { color: var(--ink); font-weight: inherit; }
.list li.past .title strong { font-weight: 500; }
.list li.past .when strong { font-weight: 600; }

/* Домашнее задание – обычный блок занятия (.blk), особых стилей нет. */

/* Таймкоды: время слева моноширинными цифрами, название справа, вся строка – ссылка. */
.timecodes { display: grid; gap: 1px; margin: 0; padding: 0; list-style: none; }
.timecodes a {
  display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 12px; align-items: baseline;
  padding: 8px 10px; border-radius: 10px; color: var(--ink); font-weight: 400;
  transition: background .15s ease;
}
.timecodes a:hover { background: var(--ivory); text-decoration: none; }
.timecodes a:hover .tt { color: var(--cobalt); }
.timecodes .tc { color: var(--cobalt); font-size: 14px; font-weight: 500; font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.timecodes .tt { font-size: 15px; line-height: 1.4; text-wrap: pretty; }

/* Ширина: список занятий уходит к левому полю страницы, контент держится в 760px.
   Колонка 260px, между ней и текстом – одна пружина, поэтому текст не растягивается
   на всю ширину даже на 1440. */
@media (min-width: 900px) {
  .lesson-layout { grid-template-columns: 260px minmax(0, var(--narrow)) minmax(0, 1fr); gap: 0 40px; }
  .lesson-body { grid-column: 2; }
}

/* ── Админка · левое меню, табы, собственные контролы · 2026-09-04 вечер ──
   Только для body.admin-body. Общие токены выше не меняются. */

.admin-body { display: block; }
.admin-body [hidden] { display: none !important; }
.admin-layout { display: grid; grid-template-columns: 220px minmax(0, 1fr); min-height: 100vh; }
.admin-side { position: sticky; top: 0; align-self: start; display: flex; flex-direction: column; gap: 20px; height: 100vh; padding: 20px 14px; background: var(--white); border-right: 1px solid var(--hairline); }
.admin-side .brand { padding-inline: 10px; }
.admin-nav ul { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.admin-nav a { display: flex; align-items: center; min-height: 40px; padding: 0 14px; border-radius: 12px; color: var(--ink); font-size: 15px; font-weight: 500; transition: background .15s ease; }
.admin-nav a:hover { background: var(--canvas); text-decoration: none; }
.admin-nav a[aria-current="page"] { background: #e8f1ff; color: var(--cobalt-deep); box-shadow: inset 0 0 0 1px #cddffd; }
.admin-side-foot { margin-top: auto; display: grid; gap: 6px; padding: 12px 14px 0; border-top: 1px solid var(--hairline); font-size: 14px; }
.admin-side-link { color: var(--cobalt); }
.admin-side-user { display: flex; align-items: center; gap: 8px; color: var(--slate); font-weight: 500; }
.admin-side-user::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--violet); }
/* В админке `main` – это сама колонка-флексбокс, в которой лежит и подвал.
   Нижний отступ `main { padding-block: 24px 80px }` в такой раскладке ложится
   ПОД подвал и даёт пустую полосу в 80px на коротких страницах. Здесь он
   снимается: воздух под содержимым уже задан `.admin-shell` (64px снизу). */
.admin-main { min-width: 0; display: flex; flex-direction: column; padding-block-end: 0; }
.admin-main > .admin-foot { margin-top: auto; }
@media (min-width: 900px) { .admin-layout { background: linear-gradient(90deg, var(--white) 0 219px, var(--hairline) 219px 220px, transparent 220px); } }
.admin-shell { width: min(100% - 64px, 1100px); margin-inline: auto; padding-block: 8px 64px; }
.admin-foot { margin-top: auto; }
.admin-foot .admin-shell { display: flex; flex-wrap: wrap; gap: 8px 32px; justify-content: space-between; padding-block: 0; }
.admin-body .page-head { padding-block: 20px 4px; }
.admin-body h1 { font-size: clamp(30px, 3.4vw, 38px); }
.admin-body h2 { font-size: 20px; }
/* Заголовки блоков занятия и материала – один кегль в обоих кабинетах (перебивает .admin-body h2) */
.admin-body .blk-title { font-size: 24px; }

/* Табы сущности: капсула-индикатор Dock, по центру контента под заголовком */
/* Ряд вкладок и действий курса: сами вкладки в капсуле, «⋯» и подсказка ⓘ – рядом с ней,
   вне капсулы, чтобы не читались шестой вкладкой (приёмка 2026-09-10) */
.tabs-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.tabs-row > .tabs { flex: 0 1 auto; }
.tabs { display: flex; flex-wrap: wrap; gap: 2px; padding: 4px; border: 1px solid var(--hairline); border-radius: var(--r-button); background: var(--white); box-shadow: var(--shadow-subtle); width: max-content; max-width: 100%; }
.tab { display: inline-flex; align-items: center; justify-content: center; min-height: 36px; padding: 0 16px; border: 0; border-radius: var(--r-button); background: transparent; color: var(--ink); font-size: 15px; font-weight: 500; cursor: pointer; transition: background .15s ease, color .15s ease; white-space: nowrap; }
.tab:hover { background: var(--canvas); }
.tab[aria-selected="true"] { background: var(--cobalt); color: #fff; }
.tab-panel { min-width: 0; }

/* Подсказка ⓘ */
.info { display: inline-grid; place-items: center; position: relative; width: 16px; height: 16px; margin-inline-start: 6px; border: 1px solid var(--steel); border-radius: 50%; color: var(--slate); font-size: 10px; font-weight: 600; font-style: normal; line-height: 1; vertical-align: -2px; cursor: help; }
.info:hover, .info:focus-visible { border-color: var(--cobalt); color: var(--cobalt); }
.info::after { content: attr(data-tip); display: none; position: absolute; left: 50%; bottom: calc(100% + 8px); transform: translateX(-50%); width: max-content; max-width: min(280px, calc(100vw - 24px)); padding: 8px 12px; border-radius: 10px; background: var(--deep-ink); color: #fff; font-size: 13px; font-weight: 400; line-height: 1.45; text-align: left; white-space: normal; z-index: 30; box-shadow: var(--shadow-lg); }
.info:hover::after, .info:focus-visible::after { display: block; }
.info.tip-start::after { left: -4px; transform: none; }
.info.tip-end::after { left: auto; right: -4px; transform: none; }
th .info { vertical-align: -3px; }

/* Дропдаун и календарь: белая скруглённая рамка hairline, шеврон справа, фокус кобальтом */
.dd { position: relative; display: inline-block; min-width: 0; max-width: 100%; }
.dd-btn { display: inline-flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 44px; padding: 0 40px 0 14px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--white); color: var(--ink); font-size: 15px; font-weight: 400; text-align: left; cursor: pointer; box-shadow: rgba(0,0,0,.04) 0 1px 1px 0; transition: border-color .15s ease, box-shadow .15s ease; }
.dd-btn::after { content: ""; position: absolute; right: 16px; top: 50%; width: 8px; height: 8px; margin-top: -6px; border-right: 1.5px solid var(--slate); border-bottom: 1.5px solid var(--slate); transform: rotate(45deg); transition: transform .15s ease; }
.dd.open .dd-btn::after { transform: rotate(-135deg); margin-top: -2px; }
.dd-btn:hover { border-color: var(--faint); }
.dd-btn:focus-visible, .dd.open .dd-btn { border-color: var(--cobalt); box-shadow: 0 0 0 3px rgba(0,104,249,.16); outline: none; }
.dd-btn[disabled] { background: var(--ivory); color: var(--slate); cursor: default; }
.dd-val { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-empty .dd-val { color: var(--steel); }
.dd-menu { position: absolute; z-index: 40; top: calc(100% + 6px); left: 0; min-width: 100%; width: max-content; max-width: min(320px, calc(100vw - 32px)); margin: 0; padding: 6px; list-style: none; border: 1px solid var(--hairline); border-radius: 14px; background: var(--white); box-shadow: var(--shadow-subtle), var(--shadow-lg); }

.dd-menu li[role="option"] { padding: 9px 12px; border-radius: 10px; font-size: 15px; cursor: pointer; }
.dd-menu li[role="option"]:hover { background: var(--canvas); }
.dd-menu li[aria-selected="true"] { background: #e8f1ff; color: var(--cobalt-deep); font-weight: 500; }
.dd-menu .dd-group { padding: 8px 12px 4px; color: var(--slate); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: .06em; }
.dd-sm .dd-btn { min-height: 36px; font-size: 14px; padding-left: 12px; }
.dd-pill .dd-btn { border-radius: var(--r-button); }
.field .dd, .field .datepick { display: block; }
.field-error .dd-btn { border-color: var(--rust); }
input.time { width: 6.5em; font-variant-numeric: tabular-nums; }
.field input.time { width: 100%; max-width: 9em; }

.cal { position: absolute; z-index: 40; top: calc(100% + 6px); left: 0; width: 292px; padding: 12px; border: 1px solid var(--hairline); border-radius: 16px; background: var(--white); box-shadow: var(--shadow-subtle), var(--shadow-lg); }
.cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; font-size: 15px; }
.cal-nav { width: 32px; height: 32px; border: 1px solid var(--hairline); border-radius: 50%; background: var(--white); color: var(--ink); font-size: 18px; line-height: 1; cursor: pointer; }
.cal-nav:hover { background: var(--canvas); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-dow { padding: 4px 0; text-align: center; color: var(--slate); font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: .06em; }
.cal-day { height: 36px; border: 0; border-radius: 10px; background: transparent; color: var(--ink); font-size: 14px; cursor: pointer; }
.cal-day:hover { background: var(--canvas); }
.cal-day.today { box-shadow: inset 0 0 0 1px var(--faint); }
.cal-day.in-range { background: #e8f1ff; border-radius: 0; }
.cal-day.selected { background: var(--cobalt); color: #fff; font-weight: 600; }
.cal-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--hairline); }
.dd-menu.dd-menu-end, .cal.dd-menu-end { left: auto; right: 0; }
.dd-menu.dd-menu-up, .cal.dd-menu-up { top: auto; bottom: calc(100% + 6px); }
.chip-date { min-height: 36px; border-radius: var(--r-button); font-size: 14px; font-weight: 500; padding-left: 14px; padding-right: 36px; }
.chip-date::after { right: 14px; }

/* Панель «Сохранить · Отменить» под формой: появляется после изменения */
.savebar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding-top: 4px; }
.savebar[hidden] { display: none; }

/* Опасная зона: красные текстовые ссылки с пояснением */
/* Вкладка «Чат»: группа выбирается из списка, ручной ввод номера – свёрнутый запасной
   путь под ссылкой. Занятая другим курсом строка списка видна, но не выбирается. */
.dd-menu .dd-taken { text-transform: none; letter-spacing: 0; font-size: 14px; font-weight: 400; color: var(--steel); }
.chat-manual > summary { display: inline-flex; align-items: center; gap: 6px; list-style: none; cursor: pointer; color: var(--cobalt); font-size: 14px; font-weight: 500; }
.chat-manual > summary::-webkit-details-marker { display: none; }
.chat-manual > summary::after { content: "▾"; color: var(--slate); font-size: 12px; line-height: 1; }
.chat-manual[open] > summary::after { content: "▴"; }
.chat-manual > summary:hover { text-decoration: underline; text-underline-offset: 3px; }
.chat-manual > form { margin-block-start: 12px; }
.danger-zone { display: grid; gap: 12px; padding: 18px 20px; border: 1px solid #f2c4bf; border-radius: var(--r-card); background: #fff8f7; }
.danger-zone h3 { font-size: 15px; color: var(--rust); }
.danger-row { display: grid; gap: 2px; }
.danger-link { color: var(--rust); font-weight: 500; }
.danger-link:hover { color: #8f1c12; }

/* Таблицы админки: без обрезки, перенос по словам, узкие колонки без переноса */
.admin-body th, .admin-body td { white-space: normal; overflow-wrap: break-word; padding: 11px 14px; }
.admin-body td a[href^="http"] { overflow-wrap: anywhere; }
.admin-body th { white-space: nowrap; }
.admin-body td.nw, .admin-body th.nw { white-space: nowrap; overflow-wrap: normal; }
.admin-body td .sub { display: block; margin-top: 2px; color: var(--slate); font-size: 13px; line-height: 1.4; }
.admin-body td .row-actions { display: flex; flex-wrap: wrap; gap: 4px 12px; white-space: nowrap; }
.admin-body .tag { white-space: nowrap; }
.admin-body td .tag + .tag { margin-inline-start: 4px; }
.drag-handle { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 6px; color: var(--steel); font-size: 14px; letter-spacing: -2px; cursor: grab; user-select: none; }
.drag-handle:hover { background: var(--canvas); color: var(--slate); }
tr.dragging td { opacity: .45; }
tr.drop-before td { box-shadow: inset 0 2px 0 var(--cobalt); }
tr.drop-after td { box-shadow: inset 0 -2px 0 var(--cobalt); }
.n-order { color: var(--slate); font-size: 13px; font-variant-numeric: tabular-nums; }
.col-type { white-space: nowrap; }
@media (min-width: 1100px) { .admin-body td .sub.type-sub { display: none; } }
@media (max-width: 1099px) { .col-type, .admin-body td.col-type { display: none; } }

/* Раскрывающаяся строка под строкой таблицы: смена тарифа, выдача доступа, новое занятие */
tr.tr-inline td { background: var(--ivory); padding: 12px 14px 14px; }
tr.tr-inline[hidden] { display: none; }
.inline-form { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; }
.inline-form strong { font-size: 14px; }
.inline-form .field { gap: 4px; }
.inline-form .field label { font-size: 13px; color: var(--slate); }
.inline-form input:not([type="hidden"]), .inline-form .dd-btn { min-height: 38px; font-size: 14px; }
.inline-form input[type="text"], .inline-form input[type="url"] { width: auto; }
.inline-form.field-error .dd-btn { border-color: var(--rust); }
tr.tr-empty td { padding: 0; }
tr.tr-empty .empty { border: 0; border-radius: 0; }
.table-foot { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; justify-content: space-between; }

/* Чипы тарифов: настоящие чекбоксы, галочка и заливка при выборе */
.chip[data-check] { position: relative; border-color: var(--hairline); background: var(--white); }
/* Чекбокс настоящий и нормального размера: он лежит поверх метки прозрачным слоем,
   поэтому получает и мышь, и фокус, и пробел, и Enter родным поведением. */
.chip[data-check] input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.chip[data-check]:has(input:focus-visible) { outline: 2px solid var(--cobalt); outline-offset: 2px; }
.chip[data-check]::before { content: ""; width: 14px; height: 14px; border-radius: 4px; border: 1.5px solid var(--steel); background: var(--white); flex: none; }
.chip[data-check][data-checked="true"] { background: #e8f1ff; border-color: #bfd8ff; color: var(--cobalt-deep); }
.chip[data-check][data-checked="true"]::before { border-color: var(--cobalt); background: var(--cobalt) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.2l2.3 2.3 4.7-4.8' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/10px no-repeat; }
.rule-group { display: grid; gap: 8px; padding-bottom: 14px; border-bottom: 1px solid var(--hairline); }
.rule-group:last-of-type { border: 0; padding-bottom: 0; }

/* Журнал: одна строка на запись, подробность в две строки, «Подробнее» в строке */
.jn-detail { display: grid; gap: 2px; font-size: 14px; line-height: 1.45; }
.jn-detail .jn-text { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.jn-detail.open .jn-text { display: block; -webkit-line-clamp: unset; overflow: visible; }
.jn-detail .link-button { justify-self: start; font-size: 13px; }
.admin-body .jn-table td { padding: 8px 12px; font-size: 14px; }
.admin-body .jn-table td.nw { font-variant-numeric: tabular-nums; }
.filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.filters input[type="search"] { flex: 1 1 220px; min-width: 0; }
.queue-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; }
.queue-row > div { display: grid; gap: 2px; padding: 12px 14px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--ivory); }
.queue-row .k { color: var(--slate); font-size: 13px; font-weight: 500; }
.queue-row .v { font-size: 15px; }

/* Обзор ученика: две колонки на десктопе */
.overview { display: grid; gap: 24px; align-items: start; }
@media (min-width: 900px) { .overview { grid-template-columns: 1fr 1fr; } }
.events { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; font-size: 14px; }
.events li { display: grid; grid-template-columns: 7.5em 1fr; gap: 10px; }
.events li .muted { font-variant-numeric: tabular-nums; }

/* Планшет и телефон: меню превращается в горизонтальную полосу под шапкой */
@media (max-width: 899px) {
  .admin-layout { grid-template-columns: 1fr; }
  /* Не sticky: на телефоне полоса меню в 100px съедала экран на каждом экране */
  .admin-side { position: static; z-index: 20; height: auto; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 16px; padding: 10px 16px; border-right: 0; border-bottom: 1px solid var(--hairline); }
  .admin-side .brand { padding-inline: 0; }
  .admin-side-foot { margin: 0; padding: 0; border: 0; display: flex; gap: 12px; margin-inline-start: auto; }
  .admin-side-user { display: none; }
  .admin-nav { flex-basis: 100%; order: 1; overflow-x: auto; }
  .admin-nav ul { display: flex; gap: 4px; }
  .admin-nav a { min-height: 36px; padding: 0 14px; border-radius: var(--r-button); white-space: nowrap; }
  .admin-shell { width: min(100% - 32px, 1100px); }
  /* Кнопки, видимые только по наведению, на планшете и телефоне видны всегда */
  .rec-filled .rec-replace, .blk-more { opacity: 1; }
  .tabs { width: 100%; overflow-x: auto; flex-wrap: nowrap; }
  .events li { grid-template-columns: 1fr; gap: 2px; }
}
@media (max-width: 580px) {
  .admin-body .table-wrap { overflow: visible; }
  .admin-body table, .admin-body thead, .admin-body tbody, .admin-body tr, .admin-body td { display: block; }
  .admin-body thead { display: none; }
  .admin-body tr { padding: 10px 14px; border-bottom: 1px solid var(--hairline); }
  .admin-body tr:last-child { border-bottom: 0; }
  .admin-body td { display: grid; grid-template-columns: 8.5em minmax(0, 1fr); gap: 4px 10px; padding: 3px 0; border: 0; white-space: normal; font-size: 14px; }
  .admin-body td::before { content: attr(data-th); color: var(--slate); font-size: 12px; font-weight: 500; padding-top: 2px; }
  .admin-body td:not([data-th]) { grid-template-columns: 1fr; }
  .admin-body td:not([data-th])::before { display: none; }
  .admin-body td[data-th=""] { grid-template-columns: 1fr; }
  .admin-body td[data-th=""]::before { display: none; }
  .admin-body tbody tr:hover td { background: transparent; }
  .admin-body tr.tr-inline td, .admin-body tr.tr-empty td { grid-template-columns: 1fr; }
  .admin-body tr.tr-inline td::before, .admin-body tr.tr-empty td::before { display: none; }
  .admin-body tr.tr-inline { background: var(--ivory); border-radius: 12px; }
  .admin-body .drag-handle { display: none; }
  /* Меню «⋯» и порядковый номер – в правом верхнем углу карточки, а не отдельными строками */
  .admin-body tr:has(> td:last-child :is(.rmenu, .row-more)) { position: relative; padding-inline-end: 52px; }
  .admin-body tr:has(> td:last-child :is(.rmenu, .row-more)) > td:last-child { position: absolute; top: 6px; right: 6px; width: auto; padding: 0; }
  .admin-body td:has(> .n-order) { position: absolute; top: 14px; right: 50px; width: auto; padding: 0; }
  /* Дата и время занятия в одну строку: «30 авг 18:00» */
  .admin-body td[data-th="Дата"] { grid-template-columns: 8.5em auto auto; justify-content: start; }
  .admin-body td[data-th="Дата"] > .sub { margin: 0; font-size: inherit; line-height: inherit; color: var(--slate); }
  /* Первая колонка (имя, название) – заголовком карточки без подписи */
  .admin-body td[data-th="Имя"], .admin-body td[data-th="Название"] { grid-template-columns: 1fr; font-size: 15px; font-weight: 500; padding-block-end: 4px; }
  .admin-body td[data-th="Имя"]::before, .admin-body td[data-th="Название"]::before { display: none; }
  .admin-body td[data-th="Имя"] .sub, .admin-body td[data-th="Название"] .sub { font-weight: 400; }
  .tab { padding: 0 10px; font-size: 14px; }
  .tabs { flex-wrap: wrap; overflow: visible; }
  .admin-shell { width: min(100% - 24px, 1100px); }
  /* Календарь на узком экране считает границы от окна, а не от кнопки-якоря:
     узкая кнопка раньше уводила его за левый край и прятала три недели из месяца. */
  .cal { position: fixed; inset-inline: 12px; inset-block-start: auto; top: auto; bottom: 12px;
         width: auto; max-width: none; max-height: calc(100vh - 24px); overflow: auto; }
  .cal.dd-menu-end, .cal.dd-menu-up { inset-inline: 12px; top: auto; bottom: 12px; }
  .cal-day { height: 40px; }
  .inline-form input[type="text"], .inline-form input[type="url"] { width: 100%; }
}

/* ==========================================================================
   Единый вертикальный ритм админских экранов
   крошки → метка 20 · метка → заголовок 8 · заголовок → подзаголовок 8
   подзаголовок → табы 24 · табы → первая карточка 24 · между карточками 20
   внутри карточки 16 · «Опасная зона» отбивается 32
   ========================================================================== */
.admin-body .admin-main > .admin-shell { display: grid; align-content: start; gap: 24px; }
.admin-body .admin-shell > .crumbs { margin-block-end: -4px; }
.admin-body .page-head { display: grid; gap: 8px; padding-block: 0; margin: 0; }
.admin-body .page-head > .head-tags,
.admin-body .page-head > .eyebrow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0; }
.admin-body .page-head > h1 { margin: 0; }
.admin-body .page-head > .lead { margin: 0; }
.admin-body .page-head-split { grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 16px 24px; }
.admin-body .page-head-split > .head-main { display: grid; gap: 8px; min-width: 0; }
.admin-body .page-head-split > .head-aside { display: flex; align-items: center; gap: 8px; }
.admin-body .tab-panel { gap: 20px; }
.admin-body .tab-panel[hidden] { display: none; }
.admin-body .card > .stack, .admin-body .card.stack { gap: 16px; }
.admin-body .card.stack-lg { gap: 16px; }
.admin-body .danger-zone { margin-block-start: 12px; }
.admin-body .tab-panel > .danger-zone { margin-block-start: 12px; }

/* Значок ⓘ: 16px, по центру строки подписи, рамка hairline, буква slate */
.info { display: inline-flex; align-items: center; justify-content: center; position: relative; width: 16px; height: 16px; flex: 0 0 16px; margin-inline-start: 6px; border: 1px solid var(--steel); border-radius: 50%; background: var(--white); color: var(--slate); vertical-align: middle; cursor: help; }
.info > i { font-size: 10px; font-weight: 600; font-style: normal; line-height: 1; letter-spacing: 0; }
.info:hover, .info:focus-visible { border-color: var(--cobalt); color: var(--cobalt); }
th .info, .admin-body th .info { vertical-align: middle; }
.lab-tip { display: inline-flex; align-items: center; gap: 0; }
.field > .lab-tip { display: flex; }
.admin-body h2 .info, .admin-body h3 .info, .danger-zone h3 .info { vertical-align: middle; }

/* Аватар ученика: фото из Telegram, иначе инициалы */
.avatar { display: inline-grid; place-items: center; flex: none; border-radius: 50%; color: #fff; font-weight: 600; letter-spacing: .01em; text-transform: uppercase; user-select: none; }
.avatar-lg { width: 56px; height: 56px; font-size: 20px; }
.avatar-md { width: 40px; height: 40px; font-size: 15px; }
.avatar-sm { width: 28px; height: 28px; font-size: 11px; }
.av-1 { background: linear-gradient(135deg, #0068f9, #4b93ff); }
.av-2 { background: linear-gradient(135deg, #7b5cf0, #a98bff); }
.av-3 { background: linear-gradient(135deg, #0f9d8c, #45c9b4); }
.av-4 { background: linear-gradient(135deg, #d9722c, #f0a35e); }
.av-5 { background: linear-gradient(135deg, #c2447a, #e57aa5); }
.av-6 { background: linear-gradient(135deg, #3c5a8f, #6f8fc4); }
.av-off { background: var(--ivory); color: var(--slate); box-shadow: inset 0 0 0 1px var(--hairline); }
.head-title { display: flex; align-items: center; gap: 16px; min-width: 0; }
.head-title h1 { margin: 0; min-width: 0; }
.head-title .info { margin-inline-start: 0; align-self: center; }
.cell-person { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cell-person > div { min-width: 0; }

/* Сводка ученика в две колонки на широком экране */
@media (min-width: 900px) {
  .dl-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; }
  .dl-2 > div { border-bottom: 1px solid var(--hairline); }
  .dl-2 > div:nth-last-child(2):nth-child(odd) { border-bottom: 0; padding-bottom: 0; }
}

/* Шапка карточки ученика: подзаголовок занимает две строки всегда,
   чтобы таб-бар стоял на одной высоте у всех карточек */
@media (min-width: 900px) {
  .admin-body .page-head .head-title + .lead { min-height: calc(2 * 1.5em); }
}

/* Строки-карточки на узком экране: длинная подпись переносится,
   а не растягивает таблицу за край */
@media (max-width: 580px) {
  .admin-body td { grid-template-columns: minmax(0, 8.5em) minmax(0, 1fr); }
  .admin-body td > * { min-width: 0; overflow-wrap: anywhere; }
  .admin-body .page-head-split { grid-template-columns: 1fr; }
  .admin-body .page-head-split > .head-aside { justify-content: flex-start; }
  /* Пять вкладок в две строки: капсула со скруглением 20px, а не пилюля */
  .tabs { border-radius: 20px; }
  .tabs > .tab { flex: 1 1 auto; }
  /* Капсула занимает всю ширину, и «⋯» переносится на свою строку. Прижимаем его
     к правому краю: слева он читался бы отдельным элементом, а не действием курса */
  .tabs-row { justify-content: flex-end; }
  .tabs-row > .tabs { flex: 1 0 100%; }
  .admin-nav a { padding: 0 10px; font-size: 14px; }
  .admin-side { gap: 8px 12px; }
  .admin-body td .tag { white-space: normal; }
}

/* Подсказка о фото ученика – значком на самом аватаре, не отдельным пятном */
.head-title { position: relative; }
.head-title h1 { overflow-wrap: anywhere; }
.head-title > .avatar { position: relative; }
.head-title > .avatar + .info { position: absolute; left: 40px; top: 36px; z-index: 3; margin: 0; background: var(--white); box-shadow: 0 0 0 2px var(--white); }

/* Буква «i» оптически по центру кружка: без этого она садится ниже центра */
.info > i { display: block; transform: translateY(-0.5px); }
.queue-row .k { display: inline-flex; align-items: center; }

/* Пустая ячейка действий не печатает свою подпись в строке-карточке */
@media (max-width: 580px) {
  .admin-body td:empty { display: none; }
}

/* Подпись над заголовком раздела в админке: обычный регистр, как на карточках */
.admin-body .page-head p.eyebrow { text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--slate); }

/* ==========================================================================
   Правка на месте в шапке: название, описание, метка статуса, даты, пояс.
   Значение выглядит как текст, на наведении получает бледную подложку,
   на фокусе – рамку и белый фон, как поле. Карандашей и иконок нет.
   ========================================================================== */
.ed {
  display: inline-block; max-width: 100%; margin-inline: -6px; padding: 1px 6px;
  border: 1px solid transparent; border-radius: 8px; background: transparent;
  font: inherit; color: inherit; letter-spacing: inherit; line-height: inherit;
  cursor: text; transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.ed:hover { background: #eef2f8; }
.ed:focus, .ed:focus-visible {
  background: var(--white); border-color: var(--cobalt);
  box-shadow: 0 0 0 3px rgba(0,104,249,.16); outline: none; cursor: text;
}
.ed-empty::before { content: attr(data-placeholder); color: var(--steel); }
h1 > .ed, .admin-body .page-head > h1 > .ed { display: inline; }

/* Описание курса в шапке: многострочное, того же вида что и абзац */
.ed-multi { display: block; min-height: 1.5em; white-space: pre-wrap; overflow-wrap: anywhere; }
.admin-body .page-head > .lead > .ed-multi { max-width: 100%; }

/* Метка статуса, дата и часовой пояс: кликабельные значения в строке меток.
   Дропдаун и календарь те же, но кнопка выглядит как метка или как текст. */
.head-tags .dd { display: inline-flex; vertical-align: middle; }
.head-tags .dd .dd-btn, .head-tags .dd .date-btn {
  min-height: 26px; width: auto; padding: 0 26px 0 10px;
  border-radius: var(--r-badge); font-size: 13px; font-weight: 500;
  box-shadow: none; white-space: nowrap;
}
.head-tags .dd .dd-btn::after { right: 10px; width: 6px; height: 6px; margin-top: -5px; border-width: 1.5px; }
.head-tags .dd.open .dd-btn::after { margin-top: -2px; }

/* Метка статуса: тот же вид, что у .tag, плюс точка состояния */
.ed-tag .dd-btn { border: 1px solid var(--hairline); background: var(--ivory); color: var(--ink); }
.ed-tag .dd-btn::before { content: ""; width: 7px; height: 7px; margin-inline-end: 7px; border: 1.5px solid var(--steel); border-radius: 50%; background: transparent; flex: none; }
.ed-tag .dd-btn:hover { background: #eef2f8; border-color: var(--faint); }
.ed-tag[data-state="running"] .dd-btn { border-color: #bfd8ff; background: #e8f1ff; color: var(--cobalt-deep); }
.ed-tag[data-state="running"] .dd-btn::before { border-color: var(--cobalt); background: var(--cobalt); box-shadow: 0 0 0 3px rgba(0,104,249,.18); }
.ed-tag[data-state="running"] .dd-btn:hover { background: #dbe9ff; }
.ed-tag .dd-btn:focus-visible, .ed-tag.open .dd-btn { border-color: var(--cobalt); box-shadow: 0 0 0 3px rgba(0,104,249,.16); }

/* Дата и часовой пояс: обычный серый текст строки, подложка на наведении */
.ed-plain .dd-btn {
  border-color: transparent; background: transparent; color: var(--slate);
  font-size: 14px; font-weight: 400; padding: 0 22px 0 6px; margin-inline: -6px;
}
.ed-plain .dd-btn::after { right: 7px; border-color: var(--steel); }
.ed-plain .dd-btn:hover { background: #eef2f8; }
.ed-plain .dd-btn:focus-visible, .ed-plain.open .dd-btn { border-color: var(--cobalt); background: var(--white); box-shadow: 0 0 0 3px rgba(0,104,249,.16); }
.head-tags .sep { color: var(--steel); font-size: 14px; }
/* В строке меток шапки подсказка идёт вниз: сверху ей некуда – первый экран */
.head-tags .info::after { top: calc(100% + 8px); bottom: auto; }

/* Панель «Сохранить» при правке в шапке: висит над содержимым у нижнего края экрана.
   Она вне потока (position: fixed), поэтому её появление и исчезновение не двигает
   ни одну строку страницы – именно этого требует задача 29. Ширина повторяет
   контентную колонку админки, на узком экране – ширину окна за вычетом полей. */
.savebar-head {
  --savebar-side: 0px; /* ширина сайдбара админки, см. .admin-body ниже */
  position: fixed; inset-inline: var(--savebar-side) 0; bottom: 16px; z-index: 20;
  inline-size: min(100% - var(--savebar-side) - 64px, 1100px); margin-inline: auto;
  display: flex; gap: 8px; align-items: center; padding: 12px 16px;
  border: 1px solid var(--hairline); border-radius: var(--r-card);
  background: rgba(255,255,255,.94); backdrop-filter: blur(8px);
  box-shadow: var(--shadow-subtle), 0 -6px 24px -12px rgba(0,0,0,.22);
}
.savebar-head[hidden] { display: none; }
.savebar-head .hint { margin-inline-end: auto; }
.savebar-head { max-width: 100%; min-width: 0; }
/* Резерв под панель нужен ровно тогда, когда панель поднята. Пока она скрыта,
   любой отступ здесь – это видимая пустая полоса: подвал прижат к низу окна и
   идёт последним, поэтому его нижний padding ничем не закрыт. Прежний резерв
   стоял безусловно и давал под строкой подвала белую полосу в 72px (на ≤580px –
   128px) на каждой странице с правкой в шапке: курс, занятие, материал, карточка
   ученика, /me. Именно её и было видно на скриншоте.

   Величина резерва берётся из реальной высоты панели (`--savebar-h`, её ставит
   `lms.js`), а не из константы: панель переносит строки и на 1280px она 70px, на
   580px – 103px, на 375px – 124px, на 320px – 176px. Прежние 104/160px на узком
   экране не закрывали панель целиком, а на широком давали лишнее. 16px – зазор
   `bottom: 16px` самой панели.

   Своего резерва у `[data-head-edit]` больше нет: он давал те же 72px пустоты и,
   в отличие от подвала, ещё и перебивал нижний отступ `.admin-shell` (64px), из-за
   чего на странице курса воздуха под содержимым было меньше, чем на списке. */
body:has(.savebar-head:not([hidden])) .site-footer {
  padding-block-end: calc(32px + var(--savebar-h, 104px) + 16px);
}
/* В админке слева стоит сайдбар: панель центрируется по контентной колонке, а не по окну.
   На ≤899px сайдбар ложится сверху полосой, и смещение снимается. */
.admin-body .savebar-head { --savebar-side: 220px; }
@media (max-width: 899px) { .admin-body .savebar-head { --savebar-side: 0px; } }
@media (max-width: 580px) {
  .savebar-head { flex-wrap: wrap; gap: 8px 10px; padding: 12px 14px; inline-size: calc(100% - 32px); }
  .savebar-head .hint { flex: 1 0 100%; margin: 0; }
  .savebar-head .button, .savebar-head .button-secondary { flex: 1 1 auto; }
}

/* Описание в шапке остаётся строкой текста: подсказка ⓘ садится в конец
   последней строки, а не уезжает под абзац */
.admin-body .page-head > .lead { display: block; }
.admin-body .page-head > .lead > .ed-multi { display: inline; }
.admin-body .page-head > .lead > .ed-multi.ed-empty::before { display: inline; }

/* Колонка с правкой в шапке. Панель «Сохранить» больше не участвует в потоке
   (position: fixed выше), поэтому высоту колонки задаёт только содержимое:
   тянуть её на экран, как раньше, незачем. */
.admin-body .head-edit { display: grid; align-content: start; gap: 24px; }

/* Пара дат в шапке потока переносится целиком: «30 авг – 19 сен» не рвётся
   так, чтобы тире осталось висеть в конце строки */
.head-dates { display: inline-flex; align-items: center; gap: 2px; white-space: nowrap; }

/* Открытый список и календарь в шапке идут поверх заголовка и вкладок */
.page-head .dd.open, .page-head .cal-wrap.open, .head-edit .dd.open { position: relative; z-index: 50; }
.page-head .dd-menu, .page-head .cal { z-index: 60; }
/* Пока в шапке открыт список или календарь, заголовок и вкладки уступают ему место */
.page-head .dd-menu { min-width: 168px; }
@media (min-width: 581px) {
  .admin-body .page-head:has(.dd.open) h1,
  .admin-body .page-head:has(.cal:not([hidden])) h1 { opacity: .12; transition: opacity .12s ease; }
  .admin-body .page-head:has(.dd.open) + .tabs,
  .admin-body .page-head:has(.cal:not([hidden])) + .tabs,
  .admin-body .page-head:has(.dd.open) + .tabs-row,
  .admin-body .page-head:has(.cal:not([hidden])) + .tabs-row { opacity: .12; transition: opacity .12s ease; }
}

/* ==========================================================================
   Обзор карточки ученика: компактные строки «подпись – значение».
   Значение правится на месте тем же приёмом, что и шапка курса; действия
   строки стоят справа. Карточек-обёрток с повторной подписью здесь нет.
   ========================================================================== */
.stack-rows { display: grid; gap: 0; padding-block: 4px; }
.sr-h { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.orow {
  display: grid; grid-template-columns: minmax(8em, 15%) minmax(0, 1fr) auto;
  gap: 8px 20px; align-items: baseline;
  padding-block: 13px; border-bottom: 1px solid var(--hairline);
}
.orow:last-child { border-bottom: 0; }
.orow-lab { color: var(--slate); font-size: 14px; font-weight: 500; display: inline-flex; align-items: center; gap: 6px; }
.orow-val { display: grid; gap: 3px; min-width: 0; font-size: 15px; }
.orow-val > .row { align-items: center; gap: 8px 10px; }
.orow-val .sub { color: var(--slate); font-size: 13px; }
.orow-val .hint { color: var(--rust); }
.orow-error .ed-line { border-color: var(--rust); background: #fff8f7; }
.orow-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; justify-content: flex-end; }
.orow-act { font-size: 14px; font-weight: 500; color: var(--cobalt); white-space: nowrap; }
.orow-act-danger { color: var(--rust); }
.orow-act-danger:hover { color: #8f1c12; }
/* Дропдаун в строке: ширина по содержимому, не во всю колонку.
   Шеврон рисуется на .dd, поэтому ширину задаём обёртке, а не кнопке. */
.orow .dd { display: inline-block; width: max-content; min-width: 13em; max-width: 100%; justify-self: start; }
.orow .dd .dd-btn { min-height: 36px; font-size: 15px; }
/* Значение-поле в строке: тот же вид, что в шапке, но с видимой рамкой на всю ширину */
.ed-line { display: block; padding: 5px 9px; margin-inline: -9px; border-radius: 9px; }
.orow .tag { align-self: center; }
@media (max-width: 720px) {
  .orow { grid-template-columns: 1fr; gap: 6px; padding-block: 14px; }
  .orow-acts { justify-content: flex-start; }
}

/* ==========================================================================
   Вкладка «Профиль» ученика: блоки с правкой на месте и заметки по занятиям.
   Один заголовок на блок, текст правится тем же приёмом, что и шапка курса.
   ========================================================================== */
.prof-card { display: grid; gap: 0; padding-block: 4px; }
.prof-updated {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0; padding-block: 4px 14px;
  color: var(--slate); font-size: 14px;
}
.prof-block { display: grid; align-content: start; gap: 6px; padding-block: 16px; border-top: 1px solid var(--hairline); }
.prof-block > h3 {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 0;
  margin: 0; color: var(--slate); font-size: 14px; font-weight: 500; line-height: 1.38; text-wrap: nowrap;
}
.prof-block > .ed { font-size: 15px; line-height: 1.55; }
.prof-hint { color: var(--slate); font-size: 13px; }
.prof-list { display: grid; gap: 2px; margin: 0; padding-inline-start: 1.25em; font-size: 15px; line-height: 1.55; }
.prof-list li::marker { color: var(--steel); }
/* Пункт списка правится на месте: значение занимает всю строку пункта,
   иначе перенос второй строки уезжает под маркер. */
.prof-list li { padding-block: 1px; }
.prof-list .ed { display: block; min-height: 1.5em; }
.prof-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 32px; }
.prof-pair > .prof-block { border-top: 1px solid var(--hairline); }
.prof-note {
  padding-block: 9px; border-bottom: 1px solid var(--hairline);
}
.prof-notes > .prof-note:first-of-type { border-top: 1px solid var(--hairline); }
.prof-note > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  cursor: pointer; list-style: none;
  font-size: 15px; font-weight: 500; color: var(--ink);
}
.prof-note > summary::-webkit-details-marker { display: none; }
.prof-note > summary::after {
  content: "▾"; color: var(--slate); font-size: 13px; line-height: 1; flex: none;
}
.prof-note[open] > summary::after { content: "▴"; }
.prof-note > summary:hover { color: var(--cobalt); }
.prof-note > .ed { display: block; margin-block-start: 8px; font-size: 15px; line-height: 1.55; color: var(--graphite, #4b5563); }
.prof-notes { gap: 12px; }
.prof-notes > .empty { margin-block: 4px; }
@media (max-width: 720px) {
  .prof-pair { grid-template-columns: 1fr; gap: 0; }
}

/* ── Журнал · вкладка «Ошибки»: три группы вместо одной таблицы ─────────── */
.er-list { display: grid; gap: 12px; }
.er-card {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px 24px; align-items: start;
  padding: 16px 18px; border: 1px solid var(--hairline); border-radius: 14px; background: var(--white);
  border-inline-start: 3px solid var(--rust);
}
.er-card.er-warm { border-inline-start-color: var(--amber); }
.er-card .er-main { display: grid; gap: 6px; min-width: 0; }
.er-card h3 { margin: 0; font-size: 16px; font-weight: 600; line-height: 1.3; color: var(--ink); }
.er-why { margin: 0; font-size: 14px; line-height: 1.5; color: var(--graphite, #4b5563); }
.er-who { margin: 2px 0 0; font-size: 14px; }
.er-who .sub { display: block; margin-top: 2px; color: var(--slate); font-size: 13px; }
.er-more { margin-top: 4px; }
.er-more .jn-text { display: none; color: var(--slate); font-size: 13px; line-height: 1.5; }
.er-more.open .jn-text { display: block; margin-bottom: 4px; }
.er-more code { padding: 1px 5px; border-radius: 5px; background: var(--ivory); border: 1px solid var(--hairline); font-size: 12.5px; }
.er-act { display: grid; gap: 8px; justify-items: stretch; text-align: center; }
.er-act .er-dismiss { font-size: 13px; color: var(--slate); }
.er-act .er-dismiss:hover { color: var(--rust); }
.er-self {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 4px 20px;
  padding-block: 10px; border-top: 1px solid var(--hairline);
}
.er-self:first-child { border-top: 0; padding-top: 0; }
.er-self strong { display: block; font-size: 15px; font-weight: 500; }
.er-self .sub { display: block; margin-top: 2px; color: var(--slate); font-size: 13px; line-height: 1.45; }
.er-when { color: var(--slate); font-size: 13px; white-space: nowrap; }
.er-fold > summary {
  display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none;
  font-size: 17px; font-weight: 600; color: var(--ink);
}
.er-fold > summary::-webkit-details-marker { display: none; }
.er-fold > summary::after { content: "▾"; margin-inline-start: auto; color: var(--steel); font-size: 12px; }
.er-fold[open] > summary::after { content: "▴"; }
.er-folded { margin-top: 12px; }
.er-folded .er-done strong { font-weight: 400; color: var(--graphite, #4b5563); }
.er-steps { margin: 0 0 4px; padding-inline-start: 22px; display: grid; gap: 8px; font-size: 15px; line-height: 1.5; }
@media (max-width: 720px) {
  .er-self { grid-template-columns: 1fr; }
  .er-when { justify-self: start; }
  .er-card { grid-template-columns: 1fr; gap: 12px; }
  .er-act { justify-items: start; }
  .er-act .button, .er-act .button-secondary { width: 100%; }
}
/* Строка роли из профиля под именем ученика в списках.
   Аватар прижимается к первой строке: с двумя подстроками центрирование
   по всей ячейке уводило круг вниз, мимо имени. */
.sub-role { color: var(--slate); }
.cell-person:has(.sub) { align-items: start; }
.cell-person:has(.sub) .avatar { margin-block-start: 1px; }
.cell-person .sub-role + .sub { color: var(--slate); }

/* ==========================================================================
   Карточка ученика одной вкладкой: «Кто он» под именем, слева идентификаторы,
   справа «Доступ», ниже профиль, заметки по занятиям и «Опасная зона».
   Строки плотнее: ~44px на строку списка, заголовки блоков 14px, между
   блоками 16px. На узком экране всё в одну колонку.
   ========================================================================== */
.head-meta { margin: 0; color: var(--slate); font-size: 13px; line-height: 1.45; }
.admin-body .page-head > .lead > .ed-multi + .info { vertical-align: 2px; }
.ov-grid { display: grid; gap: 16px; align-items: start; }
@media (min-width: 1000px) { .ov-grid { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); } }
.ov-grid > .card { padding-block: 4px; }
.ov-grid .orow { padding-block: 10px; gap: 8px 16px; }
.ov-grid .orow-val { font-size: 15px; }
.ov-grid .orow .dd .dd-btn { min-height: 34px; }
.ov-grid .ed-line { padding: 4px 9px; }
/* Три действия строки не сжимают значение в узкий столбик: при трёх и больше
   действия уходят второй строкой под значение, в ту же колонку */
.ov-grid .orow:has(.orow-acts > :nth-child(3)) { grid-template-columns: minmax(8em, 15%) minmax(0, 1fr); row-gap: 4px; }
.ov-grid .orow:has(.orow-acts > :nth-child(3)) .orow-acts { grid-column: 2; justify-content: flex-start; }
/* Последняя видимая строка без нижней черты: скрытые подстроки после неё не в счёт */
.stack-rows > .orow:last-child { border-bottom: 1px solid var(--hairline); }
.stack-rows > .orow:not(:has(~ :not([hidden]))) { border-bottom: 0; }
.stack-rows > .orow-sub { margin-block-end: 6px; }

/* Подстрока под строкой списка: смена аккаунта, отвязка, новый ник, новый тариф */
.orow-sub {
  margin-block: 2px 8px; padding: 10px 12px 12px;
  border: 1px solid var(--hairline); border-radius: 12px; background: var(--ivory);
}
.orow-sub[hidden] { display: none; }
.orow-sub .inline-form strong { flex: 1 0 100%; font-size: 14px; }
.orow-sub .inline-form .hint { flex: 1 0 100%; color: var(--rust); font-size: 13px; }
.orow-sub .inline-form input[type="text"] { min-height: 36px; }
.sub-confirm { display: grid; gap: 8px; font-size: 14px; }
.sub-confirm strong { font-size: 14px; }
.sub-confirm ul { margin: 0; padding-inline-start: 1.2em; display: grid; gap: 3px; color: var(--graphite, #4b5563); line-height: 1.45; }
.orow-act[type="button"] { background: none; border: 0; padding: 0; font: inherit; font-size: 14px; font-weight: 500; cursor: pointer; }
.orow-act[type="button"]:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Блок «Доступ»: курс и тариф одной строкой, история свёрнута */
.acc-card { display: grid; gap: 0; padding: 6px 20px; }
.acc-card > h3 { margin: 0; padding-block: 10px 4px; color: var(--slate); font-size: 14px; font-weight: 500; }
.arow {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 16px; align-items: baseline;
  padding-block: 8px; border-bottom: 1px solid var(--hairline);
}
.arow-main { display: grid; gap: 2px; min-width: 0; }
.arow-name { font-size: 15px; }
.arow-main .sub { color: var(--slate); font-size: 13px; }
.arow-empty { border-bottom: 1px solid var(--hairline); }
.arow-foot { padding-block: 9px; }
.arow-foot .link-button { font-size: 14px; }
.acc-hist { border-top: 1px solid var(--hairline); padding-block: 8px 4px; }
.acc-hist > summary { cursor: pointer; list-style: none; color: var(--slate); font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 8px; }
.acc-hist > summary::-webkit-details-marker { display: none; }
.acc-hist > summary::after { content: "▾"; font-size: 12px; color: var(--steel); }
.acc-hist[open] > summary::after { content: "▴"; }
.acc-hist-list { margin: 8px 0 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.acc-hist-list li { display: grid; gap: 1px; font-size: 14px; color: var(--graphite, #4b5563); }
.acc-hist-list .sub { color: var(--slate); font-size: 13px; }

/* Профиль на общей вкладке: плотнее, заметки с меткой присутствия */
.prof-card { padding-block: 2px; }
.prof-card .prof-updated { padding-block: 10px 8px; }
.prof-block { padding-block: 10px; }
.prof-block > .ed, .prof-list { font-size: 14.5px; line-height: 1.5; }
.prof-note { padding-block: 7px; }
.prof-note > summary > span:first-child { flex: 1 1 auto; min-width: 0; }
.note-flag {
  display: inline-flex; align-items: center; min-height: 20px; padding: 0 8px; margin-inline-start: auto;
  border: 1px solid var(--hairline); border-radius: var(--r-badge); background: var(--ivory);
  color: var(--slate); font-size: 12px; font-weight: 500; white-space: nowrap;
}
.prof-note > summary::after { margin-inline-start: 4px; }
.note-form { margin-block-start: 8px; }
.note-form .field label { font-size: 13px; color: var(--slate); }
.note-form textarea { min-height: 88px; }
.note-form .dd { display: inline-block; width: max-content; min-width: 16em; max-width: 100%; }
.note-form .dd .dd-btn { min-height: 36px; font-size: 14px; }

/* Шапка занятия: тип меткой без точки, время текстовым полем рядом с датой */
.ed-tag-kind .dd-btn::before { display: none; }
.head-tags input.time {
  display: inline-block; width: 4.6em; min-height: 26px; padding: 0 6px; margin-inline-start: 2px;
  border: 1px solid transparent; border-radius: 8px; background: transparent; box-shadow: none;
  color: var(--slate); font-size: 14px; font-weight: 400; text-align: center;
}
.head-tags input.time:hover { background: #eef2f8; }
.head-tags input.time:focus { border-color: var(--cobalt); background: var(--white); color: var(--ink); box-shadow: 0 0 0 3px rgba(0,104,249,.16); }
.head-tags .ed-tag + .info { margin-inline-start: 2px; }
@media (max-width: 580px) {
  .head-tags { row-gap: 8px; }
  .head-tags .sep { display: none; }
  .ov-grid > .card, .acc-card { padding-inline: 16px; }
  /* Поля не мельче 16px: iOS Safari иначе зумит страницу на фокусе */
  input:not([type="checkbox"]):not([type="radio"]), textarea, select, [contenteditable] { font-size: max(16px, 1em); }
  /* Цели нажатия не ниже 40px */
  .orow-act, .link-button, .tc-add, .vis-btn, .er-dismiss, [data-more], a.back, .tg-back, .admin-side-link { display: inline-flex; align-items: center; min-height: 40px; }
  .rmenu-btn, .blk-more, .row-more { width: 40px; height: 40px; }
  .blk-more { top: 8px; right: 8px; }
  .blk-menu { top: 50px; }
  .rmenu-list { top: 44px; }
  .tab, .chip, .button-sm { min-height: 40px; }
  .primary-nav a { min-height: 40px; }
}
/* Подсказка на телефоне: полоса на ширину экрана над значком (или под ним, если сверху нет места).
   Позиция считается от самого значка через anchor(), поэтому край окна её не режет. */
@media (max-width: 580px) {
  .info::after, .info.tip-start::after, .info.tip-end::after, .head-tags .info::after {
    position: fixed; inset: auto 12px; width: auto; max-width: none; transform: none;
    top: auto; bottom: anchor(top); margin-block-end: 8px; position-try-fallbacks: flip-block;
  }
}
/* На сенсорном экране у ⓘ зона нажатия 40×40 */
@media (hover: none) {
  .info::before { content: ""; position: absolute; inset: -12px; border-radius: 50%; }
}

/* Навигация кабинета: имя и аватар справа */
.primary-nav ul { align-items: center; }
.primary-nav .nav-me { margin-inline-start: auto; }
.primary-nav .nav-user { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; }
.primary-nav .nav-user .avatar { box-shadow: 0 0 0 2px var(--white); }
@media (max-width: 580px) { .primary-nav .nav-user > span:last-child { display: none; } }

/* ==========================================================================
   Аватар с заменой фото: клик по кругу открывает выбор файла,
   на наведении и фокусе поверх круга появляется «Заменить фото».
   Тот же круг в карточке ученика админки и в профиле кабинета.
   ========================================================================== */
.avatar-pick { position: relative; display: inline-grid; place-items: center; flex: none; width: 56px; height: 56px; border-radius: 50%; overflow: hidden; cursor: pointer; }
.avatar-pick:has(> .avatar-md) { width: 40px; height: 40px; }
.avatar-pick > input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border-radius: 50%; z-index: 2; }
.avatar-pick > .avatar { grid-area: 1 / 1; }
.avatar-pick-hint {
  position: absolute; inset: 0; z-index: 1; display: grid; place-items: center; width: auto; height: auto; border-radius: 50%;
  background: rgba(17,19,26,.62); color: #fff; font-size: 9px; font-weight: 600; line-height: 1.15;
  text-align: center; padding: 4px; overflow-wrap: anywhere; opacity: 0; transition: opacity .15s ease; pointer-events: none;
}
/* Наведение мышью и фокус с клавиатуры. `:focus-visible` вместо `:focus-within`:
   тап по кругу на тач-экране тоже ставит фокус на input, но подпись там не нужна –
   тап сразу открывает выбор файла. */
.avatar-pick:hover .avatar-pick-hint,
.avatar-pick > input[type="file"]:focus-visible ~ .avatar-pick-hint { opacity: 1; }
.avatar-pick:has(> input[type="file"]:focus-visible) { box-shadow: 0 0 0 3px rgba(0,104,249,.32); }
.avatar-pick.av-picked > .avatar { background: linear-gradient(135deg, #1a1d29, #4a4f66); color: transparent; }
.head-title > .avatar-pick + .info { position: absolute; left: 40px; top: 36px; z-index: 3; margin: 0; background: var(--white); box-shadow: 0 0 0 2px var(--white); }
/* Описание под именем в профиле – одно в обоих кабинетах: 16px, graphite */
.page-head:has(> .head-title > .avatar-pick) > .lead { font-size: 16px; color: var(--graphite); }

/* ==========================================================================
   Профиль ученика в кабинете: та же шапка и строки, что в карточке админки.
   Имя правится по клику, метки и «кто он» под ним, строки ~44px,
   панель «Сохранить · Отменить» липнет ко дну после первого изменения.
   ========================================================================== */
.me-head.page-head { display: grid; gap: 8px; padding-block: 24px 0; }
.head-edit:not(.admin-body *) { display: grid; gap: 24px; }
.me-head .head-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0; }
.me-head .head-title { display: flex; align-items: center; gap: 16px; min-width: 0; position: relative; }
.me-head h1 { font-size: clamp(30px, 3.4vw, 38px); margin: 0; min-width: 0; overflow-wrap: anywhere; }
.me-head .lead { margin: 0; font-size: 16px; color: var(--graphite, #4b5563); }
.me-rows { padding-block: 4px; }
.me-rows .orow { padding-block: 10px; gap: 8px 16px; min-height: 44px; }
.me-rows .orow .dd .dd-btn { min-height: 34px; }
.me-rows .orow-val .tag { justify-self: start; }
.me-exit { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; padding-block: 4px 8px; }
@media (max-width: 580px) {
  .me-head .head-tags { row-gap: 8px; }
  .me-rows { padding-inline: 16px; }
}

/* materials: библиотека, карточки, промпт для агента, привязка */
.blk-body code { padding: 1px 6px; border-radius: 6px; background: var(--ivory); border: 1px solid var(--hairline); font-size: .92em; }
.mat-search input[type="search"] { max-width: 420px; }
.mat-grid { display: grid; gap: 12px; }
.mat-card { gap: 8px; padding: 18px 20px; }
.mat-card-title { font-size: 17px; font-weight: 500; letter-spacing: -.01em; color: var(--ink); }
.mat-card > .muted { font-weight: 400; }
.mat-card-foot { gap: 6px 16px; }
.mat-card[hidden] { display: none; }
.mat-meta a { color: var(--slate); text-decoration: underline; text-decoration-color: var(--hairline); text-underline-offset: 3px; font-weight: 400; }
.mat-meta a:hover { color: var(--cobalt); }
.mat-bind { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: 14px; color: var(--slate); }
.mat-bind-btn { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; margin-inline-start: -9px; border: 1px solid transparent; border-radius: 9px; background: transparent; color: var(--slate); font-size: 14px; cursor: pointer; text-align: left; }
.mat-bind-btn strong { color: var(--ink); font-weight: 500; }
.mat-bind-btn::after { content: ""; width: 6px; height: 6px; border-right: 1.5px solid var(--steel); border-bottom: 1.5px solid var(--steel); transform: rotate(45deg) translateY(-2px); flex: none; }
.mat-bind-btn:hover { background: #eef2f8; border-color: var(--hairline); }
.mat-bind-pick { display: grid; gap: 12px; }
.mat-bind-pick .dd { display: inline-block; width: max-content; min-width: 16em; max-width: 100%; }
.mat-bind-pick .choices .chip { font-size: 14px; min-height: 34px; }
.page-head .lead .ed-multi { display: block; }
.row-more { width: 32px; height: 32px; border: 1px solid transparent; border-radius: 50%; background: transparent; color: var(--slate); font-size: 18px; line-height: 1; cursor: pointer; }
.row-more:hover { background: var(--ivory); border-color: var(--hairline); color: var(--ink); }
.mat-acts { gap: 8px 16px; }
.mat-acts strong { flex: 1 0 100%; }
.mat-acts .hint { flex: 1 0 100%; }
.mat-table .col-more { width: 48px; text-align: right; }
@media (max-width: 580px) {
  .mat-card-foot { display: grid; }
  .blk, .mat-card { padding-inline: 16px; }
}

/* ==========================================================================
   Блоки занятия и материала: общий контракт для ученика и админа.
   <section class="blk"><h2 class="blk-title">…</h2><div class="blk-body">…</div></section>
   У ученика – карточка как раньше. У админа те же классы плюс contenteditable,
   кнопка «⋯» в правом верхнем углу и «Добавить блок» после последнего.
   ========================================================================== */
.blocks { display: grid; gap: 24px; min-width: 0; }
.blk { position: relative; display: grid; gap: 16px; padding: 20px; border: 1px solid var(--hairline); border-radius: var(--r-card); background: var(--white); color: var(--ink); box-shadow: var(--shadow-subtle); min-width: 0; }
@media (min-width: 768px) { .blk { padding: 24px; } }
.blk-title { font-size: 24px; line-height: 1.33; letter-spacing: -.02em; }
.blk-body { display: grid; gap: 10px; color: var(--graphite); min-width: 0; overflow-wrap: anywhere; }
.blk-body p { margin: 0; color: var(--graphite); }
.blk-body ol, .blk-body ul { display: grid; gap: 6px; margin: 0; padding-inline-start: 22px; color: var(--graphite); font-size: 15px; }
.blk-body li::marker { color: var(--slate); font-weight: 500; }
.blk-body a { font-weight: 500; }
.blk-body strong, .blk-body b { color: var(--ink); font-weight: 600; }

/* Правка на месте у админа: без рамок и карандашей, бледный фон при наведении */
.blk-title[contenteditable], .blk-body[contenteditable] { margin-inline: -6px; padding: 1px 6px; border: 1px solid transparent; border-radius: 8px; cursor: text; transition: background .12s ease, border-color .12s ease, box-shadow .12s ease; }
.blk-title[contenteditable]:hover, .blk-body[contenteditable]:hover { background: #eef2f8; }
.blk-title[contenteditable]:focus, .blk-body[contenteditable]:focus { outline: none; background: var(--white); border-color: var(--cobalt); box-shadow: 0 0 0 3px rgba(0,104,249,.16); }
.blk-title[contenteditable].is-empty::before, .blk-body[contenteditable].is-empty::before { content: attr(data-placeholder); color: var(--steel); }
.blk-body[contenteditable].is-empty::before { display: block; }
/* Заголовок блока кончается до кнопки «⋯»: она лежит абсолютом в правом верхнем углу
   (32px при right: 12px), а поле правки растянуто на всю ширину и на -6px наружу,
   поэтому длинное название заезжало под кнопку (приёмка staging 2026-09-08).
   Ширина поля режется, а не только внутренний отступ: иначе текст не наезжает,
   но клик рядом с кнопкой всё равно попадает в поле, а не в «⋯».
   Место под кнопку считается от padding блока – одна формула на все ширины. */
.blk-title[contenteditable] { margin-inline-end: calc(32px + 12px + 8px - 24px); }
@media (max-width: 767px) { .blk-title[contenteditable] { margin-inline-end: calc(32px + 12px + 8px - 20px); } }
@media (max-width: 720px) { .blk-title[contenteditable] { margin-inline-end: calc(40px + 8px + 8px - 20px); } }
.blk-more { position: absolute; top: 12px; right: 12px; z-index: 2; width: 32px; height: 32px; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--slate); font-size: 18px; line-height: 1; cursor: pointer; opacity: 0; transition: opacity .12s ease, background .12s ease; }
.blk:hover .blk-more, .blk:focus-within .blk-more, .blk-more:focus-visible, .blk-more[aria-expanded="true"] { opacity: 1; }
.blk-more:hover, .blk-more[aria-expanded="true"] { background: var(--ivory); border-color: var(--hairline); color: var(--ink); }
.blk-menu { position: absolute; top: 46px; right: 12px; z-index: 40; display: grid; min-width: 150px; padding: 6px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--white); box-shadow: var(--shadow-lg); }
.blk-menu[hidden] { display: none; }
.blk-menu button, .rmenu-list button { display: block; width: 100%; padding: 8px 12px; border: 0; border-radius: 8px; background: transparent; color: var(--ink); font-size: 14px; text-align: left; cursor: pointer; }
.blk-menu button:hover, .rmenu-list button:hover { background: var(--ivory); }
.blk-menu button.danger, .rmenu-list button.danger { color: var(--rust); }
.blk-add { justify-self: start; min-height: 40px; padding: 8px 18px; border: 1px dashed var(--faint); border-radius: var(--r-button); background: transparent; color: var(--slate); font-size: 15px; font-weight: 500; cursor: pointer; }
.blk-add:hover { border-color: var(--cobalt); color: var(--cobalt); background: #f3f7ff; }

/* ── Подблоки внутри блока (Task 31) ───────────────────────────────────────
   Блок – контейнер: заголовок и список подблоков heading · subheading · text ·
   copy · video · timecodes. У ученика подблоки идут подряд без рамок; у админа
   каждый получает своё «⋯» слева от края и правится на месте. */
.blk-subs { display: grid; gap: 16px; min-width: 0; }
.sub { position: relative; display: grid; gap: 10px; min-width: 0; }
.sub-heading { font-size: 18px; line-height: 1.4; letter-spacing: -.01em; color: var(--ink); font-weight: 600; }
.sub-subheading { font-size: 15px; line-height: 1.45; color: var(--ink); font-weight: 600; }
.sub-heading[contenteditable], .sub-subheading[contenteditable], .copy-text[contenteditable] { margin-inline: -6px; padding: 1px 6px; border: 1px solid transparent; border-radius: 8px; cursor: text; transition: background .12s ease, border-color .12s ease, box-shadow .12s ease; }
.sub-heading[contenteditable]:hover, .sub-subheading[contenteditable]:hover { background: #eef2f8; }
.sub-heading[contenteditable]:focus, .sub-subheading[contenteditable]:focus, .copy-text[contenteditable]:focus { outline: none; background: var(--white); border-color: var(--cobalt); box-shadow: 0 0 0 3px rgba(0,104,249,.16); }
.sub-heading[contenteditable].is-empty::before, .sub-subheading[contenteditable].is-empty::before, .copy-text[contenteditable].is-empty::before { content: attr(data-placeholder); color: var(--steel); }
.copy-text[contenteditable].is-empty::before { display: block; font-family: var(--sans); font-size: 15px; }

/* «⋯» подблока: тот же вид, что у блока, но левее кнопки блока и на 4px ниже,
   чтобы два меню не наезжали друг на друга в первом подблоке. */
.sub-more { position: absolute; top: -4px; right: -4px; z-index: 3; width: 28px; height: 28px; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--slate); font-size: 16px; line-height: 1; cursor: pointer; opacity: 0; transition: opacity .12s ease, background .12s ease; }
.sub:hover > .sub-acts .sub-more, .sub:focus-within > .sub-acts .sub-more, .sub-more:focus-visible, .sub-more[aria-expanded="true"] { opacity: 1; }
.sub-more:hover, .sub-more[aria-expanded="true"] { background: var(--ivory); border-color: var(--hairline); color: var(--ink); }
.sub-acts { position: static; }

/* «Добавить подблок»: пунктирная кнопка в конце блока, как «Добавить блок» */
/* Всплывашка «Добавить подблок» открывается от левого края своей кнопки:
   кнопка широкая и стоит слева, `right: 0` уводил меню за край блока. */
.sub-add { justify-self: start; }
.sub-add .rmenu-list { left: 0; right: auto; }
.sub-add-btn { display: inline-flex; align-items: center; gap: 8px; min-height: 34px; padding: 6px 14px; border: 1px dashed var(--faint); border-radius: var(--r-button); background: transparent; color: var(--slate); font-size: 14px; font-weight: 500; line-height: 1.2; white-space: nowrap; cursor: pointer; }
.sub-add-btn:hover, .sub-add-btn[aria-expanded="true"] { border-color: var(--cobalt); color: var(--cobalt); background: #f3f7ff; }

/* Текст для копирования: моноширинное поле и кнопка «Скопировать».
   На широком экране кнопка лежит на верхнем крае поля, а не отдельной строкой над ним:
   иначе между кнопкой и текстом зияет пустая полоса (проверка в браузере). Коридор под
   неё задан одной переменной, её же ширину фиксирует `.copy-btn`, поэтому длинная строка
   без пробелов не заезжает под кнопку ни в состоянии «Скопировать», ни «Скопировано». */
.sub-copy { position: relative; gap: 0; --copy-btn-w: 150px; --copy-btn-gap: 8px; }
.copy-head { position: absolute; top: 8px; right: var(--copy-btn-gap); z-index: 1; display: flex; }
.copy-btn { min-width: var(--copy-btn-w); justify-content: center; background: var(--white); }
.copy-text { margin: 0; padding: 16px calc(var(--copy-btn-w) + var(--copy-btn-gap) * 2) 16px 18px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--ivory); color: var(--graphite); font: 13.5px/1.55 ui-monospace, "SF Mono", Menlo, Consolas, monospace; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 480px; overflow: auto; }
/* Общее правило правки на месте (заголовки) сплющивало поле копирования до
   `padding: 1px 6px` и уводило коридор под кнопку: у `.copy-text` свой бокс. */
.copy-text[contenteditable] { margin-inline: 0; padding: 16px calc(var(--copy-btn-w) + var(--copy-btn-gap) * 2) 16px 18px; }
.copy-text[contenteditable]:hover { background: #f6f7fa; }
.copy-btn.is-done { border-color: #c6ecd3; background: #edf9f1; color: var(--forest); }

/* Узкий экран: коридор в 150px съедал бы почти половину поля – кнопка встаёт
   отдельной строкой над текстом, коридор не нужен. */
@media (max-width: 580px) {
  .sub-copy { display: flex; flex-direction: column; gap: 8px; }
  .copy-head { position: static; justify-content: flex-end; }
  .copy-text, .copy-text[contenteditable] { padding: 16px 18px; }
}

/* Видео: плеер во всю ширину блока, 16:9 */
.vid-frame { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; border-radius: 12px; background: var(--ink); }
.vid-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.vid-form[hidden] { display: none; }
.vid-form input { flex: 1 1 260px; min-height: 38px; padding: 8px 12px; border: 1px solid var(--hairline); border-radius: 10px; font-size: 15px; }
.vid-replace { justify-self: start; min-height: 32px; padding: 5px 12px; border: 1px solid var(--hairline); border-radius: var(--r-button); background: var(--white); color: var(--slate); font-size: 13px; cursor: pointer; }
.vid-replace:hover { border-color: var(--cobalt); color: var(--cobalt); }

/* Плавающая панель над выделением: жирный, ссылка, список */
.blk-tools { position: absolute; z-index: 70; display: flex; gap: 2px; align-items: center; padding: 4px; border: 1px solid var(--hairline); border-radius: 10px; background: var(--white); box-shadow: var(--shadow-lg); }
.blk-tools[hidden] { display: none; }
.blk-tools button { min-height: 30px; padding: 4px 10px; border: 0; border-radius: 7px; background: transparent; color: var(--ink); font-size: 13px; font-weight: 500; cursor: pointer; white-space: nowrap; }
.blk-tools button:hover, .blk-tools button[aria-pressed="true"] { background: var(--ivory); }
.blk-tools-url { display: flex; gap: 4px; align-items: center; padding-inline-start: 4px; border-inline-start: 1px solid var(--hairline); }
.blk-tools-url[hidden] { display: none; }
.blk-tools-url input { width: 220px; max-width: 50vw; min-height: 30px; padding: 3px 8px; border: 1px solid var(--hairline); border-radius: 7px; font-size: 13px; }

/* Таймкоды у админа: строка правится на месте, ссылка строится сама */
.sub-tc .tc-hint { color: var(--slate); font-size: 14px; }
.timecodes .tc-link { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 12px; align-items: baseline; padding: 8px 10px; border-radius: 10px; color: var(--ink); }
[data-blocks] .timecodes li { border-radius: 10px; }
[data-blocks] .timecodes li > a, [data-blocks] .timecodes li > .tc-link { cursor: text; }
[data-blocks] .timecodes li:hover > a, [data-blocks] .timecodes li:hover > .tc-link { background: #eef2f8; }
[data-blocks] .timecodes li:hover .tt { color: var(--ink); }
.tc-row { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 12px; align-items: baseline; padding: 4px 10px; border-radius: 10px; background: var(--white); box-shadow: 0 0 0 1px var(--cobalt), 0 0 0 4px rgba(0,104,249,.16); }
.tc-row input { min-height: 28px; padding: 2px 0; border: 0; border-radius: 0; background: transparent; font-size: 15px; line-height: 1.4; box-shadow: none; }
.tc-row input:focus { outline: none; box-shadow: none; }
.tc-row .tc-time { color: var(--cobalt); font-size: 14px; font-weight: 500; font-variant-numeric: tabular-nums; }
.tc-add { justify-self: start; margin-top: 4px; padding: 0; border: 0; background: none; color: var(--slate); font-size: 14px; font-weight: 500; cursor: pointer; }
.tc-add:hover { color: var(--cobalt); }

/* Запись у админа: заглушка плеера с полем ссылки или плеер с «Заменить запись» */
.rec { position: relative; aspect-ratio: 16 / 9; display: grid; place-items: center; min-width: 0; border-radius: var(--r-card); }
.rec-empty { aspect-ratio: auto; min-height: 168px; padding: 24px; text-align: center; border: 1.5px dashed var(--faint); background: linear-gradient(180deg, var(--lavender), var(--white)); color: var(--graphite); box-shadow: var(--shadow-lg); }
.rec-empty .rec-hint { border: 0; background: transparent; color: var(--ink); font-size: 16px; font-weight: 500; cursor: pointer; padding: 8px 12px; border-radius: 10px; }
.rec-empty .rec-hint:hover { background: rgba(255,255,255,.7); color: var(--cobalt); }
.rec-empty .rec-hint[hidden] { display: none; }
.rec-form { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: center; width: min(100%, 520px); }
.rec-form[hidden] { display: none; }
.rec-form input { flex: 1 1 240px; min-height: 40px; }
.rec-filled { background: var(--deep-ink); color: #b8bcc4; box-shadow: var(--shadow-lg); }
.rec-filled .play { display: grid; place-items: center; width: 72px; height: 72px; border-radius: 50%; background: rgba(255,255,255,.92); box-shadow: var(--shadow-lg); }
.rec-filled .play::before { content: ""; width: 0; height: 0; margin-inline-start: 5px; border-block: 12px solid transparent; border-inline-start: 20px solid var(--deep-ink); }
.rec-filled .len { position: absolute; right: 12px; bottom: 12px; padding: 3px 8px; border-radius: 6px; background: rgba(0,0,0,.72); color: #fff; font-size: 13px; font-weight: 500; }
.rec-filled .rec-replace { position: absolute; top: 12px; right: 12px; min-height: 34px; padding: 6px 14px; border: 1px solid rgba(255,255,255,.3); border-radius: var(--r-button); background: rgba(17,19,26,.7); color: #fff; font-size: 13px; font-weight: 500; cursor: pointer; opacity: 0; transition: opacity .12s ease; }
.rec-filled:hover .rec-replace, .rec-filled:focus-within .rec-replace, .rec-replace:focus-visible { opacity: 1; }
.rec-filled .rec-form { position: absolute; inset: auto 16px 16px; padding: 10px; border-radius: 12px; background: rgba(255,255,255,.96); }

/* Шапка занятия у админа: строка «Видят» с чипами тарифов и строка Zoom */
.lhead-rows { display: grid; gap: 8px; margin-block-start: -8px; }
.vis-btn { display: inline-block; max-width: 100%; margin-inline: -6px; padding: 2px 6px; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--slate); font-size: 14px; line-height: 1.45; cursor: pointer; text-align: left; white-space: normal; }
.vis-btn strong { color: var(--ink); font-weight: 500; }
.vis-btn::after { content: ""; display: inline-block; width: 6px; height: 6px; margin-inline-start: 8px; vertical-align: 2px; border-right: 1.5px solid var(--steel); border-bottom: 1.5px solid var(--steel); transform: rotate(45deg); }
.vis-btn[aria-expanded="true"]::after { transform: rotate(-135deg); vertical-align: -2px; }
.vis-btn:hover { background: #eef2f8; }
.vis-panel { display: grid; gap: 10px; padding: 12px 14px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--white); box-shadow: var(--shadow-subtle); }
.vis-panel[hidden] { display: none; }
.vis-group { display: grid; grid-template-columns: 9.5em minmax(0, 1fr); gap: 6px 12px; align-items: center; }
.vis-group .vis-lab { color: var(--slate); font-size: 14px; }
.vis-group .choices { gap: 6px; }
.vis-group .chip { min-height: 30px; padding-inline: 12px; font-size: 14px; }
@media (max-width: 580px) { .vis-group { grid-template-columns: 1fr; } }
.zoom-row { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: baseline; color: var(--slate); font-size: 14px; }
.zoom-row .ed { color: var(--ink); font-size: 14px; overflow-wrap: anywhere; }

/* Таблица занятий курса: меню «⋯» в строке, строка правки на месте, подтверждение удаления */
.rmenu { position: relative; display: inline-block; }
.rmenu-btn { width: 32px; height: 32px; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--slate); font-size: 18px; line-height: 1; cursor: pointer; }
.rmenu-btn:hover, .rmenu-btn[aria-expanded="true"] { background: var(--ivory); border-color: var(--hairline); color: var(--ink); }
.rmenu-list { position: absolute; top: 36px; right: 0; z-index: 40; display: grid; min-width: 150px; padding: 6px; border: 1px solid var(--hairline); border-radius: 12px; background: var(--white); box-shadow: var(--shadow-lg); }
.rmenu-list[hidden] { display: none; }
.admin-body td .rmenu-list button { text-align: left; }
tr.tr-edit td, tr.tr-del td { background: var(--ivory); vertical-align: middle; }
tr.tr-edit[hidden], tr.tr-del[hidden], tr.tr-view[hidden] { display: none; }
tr.tr-edit .field { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; vertical-align: middle; }
tr.tr-edit td.nw { white-space: normal; }
tr.tr-edit input[type="text"] { min-height: 34px; padding: 5px 10px; font-size: 14px; width: 100%; min-width: 150px; }
tr.tr-edit input.time { width: 4.6em; min-width: 0; }
tr.tr-edit .dd-sm .dd-btn { min-height: 34px; padding-left: 10px; }
tr.tr-edit .choices { gap: 4px; }
tr.tr-edit .chip { min-height: 26px; padding-inline: 8px; gap: 5px; font-size: 12px; }
tr.tr-edit .chip[data-check]::before { width: 12px; height: 12px; }
tr.tr-edit .row-acts { display: grid; gap: 6px; justify-items: start; }
tr.tr-del .del-box { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; justify-content: space-between; }
tr.tr-del .del-box span { color: var(--ink); font-size: 14px; }
@media (max-width: 767px) {
  .admin-body tr.tr-edit td, .admin-body tr.tr-del td { grid-template-columns: 7em minmax(0, 1fr); background: transparent; }
  .admin-body tr.tr-edit, .admin-body tr.tr-del { background: var(--ivory); border-radius: 12px; }
  .admin-body tr.tr-edit td:not([data-th]), .admin-body tr.tr-del td { grid-template-columns: 1fr; }
  .admin-body tr.tr-edit input[type="text"] { min-width: 0; }
  .rmenu-list { right: auto; left: 0; }
}

/* materials: четыре пункта меню админки на 375 прокручиваются внутри полосы, а не растягивают экран */
@media (max-width: 899px) { .admin-side { min-width: 0; } }

/* сверка ученик ↔ админ (2026-09-05): «Кто он» одной строкой в списке, тариф словами на курсе, строка правки тарифа */
/* Описание не задаёт ширину ячейки (width: 0 + min-width: 100%), ячейке имени отдаётся 42% таблицы */
.sub-role { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 0; min-width: 100%; max-inline-size: none; }
.cell-person > div { flex: 1 1 auto; }
@media (min-width: 581px) { .admin-body td:has(.sub-role) { width: 42%; } }
@media (max-width: 580px) { .sub-role, .admin-body td .sub-role { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; white-space: normal; } }
/* Список учеников: «Курс · тариф» одной строкой, имя не сжимается до трёх строк описания */
@media (min-width: 1000px) { .admin-body td[data-th="Курс · тариф"] { min-width: 12em; } }
.course-tariff { margin: 0; color: var(--slate); font-size: 14px; }
.course-tariff strong { color: var(--ink); font-weight: 600; }
tr.tr-edit input[type="number"] { min-height: 34px; padding: 5px 8px; width: 4.2em; font-size: 14px; }


/* mechanics */
/* ── Единые механики (2026-09-06): меню «⋯» на все места, Escape, модалка,
   клавиатура в таймкодах и календаре, видимость hover-кнопок на телефоне,
   цели нажатия и панель «Сохранить» на узком экране. Только дописано в конец. ── */

/* Меню «⋯»: кнопка и всплывашка рядом; у края экрана переворачивается влево или вверх */
.rmenu-btn { width: 36px; height: 36px; }
.rmenu-btn:focus-visible { outline: none; border-color: var(--cobalt); background: var(--white); color: var(--ink); box-shadow: 0 0 0 3px rgba(0,104,249,.16); }
.rmenu-list { top: calc(100% + 4px); right: 0; left: auto; max-width: calc(100vw - 32px); }
.rmenu-list.rmenu-list-start { left: 0; right: auto; }
.rmenu-list.rmenu-list-up { top: auto; bottom: calc(100% + 4px); }
.rmenu-list button, .rmenu-list a[role="menuitem"] { display: flex; align-items: center; gap: 8px; width: 100%; box-sizing: border-box; padding: 9px 12px; border: 0; border-radius: 8px; background: transparent; color: var(--ink); font: inherit; font-size: 14px; font-weight: 400; line-height: 1.3; text-align: left; text-decoration: none; white-space: nowrap; cursor: pointer; }
.rmenu-list button:hover, .rmenu-list a[role="menuitem"]:hover { background: var(--ivory); text-decoration: none; }
.rmenu-list button:disabled { opacity: .45; cursor: not-allowed; background: transparent; }
.rmenu-list button.danger, .rmenu-list a[role="menuitem"].danger { color: var(--rust); }
.rmenu-list [role="menuitem"]:focus-visible { outline: none; background: var(--ivory); box-shadow: inset 0 0 0 2px var(--cobalt); }
/* Иконка пункта меню (Task 29): один линейный набор. Нажатие проходит сквозь неё,
   чтобы e.target всегда был самой кнопкой.

   Цвет по умолчанию серый (--slate), а не цвет текста – осознанно: иконка здесь
   вторична, она помогает найти нужный пункт взглядом, но не спорит с подписью.
   Наведение и .danger возвращают ей цвет пункта, поэтому корзина у «Удалить»
   краснеет вместе с текстом, а активный пункт читается целиком. */
.rmenu-list .ic { flex: none; pointer-events: none; color: var(--slate); }
.rmenu-list .danger .ic { color: inherit; }
.rmenu-list [role="menuitem"]:hover .ic { color: inherit; }

/* Строка карточки и строка доступа: меню справа, по центру строки */
.orow > .rmenu, .arow > .rmenu { justify-self: end; align-self: center; }
@media (max-width: 720px) {
  .orow:has(> .rmenu) { grid-template-columns: minmax(0, 1fr) auto; }
  .orow:has(> .rmenu) > .orow-val { grid-column: 1 / -1; }
  .orow > .rmenu { grid-column: 2; grid-row: 1; }
}
/* Карточка ошибки в журнале: главная кнопка и «⋯» рядом, столбец действий по центру
   карточки. С `align-items: start` у самой карточки кнопка висела у верхнего края
   рядом с заголовком, и текст выглядел прижатым к верху (приёмка staging 2026-09-08). */
.er-card { align-items: center; }
.er-card > .er-main { align-self: center; }
.er-act { grid-template-columns: minmax(0, 1fr) auto; align-items: center; align-self: center; }
.er-act > .rmenu { justify-self: end; }
/* Блок занятия и материала: то же меню в правом верхнем углу */
.blk > .blk-acts { position: absolute; top: 12px; right: 12px; z-index: 2; }
.blk-acts .blk-more { position: static; top: auto; right: auto; }
.blk-acts .rmenu-list { z-index: 40; }

/* Всё, что появлялось по наведению, на узком экране и без мыши видно всегда.
   Подпись «Заменить фото» – исключение: она лежит поверх самого круга и, показанная
   постоянно, закрывает фото (приёмка staging 2026-09-08). Остаётся наведение и фокус
   с клавиатуры, а на тач-экране подписи нет вовсе: тап сразу открывает выбор файла. */
@media (max-width: 899px), (hover: none) {
  .blk-more, .rec-filled .rec-replace { opacity: 1; }
}

/* Фокус-рамка у тега-пилюли (Статус курса, Тип занятия) как у остальных значений */
.ed-tag .dd-btn:focus-visible, .ed-tag.open .dd-btn { outline: none; border-color: var(--cobalt); background: var(--white); box-shadow: 0 0 0 3px rgba(0,104,249,.16); }

/* Таймкод без записи – кнопка, доступная с клавиатуры */
button.tc-link { width: 100%; border: 0; background: transparent; font: inherit; color: var(--ink); cursor: text; }
button.tc-link:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--cobalt); }
.cal-day:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--cobalt); }

/* Модалка: фокус внутри, подложка вне порядка табуляции */
.confirm:focus { outline: none; }
.modal-backdrop .confirm .row { flex-wrap: wrap; }

/* Узкий экран: панель «Сохранить · Отменить» в ширину экрана, цели нажатия не меньше 40px */
@media (max-width: 580px) {
  .savebar-head { flex-wrap: wrap; }
  .savebar-head .hint { flex: 1 0 100%; margin: 0 0 4px; }
  .savebar-head .button, .savebar-head .button-secondary { flex: 1 1 auto; text-align: center; }
  .link-button, .tc-add, .vis-btn, .mat-bind-btn, summary, [data-more], .button-sm, .tab, .chip, .admin-side-link, a.back, .tg-back, .dd-btn, input.time { min-height: 40px; }
  .dd .dd-btn, .orow .dd .dd-btn, .ov-grid .orow .dd .dd-btn, .me-rows .orow .dd .dd-btn, .ed-plain .dd-btn, .ed-tag .dd-btn, .head-tags .dd .dd-btn, .head-tags .dd .date-btn, .head-tags input.time, tr.tr-edit .dd-sm .dd-btn, .inline-form .dd-btn { min-height: 40px; }
  .link-button, a.back, .admin-side-link, .tc-add, summary { display: inline-flex; align-items: center; }
  .acc-hist > summary, .prof-note > summary, .er-fold > summary, .lesson-nav-mobile summary { display: flex; }
  .rmenu-btn, .blk-more { width: 40px; height: 40px; }
  .info::before { content: ""; position: absolute; inset: -12px; }
  .page-head:has(.dd.open) h1 { opacity: 1; }
  input:not([type="checkbox"]):not([type="radio"]):not([type="file"]), textarea, .dd-btn, .ed-line, .tr-edit input { font-size: 16px; }
}

/* admin-paths: второстепенные поля строки-карточки на 375 одной строкой, подсказка обложки под полосой */
.admin-body .m-sub { display: none !important; }
@media (max-width: 580px) {
  .admin-body td.m-hide { display: none; }
  .admin-body .m-sub { display: block !important; color: var(--slate); font-weight: 400; font-size: 13px; margin-top: 2px; }
}
.card-title-link { color: inherit; text-decoration: none; }
.card-title-link:hover strong { color: var(--cobalt); }
.er-card[hidden], .admin-body tr[hidden] { display: none; }
/* admin-paths: открытый список или календарь в строке таблицы не режется рамкой таблицы; длинный список прокручивается */
.admin-body .table-wrap:not(.rmenu-scroll-open):has(.dd.open, .rmenu-list:not([hidden])) { overflow: visible; }
.dd-menu { max-height: 360px; overflow-y: auto; }

/* ── Профиль и карточка ученика (Task 16): фото в круге, модалка по data-confirm-open ── */
.avatar > img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
.av-photo { background: var(--ivory); }
.modal-backdrop { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 16px; background: rgba(17,19,26,.48); }
.modal-backdrop[hidden] { display: none; }
.modal-backdrop .confirm { inline-size: 100%; max-inline-size: 540px; max-block-size: calc(100vh - 32px); overflow: auto; }
.modal-backdrop .confirm form { display: contents; }
body.modal-open { overflow: hidden; }
.orow > .orow-acts { justify-self: end; align-self: center; }

/* Карточка ученика (Task 17): «Отозвать доступ» в «Опасной зоне» – кнопка-ссылка,
   прижатая к левому краю как ссылка макета; форма-пункт в меню «⋯» не ломает сетку */
.danger-row > button.danger-link { justify-self: start; text-align: left; font: inherit; font-weight: 500; }
.rmenu-list form { display: contents; }

/* ── Тост результата (Task 28): внизу справа, вместо зелёной плашки ?saved= ──
   Карточка в стиле .notice-ok (галочка, жирный заголовок, вторая строка текстом),
   под ней полоса времени на 3 секунды. Наведение и фокус останавливают отсчёт.
   На узком экране тост занимает ширину экрана с отступами. */
.toast-host { position: fixed; z-index: 60; inset-block-end: 20px; inset-inline-end: 20px; inline-size: min(420px, calc(100vw - 40px)); pointer-events: none; }
.toast { pointer-events: auto; display: grid; gap: 6px; padding: 14px 16px 0; border: 1px solid #c6ecd3; border-radius: 12px; background: #edf9f1; box-shadow: 0 1px 2px rgba(18,23,34,.04), 0 8px 20px rgba(18,23,34,.08), 0 24px 48px rgba(18,23,34,.06); animation: toast-in .18s ease-out both; }
.toast > .toast-row { display: flex; align-items: flex-start; gap: 12px; }
.toast > .toast-row > div { flex: 1; display: grid; gap: 4px; min-inline-size: 0; }
.toast strong { display: flex; align-items: center; gap: 8px; color: var(--forest); font-weight: 600; }
.toast strong::before { content: "✓"; width: 18px; height: 18px; border-radius: 50%; background: var(--forest); color: #fff; font-size: 11px; font-weight: 700; display: grid; place-items: center; flex: none; }
.toast .hint { color: var(--slate); font-size: 14px; line-height: 1.45; }
.toast .hint strong { display: inline; font-weight: 600; color: var(--ink); }
.toast .hint strong::before { content: none; }
.toast form { display: contents; }
.toast-undo { flex: none; align-self: center; }
.toast-bar { block-size: 3px; margin: 12px -16px 0; border-end-start-radius: 11px; border-end-end-radius: 11px; background: #c6ecd3; overflow: hidden; }
.toast-bar > i { display: block; block-size: 100%; inline-size: 100%; background: var(--forest); transform-origin: left center; animation: toast-bar var(--toast-ms, 3000ms) linear both; }
.toast:hover .toast-bar > i, .toast:focus-within .toast-bar > i { animation-play-state: paused; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes toast-bar { from { transform: scaleX(1); } to { transform: scaleX(0); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
@media (max-width: 480px) { .toast-host { inset-inline: 16px auto; inline-size: calc(100vw - 32px); inset-block-end: 16px; } }

/* Встроенный плеер записи занятия (правка 15.09.2026): запись смотрят на
   странице курса, а не на YouTube. Рамка держит пропорции 16:9 на любой
   ширине, поэтому на телефоне плеер не ломает раскладку. */
.player-frame{position:relative;width:100%;aspect-ratio:16/9;border-radius:var(--aicjm-radius-lg,16px);overflow:hidden;background:#000}
.player-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}

/* Блок записи в админке занятия (R2). Стили жили только в макетах, из-за чего
   на странице подпись слипалась со значением («СтатусОпубликована»), а кнопки
   шли лестницей. Раскладка — подпись слева, значение справа; на узком экране
   значение переносится под подпись. */
.recb{display:grid;gap:var(--aicjm-space-12,12px)}
.recb-row{display:flex;flex-wrap:wrap;gap:4px 12px;align-items:baseline}
.recb-row>span:first-child{min-width:170px;color:var(--aicjm-text-secondary,#6b7280)}
.recb-acts{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.recb-acts form{margin:0}
.recb h4{margin:var(--aicjm-space-8,8px) 0 0}
.alts{list-style:none;padding:0;margin:0;display:grid;gap:8px}
.alt{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;padding:12px;
  border:1px solid var(--aicjm-border,#e5e7eb);border-radius:var(--aicjm-radius-md,12px)}
.alt-main{display:grid;gap:2px;min-width:0;flex:1 1 260px}
@media (max-width:520px){.recb-row>span:first-child{min-width:0;flex-basis:100%}}

/* Плеер внутри блока записи админки занимает всю плитку. */
.rec-filled{aspect-ratio:auto;display:block}
.rec-filled .player-frame{width:100%}
.rec-filled .rec-replace{position:absolute;top:12px;right:12px;z-index:2}

/* Вложение в блоке: презентация, документ, таблица (подблок `file`). Ссылка
   выглядит строкой с иконкой формата, именем и подписью «PPTX · 2,4 МБ». */
.sub-file { margin: 12px 0; grid-template-columns: minmax(0, 1fr) 44px; }
.file-link {
  display: flex; align-items: center; gap: 10px;
  grid-column: 1 / -1; grid-row: 1;
  padding: 12px 58px 12px 14px;
  border: 1px solid var(--hairline); border-radius: var(--r-badge);
  background: var(--white); color: var(--ink);
  font-weight: 500; text-decoration: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.file-link:hover { border-color: var(--cobalt); box-shadow: var(--shadow-subtle); }
.file-link .ic { flex: none; color: var(--steel); }
.file-link:hover .ic { color: var(--cobalt); }
.file-name { overflow-wrap: anywhere; }
.file-meta {
  margin-left: auto; padding-left: 12px;
  color: var(--slate); font-size: 14px; font-weight: 400; white-space: nowrap;
}
.file-empty {
  grid-column: 1 / -1; grid-row: 1;
  padding: 14px 58px 14px 14px;
  border: 1px dashed var(--faint); border-radius: var(--r-badge);
}
.file-hint { margin: 8px 0 0; color: var(--slate); font-size: 14px; }
.file-swap { grid-column: 1 / -1; margin-top: 8px; }
.file-input { font-size: 14px; max-width: 100%; }
/* У файлового подблока меню относится ко всей карточке, а не к её верхнему
   краю. Карточка (ссылка или пустое состояние) занимает полную ширину, а
   правый внутренний коридор оставляет подпись формата слева от кнопки. */
.blocks .sub-file:has(> .sub-acts) { padding-inline-end: 0; }
.blocks .sub-file > .sub-acts {
  position: relative; inset: auto;
  grid-column: 2; grid-row: 1; align-self: center; justify-self: end;
  inline-size: 44px; block-size: 44px; z-index: 3;
  display: grid; place-items: center;
  transform: none;
}
.blocks .sub-file > .sub-acts .sub-more {
  position: static; top: auto; right: auto;
}
/* Узкий экран: подпись формата уходит под имя, а не сжимает его до переносов
   по одной букве. Иконка остаётся на строке имени: сетка с двумя колонками
   держит её слева, а `flex-wrap` отрывал её на свою строку. */
@media (max-width: 520px) {
  .file-link {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    column-gap: 10px;
    row-gap: 2px;
  }
  .file-link .ic { margin-top: 4px; }
  .file-meta { grid-column: 2; margin-left: 0; padding-left: 0; }
}

/* Коммерческий каталог: те же карточки, строки и панель сохранения. */
.commerce .dl dd { min-width: 0; overflow-wrap: anywhere; }
.commerce .ed-long { max-width: 100%; overflow-wrap: anywhere; }
.commerce-selects { flex-wrap: wrap; }
.commerce-selects .dd { max-width: 100%; }
.commerce-filters { display: flex; align-items: flex-end; flex-wrap: wrap; }
.commerce-filters .field { flex: 1 1 180px; min-width: 0; }
.commerce-filters input, .commerce-filters select { width: 100%; min-width: 0; }
.commerce-offer-choices { margin-top: 12px; }
.commerce-offer-choices .chip { white-space: normal; }
.commerce-error { color: var(--danger, #a52727); font-size: 14px; margin: 8px 0 0; }
.commerce code { overflow-wrap: anywhere; }
/* Мобильная навигация и фильтры: desktop сохраняет полную форму, без JS всё доступно. */
.admin-nav-toggle, .mobile-filter-toggle { display: none; }
.mobile-search-row, [data-filter-options] { display: contents; }
@media (max-width: 899px) {
  .admin-layout { grid-template-rows: auto minmax(0, 1fr); }
  .admin-side { gap: 8px; }
  .admin-side.mobile-nav-ready .admin-nav-toggle { display: inline-flex; margin-inline-start: auto; min-height: 44px; }
  .admin-side.mobile-nav-ready:not(.mobile-nav-open) :is(.admin-nav, .admin-side-foot) { display: none; }
  .admin-side .admin-nav { overflow: visible; }
  .admin-side .admin-nav ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; }
  .admin-side .admin-nav a { min-height: 44px; white-space: normal; }
  .admin-side .admin-side-foot { flex-basis: 100%; order: 2; display: grid; grid-template-columns: 1fr; padding-top: 8px; border-top: 1px solid var(--hairline); }
  .admin-side .admin-side-foot a { display: flex; align-items: center; min-height: 44px; }
}
@media (max-width: 580px) {
  .admin-body .admin-main { padding-block-start: 0; }
  .admin-body .admin-main > .admin-shell { gap: 12px; padding-block-start: 12px; }
  .admin-body .page-head-split { gap: 12px; }
  .admin-body .page-head .head-main { gap: 4px; }
  .admin-body .tab-panel { gap: 16px; }
  .admin-body :is(.button, .button-secondary, .dd-btn, select, .tab, .chip, .rmenu-btn) { min-height: 44px; }
  .admin-body :is(input:not([type=hidden]), select, textarea, .dd-btn) { font-size: 16px; }
  .admin-body .tabs { flex-wrap: nowrap; overflow-x: auto; }
  .admin-body .tab { white-space: normal; text-align: center; flex: 1 0 auto; }
  .admin-body form[data-mobile-filters], .admin-body form.card[data-mobile-filters] { display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 10px 12px; }
  .admin-body form.filters[data-mobile-filters] { padding: 0; }
  [data-mobile-filters] > .filters { display: contents; }
  [data-mobile-filters] .mobile-search-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 8px; }
  [data-mobile-filters] .mobile-search-row :is(input, .field) { width: 100%; min-width: 0; margin: 0; }
  [data-mobile-filters] .mobile-search-row button { padding-inline: 14px; }
  [data-mobile-filters] .mobile-search-row .field > label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  [data-mobile-filters] [data-filter-options] { order: 2; display: flex; flex-wrap: wrap; align-items: end; gap: 8px; }
  [data-mobile-filters] [data-filter-options] > :is(.dd, .field) { flex: 1 1 160px; min-width: 0; }
  [data-mobile-filters] [data-filter-options] :is(select, .dd-btn) { width: 100%; }
  [data-mobile-filters] [data-filter-options] .choices { display: grid; width: 100%; grid-template-columns: 1fr; gap: 4px; }
  [data-mobile-filters] [data-filter-options] .chip { justify-content: start; white-space: normal; }
  [data-mobile-filters][data-mobile-enhanced]:not([data-filter-open]) [data-filter-options] { display: none; }
  .mobile-filter-toggle { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 44px; padding: 6px 4px; border: 0; background: transparent; color: var(--cobalt-deep); font: inherit; font-size: 14px; text-align: left; cursor: pointer; order: 1; }
  .mobile-filter-toggle::after { content: "+"; margin-inline-start: auto; font-size: 22px; }
  .mobile-filter-toggle[aria-expanded=true]::after { content: "−"; }
  .mobile-filter-summary { color: var(--slate); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1; }
}
/* Мобильные строки админки: смысловые группы вместо пяти пар подпись/значение. */
.admin-mobile-only { display: none; }
@media (max-width: 580px) {
  .admin-mobile-only { display: block; }
  .student-desktop-meta, .material-desktop-summary, .journal-desktop-detail,
  .course-open-label { display: none !important; }
  .student-list-entry .cell-person { align-items: flex-start; }
  .student-list-entry .avatar { margin-top: 8px; }
  .student-name-link, .material-name-link { display: flex; align-items: center; min-height: 44px; }
  .student-mobile-meta { display: grid; gap: 3px; font-size: 14px; font-weight: 400; line-height: 1.4; }
  .student-mobile-nick, .student-mobile-last { color: var(--slate); }
  .student-mobile-status { font-size: 13px; color: var(--slate); }
  .student-mobile-meta p, .material-mobile-summary p, .journal-mobile-detail p { margin: 4px 0 8px; overflow-wrap: anywhere; }
  .student-mobile-meta summary, .material-mobile-summary summary,
  .journal-mobile-detail summary { display: list-item; min-height: 44px; padding-block: 10px; cursor: pointer; color: var(--cobalt); }
  .admin-body .material-list-entry td.material-location { display: block; font-size: 13px; padding-block: 2px; color: var(--slate); }
  .admin-body .material-list-entry td.material-location::before { display: none; }
  .admin-body .material-list-entry td.material-updated { display: block; font-size: 12px; color: var(--slate); padding-block: 2px; }
  .admin-body .material-list-entry td.material-updated::before { display: inline; content: "Обновлён: "; font-size: inherit; }
  .material-list-entry .rmenu-btn, .material-list-entry .rmenu-list > [role="menuitem"] { min-height: 44px; min-width: 44px; }
  .admin-body tr.journal-list-entry { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "action time" "object object" "change change" "who who"; gap: 3px 8px; padding: 12px; }
  .admin-body .journal-list-entry td { display: block; padding: 0; min-width: 0; }
  .admin-body .journal-list-entry td::before { display: none; }
  .journal-action { grid-area: action; }
  .journal-action .tag { white-space: normal; }
  .journal-time { grid-area: time; color: var(--slate); font-size: 12px !important; }
  .journal-object { grid-area: object; }
  .journal-object a { display: flex; align-items: center; min-height: 44px; }
  .journal-change { grid-area: change; }
  .journal-who { grid-area: who; color: var(--slate); font-size: 12px !important; }
  .admin-body .journal-list-entry .journal-who::before { display: inline; content: "Кто: "; font-size: inherit; }
  .journal-mobile-detail { font-size: 14px; line-height: 1.4; }
  .journal-mobile-detail summary { color: inherit; padding-block: 2px; }
  .journal-expand-label { display: block; color: var(--cobalt); font-size: 13px; margin-top: 2px; }
  .course-list-card { gap: 8px; }
  .course-list-card .row { gap: 6px; }
  .course-list-card strong { min-width: 0; overflow-wrap: anywhere; }
}
@media (max-width: 580px) {
  .material-mobile-summary { font-size: 14px; }
}
@media (max-width: 580px) {
  /* Длинный список выбора в пределах окна, включая повторное открытие. */
  .dd .dd-menu, .dd .dd-menu.dd-menu-up, .dd .dd-menu.dd-menu-end {
    position: fixed; inset: auto 12px calc(12px + env(safe-area-inset-bottom, 0px));
    width: auto; min-width: 0; max-width: none;
    max-height: min(50vh, 360px); max-height: min(50dvh, 360px);
    overscroll-behavior: contain;
  }
  .dd .dd-menu li[role=option] { min-height: 44px; display: flex; align-items: center; }
}

/* Обучение: один список, три дорожки расписания и обычные формы событий. */
.learning-toolbar { display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap; }
.learning-kinds, .learning-views, .schedule-year-nav { display:flex; gap:6px; flex-wrap:wrap; }
.learning-kinds a, .learning-views a { display:inline-flex; align-items:center; min-height:40px; padding:0 14px; border-radius:12px; color:var(--slate); font-weight:500; text-decoration:none; transition:background .15s ease; }
.learning-kinds a:hover, .learning-views a:hover { background:var(--canvas); text-decoration:none; }
.learning-kinds a[aria-current], .learning-views a[aria-current] { background:#e8f1ff; color:var(--cobalt-deep); box-shadow:inset 0 0 0 1px #cddffd; }
.learning-filters { display:flex; flex-wrap:wrap; align-items:end; gap:12px; }
.learning-filters label { display:grid; gap:6px; font-size:13px; color:var(--slate); max-width:100%; }
.learning-filters select, .event-editor select { max-width:100%; }
.learning-filters input[type=number] { width:100px; }
/* Скрытая подпись заголовка действий остаётся внутри прокрутки таблицы. */
.learning-table .table-wrap { position:relative; }
.learning-table td:first-child { min-width:180px; }
.learning-choices { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
.learning-choice { display:grid; gap:16px; padding:26px; border:1px solid var(--hairline); border-radius:var(--r-card); background:#fff; color:var(--ink); text-decoration:none; }
.learning-choice strong { font-size:21px; display:flex; justify-content:space-between; gap:16px; }
.learning-choice > span { color:var(--slate); font-size:14px; line-height:1.6; }
.learning-choice:hover { border-color:#82afe9; background:#f8fbff; }
.learning-checkbox { display:flex; align-items:center; gap:10px; font-weight:500; }
.learning-checkbox input { width:18px; height:18px; min-height:18px; flex-shrink:0; }
.event-editor { display:grid; grid-template-columns:minmax(0,1.3fr) minmax(240px,.7fr); gap:24px; align-items:start; }
.event-fields, .event-preview { padding:26px; min-width:0; }
.event-preview { position:sticky; top:24px; }
.event-preview-inner { padding:20px; border:1px solid var(--hairline); border-radius:12px; background:var(--canvas); overflow-wrap:anywhere; }
.event-preview-inner .tag { justify-self:start; }
.event-fields input, .event-fields select, .event-fields textarea { width:100%; min-width:0; }
.event-fields .field-error { color:var(--rust); font-size:13px; }
.event-fields [aria-invalid=true] { border-color:var(--rust); }
.rmenu-list > a { display:flex; align-items:center; gap:8px; width:100%; padding:10px 12px; color:inherit; text-decoration:none; white-space:nowrap; font-size:13px; }
.rmenu-list > a:hover, .rmenu-list > a:focus-visible { background:#f0f5fd; }
.schedule-scroll { overflow:auto; border:1px solid var(--hairline); border-radius:12px; background:#fff; }
.schedule-map { min-width:960px; }
.schedule-months, .schedule-lane { display:grid; grid-template-columns:112px minmax(0,1fr); }
.schedule-months { height:42px; border-bottom:1px solid var(--hairline); }
.schedule-months > div { position:relative; }
.schedule-months > div > span { position:absolute; text-align:center; padding-top:12px; font-size:11px; color:var(--slate); }
.schedule-lane { border-bottom:1px solid var(--hairline); }
.schedule-lane:last-child { border-bottom:0; }
.schedule-lane h3 { display:flex; align-items:center; padding:16px; margin:0; font-size:12px; font-weight:500; color:var(--slate); }
.schedule-track { position:relative; min-width:0; }
/* Поле после последнего месяца: подписи встреч у правого края выходят в него. */
.schedule-map { --map-gutter:160px; }
.schedule-track-inner { position:absolute; inset:0 var(--map-gutter) 0 0; }
.schedule-months > div { margin-right:var(--map-gutter); }
.schedule-track-height { display:block; }
.schedule-gridline { position:absolute; top:0; bottom:0; border-left:1px solid #f0f1f4; }
.schedule-entry { position:absolute; z-index:1; display:block; border-radius:7px; padding:8px 10px; min-height:34px; font-size:11px; font-weight:500; color:#fff; text-decoration:none; white-space:nowrap; max-width:260px; }
.schedule-entry span:first-child { display:block; overflow:hidden; text-overflow:ellipsis; }
.schedule-entry-program { background:#0863df; max-width:none; }
.schedule-entry-webinar { background:#6843cb; }
.schedule-entry-meeting { background:#d8eeea; color:#15554c; }
.schedule-entry.is-past { background:#e9eaec; color:#626773; }
.schedule-entry.is-cancelled { text-decoration:line-through; background:#f7e5e7; color:#912c3b; }
.schedule-today { position:absolute; top:0; bottom:0; border-left:2px solid #d64145; pointer-events:none; z-index:2; }
.schedule-fallback { border:1px solid var(--hairline); border-radius:12px; padding:16px 20px; background:#fff; }
.schedule-list article { display:flex; gap:18px; justify-content:space-between; align-items:center; padding:18px 0; border-bottom:1px solid var(--hairline); }
.schedule-list article:last-child { border-bottom:0; }
.schedule-list article > div { min-width:0; overflow-wrap:anywhere; }
@media(max-width:1100px) { .event-editor { grid-template-columns:1fr; } .event-preview { position:static; } }
@media(max-width:580px) { .learning-choices { grid-template-columns:1fr; } .learning-filters label { flex:1 1 130px; } .learning-filters select { width:100%; } .event-fields, .event-preview { padding:18px; } .schedule-list article { align-items:start; } .learning-kinds a { padding:0 10px; } }
.event-fields { border:0; margin:0; }
.event-fields:disabled { opacity:.75; }
body .savebar-head :is(.button, .button-secondary) { white-space:normal; overflow-wrap:anywhere; height:auto; min-height:44px; }

/* Кабинет ученика: общая оболочка, один бренд и доступная навигация без JS. */
.student-layout { display:grid; grid-template-columns:220px minmax(0,1fr); min-height:100dvh; }
.student-main { min-width:0; display:flex; flex-direction:column; }
.student-main > main { flex:1; padding-block:32px; min-width:0; }
/* Те же токены, что у .admin-side: 20px 14px, бренд 10px, пункт 40px · 15px/500 · 12px,
   активный #e8f1ff с кольцом, подвал 14px. Различается только набор пунктов. */
.student-side { position:sticky; top:0; height:100dvh; overflow:auto; display:flex; flex-direction:column; gap:20px; padding:20px 14px; border-right:1px solid var(--hairline); background:var(--white); }
.student-side .brand { padding:0 10px; }
.student-nav, .student-programs { display:grid; gap:2px; min-width:0; }
.student-nav a, .student-programs a { display:flex; align-items:center; min-height:40px; padding:8px 14px; border-radius:12px; color:var(--ink); font-size:15px; font-weight:500; overflow-wrap:anywhere; transition:background .15s ease; }
.student-nav a:hover, .student-programs a:hover, .student-side-foot a:hover { background:var(--canvas); text-decoration:none; }
.student-nav a[aria-current], .student-programs a[aria-current], .student-side-foot a[aria-current] { background:#e8f1ff; color:var(--cobalt-deep); box-shadow:inset 0 0 0 1px #cddffd; }
.student-programs { gap:4px; }
.student-programs .eyebrow { padding:0 14px 4px; font-size:12px; }
.student-programs a { font-size:14px; font-weight:500; color:var(--slate); }
.student-side-foot { margin-top:auto; display:grid; gap:2px; padding:12px 0 0; border-top:1px solid var(--hairline); font-size:14px; }
.student-side-foot a { display:flex; align-items:center; gap:10px; min-height:40px; padding:6px 14px; border-radius:12px; color:var(--cobalt); overflow-wrap:anywhere; transition:background .15s ease; }
.student-side-foot a span { min-width:0; }
.student-mobile-head, .student-menu-close { display:none; }
.student-body .savebar-head { --savebar-side:220px; }
.student-home { max-width:1200px; }
.student-home > .page-head { padding-block:0; }
.student-home .schedule-section { order:1; }
.student-home .next-meeting { order:2; }
.student-home > :not(.page-head):not(.schedule-section):not(.next-meeting) { order:3; }
.event-details { overflow-wrap:anywhere; }
.event-details h1 { font-size:28px; }
.event-description { white-space:pre-wrap; }
.event-dialog { position:relative; max-height:calc(100dvh - 32px); overflow:auto; width:min(600px,100%); }
.event-dialog-close { margin:0 0 20px auto; display:flex; }
@media(min-width:900px) and (max-width:1199px) {
  .student-main .lesson-layout { grid-template-columns:minmax(0,1fr); }
  .student-main .lesson-nav ul.lesson-nav-list { display:none; }
  .student-main .lesson-nav { position:static; }
  .student-main .lesson-body { grid-column:1; }
  .student-main .lesson-nav-mobile { display:block; }
}
@media(max-width:899px) {
  .student-layout { grid-template-columns:minmax(0,1fr); }
  .student-side { position:static; height:auto; border-right:0; border-bottom:1px solid var(--hairline); }
  .student-nav-ready .student-mobile-head { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:12px 16px; border-bottom:1px solid var(--hairline); background:#fff; }
  .student-nav-ready .student-menu-close { display:block; }
  .student-drawer.modal-backdrop { padding:0; align-items:stretch; justify-content:flex-start; }
  .student-drawer.modal-backdrop .student-side { position:relative; width:min(280px,100vw); height:100dvh; padding:22px 16px; border:0; }
  .student-nav a, .student-programs a, .student-side-foot a { min-height:44px; }
  .student-body .savebar-head { --savebar-side:0px; }
  .student-main > main { padding-block:24px; }
}
@media(max-width:580px) {
  .student-home .next-meeting { order:0; }
  .student-main .site-footer .shell { overflow-wrap:anywhere; }
}

/* Компактная карта: 28+56+68+52 px, границы 5 px. Коллизии добавляют ряды. */
.schedule-section { min-width:0; }
.schedule-scroll { display:none; max-width:100%; overflow:auto; }
.schedule-map { min-width:820px; }
.schedule-months { height:28px; border-bottom:0; }
.schedule-months > div > span { padding-top:5px; font-size:11px; }
.schedule-lane, .schedule-lane:last-child { border-top:1px solid var(--hairline); border-bottom:0; }
.schedule-lane h3 { padding:10px 14px; font-size:11px; }
.schedule-track { min-height:52px; }
.schedule-entry { height:24px; min-height:24px; padding:5px 9px; line-height:14px; max-width:260px; font-size:11px; }
.schedule-entry-program { height:34px; min-height:34px; padding:10px 0; max-width:none; }
.schedule-entry-label { display:block; overflow:hidden; text-overflow:ellipsis; }
.schedule-entry-program .schedule-entry-label { margin-inline:6px; }
.schedule-entry:not(.schedule-entry-program)::before { content:""; position:absolute; width:5px; height:5px; border-radius:50%; background:currentColor; left:var(--anchor-offset,0px); top:-1px; transform:translateX(-50%); }
/* Плашка при наведении и фокусе вместо нативного title: над подписью, у правой
   половины карты прижата к правому краю, чтобы не расширять прокрутку. */
.schedule-entry .schedule-full-title { display:none; position:absolute; left:0; bottom:calc(100% + 8px); z-index:6; width:max-content; max-width:320px; padding:8px 12px; border:1px solid var(--hairline); border-radius:10px; background:#fff; color:var(--ink); font-size:12px; font-weight:400; line-height:1.45; white-space:normal; text-align:left; box-shadow:0 8px 24px rgba(23,35,56,.14); pointer-events:none; }
.schedule-entry .schedule-full-title > b { display:block; font-weight:600; }
.schedule-entry .schedule-full-title > span { display:block; color:var(--slate); }
.schedule-entry:is(:hover,:focus) .schedule-full-title { display:block; }
.schedule-entry[data-tip-align="end"] .schedule-full-title { left:auto; right:0; }
.schedule-entry-program .schedule-full-title { bottom:auto; top:calc(100% + 8px); }
.schedule-entry:is(:focus,:hover) { z-index:4; }
.schedule-entry:focus { outline:2px solid #172338; outline-offset:2px; }
.schedule-section[data-ready="1"][data-schedule-view="list"] .schedule-legend { display:none; }
.schedule-section[data-ready="1"] .schedule-list { max-height:520px; overflow:auto; position:relative; }
.schedule-list article { padding-block:12px; }
.schedule-list .tag { flex-shrink:0; }
.schedule-section h2 { font-size:18px; }

@media(min-width:1200px) {
  .student-main .lesson-layout { grid-template-columns:220px minmax(0,1fr); gap:24px; }
  .student-main .lesson-nav { top:24px; }
}
/* Служебные подписи доступны скринридеру и не меняют геометрию чипов. */
.sr-only { position:absolute!important; width:1px!important; height:1px!important; padding:0!important; margin:-1px!important; overflow:hidden!important; clip:rect(0,0,0,0)!important; white-space:nowrap!important; border:0!important; }
.schedule-entry:not(.schedule-entry-program) { max-width:200px; }

.schedule-focus-detail { overflow-wrap:anywhere; padding:8px 12px; border-left:2px solid var(--cobalt); background:#eaf2ff; }
