@import url("fonts.css");

@layer oris {
  /* Оформление кабинета ӨRIS.
     Палитра, гарнитуры и радиус — те же, что на сайте: кабинет и сайт читаются
     как одно целое. Роли двух цветов те же, что на странице: бирюза — действие
     и принято, охра — число, за которым следят, и работа, вернувшаяся
     на доработку. */


  /* Кабинет пользуется теми же токенами, что и сайт: имена внутри файла
     короткие, значения приходят из палитры (src.css → landing.css).
     Второй палитры у платформы нет — именно из-за неё сайт и кабинет
     читались как два разных продукта. */
  :root{
    --bg:var(--color-canvas);
    --surface:var(--color-surface);
    --surface-2:var(--color-surface-2);
    --track:var(--color-line);
    --line:var(--color-line);
    --text:var(--color-ink);
    --muted:var(--color-dim);
    --accent:var(--color-brand);          /* действие, ссылка, принято */
    --accent-hover:color-mix(in oklab, var(--color-brand) 86%, var(--color-ink));
    --accent-2:var(--color-brand);
    --warn:var(--color-signal);           /* число под наблюдением и возврат на доработку */
    --dark:var(--color-dark);
    --on-dark:var(--color-on-dark);
    --muted-on-dark:var(--color-muted-on-dark);
    --accent-on-dark:var(--color-accent-on-dark);
    --error:var(--color-danger);
    --r:var(--radius);                    /* 22 — карточка */
    --rf:var(--radius-field);             /* 14 — поле ввода и кнопка формы */
    --r-sm:var(--radius-sm);              /* 12 — мелочь внутри карточки */
    --r-pill:var(--radius-pill);
    --field:var(--color-field);           /* рамка поля: темнее линии карточки */
    --field-bg:var(--color-field-bg);      /* заливка поля: светлее карточки */
    --line-soft:var(--color-line-soft);   /* линия внутри карточки */
    --mint:var(--color-mint);
    --sand:var(--color-sand);
    --curve:var(--ease-oris);
  }

  *{box-sizing:border-box}
  html{-webkit-text-size-adjust:100%}
  body{
    margin:0;background:var(--bg);color:var(--text);
    font-family:var(--font-body),system-ui,sans-serif;line-height:1.55;  /* кегль задан в @layer base лендинга */
    -webkit-font-smoothing:antialiased;
  }
  h1,h2,h3,h4{font-family:var(--font-display),sans-serif;font-weight:800;letter-spacing:-.025em;margin:0}
  h1{font-size:clamp(30px,3.4vw,42px);line-height:1.08}
  h2{font-size:26px;line-height:1.2;margin-top:0}
  h3{font-size:19px;font-weight:700;letter-spacing:-.01em}
  p{margin:0 0 14px}
  a{color:var(--accent)}
  a:focus-visible,button:focus-visible,input:focus-visible,textarea:focus-visible{
    outline:2px solid var(--accent-2);outline-offset:2px}

  /* Ширина полосы одна на всю платформу, как у шапки и подвала. */
  .wrap{max-width:88rem;margin:0 auto;padding:0 20px}
  @media (min-width:1280px){.wrap{padding:0 32px}}
  .muted{color:var(--muted)}

  /* Отступы кабинета живут на его контейнере, не на main: иначе между
   последней секцией сайта и тёмным подвалом появлялась светлая полоса. */
  .page-head{margin-bottom:28px}
  .page-head .crumb{font-size:14px;color:var(--muted);margin:0}
  /* 44 пикселя зоны нажатия и здесь: хлебные крошки — единственный путь назад
     на странице урока и задания, а на телефоне 17 пикселей не берутся. */
  .page-head .crumb a{display:inline-flex;align-items:center;min-height:44px}
  .lede{color:var(--muted);max-width:62ch;margin:14px 0 0}  /* размер — в platform.css */

  /* ——— карточки и сетки ——— */
  .card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
    box-shadow:var(--shadow-card);
    padding:24px;margin:0 0 18px;
    transition:border-color var(--dur-base) var(--curve)}
  /* Карточка с формой уже основной: строка ввода длиной во весь экран
     читается хуже. Ширина живёт здесь, а не пятью инлайновыми style. */
  .card-form{max-width:38rem}

  /* Карточка с обложкой во всю ширину: поля карточки сняты, их держит тело
     карточки. Иначе фотография вставала в рамку из 24 пикселей фона, а в
     макете она доходит до краёв и скругляется вместе с карточкой. */
  .card.flush{padding:0}
  /* Имя .grid принадлежит утилите Tailwind (display:grid). Своё имя —
     чтобы кабинет и сайт не переопределяли друг друга молча. */
  .split{display:grid;gap:28px;grid-template-columns:1fr 320px;align-items:start}
  @media (max-width:860px){.split{grid-template-columns:1fr}}

  /* ——— набор строк образования (анкета) ——— */
  /* Каждое образование — отдельная рамка: без неё поля четырёх записей
     сливаются в один длинный столбец, и человек не видит, где кончается
     колледж и начинается бакалавриат. */
  .edu-set{display:grid;gap:14px;margin:14px 0 6px}
  .edu-row{border:1px solid var(--line);border-radius:var(--rf);
    padding:14px 16px 4px;margin:0}
  .edu-row legend{font-size:13px;padding:0 6px}
  .edu-row p{margin:0 0 12px}

  /* ——— анкета по шагам ———
     Шесть обязательных строк и вчетверо больше необязательных не помещаются
     в один столбец так, чтобы человек видел, где кончается необходимое.
     Поэтому полоса шагов сверху, разделы под ней, и переход между ними
     появляется только со скриптом: без скрипта это та же сплошная форма. */
  .anketa-progress{margin:0 0 22px}
  .anketa-count{margin:0 0 12px;font-size:15px;color:var(--muted)}
  .anketa-rail{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;
    list-style:none;margin:0;padding:0}
  @media (max-width:640px){.anketa-rail{grid-template-columns:repeat(2,1fr)}}
  /* Полоска над подписью — то же, что и в полосе оценки: заполненный шаг
     закрашен, текущий выделен цветом действия, остальные — линия. */
  .anketa-bar{display:block;height:4px;border-radius:999px;background:var(--track)}
  .anketa-rail-item.is-done .anketa-bar{background:color-mix(in oklab, var(--accent-2) 45%, var(--track))}
  .anketa-rail-item.is-current .anketa-bar{background:var(--accent-2)}
  .anketa-link{display:flex;align-items:center;gap:9px;min-height:44px;
    font-size:15px;color:var(--muted);text-decoration:none}
  .anketa-rail-item.is-current .anketa-link{color:var(--text);font-weight:600}
  .anketa-link:hover{color:var(--text)}
  .anketa-link:focus-visible{outline:2px solid var(--accent-2);outline-offset:2px}
  .anketa-num{flex:0 0 auto;width:22px;height:22px;border-radius:50%;
    display:inline-flex;align-items:center;justify-content:center;
    font-size:12px;font-weight:700;background:var(--surface-2);color:var(--muted)}
  .anketa-rail-item.is-current .anketa-num{background:color-mix(in oklab, var(--accent-2) 16%, var(--surface));
    color:var(--accent-2)}
  .anketa-rail-item.is-done .anketa-num{background:var(--accent-2);color:var(--surface)}

  /* Разделы разделены линией только без скриптов: со скриптом на экране
     всегда один, и линия между невидимыми разделами лишняя. */
  .anketa-step + .anketa-step{margin-top:28px;padding-top:24px;border-top:1px solid var(--line)}
  .js-steps .anketa-step + .anketa-step{margin-top:0;padding-top:0;border-top:0}
  /* Полоса анкеты: карточка на всю ширину кабинета, поля по два в ряд.
     Высота шага задана снизу, чтобы карточка не подпрыгивала при переходе
     между шагами: на «Контактах» полей два, на «Опыте» — большое поле текста
     и набор навыков, и без нижней границы страница дёргалась под курсором. */
  .anketa-card{max-width:64rem;padding:30px 32px}
  .js-steps .anketa-card{min-height:24rem}
  .anketa-pair{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr))}
  .anketa-pair > p{margin:0}
  .anketa-step-title{margin:0 0 6px}
  .anketa-step-text{margin:0 0 18px}
  .anketa-step-nav{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
    margin-top:24px;padding-top:20px;border-top:1px solid var(--line)}
  .anketa-step-nav .quiet{font-size:15px}
  .anketa-step-nav .msg{width:100%;margin:0}

  /* ——— навыки отметками ———
     Навыки хранятся одной строкой через запятую; отметки — оформление над
     ней. Поле со строкой скрывает скрипт, и он же его заполняет.
     Имя .chip уже занято отбором в каталоге, поэтому здесь .skill: два
     разных вида отметки под одним именем перекрасили бы друг друга. */
  .skill-set{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 10px}
  .skill{display:inline-flex;align-items:center;gap:8px;
    background:color-mix(in oklab, var(--accent-2) 10%, var(--surface));
    color:var(--accent-2);border-radius:999px;padding:8px 14px;font-size:15px}
  .skill button{appearance:none;background:none;border:0;padding:0;
    font:inherit;font-size:17px;line-height:1;color:inherit;cursor:pointer}
  .skill button:focus-visible{outline:2px solid var(--accent-2);outline-offset:2px}

  /* ——— резюме файлом ———
     Поле выбора файла родного вида читается как чужая кнопка посреди формы.
     Рамка пунктиром — единственная зона на странице, куда файл можно и
     принести мышью, и выбрать нажатием. */
  .drop{position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;
    text-align:center;padding:34px 20px;cursor:pointer;
    background:var(--surface);border:1.5px dashed var(--line);border-radius:var(--r);
    transition:border-color var(--dur-base) var(--curve),
               background-color var(--dur-base) var(--curve)}
  .drop:hover,.drop.is-over{border-color:var(--accent-2);
    background:color-mix(in oklab, var(--accent-2) 5%, var(--surface))}
  .drop input[type=file]{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
  .drop-title{font-weight:600;color:var(--accent-2)}
  .drop-note{font-size:14px;color:var(--muted)}
  .drop:focus-within{outline:2px solid var(--accent-2);outline-offset:2px}
  /* Строка приложенного файла: имя, размер и «Убрать» в один ряд. Имя
     усекается, а не переносит строку — файлы называют как попало. */
  .file-row{display:flex;align-items:center;gap:14px;margin:0 0 14px;
    background:var(--surface-2);border:1px solid var(--line);
    border-radius:var(--rf);padding:14px 18px}
  .file-name{flex:1;min-width:0;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis}
  .file-row .num{flex:0 0 auto;font-size:14px}
  .file-drop{flex:0 0 auto;appearance:none;background:none;border:0;padding:0;
    font:inherit;font-size:15px;color:var(--error);cursor:pointer}
  .file-drop:focus-visible{outline:2px solid var(--accent-2);outline-offset:2px}

  /* Подпись только для чтения вслух: отметка «заполнено» на полосе шагов
     нарисована галочкой, и голосом её иначе не передать. */
  .sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
    overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}

  /* ——— кнопки ——— */
  /* Кнопка платформы описана в platform.css — одна на сайт и кабинет. */
  .btn.ghost:hover{background:var(--surface-2)}

  /* ——— состояния ——— */
  .pill{display:inline-block;font-size:13px;padding:5px 11px;border-radius:var(--r-pill);
    border:1px solid var(--line);background:var(--surface-2);
    color:var(--muted);white-space:nowrap;font-weight:600}
  .pill.wait{color:var(--muted)}
  .pill.back{color:var(--warn);background:var(--color-signal-tint);
    border-color:color-mix(in oklab, var(--warn) 30%, transparent)}
  .pill.ok{color:var(--accent-2);background:var(--color-brand-tint);
    border-color:color-mix(in oklab, var(--accent-2) 30%, transparent)}
  /* Закрытая строка: плашка без заливки — она не состояние работы, а отказ
     в доступе, и заливкой спорила бы с «пройден» и «не отмечен». */
  .pill.lock{color:var(--muted);background:transparent;border-color:var(--line)}

  /* ——— сообщения ——— */
  .msg{border:1px solid var(--line);border-left:3px solid var(--warn);
    background:var(--surface);border-radius:var(--rf);padding:12px 16px;margin:0 0 16px;font-size:15px}
  .msg.error{border-left-color:var(--error)}
  .msg.success{border-left-color:var(--accent-2)}

  /* ——— таблицы ——— */
  table{border-collapse:collapse;width:100%;font-size:15px}
  th{text-align:left;font-family:var(--font-display),sans-serif;font-weight:500;font-size:14px;
    color:var(--muted);padding:0 12px 10px 0;border-bottom:1px solid var(--line)}
  td{padding:12px 12px 12px 0;border-bottom:1px solid var(--line);vertical-align:top}
  td.num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--font-display),sans-serif;
    font-weight:800;font-size:19px;width:80px;color:var(--warn)}
  td.num.zero{color:var(--muted);font-weight:500}
  tr:last-child td{border-bottom:0}

  /* ——— формы ——— */
  label{display:block;font-size:14px;color:var(--muted);margin-bottom:4px}
  input[type=text],input[type=email],input[type=password],input[type=number],input[type=url],textarea,select{
    width:100%;max-width:38rem;font:inherit;font-size:15px;color:var(--text);
    background:var(--color-surface);border:1px solid var(--field);border-radius:var(--rf);
    min-height:52px;padding:13px 16px}
  textarea{min-height:9rem;resize:vertical}
  form p{margin:0 0 16px}
  .helptext,.field-help,form ul.errorlist{display:block;max-width:38rem;font-size:13px;
    color:var(--muted);margin:4px 0 0;padding:0;list-style:none}

  /* Обязательные поля помечены: без пометки человек узнаёт об обязательности
     из ошибки после отправки. */
  label.required::after{content:" *";color:var(--error)}

  /* Согласие — это фраза, под которой ставят отметку, а не подпись поля:
     квадратик и текст стоят в одну строку, и нажать можно по всей фразе. */
  .form-consent label{display:flex;align-items:flex-start;gap:10px;
    max-width:38rem;color:var(--text);font-size:15px;cursor:pointer}
  .form-consent input[type=checkbox]{flex:0 0 auto;width:18px;height:18px;margin:2px 0 0}
  /* Ссылки на документы, под которыми ставится отметка, должны быть видны
     ссылками: подпись под невидимой ссылкой — это подпись вслепую. */
  .form-consent a{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
  /* Звёздочка ставится за текстом фразы, а не за самой подписью: label
     здесь флексовый, и ::after на нём уезжает отдельным столбцом к правому
     краю карточки, где читается как посторонний знак на полях. */
  .form-consent span.required::after{content:" *";color:var(--error)}
  /* Пояснение — сноска к согласию, а не равная ему по весу строка. */
  .form-consent + .muted{font-size:13px;max-width:38rem;margin-top:-6px}
  /* Отключённый список города до выбора области: видно, что он ещё не работает. */
  select:disabled{color:var(--muted);background:var(--surface-2,var(--surface));cursor:not-allowed}

  /* ——— выбор файла ———
     Родная кнопка браузера не подчиняется теме и на каждой платформе своя.
     Оформляется сама кнопка внутри поля, чтобы вложение не выглядело
     системным окном посреди страницы платформы. Высота 44: файл на телефоне
     прикладывают пальцем. */
  input[type=file]{display:block;width:100%;max-width:38rem;font:inherit;font-size:15px;
    color:var(--text);background:var(--color-surface);border:1px solid var(--field);
    border-radius:var(--rf);padding:9px 12px}
  input[type=file]::file-selector-button{font:inherit;font-family:var(--font-display),sans-serif;
    font-weight:500;font-size:14px;min-height:32px;margin:0 14px 0 0;padding:0 14px;
    color:var(--text);background:var(--surface-2);border:1px solid var(--field);
    border-radius:var(--r-sm);cursor:pointer}
  input[type=file]::file-selector-button:hover{background:var(--track)}

  /* ——— отбор в каталоге ———
     Фишка направления — это переключатель, а не ссылка: сам кружок скрыт,
     нажимается вся подложка. Высота 44 обязательна, выбранная фишка
     показывается заливкой И рамкой, чтобы состояние читалось не одним цветом. */
  .chip{display:inline-flex;align-items:center;gap:8px;min-height:44px;
    padding:0 16px;border:1px solid var(--field);border-radius:var(--r-pill);
    background:var(--surface);color:var(--text);font-size:15px;cursor:pointer;
    margin:0;white-space:nowrap;
    transition:border-color 180ms var(--curve),background-color 180ms var(--curve)}
  .chip input{position:absolute;opacity:0;width:1px;height:1px;margin:0}
  .chip:hover{border-color:var(--accent)}
  .chip:has(input:checked){background:var(--accent);border-color:var(--accent);
    color:var(--surface);font-weight:500}
  .chip:has(input:focus-visible){outline:2px solid var(--accent-2);outline-offset:2px}
  .chip-n{font-size:13px;color:var(--muted)}
  .chip:has(input:checked) .chip-n{color:var(--surface)}

  /* ——— направление в отборе каталога ———
     Столбик строк «название — число», по макету. Кружок переключателя скрыт,
     нажимается вся строка; выбранная залита цветом действия. Число прижато
     к правому краю: по этой колонке видно, где наборов больше, а фишками
     вразброс такой колонки не получалось.

     Строка не таблетка, а прямоугольник с радиусом 12: таблетки в макете
     носят состояния, а это переключатель отбора. */
  .dir{display:flex;align-items:center;gap:10px;min-height:44px;width:100%;
    padding:0 14px;border:1px solid transparent;border-radius:var(--r-sm);
    background:var(--surface-2);color:var(--text);font-size:15px;cursor:pointer;
    margin:0;
    transition:border-color 180ms var(--curve),background-color 180ms var(--curve)}
  .dir input{position:absolute;opacity:0;width:1px;height:1px;margin:0}
  .dir-t{flex:1;min-width:0}
  .dir-n{flex:0 0 auto;font-size:13px;color:var(--muted)}
  .dir:hover{border-color:var(--field)}
  .dir:has(input:checked){background:var(--accent);border-color:var(--accent);
    color:var(--surface);font-weight:500}
  .dir:has(input:checked) .dir-n{color:var(--surface)}
  .dir:has(input:focus-visible){outline:2px solid var(--accent-2);outline-offset:2px}

  /* Поля выбора каталога: те же, что и в кабинете, но своим именем, чтобы
     утилиты публичной части их не перебивали. */
  .selector{min-height:52px;min-width:14rem;max-width:100%;padding:0 16px;
    font:inherit;font-size:15px;color:var(--text);background:var(--color-surface);
    border:1px solid var(--field);border-radius:var(--rf)}
  .selector:hover{border-color:var(--accent)}

  /* ——— карточка программы ——— */
  .course-cover{display:block;width:100%;height:auto;aspect-ratio:16/9;
    object-fit:cover;background:var(--surface-2)}
  .course-kind{margin:0 0 6px;font-family:var(--font-display),sans-serif;font-weight:500;
    font-size:13px;letter-spacing:.02em;color:var(--accent)}

  /* ——— проигрыватель урока ———
     Кадр 16:9 занимает карточку целиком, без полей: крупная плоскость по
     правилу системы идёт с нулевым радиусом, а скругление даёт сама карточка
     своим overflow. Высота считается пропорцией, а не подпоркой изнутри:
     тогда кадр не прыгает при загрузке и не даёт сдвига разметки. */
  .card-video{padding:0;overflow:hidden}
  .player{aspect-ratio:16/9;background:var(--text);line-height:0}
  .player iframe{display:block;width:100%;height:100%;border:0}
  .card-video-note{padding:16px 22px 8px}
  .card-video-note p{margin:0;font-size:14px}
  .video-link{display:inline-flex;align-items:center;min-height:44px;
    font-family:var(--font-display),sans-serif;font-weight:500;font-size:14px}

  /* ——— вложение в сдаче ——— */
  .attach{margin:14px 0 0;padding-top:14px;border-top:1px solid var(--line);font-size:15px}
  /* Работа, сданная одним файлом, без текста: линия отделяла бы вложение от
     пустоты. */
  .review .body > .attach:first-child{margin-top:0;padding-top:0;border-top:0}
  .attach a{display:inline-flex;align-items:center;min-height:44px;
    font-family:var(--font-display),sans-serif;font-weight:500}
  form ul.errorlist{color:var(--error)}

  /* ——— страница курса ———
     Колонка 1080 и сетка 1.6 / 0.8, как в макете. На всю ширину шкафа
     перечень уроков растягивался, и название урока отрывалось от плашки
     состояния на треть экрана. */
  .cp-page{max-width:1080px;margin:0 auto;display:flex;flex-direction:column;gap:24px}
  .cp-page > .crumb{margin:0;font-size:15px;font-weight:500;color:var(--accent)}
  .cp-page > .crumb a{min-height:0;color:inherit;text-decoration:none}
  .cp-head{display:flex;flex-direction:column;gap:10px}
  .cp-head h1{font-size:clamp(30px,3.4vw,42px);line-height:1.08;font-weight:700}
  .cp-meta{margin:0;font-size:16px;color:var(--muted)}
  .cp-grid{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(260px,0.8fr);
    gap:22px;align-items:start}
  @media (max-width:900px){.cp-grid{grid-template-columns:1fr}}
  .cp-card{margin:0}
  .cp-card + .cp-card{margin-top:16px}
  .cp-foot{margin:16px 0 0;padding-top:16px;border-top:1px solid var(--line-soft);
    font-size:14px}
  .cp-side{position:sticky;top:88px;display:flex;flex-direction:column;gap:14px}
  @media (max-width:900px){.cp-side{position:static}}

  /* Правый столбец: кольцо и под ним строки «подпись слева, число справа».
     Прежде это были три песочные плитки, и они читались как три отдельных
     показателя, а не как один ответ «где я стою». */
  .cp-stat{margin:0;padding:24px;display:flex;flex-direction:column;align-items:center}
  .cp-stat .ring{margin:4px auto 18px}
  .cp-rows{width:100%;margin:0;display:flex;flex-direction:column;gap:12px}
  .cp-rows > div{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
  .cp-rows dt{font-size:15px;color:var(--muted)}
  .cp-rows dd{margin:0;font-size:16px;font-weight:600}
  .cp-rows dd.warn{color:var(--warn)}
  .cp-score-bar{width:100%;margin:12px 0}
  .cp-score-bar i{background:var(--color-signal-bar)}
  .cp-note{width:100%;margin:14px 0 0;font-size:14px;line-height:1.55}
  .cp-book{align-self:flex-start;margin-top:12px;font-size:15px;font-weight:600}

  /* ——— страница урока ———
     Раскладка макета: липкая строка во всю ширину, слева содержимое урока,
     справа отметка и путь программы. */
  .lp-bar{position:sticky;top:0;z-index:5;background:var(--surface);
    border-bottom:1px solid var(--line)}
  .lp-bar-in{max-width:1180px;margin:0 auto;display:flex;align-items:center;
    gap:20px;flex-wrap:wrap;padding:14px 20px}
  @media (min-width:1280px){.lp-bar-in{padding-left:48px;padding-right:48px}}
  .lp-back{font-size:15px;font-weight:500;color:var(--accent);text-decoration:none}
  .lp-back:hover{color:var(--accent-hover)}
  .lp-bar-progress{flex:1;min-width:160px;display:flex;align-items:center;gap:12px}
  .lp-bar-progress .bar{flex:1;height:5px;margin:0}
  .lp-bar-progress .bar i{background:var(--color-brand-solid)}
  .lp-bar-progress .num{flex:0 0 auto;font-size:14px;font-weight:600;color:var(--accent)}
  .lp-bar-count{flex:0 0 auto;font-size:15px;color:var(--muted)}

  .lp-page{padding:32px 20px 96px}
  @media (min-width:1280px){.lp-page{padding-left:48px;padding-right:48px}}
  .lp-grid{max-width:1180px;margin:0 auto;display:grid;
    grid-template-columns:minmax(0,1fr) minmax(290px,0.42fr);gap:28px;align-items:start}
  @media (max-width:900px){.lp-grid{grid-template-columns:1fr}}
  .lp-main{display:flex;flex-direction:column;gap:24px;min-width:0}
  .lp-title{display:flex;flex-direction:column;gap:8px}
  .lp-title .eyebrow{margin:0;font-size:13px;font-weight:600;letter-spacing:.1em;
    text-transform:uppercase;color:var(--muted)}
  .lp-title h1{font-size:clamp(28px,3.2vw,38px);line-height:1.1;font-weight:700}

  /* Видео с подписью под кадром в одной рамке: подпись относится к ролику, а
     не к странице, и отдельной карточкой отрывалась от него. */
  .lp-video{border-radius:var(--r);overflow:hidden;background:var(--sand);
    border:1px solid var(--line)}
  .lp-video-note{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
    padding:14px 20px;font-size:15px}
  .lp-video-note a{margin-left:auto;font-weight:600;text-decoration:none}

  .lp-body{font-size:18px;line-height:1.65;color:var(--text)}
  .lp-body > :first-child{margin-top:0}
  .lp-body > :last-child{margin-bottom:0}

  .lp-block{display:flex;flex-direction:column;gap:10px}
  .lp-block h2{font-size:19px;font-weight:700;letter-spacing:-.02em}
  .lp-block > .quiet{margin:0;font-size:16px}

  /* Файл урока: значок, имя с размером под ним и действие справа. */
  .lp-file{display:flex;align-items:center;gap:14px;margin:0;
    background:var(--surface);border:1px solid var(--line);
    border-radius:16px;padding:14px 18px}
  .lp-file-ico{flex:0 0 auto;width:28px;height:34px;border:1.5px solid var(--field);
    border-radius:5px}
  .lp-file-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
  .lp-file-name{font-size:16px;font-weight:500;white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis}
  .lp-file .quiet{font-size:14px}
  .lp-file a{flex:0 0 auto;font-size:15px;font-weight:600;text-decoration:none}

  /* Работа урока: вся строка — ссылка. */
  .lp-work{display:flex;align-items:center;gap:14px;background:var(--surface);
    border:1px solid var(--line);border-radius:16px;padding:16px 18px;
    text-decoration:none;color:var(--text);
    transition:border-color var(--dur-base) var(--curve)}
  .lp-work:hover{border-color:var(--color-mint-line)}
  .lp-work-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
  .lp-work .t{font-size:17px;font-weight:600;color:var(--accent)}
  .lp-work .quiet{font-size:14px}
  .lp-work .pill{flex:0 0 auto}

  .lp-nav{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
    padding-top:22px;border-top:1px solid var(--line)}
  .lp-nav .quiet{font-size:15px}
  .lp-nav .btn[aria-disabled="true"]{background:color-mix(in oklab, var(--accent) 34%, var(--bg));
    cursor:default}

  .lp-side{position:sticky;top:96px;display:flex;flex-direction:column;gap:14px;min-width:0}
  @media (max-width:900px){.lp-side{position:static}}
  .lp-mark{margin:0;padding:22px 24px;display:flex;flex-direction:column;gap:12px}
  .lp-mark form{margin:0}
  .lp-mark .btn{width:100%}
  .lp-mark .quiet{font-size:15px;line-height:1.5}
  /* Отмеченный урок: та же кнопка, но мятная и без действия — состояние, а не
     предложение нажать ещё раз. */
  .lp-mark .mark-done{background:var(--mint);color:var(--accent);
    border:1px solid var(--color-mint-line);box-shadow:none;cursor:default}

  /* Путь программы в правом столбце. Текущий урок подсвечен мятным, отметка
     стоит кружком: тот же знак, что в содержании. */
  .lp-nav-list{margin:0;padding:8px 10px 12px}
  .lp-nav-list .eyebrow{margin:0;padding:14px 14px 10px;font-size:13px;font-weight:600;
    letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
  .lp-nav-list ol{list-style:none;margin:0;padding:0}
  .lp-nav-list a,.lp-nav-list li > span{display:flex;gap:12px;padding:12px 14px;
    border-radius:var(--rf);color:var(--text);text-decoration:none}
  .lp-nav-list a:hover{background:var(--surface-2)}
  .lp-nav-list li.on > a,.lp-nav-list li.on > span{background:var(--mint)}
  .lp-nav-list li.locked > span{color:var(--muted)}
  .lp-nav-list .dot{flex:0 0 auto;width:24px;height:24px;margin-top:1px;border-radius:50%;
    display:inline-flex;align-items:center;justify-content:center;
    font-family:var(--font-display),sans-serif;font-size:12px;font-weight:700;
    background:var(--track);color:var(--muted)}
  .lp-nav-list .dot.done{background:var(--color-brand-solid);color:var(--surface)}
  .lp-nav-list .dot.now{background:var(--color-signal-bar);color:var(--surface)}
  .lp-nav-list .t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
  .lp-nav-list .n{font-size:16px;font-weight:500;line-height:1.35}
  .lp-nav-list li.on .n{font-weight:600}
  .lp-nav-list .m{font-size:13px;color:var(--muted)}

  /* ——— «Мои данные» ———
     Одна карточка на колонке 940, поля сеткой по 230 — так в макете. */
  .data-page{max-width:940px;margin:0 auto}
  .data-card{margin:0;padding:28px 30px;display:flex;flex-direction:column;gap:22px}
  .data-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
    gap:18px;min-width:0}
  .data-grid .form-field{margin:0;min-width:0}
  .data-grid input{max-width:none}
  .data-lang{display:flex;flex-direction:column;gap:8px;min-width:0}
  .data-lang-t{font-size:14px;font-weight:500}
  .data-lang .site-lang{align-self:flex-start}
  .data-act{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
    padding-top:20px;border-top:1px solid var(--line-soft)}
  .data-link{font-size:15px;font-weight:600}
  .data-note{margin:14px 0 0;padding:0 4px;font-size:14px}

  /* Удаление раскрывается отдельно и красным: это единственное действие на
     платформе, которое человек не отменит сам. */
  .data-del{margin:22px 0 0;padding:18px 22px}
  .data-del > summary{font-family:var(--font-display),sans-serif;font-weight:600;
    font-size:16px;color:var(--error);cursor:pointer;min-height:44px;
    display:flex;align-items:center}
  .data-del form{margin:14px 0 0;display:flex;flex-direction:column;gap:14px;
    align-items:flex-start}
  .data-del .quiet{margin:0;max-width:66ch;font-size:15px;line-height:1.6}
  .data-confirm{display:flex;align-items:center;gap:10px;font-size:15px;
    min-height:44px;cursor:pointer}
  .data-confirm input{width:auto;min-height:0;margin:0}
  .btn.danger{background:var(--error)}
  .btn.danger:hover{background:color-mix(in oklab, var(--error) 86%, var(--color-ink))}

  /* ——— «Оплата и возврат», «Вопросы», «О компании» ———
     Три страницы из макета на одной колонке 1080 и с общими блоками: полосы
     разной заливки, карточки со сведениями и мятная плашка с границей
     услуги. Правила ширины и отступов держатся здесь, а не в каждом
     шаблоне: три страницы обязаны стоять на одной сетке. */
  .pay-in{max-width:1080px;margin:0 auto;padding:0 20px}
  @media (min-width:1280px){.pay-in{padding:0 48px}}
  .pay-head{padding:56px 0 0}
  .pay-head h1{margin:0 0 14px}
  .pay-facts{padding:34px 0 0}
  .pay-steps{padding:56px 0}
  .faq-page,.about-cards{padding:40px 0 56px}
  .about-limits{padding:0 0 56px}

  /* Число в карточке: подпись, значение, пояснение. */
  .fact{margin:0;padding:22px 24px;border-radius:20px;
    display:flex;flex-direction:column;gap:6px}
  .fact-v{font-family:var(--font-display),sans-serif;font-weight:700;font-size:27px;
    letter-spacing:-.03em;line-height:1.1}
  .fact-v.ok{color:var(--accent)}

  /* Шаг оплаты: номер под чертой, как в макете. */
  .pay-step{display:flex;flex-direction:column;gap:9px;padding-top:16px;
    border-top:2px solid var(--color-mint-line)}
  .pay-num{font-size:14px;font-weight:700;color:var(--accent)}
  .pay-step h3{margin:0;font-size:19px;font-weight:700;letter-spacing:-.02em}
  .pay-step p{margin:0;font-size:16px;line-height:1.55;color:var(--muted)}

  /* Полоса возврата: мятная, с карточками «когда — что». */
  .pay-back{padding:56px 0;background:var(--mint);color:var(--color-on-mint)}
  .pay-back .h2,.pay-back h3{color:var(--text)}
  .pay-back .quiet{color:var(--color-on-mint-dim)}
  .pay-refund{display:flex;gap:18px;align-items:flex-start;flex-wrap:wrap;
    background:var(--surface);border-radius:18px;padding:20px 22px}
  .pay-refund .when{flex:0 0 auto;min-width:96px;font-size:15px;font-weight:700;
    color:var(--accent)}
  .pay-refund .what{flex:1;min-width:180px;display:flex;flex-direction:column;gap:3px}
  .pay-refund .t{font-size:17px;font-weight:600}
  .pay-refund .d{font-size:16px;line-height:1.5;color:var(--muted)}
  .pay-how{margin:0;padding:26px 28px;display:flex;flex-direction:column;gap:14px}
  .pay-how h3{margin:0;font-size:19px;font-weight:700;letter-spacing:-.02em}
  .pay-how-row{display:flex;gap:12px;align-items:flex-start;margin:0;
    font-size:16px;line-height:1.5}
  .pay-how-row .n{flex:0 0 auto;width:22px;height:22px;border-radius:50%;
    background:var(--mint);color:var(--accent);font-size:12px;font-weight:700;
    display:inline-flex;align-items:center;justify-content:center}
  .pay-mail{align-self:flex-start;font-size:16px;font-weight:600}

  /* Перечень вопросов: строки в одной карточке, знак «плюс» справа. */
  .qa{margin:0;padding:8px 26px 20px}
  .qa > details{border-top:1px solid var(--line-soft)}
  .qa > details > summary{display:flex;align-items:center;gap:16px;
    padding:20px 0;font-size:18px;font-weight:600;line-height:1.4;cursor:pointer;
    list-style:none}
  .qa > details > summary::-webkit-details-marker{display:none}
  .qa > details > summary::after{content:"+";margin-left:auto;flex:0 0 auto;
    font-size:20px;font-weight:400;color:var(--field)}
  .qa > details[open] > summary::after{content:"−"}
  .qa > details > p{margin:0;padding:0 0 22px;max-width:620px;font-size:17px;
    line-height:1.65;color:var(--muted)}

  .faq-price{margin:0;padding:24px 26px;display:flex;flex-direction:column;gap:14px}
  .faq-price h2{font-size:19px;font-weight:700;letter-spacing:-.02em}
  .faq-price dl{display:flex;flex-direction:column;gap:12px}
  .faq-price dl > div{display:flex;justify-content:space-between;gap:14px;
    padding-top:12px;border-top:1px solid var(--line-soft)}
  .faq-price dt{font-size:15px;color:var(--muted)}
  .faq-price dd{margin:0;font-size:15px;font-weight:600;text-align:right}

  .faq-gains{padding:24px 26px;display:flex;flex-direction:column;gap:12px}
  .faq-gains h2{font-size:19px;font-weight:700;letter-spacing:-.02em}
  .faq-gains p{display:flex;gap:11px;align-items:flex-start;margin:0;
    font-size:16px;line-height:1.5}
  .faq-gains .tick{flex:0 0 auto;width:20px;height:20px;margin-top:2px;
    border-radius:50%;background:var(--color-brand-solid);color:var(--surface);
    font-size:11px;font-weight:700;display:inline-flex;align-items:center;
    justify-content:center}

  /* Карточка сведений: строки «подпись — значение». */
  .about-card{margin:0;padding:24px 26px;display:flex;flex-direction:column;gap:10px}
  .about-card h2{font-size:19px;font-weight:700;letter-spacing:-.02em}
  .about-card p{display:flex;flex-direction:column;gap:2px;margin:0}
  .about-card .k{font-size:14px;color:var(--muted)}
  .about-card .v{font-size:16px;line-height:1.5}
  .about-no{padding:28px 30px;display:flex;flex-direction:column;gap:12px}
  .about-no h2{font-size:21px;font-weight:700;letter-spacing:-.02em}
  .about-no p{margin:0;font-size:17px;line-height:1.65}

  /* ——— каталог ———
     Одна колонка 1180, как в макете: столбца отбора слева больше нет. Ширина
     живёт здесь, а не классами в шаблоне: её задаёт раздел, а не разметка. */
  /* 1180 — ширина содержимого, поэтому поля добавлены к ней: иначе в сетку
     помещалось на одну карточку меньше, чем в макете. */
  .cat-page{max-width:1220px;margin:0 auto;padding:52px 20px 96px;
    display:flex;flex-direction:column;gap:32px}
  @media (min-width:1280px){.cat-page{max-width:1276px;padding-left:48px;padding-right:48px}}
  .cat-form{display:flex;flex-direction:column;gap:20px}
  .cat-bar{display:flex;align-items:center;justify-content:space-between;
    gap:16px;flex-wrap:wrap;padding-bottom:18px;border-bottom:1px solid var(--line)}
  .cat-dirs{display:flex;gap:8px;flex-wrap:wrap}
  .cat-side{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .cat-side .selector{width:auto;min-width:200px;height:44px;min-height:44px;font-size:15px}

  /* Направление — пилюля: выбранная берёт мятный фон и цвет действия. */
  .chip{appearance:none;font:inherit;display:inline-flex;align-items:center;gap:9px;
    white-space:nowrap;font-size:15px;font-weight:500;cursor:pointer;
    border-radius:var(--r-pill);padding:9px 16px;background:var(--surface);
    color:var(--text);border:1px solid var(--line)}
  .chip:hover{border-color:var(--muted)}
  .chip.on{font-weight:600;background:var(--mint);color:var(--accent);
    border-color:var(--color-mint-line)}
  .chip-n{font-size:13px;font-weight:600;color:var(--muted)}
  .chip.on .chip-n{color:var(--accent)}

  /* Сетка карточек: от 280 и сколько поместится, как в макете. */
  .cat-grid{list-style:none;margin:0;padding:0;display:grid;gap:18px;
    grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}

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

     Зона нажатия у варианта ответа — всё поле, а не кружок в 13 пикселей:
     на телефоне по нему не попасть. Высота поля поэтому не меньше 56. */
  .quiz-page{max-width:760px;margin-inline:auto}
  .quiz-head{display:flex;flex-direction:column;gap:6px}
  .quiz-head .crumb a{min-height:0}   /* строка назад стоит вплотную к надстрочной */
  .quiz-head .eyebrow{margin:0;font-size:13px;font-weight:600;letter-spacing:.1em;
    text-transform:uppercase;color:var(--muted)}
  /* Название теста мельче заголовка раздела: над ним уже стоят название
     программы и надстрочная строка, и третий крупный кегль подряд спорил бы
     с ними за первое место. */
  .quiz-head h1{font-size:clamp(26px,3vw,34px);line-height:1.12}
  .quiz-head .muted{margin:6px 0 0;font-size:15px}
  /* Проходной балл держится у правого края на одной строке с названием:
     он ответ на вопрос «сколько нужно», а не подпись к тесту. */
  .quiz-title{display:flex;align-items:flex-end;justify-content:space-between;
    gap:20px;flex-wrap:wrap}
  .quiz-title .quiet{font-size:15px;color:var(--muted)}

  .quiz-progress{display:flex;align-items:center;gap:14px;margin:0 0 20px}
  .quiz-progress .bar{flex:1;margin:0}
  /* Заливка светлее действия: рядом стоит зелёная кнопка, и полоса в тот же
     тон спорила бы с ней. */
  .quiz-progress .bar i{background:color-mix(in oklab, var(--accent) 58%, var(--bg))}
  .quiz-progress .num{flex:0 0 auto;font-size:14px;font-weight:600;color:var(--accent)}

  .quiz-card{padding:30px 32px}
  .quiz{border:0;padding:0;margin:0;min-width:0}
  .quiz + .quiz{margin-top:24px;padding-top:24px;border-top:1px solid var(--line-soft)}
  /* Линия разделяет два видимых вопроса. Когда предыдущий убран шагом, делить
     нечего, и линия висела бы над карточкой пустой чертой. */
  .quiz[hidden] + .quiz{margin-top:0;padding-top:0;border-top:0}
  .quiz-q{margin:0 0 22px;font-size:22px;font-weight:600;letter-spacing:-.015em;
    line-height:1.35}
  .quiz-kind{margin:-14px 0 18px;font-size:14px;color:var(--muted)}

  .opt{display:flex;gap:14px;align-items:center;min-height:56px;padding:16px 18px;
    margin:0 0 10px;border:1px solid var(--field);border-radius:16px;
    background:var(--field-bg);color:var(--text);font-size:17px;line-height:1.45;
    cursor:pointer;
    transition:border-color var(--dur-base) var(--curve),
               background var(--dur-base) var(--curve)}
  .opt:last-child{margin-bottom:0}
  .opt:hover{border-color:var(--accent)}
  .opt input{width:auto;max-width:none;margin:0;flex:none}
  .opt:focus-within{outline:2px solid var(--accent-2);outline-offset:2px}
  /* Буква вместо номера: перечень русский, и латинская буква счётчика CSS
     читалась бы здесь как чужая вставка. Номер занят вопросом. */
  .opt .letter{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
    width:28px;height:28px;border-radius:50%;background:var(--sand);
    font-size:14px;font-weight:700;color:var(--muted)}
  .opt-text{flex:1;min-width:0}

  /* Отметку показывает само поле: рамка, фон и буква. Кружок переключателя
     при этом убирается, но только там, где браузер умеет :has, — иначе
     выбранный вариант остался бы вовсе без признака. */
  @supports selector(:has(*)){
    .opt input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
    .opt:has(input:checked){border-color:var(--color-brand-solid);background:var(--mint)}
    .opt:has(input:checked) .letter{background:var(--color-brand-solid);color:var(--surface)}
  }

  .quiz-nav{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
    margin-top:22px;padding-top:20px;border-top:1px solid var(--line-soft)}
  /* Погашенная кнопка остаётся кнопкой, а не бледнеет прозрачностью: рядом
     стоит подпись «Выберите ответ», и вместе они читаются как одно правило. */
  .quiz-nav .btn:disabled{background:color-mix(in oklab, var(--accent) 34%, var(--bg));
    cursor:default}
  .quiz-hint{margin:0;font-size:15px;color:var(--muted)}
  .quiz-rule{margin:18px 0 0;font-size:14px;line-height:1.6;color:var(--muted)}

  /* ——— растущая дуга: сигнатура, та же, что на лендинге ——— */
  .arc{display:block;width:100%;max-width:180px}
  .arc .track{fill:none;stroke:var(--track);stroke-width:9;stroke-linecap:butt}
  .arc .fill{fill:none;stroke-width:9;stroke-linecap:butt;transition:stroke-dasharray 560ms var(--curve)}
  .arc .fill.below{stroke:var(--warn)}
  .arc .fill.above{stroke:var(--accent-2)}
  /* Центр поворота засечки задан прямо в атрибуте: rotate(угол 70 70).
     Здесь стоял ещё и transform-origin: Chrome складывал его с центром из
     атрибута, поворот применялся дважды, и линия уходила за габарит svg,
     где её срезал overflow. Подпись рядом при этом обещала отметку. */
  .arc .notch{stroke:var(--text);stroke-width:3}
  .arc .val{font-family:var(--font-display),sans-serif;font-weight:800;font-size:34px;fill:var(--text);
    text-anchor:middle;font-variant-numeric:tabular-nums;letter-spacing:-.03em}
  .arc-sub{text-align:center;font-size:14px;color:var(--muted);margin:8px 0 0}

  /* ——— полоса прогресса: зелёный значит пройдено ——— */
  .bar{height:6px;background:var(--track);border-radius:999px;overflow:hidden;margin:10px 0}
  /* Долю задаёт разметка своим свойством --fill: это данные, а не
     оформление, и в теме их взять неоткуда. */
  .bar i{display:block;height:100%;width:var(--fill,0%);background:var(--accent-2)}

  /* ——— путь по программе ———
     Уроки и работы одной последовательностью. Прежде здесь был список .steps
     из одних уроков: тесты и задания, привязанные к уроку (п. 7.4), в
     оглавление не попадали, и выбрать работу было негде. */
  .path{list-style:none;margin:0;padding:0}
  .path > li{position:relative;border-top:1px solid var(--line-soft);padding:18px 0}
  .path > li:first-child{border-top:0}
  /* Дорожка: линия от кружка к кружку. Рисуется псевдоэлементом строки, а не
     отдельным узлом: узел пришлось бы ставить в разметку ради оформления. */
  .path > li:not(:last-child)::before{content:"";position:absolute;left:13px;
    top:calc(50% + 13px);bottom:-13px;width:1px;background:var(--line)}
  .path > li.locked{color:var(--muted)}

  /* Нажимается вся строка, а не одна надпись в 23 пикселя: ссылка растянута
     псевдоэлементом, чтобы не раздувать сетку высотой самой ссылки. */
  .step{position:relative;display:grid;grid-template-columns:26px 1fr auto;
    gap:3px 16px;align-items:center}
  .step h3 a::after{content:"";position:absolute;inset:-8px 0}
  /* Название первым, подпись под ним — так в макете. Прежде сверху стояла
     подпись «Урок 1 из 5», и глаз читал нумерацию раньше самого урока. */
  .step h3{grid-column:2;grid-row:1;margin:0;font-size:17px;font-weight:600;
    line-height:1.3}
  .step h3 a{color:var(--text);text-decoration:none}
  .step h3 a:hover{color:var(--accent)}
  .step .no{grid-column:2;grid-row:2;font-size:14px;color:var(--muted);margin:0}
  .step .pill{grid-column:3;grid-row:1/3;align-self:center}

  /* Кружок урока: у пройденного галка на заливке действия, у остальных
     номер. Дорожка между кружками связывает уроки в одну
     последовательность — в макете это её главная работа. */
  .step-dot{grid-column:1;grid-row:1/3;align-self:center;
    display:inline-flex;align-items:center;justify-content:center;
    width:26px;height:26px;border-radius:50%;border:1px solid var(--line);
    background:var(--surface);color:var(--muted);
    font-family:var(--font-display),sans-serif;font-size:12px;font-weight:700}
  .step-dot.done{background:var(--color-brand-solid);border-color:var(--color-brand-solid);
    color:var(--surface)}
  /* На телефоне подпись состояния уходит под название: «откроется после
     предыдущего» в одну строку справа расширяла страницу на 39 пикселей. */
  @media (max-width:640px){
    .step{grid-template-columns:26px 1fr}
    .step .pill{grid-column:2;grid-row:3;justify-self:start;margin-top:6px}
  }
  .path > li.locked .step h3{color:var(--muted)}

  /* Отметка состояния. Квадрат со скруглением, а не кружок: окружность в
     системе занята дугой оценки и больше нигде не повторяется. Цвет здесь
     дублирует подпись рядом, а не заменяет её. */
  .mark{grid-column:1;grid-row:2;width:18px;height:18px;border-radius:5px;
    border:1.5px solid var(--line);background:transparent;align-self:center}
  .mark.done{background:var(--accent-2);border-color:var(--accent-2)}
  .mark.action{border-color:var(--warn);border-width:2px}

  /* Работы урока. Отступ слева ставит их под урок, которому они принадлежат. */
  .works{list-style:none;margin:14px 0 0;padding:0 0 0 42px}

  /* Работа урока в макете — серая плашка со скруглением, а не строка на
     линии: так видно, что она принадлежит уроку над ней, а не перечню. */
  .works.nested > li{border-top:0;background:var(--surface-2);border-radius:var(--rf);
    padding:12px 16px;margin:0 0 8px;grid-template-columns:1fr auto auto}
  .works.nested > li:last-child{margin-bottom:0}
  .works.nested .t{grid-column:1;grid-row:1;font-size:16px}
  .works.nested .kind{grid-column:1;grid-row:2;font-size:14px}
  .works.nested .note{grid-column:2;grid-row:1/3}
  .works.nested .sc{grid-column:3;grid-row:1/3}

  /* Зачётные работы всей программы: значок слева отличает тест от задания,
     балл прижат к правому краю. */
  .works.big{padding-left:0}
  .works.big > li{grid-template-columns:34px 1fr auto auto;gap:3px 16px;
    align-items:center;padding:18px 0;border-top:1px solid var(--line-soft)}
  .works.big > li:first-child{border-top:0}
  .works.big .t{grid-column:2;grid-row:1;font-size:17px;font-weight:600}
  .works.big .kind{grid-column:2;grid-row:2;font-size:14px}
  .works.big .pill{grid-column:3;grid-row:1/3;align-self:center}
  .works.big .sc{grid-column:4;grid-row:1/3;align-self:center;font-size:19px}
  .w-ico{grid-column:1;grid-row:1/3;align-self:center;
    display:inline-flex;align-items:center;justify-content:center;
    width:34px;height:34px;border-radius:11px;font-size:15px;font-weight:700;
    background:var(--color-brand-tint);color:var(--accent-2)}
  .w-ico.задание{background:var(--sand);color:var(--warn)}
  .works > li{position:relative;display:grid;grid-template-columns:18px 1fr auto auto;
    gap:2px 12px;align-items:baseline;padding:11px 0;border-top:1px solid var(--line)}
  .works .t::after{content:"";position:absolute;inset:0}
  .works .mark{grid-column:1;grid-row:1;align-self:baseline;position:relative;top:3px}
  /* Название работы набрано цветом действия, а не текста: в свежем макете
     строка работы вся стала нажимаемой, и на неё нужно указать заранее —
     иначе о том, что сюда можно зайти, узнают только наведением. */
  .works .t{grid-column:2;grid-row:1;font-family:var(--font-display),sans-serif;font-weight:500;
    color:var(--accent);text-decoration:none}
  .works .t:hover{color:var(--accent-hover)}
  .works .kind{grid-column:2;grid-row:2;font-size:13px;color:var(--muted)}
  .works .note{grid-column:3;grid-row:1/3;align-self:center;
    font-size:13px;color:var(--muted);text-align:right}
  .works .note.action{color:var(--warn)}
  .works .note.done{color:var(--accent-2)}
  .works .sc{grid-column:4;grid-row:1/3;align-self:center;width:2.5rem;text-align:right;
    color:var(--warn);
    font-family:var(--font-display),sans-serif;font-weight:800;font-size:19px;font-variant-numeric:tabular-nums}
  .works .sc.zero{color:var(--muted);font-weight:400}

  /* Ниже 640 балл уходит под название: три колонки текста в ряд на телефоне
     сжимаются до двух-трёх символов на строку. */
  @media (max-width:640px){
    .works{padding-left:0}
    .works > li{grid-template-columns:18px 1fr auto}
    .works .sc{grid-column:3;grid-row:1;align-self:baseline}
    .works .note{grid-column:2;grid-row:3;text-align:left}
  }

  /* ——— следующий шаг ———
     Одно названное действие. Без него человек, открывший программу, видел
     оглавление и никакого указания, с чего продолжать. */
  .next{margin:0 0 18px;padding:16px 18px;background:var(--surface-2);
    border-radius:var(--r);border-left:3px solid var(--warn)}
  .next.done{border-left-color:var(--accent-2)}
  .next .k{margin:0;font-size:13px;color:var(--muted)}
  .next .v{margin:6px 0 0;font-family:var(--font-display),sans-serif;font-weight:500;font-size:19px}
  .next .v a{display:inline-flex;align-items:center;min-height:44px;
    color:var(--text);text-decoration:none}
  .next .v a:hover{color:var(--accent)}
  .next .why{margin:4px 0 0;font-size:14px;color:var(--muted)}

  /* ——— результат пройденного курса ———
     Одна строка вместо трёх плиток и блока «дальше». Зелёная граница и
     зелёное число — семантика закрытого: у пройденного курса условия зачёта
     уже выполнены, и показывать их проценты значит спорить со словом
     «пройден». Кегль числа тот же, что внутри дуги: второй сигнатуры на
     странице не заводится, дуга остаётся за журналом и страницей задания. */
  .result{display:flex;gap:20px;align-items:flex-start;margin:16px 0 0;
    padding:18px 20px;background:var(--surface-2);border-radius:var(--r);
    border-left:3px solid var(--accent-2)}
  .result-n{flex:none;margin:0;font-family:var(--font-display),sans-serif;font-weight:800;
    font-size:38px;line-height:1;color:var(--warn);
    font-variant-numeric:tabular-nums;letter-spacing:-.03em}
  .result-t{margin:0 0 4px;font-family:var(--font-display),sans-serif;font-weight:500;font-size:19px}
  .result .muted{margin:0;font-size:14px;max-width:64ch}
  @media (max-width:520px){.result{flex-direction:column;gap:10px}}

  /* ——— два условия зачёта ———
     Состояние «курс пройден» требует обоих сразу (п. 6.3), поэтому и показаны
     оба числами. Полоса прогресса по урокам отвечала лишь на половину
     вопроса «сколько я прошёл». */
  .terms{display:grid;gap:14px;margin:0;grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
  .term{background:var(--surface-2);border-radius:var(--r);padding:14px 16px;margin:0}
  .term dt{font-size:13px;color:var(--muted)}
  .term dd{margin:6px 0 0;font-family:var(--font-display),sans-serif;font-weight:800;font-size:22px;
    color:var(--warn);font-variant-numeric:tabular-nums}
  .term dd small{font-family:var(--font-body),system-ui,sans-serif;font-size:14px;
    font-weight:400;color:var(--muted)}
  .term dd .bar{margin:10px 0 0}
  .term dd .note{display:block;margin:6px 0 0;font-family:var(--font-body),system-ui,sans-serif;
    font-size:13px;font-weight:400;color:var(--muted)}
  /* Зелёный только у двух условий зачёта (п. 6.3). Счётчик работ им не
     красится: закрытая работа может быть и провалом, а зелёный в системе
     значит «зачтено». */
  .term.met dd{color:var(--accent-2)}  /* условие выполнено: бирюза */

  /* ——— вкладки ———
     Полоса из макета: группа кнопок в песочной таблетке, выбранная залита
     поверхностью и приподнята. Полосу рисует static/js/tabs.js, поэтому без
     скриптов этих правил просто некому применяться, а оба раздела стоят
     подряд со своими заголовками.

     Высота 44 у кнопки обязательна: вкладки переключают пальцем. */
  .tabs{display:inline-flex;gap:6px;align-self:flex-start;margin:0 0 16px;
    padding:5px;background:var(--sand);border-radius:var(--r-pill);max-width:100%;
    flex-wrap:wrap}
  .tab{appearance:none;font:inherit;font-family:var(--font-display),sans-serif;
    font-weight:600;font-size:15px;min-height:44px;padding:0 20px;
    border:0;border-radius:var(--r-pill);background:none;color:var(--muted);
    cursor:pointer;white-space:nowrap;
    transition:background-color 180ms var(--curve),color 180ms var(--curve)}
  .tab:hover{color:var(--text)}
  .tab.is-on{background:var(--surface);color:var(--text);
    box-shadow:0 1px 3px rgba(20,32,28,.08)}
  .tab:focus-visible{outline:2px solid var(--accent-2);outline-offset:2px}

  /* ——— кольцо пройденного ———
     Доля отмеченных уроков одной фигурой, по макету. Собрано conic-gradient,
     без SVG и без скриптов: значение приходит одним числом в --p, всё
     остальное — оформление. Внутренний круг закрашен цветом карточки, а не
     вырезан маской: маска в Safari до 15.4 не поддерживалась, и кольцо
     превращалось в сплошной диск.

     Для чтения вслух фигура закрыта подписью на самом элементе (role="img"),
     поэтому число внутри читать второй раз не нужно. */
  .ring{width:132px;height:132px;margin:4px auto 20px;border-radius:50%;
    display:flex;align-items:center;justify-content:center;
    background:conic-gradient(var(--accent-2) calc(var(--p,0) * 1%), var(--track) 0)}
  .ring-in{width:104px;height:104px;border-radius:50%;background:var(--surface);
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px}
  .ring-n{font-family:var(--font-display),sans-serif;font-weight:800;font-size:26px;
    letter-spacing:-.03em;line-height:1}
  .ring-t{font-size:13px;color:var(--muted)}

  /* ——— следующий шаг на зелёной плашке ———
     Тот же блок, что .next, но на плашке и с кнопкой: на странице программы
     это единственное действие, и в ряду серых плиток оно терялось. Внутри
     «Моих курсов» блок остаётся прежним .next — там строк несколько, и
     зелёная плашка в каждой перестала бы что-либо выделять. */
  .next-go{margin:0 0 18px;padding:22px 24px}
  .next-go .k{margin:0;font-size:13px;font-weight:600;letter-spacing:.08em;
    text-transform:uppercase;color:var(--color-on-mint-dim)}
  .next-go .v{margin:8px 0 16px;font-family:var(--font-display),sans-serif;
    font-weight:700;font-size:20px;letter-spacing:-.015em;color:var(--text)}
  .next-go .why{margin:4px 0 16px;font-size:14px;color:var(--color-on-mint)}
  .next-go .btn{margin:0}

  /* Шапка «Моих курсов»: заголовок слева, счёт курсов справа на той же
     строке — так в макете. На узком экране счёт уходит под заголовок. */
  /* Перечень уже страницы: в макете он идёт колонкой около 60rem. На всю
     ширину шкафа строка растягивалась, и между названием и кнопкой вставала
     пустая половина экрана. Заголовок держит ту же ширину, иначе счёт курсов
     справа не встаёт над краем карточки. */
  .my-head,.course-list{max-width:940px;margin-inline:auto}
  .my-head{display:flex;align-items:baseline;justify-content:space-between;
    gap:20px;flex-wrap:wrap}
  .my-count{margin:0;font-size:15px;color:var(--muted)}

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

     Правый столбец прижат по правому краю и имеет свою минимальную ширину:
     отметка состояния, кнопка и оценка обязаны стоять друг под другом одной
     колонкой, иначе глаз ищет состояние заново в каждой строке. */
  .course-list{padding:0;overflow:hidden}
  .course-row{padding:24px 26px}
  .course-row + .course-row{border-top:1px solid var(--line-soft)}

  .course-line{display:flex;align-items:center;gap:24px;flex-wrap:wrap}

  /* Обложка та же, что в каталоге, и в радиусе поля, а не карточки: она
     вложена в карточку и повторять её скругление не должна. */
  .course-thumb{flex:0 0 auto;width:104px;height:104px;object-fit:cover;
    border-radius:var(--rf);background:var(--surface-2)}
  .course-thumb-empty{display:inline-flex;align-items:center;justify-content:center;
    font-family:var(--font-display),sans-serif;font-weight:700;font-size:12px;
    letter-spacing:.08em;color:var(--muted)}

  .course-mid{flex:1 1 17rem;min-width:0;display:flex;flex-direction:column;gap:8px}
  .course-mid h2{font-size:21px;line-height:1.25;margin:0;font-weight:700}
  .course-mid h2 a{color:var(--text);text-decoration:none}
  .course-mid h2 a:hover{color:var(--accent)}
  .course-emp{margin:0;font-size:15px;color:var(--muted);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .course-next{margin:0;font-size:15px;color:var(--muted)}

  /* Полоса и процент в одной строке: процент прижат к полосе, а не подписан
     под ней, иначе он читается как отдельное число. */
  .course-bar{display:flex;align-items:center;gap:12px;max-width:26rem}
  .course-bar .bar{flex:1;margin:0}
  .course-bar .num{flex:0 0 auto;font-size:14px;font-weight:600;color:var(--accent-2)}
  /* Заливка полосы светлее действия: рядом стоит зелёная кнопка, и полоса
     в тот же тон спорила бы с ней. В макете это отдельный светлый зелёный. */
  .course-bar .bar i{background:color-mix(in oklab, var(--accent) 58%, var(--bg))}

  .course-side{flex:0 0 auto;min-width:170px;display:flex;flex-direction:column;
    align-items:flex-end;gap:12px;margin-left:auto}
  /* Плашка «идёт обучение» в макете песочная с охряной надписью, а не серая:
     серая читалась как выключенное состояние, хотя обучение идёт. */
  .course-side .pill{border-color:transparent;background:var(--sand);color:var(--warn)}
  .course-side .pill.ok{background:var(--color-brand-tint);color:var(--accent-2)}
  /* Кнопка строки — кегль и вес из макета: 16/600 и радиус 12. */
  .course-side .btn{min-height:0;padding:13px 22px;font-size:16px;font-weight:600;
    border-radius:var(--r-sm)}
  /* Оценка подписью под кнопкой, как в макете: спокойным серым и обычным
     кеглем. Крупное охряное число спорило за взгляд с «Продолжить», хотя
     действие в строке одно. */
  .course-score{margin:0;text-align:right;font-size:14px;color:var(--muted);
    line-height:1.3}

  /* На узком экране правый столбец распрямляется в строку под серединой:
     колонка в 11rem рядом с обложкой 104 пикселя не оставляет названию
     ничего. */
  @media (max-width:720px){
    .course-row{padding:20px}
    .course-thumb{width:72px;height:72px}
    .course-side{width:100%;min-width:0;flex-direction:row;align-items:center;
      flex-wrap:wrap;gap:10px;margin-left:0}
    .course-side .btn{order:3}
    .course-score{text-align:left;order:2;margin-left:auto}
  }

  /* Возврат на доработку и разбор стоят под строкой: это состояния записи,
     а не часть её раскладки. */
  .works.returned{margin:18px 0 0;padding-left:0}
  .works.returned > li:first-child{border-top:0}
  .course-row .review{margin:18px 0 0}

  /* ——— переход между уроками ———
     Страница урока была тупиком: из неё вела одна ссылка, «ко всем урокам». */
  .lesson-nav{display:flex;gap:12px;justify-content:space-between;flex-wrap:wrap;
    margin:24px 0 0;padding:18px 0 0;border-top:1px solid var(--line)}
  .lesson-nav a{display:inline-flex;align-items:center;min-height:44px;
    color:var(--accent);text-decoration:none;font-family:var(--font-display),sans-serif;font-weight:500}
  .lesson-nav a:hover{color:var(--text)}
  .lesson-nav .end{margin-left:auto;text-align:right}

  /* ——— разбор проверяющего ——— */
  .review{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin:0 0 16px}
  .review .head{display:flex;gap:6px 12px;align-items:center;flex-wrap:wrap;
    padding:12px 18px;border-bottom:1px solid var(--line);background:var(--surface-2);
    font-size:14px;color:var(--muted)}
  .review .head b{font-family:var(--font-display),sans-serif;font-weight:600;color:var(--text)}
  .review .head .pill{margin-left:auto;white-space:normal}
  .review .head .num{font-family:var(--font-display),sans-serif;font-weight:600;font-size:19px;color:var(--text)}
  .review .body{padding:18px;font-size:15px;line-height:1.65}
  .review .body a{display:inline-flex;align-items:center;min-height:44px}
  .review .body p:last-child{margin:0}
  /* Разбор внутри истории отделён линией от собственного ответа: без неё
     чужой текст читался как продолжение своего. */
  .review .body .note-head{margin:16px 0 6px;padding-top:16px;font-size:14px;
    border-top:1px solid var(--line)}

  /* ——— история сдач ———
     Сохраняется целиком (4.2.6), но развёрнутой быть не обязана: свежий разбор
     стоит выше страницей. Нативный details, без скриптов. */
  /* Стрелка обязательна: общий стиль платформы снимает у summary родной
     маркер, и без неё заголовок читается мёртвой строкой, а не кнопкой.
     Та же фигура и тот же поворот, что у вопросов на сайте. */
  .hist > summary{cursor:pointer;display:flex;align-items:center;gap:14px;min-height:44px;
    font-family:var(--font-display),sans-serif;font-weight:600;font-size:19px;color:var(--text)}
  .hist > summary .chev{flex:none}
  .hist[open] > summary{margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--line)}
  .hist > summary:focus-visible{outline:2px solid var(--accent-2);outline-offset:2px}
  .hist .review:last-child{margin-bottom:0}

  /* Подвал платформы описан в platform.css. */

  /* ——— находки приёмки форм ———
     Телефон набирается в поле tel: без него на телефоне открывается буквенная
     клавиатура. Поле с ошибкой обведено цветом ошибки, не только подписано. */
  input[type=tel]{width:100%;max-width:38rem;font:inherit;font-size:15px;color:var(--text);
    background:var(--color-surface);border:1px solid var(--field);border-radius:var(--rf);
    min-height:52px;padding:13px 16px}
  .has-error input,.has-error select,.has-error textarea{border-color:var(--error)}
  .form-field{margin:0 0 16px}

  /* Флажок в строку с подписью: нажимается вся фраза, не только квадратик. */
  .form-check label{display:flex;align-items:flex-start;gap:10px;max-width:38rem;
    color:var(--text);font-size:15px;cursor:pointer;min-height:44px;margin:0}
  .form-check input[type=checkbox]{flex:0 0 auto;width:18px;height:18px;margin:3px 0 0}

  /* Сообщение с действием: текст и кнопка в одну строку, на узком экране
     кнопка переносится под текст. */
  /* Полоса сообщения над страницей: свой отступ снизу не нужен, его даёт
     отступ самой страницы; иначе между баннером и заголовком пустой экран. */
  main > .wrap.wrap-notice{padding-bottom:0}
  .msg-act{display:flex;align-items:center;justify-content:space-between;gap:12px 20px;flex-wrap:wrap}
  .msg-act form{margin:0}
  .msg-act .btn.sm{min-height:40px}

  /* Две кнопки рядом; на 390px переносятся без наползания. */
  .actions{display:flex;gap:10px;flex-wrap:wrap}
  /* На телефоне поле ввода не мельче 16px: иначе iOS приближает страницу
     при фокусе, и после отправки её приходится отодвигать обратно. */
  @media (max-width:760px){
    input[type=text],input[type=email],input[type=password],input[type=number],input[type=url],
    input[type=tel],input[type=file],textarea,select{font-size:16px}
  }
}
