/* EAHypno V2 — токены и компоненты.
   Источники: dizajn-sistema-2026-08-26.md (палитра, типографика),
   razbavlenie-teksta-2026-08-26.md (блоки), wireframe-2026-08-25.md (структура). */

/* ── шрифты: свои сабсеты, ничего внешнего ─────────────
   Диапазон: латиница + кириллица + пунктуация + ёлочки + тире + № + ё.
   Пять файлов, 69,0 КиБ суммарно при бюджете 120. */
@font-face{font-family:"PT Serif";font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/ptserif400.woff2) format("woff2")}
@font-face{font-family:"PT Serif";font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/ptserif700.woff2) format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/inter400.woff2) format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/inter700.woff2) format("woff2")}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url(../fonts/mono400.woff2) format("woff2")}

:root{
  /* ── цвет ───────────────────────────────────────────── */
  --paper:#F5F5F4;          /* фон страницы */
  --card:#FFFFFF;           /* карточки и поля */
  --inset:#F2F3F5;          /* вставки и врезки */
  --line:#DDE0E4;           /* границы и разделители */
  --line-strong:#848C95;    /* граница поля: 3.41:1 к белому и 3.12:1 к --paper.
                               Порог 3:1 (WCAG 1.4.11) должен выполняться к тому
                               фону, на котором поле реально стоит, а не только
                               к белому — прежнее #8B939C давало на --paper 2.85. */

  /* Цифры — отношение к --paper (#F5F5F4), на котором текст и стоит. */
  --ink:#14181D;            /* основной текст   16.34:1 */
  --ink-2:#454F5A;          /* вторичный         7.64:1 */
  --ink-3:#636D77;          /* приглушённый      4.83:1 */

  --accent:#1B2A5E;         /* единственная краска: 12.50:1 к --paper */
  --accent-strong:#132043;  /* наведение и нажатие */
  --accent-soft:#E7EAF1;    /* подложка акцента */
  --status:#724C26;         /* только статус набора: 6.93:1 к --paper */

  --err:#8A1F1F;            /* ошибка: 9.14:1 к белому, 8.03:1 к --err-bg */
  --err-bg:#FBEDED;
  --ok:#1F5D3A;             /* успех: 7.82:1 к белому, 6.91:1 к --ok-bg */
  --ok-bg:#EAF3EE;

  /* ── типографика ────────────────────────────────────── */
  --font-display:"PT Serif",Georgia,"Times New Roman",serif;
  --font-text:"Inter",-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-mono:"IBM Plex Mono","SFMono-Regular",Consolas,monospace;

  --t-h1:38px;  --lh-h1:1.14;
  --t-h2:25px;  --lh-h2:1.22;
  --t-h3:19px;  --lh-h3:1.26;
  --t-lead:18.5px;
  --t-body:17px; --lh-body:1.62;
  --t-small:14px; --lh-small:1.5;
  --t-micro:12.5px;

  /* ── ритм и форма ───────────────────────────────────── */
  --step:8px;
  --radius:4px;
  --radius-lg:6px;
  --measure:68ch;           /* предел ширины полосы текста */
  --transition:200ms ease;
  --focus-color:#724C26;    /* кольцо фокуса на светлом — 7.6:1 к белому */
  --focus:3px solid var(--focus-color);
  --focus-offset:2px;
}

@media (max-width:760px){
  :root{ --t-h1:28px; --t-h2:21px; --t-h3:18px; --t-lead:17px; --t-body:16px; }
}

/* ── база ─────────────────────────────────────────────── */
/* Без этого поля с width:100% и горизонтальными padding вылезают за
   контейнер на 28 px и дают горизонтальную прокрутку на мобильном. */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font:400 var(--t-body)/var(--lh-body) var(--font-text);
  text-rendering:optimizeLegibility;
}
/* Селекторы по тегам ограничены корневым классом витрины `.eah`.
   Иначе они накрыли бы вывод Guru, RSForm, Finder и личного кабинета
   до того, как для них написаны собственные переопределения. */
.eah h1,.eah h2,.eah h3{font-family:var(--font-display);font-weight:700;margin:0 0 calc(var(--step)*1.5);letter-spacing:-.01em}
.eah h1{font-size:var(--t-h1);line-height:var(--lh-h1)}
.eah h2{font-size:var(--t-h2);line-height:var(--lh-h2);margin-top:calc(var(--step)*5)}
.eah h3{font-size:var(--t-h3);line-height:var(--lh-h3);margin-top:calc(var(--step)*3.5)}
.eah p{margin:0 0 calc(var(--step)*2);max-width:var(--measure)}
.lead{font-size:var(--t-lead);color:var(--ink-2)}
.eah small,.small{font-size:var(--t-small);line-height:var(--lh-small)}
.mono{font-family:var(--font-mono);font-size:var(--t-small);letter-spacing:-.01em}
.micro{font:400 var(--t-micro)/1.2 var(--font-mono);letter-spacing:.07em;text-transform:uppercase;color:var(--ink-3)}
.eah b,.eah strong{font-weight:600}
/* Курсив в кириллице читается хуже латинского, поэтому в тексте витрины он
   заменяется полужирным. Область сужена до содержимого: em внутри cite, blockquote
   и подписей сохраняет собственное начертание, иначе теряется смысловая разница. */
.eah-content em,.eah-content i{font-style:normal;font-weight:600}

/* ── ссылки и фокус ─────────────────────────────────────
   Одного цвета кольца на светлом и тёмном не хватает: охра на акцентной
   заливке даёт 1.8:1. Поэтому в тёмных блоках токен переопределяется на
   светлый янтарь — 7.2:1 к акценту. Проверено расчётом. */
/* `:where(.eah)` даёт нулевой вес, поэтому базовое правило ссылок имеет
   специфичность (0,1,0) и его перебивает любой одноклассовый вариант —
   .skip-link, ссылка подвала, кнопка. Прежний вариант `.eah a:not(.btn)`
   весил (0,2,1) и красил их все в акцентный цвет. */
:where(.eah) a:not(.btn){color:var(--accent);text-decoration-thickness:1px;text-underline-offset:2px}
:where(.eah) a:not(.btn):hover{color:var(--accent-strong)}
/* Фокус намеренно глобальный: видимый индикатор нужен и в выводе расширений,
   для которых переопределений ещё нет. Это единственное правило по тегам,
   оставленное вне `.eah` сознательно. */
:focus-visible{outline:var(--focus);outline-offset:var(--focus-offset);border-radius:2px}

/* ── кнопки ───────────────────────────────────────────── */
.btn{
  display:inline-block;border:1px solid transparent;border-radius:var(--radius);
  font:600 15px/1.2 var(--font-text);padding:12px 22px;cursor:pointer;
  text-decoration:none;transition:background var(--transition),color var(--transition);
}
.btn-primary{background:var(--accent);color:#fff;--focus-color:#E0B84C}
.btn-primary:hover{background:var(--accent-strong);color:#fff}
.btn-primary:active{background:var(--accent-strong);transform:translateY(1px)}
.btn-secondary{background:transparent;color:var(--accent);border-color:var(--line-strong)}
.btn-secondary:hover{border-color:var(--accent);background:var(--accent-soft)}
.btn[data-loading]{position:relative;color:transparent}
/* disabled объявлен ПОСЛЕ loading: недоступность важнее и должна перекрывать.
   Ссылку с aria-disabled браузер всё равно оставит кликабельной — это
   обеспечивается разметкой (снять href) или скриптом, не CSS. */
.btn[disabled],.btn[aria-disabled="true"]{background:var(--line);color:var(--ink-3);cursor:not-allowed;border-color:transparent}
/* Разметка кнопки в загрузке обязана нести aria-busy="true": текст становится
   прозрачным только визуально, и без атрибута состояние не объявляется. */
.btn[data-loading]:after{
  content:"";position:absolute;inset:0;margin:auto;width:15px;height:15px;
  border:2px solid var(--spinner-track,rgba(255,255,255,.4));
  border-top-color:var(--spinner,#fff);           /* видимый сегмент кольца */
  border-radius:50%;animation:spin .7s linear infinite;
}
.btn-secondary[data-loading]{--spinner:var(--accent);--spinner-track:var(--line)}
/* disabled сильнее loading: текст возвращается, кольцо убирается — иначе
   спиннер крутится поверх видимой надписи. */
.btn[data-loading][disabled]{color:var(--ink-3)}
.btn[data-loading][disabled]:after{display:none}
@keyframes spin{to{transform:rotate(360deg)}}
/* Не «ускоряем до нуля», а останавливаем: бесконечная анимация с периодом
   .001ms превращается в мельтешение, а не в покой. Область — свои компоненты,
   а не «*»: глобальное правило подавило бы и переходы Joomla с расширениями. */
@media (prefers-reduced-motion:reduce){
  .btn[data-loading]:after{animation:none}
  .btn,.field :is(input,textarea,select),.eah a{transition:none}
  html{scroll-behavior:auto}
}

/* ── формы ────────────────────────────────────────────── */
.field{margin-bottom:calc(var(--step)*2.5);max-width:var(--measure)}
.field label{display:block;font-size:var(--t-small);color:var(--ink-2);margin-bottom:6px}
.field .req{color:var(--status)}
.field :is(input,textarea,select){
  width:100%;font:400 16px/1.4 var(--font-text);color:var(--ink);
  background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);
  padding:11px 13px;transition:border-color var(--transition);
}
.field :is(input,textarea,select):hover{border-color:var(--ink-3)}
.field :is(input,textarea,select):focus-visible{border-color:var(--accent);outline:var(--focus);outline-offset:1px}
.field .hint{font-size:var(--t-micro);color:var(--ink-3);margin-top:6px;font-family:var(--font-text);letter-spacing:0;text-transform:none}
.field.is-error :is(input,textarea,select){border-color:var(--err);background:var(--err-bg)}
.field .err{font-size:var(--t-small);color:var(--err);margin-top:6px;display:block}
/* Приоритет состояний: disabled > loading > error > focus > hover.
   Поэтому disabled объявлен последним и перекрывает остальные. */
.field :is(input,textarea,select)[disabled]{background:var(--inset);color:var(--ink-3);cursor:not-allowed;border-color:var(--line)}
.consent{display:flex;gap:10px;align-items:flex-start;font-size:var(--t-small);color:var(--ink-2);max-width:var(--measure)}
.consent input{margin-top:3px;width:16px;height:16px;flex:none;accent-color:var(--accent)}
.note-ok{background:var(--ok-bg);border-left:3px solid var(--ok);padding:14px 18px;font-size:15px;border-radius:0 var(--radius) var(--radius) 0}
.note-err{background:var(--err-bg);border-left:3px solid var(--err);padding:14px 18px;font-size:15px;border-radius:0 var(--radius) var(--radius) 0}

/* ── таблицы ──────────────────────────────────────────── */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.eah table{width:100%;border-collapse:collapse;font-size:15px}
.eah th,.eah td{text-align:left;padding:11px 12px;border-bottom:1px solid var(--line);vertical-align:top}
.eah th{font:400 var(--t-micro)/1.2 var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.eah td.num{font-family:var(--font-mono);font-size:var(--t-small);color:var(--ink-2);white-space:nowrap}
@media (max-width:640px){
  /* Заголовок прячем двумя ОТДЕЛЬНЫМИ правилами, а не списком через запятую.
     Причина: неподдерживаемый селектор в списке делает недействительным всё
     правило целиком — браузер без :has() потерял бы и рабочую строку с thead.
     Первое правило — основной путь, второе — страховка на случай, когда
     <thead> в разметке забыли и браузер создал только <tbody>. */
  .eah table.stack thead{position:absolute;left:-9999px}
  .eah table.stack tr:has(> th){position:absolute;left:-9999px}
  .eah table.stack tr{display:block;border-bottom:1px solid var(--line);padding:10px 0}
  .eah table.stack td{display:grid;grid-template-columns:38% 1fr;gap:10px;border:0;padding:5px 0}
  .eah table.stack td:before{content:attr(data-th);font:400 var(--t-micro)/1.3 var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
}

/* ── каркас витрины (index.php дочернего шаблона) ─────── */
.skip-link{position:absolute;left:-9999px;top:0;background:var(--accent);color:#fff;padding:10px 16px;z-index:100}
.skip-link:focus{left:0}
.eah-shell{max-width:1180px;margin:0 auto;padding:0 28px}
.eah-header{background:var(--card);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:20}
.eah-header__row{display:flex;align-items:center;gap:28px;min-height:74px;padding:12px 28px}
.eah-logo{text-decoration:none;line-height:1.05}
.eah-logo__sub{display:block;margin-top:5px;font:400 10px/1.2 var(--font-mono);letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
.eah-header__aside{display:flex;align-items:center;gap:16px;margin-left:auto;min-width:0}
.eah-tel{font:400 14px/1 var(--font-mono);color:var(--ink);text-decoration:none;white-space:nowrap}
.eah-logo img{height:36px;width:auto;display:block}
.eah-logo__text{font:700 18px/1.15 var(--font-display);color:var(--ink);white-space:nowrap;display:block}
.eah-nav{flex:0 1 auto;min-width:0;margin-left:20px}
/* Перенос запрещён намеренно: при нехватке пары десятков пикселей меню
   вставало в три строки и роняло шапку со 74 до 131 пикселя. */
.eah-nav ul{list-style:none;display:flex;flex-direction:row;flex-wrap:nowrap;gap:16px;margin:0;padding:0;font-size:14.5px}
.eah-nav a{text-decoration:none;color:var(--ink-2);padding:6px 0;border-bottom:2px solid transparent;display:block;white-space:nowrap}
.eah-nav a:hover,.eah-nav .current > a{color:var(--accent);border-bottom-color:var(--accent)}
.eah-nav li{margin:0}
.eah-hero{background:var(--accent);color:#fff;padding:72px 0 78px}
.eah-hero__grid{display:grid;grid-template-columns:1.35fr .65fr;gap:56px;align-items:start}
.eah-hero__act{display:flex;gap:12px;flex-wrap:wrap}
/* Боковая колонка героя: портрет и паспорт идут стопкой. Портрет бывает только
   на странице человека; у программ его нет, и колонка равна одному паспорту. */
.eah-hero__bok{display:flex;flex-direction:column;gap:18px}
.eah-hero__portret{border-radius:8px;overflow:hidden;background:rgba(255,255,255,.08)}
.eah-hero__portret img{display:block;width:100%;height:auto}
/* С портретом правая колонка вдвое выше текста, и внизу слева остаётся дыра.
   Прижимать текст к верху нечем, поэтому он центрируется по стопке справа. */
.eah-hero__grid:has(.eah-hero__portret) > :first-child{align-self:center}
/* Паспорт программы: сухая таблица фактов вместо снимка. Своих фотографий
   учебного процесса у Академии почти нет, а чужой сток мы не берём. */
.eah-pasport{border:1px solid rgba(255,255,255,.28);border-radius:8px;padding:4px 20px}
.eah-pasport dl{margin:0}
.eah-pasport div{display:flex;justify-content:space-between;gap:16px;padding:14px 0;border-bottom:1px solid rgba(255,255,255,.16)}
.eah-pasport div:last-child{border-bottom:0}
.eah-pasport dt{flex:0 1 auto;max-width:46%;font:400 11.5px/1.3 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:rgba(255,255,255,.66)}
.eah-pasport dd{flex:1 1 auto;margin:0;font-size:14.5px;text-align:right;color:#fff}
.eah-hero h1{color:#fff;max-width:22ch}   /* заголовок героя короче полосы текста: длинная строка в 38 px не читается одним взглядом */
.eah-breadcrumbs{padding-top:14px;font-size:13px;color:var(--ink-3)}
.eah-main{padding:30px 0 10px}
.eah-main__grid{display:grid;grid-template-columns:1fr;gap:34px}
.eah-main.has-side .eah-main__grid{grid-template-columns:minmax(0,1fr) 280px}
.eah-side{font-size:14.5px}
.eah-section{padding:64px 0}
/* Рубрикация раздела номером и линией — приём Works in Progress. */
.eah-sect-head{display:flex;align-items:baseline;gap:16px;border-top:1px solid var(--line);padding-top:18px;margin-bottom:26px}
.eah-sect-head .n{font:400 12px/1 var(--font-mono);letter-spacing:.08em;color:var(--ink-3)}
.eah-sect-head h2{margin:0}
.eah-section--inset{background:var(--inset);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.eah-section--accent{background:var(--accent);color:#fff}
.eah-section--accent h2{color:#fff}
.eah-footer{background:var(--accent-strong);color:rgba(255,255,255,.78);padding:52px 0 40px;font-size:14.5px}
.eah-footer a{color:rgba(255,255,255,.78);text-decoration:none;display:block;padding:4px 0}
.eah-footer a:hover{color:#fff}
/* Сетка задаётся обёртке модуля, а не строке подвала: Joomla оборачивает
   содержимое произвольного модуля в div.mod-custom, и он один был бы
   единственной колонкой сетки. */
.eah-footer .mod-custom{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:40px}
.eah-footer__law{grid-column:1/-1}
.eah-footer b{color:#fff;display:block;margin-bottom:12px;font-family:var(--font-display);font-size:16px}
/* ── строка соцсетей в подвале ─────────────────────────────────────────
   Ссылки подвала по умолчанию блочные, поэтому строка задаётся flex-ом, а
   не полагается на поведение по умолчанию. Подписи видимые: шесть
   пиктограмм без слов — это «значок без содержания», которого дизайн-система
   не хочет, и звезда Дзена с монохромной «R» сами себя не называют.
   Собственной верхней отбивки нет: её уже даёт зазор сетки. */
.eah-footer__soc{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:6px 20px;
  align-items:center}
.eah-footer__soc b{width:100%}
.eah-footer__soc a{display:inline-flex;align-items:center;gap:8px;min-height:44px;
  padding:0}
.eah-footer__soc svg{width:20px;height:20px;flex:none}
/* ── соцсети в теле страницы ───────────────────────────────────────────
   На контактах у ссылок есть подписи: шесть пиктограмм без слов — это
   как раз «значок без содержания», которого не хочет дизайн-система.
   Поле нажатия здесь задаёт сама строка со словом, отдельная высота не
   нужна. При печати блок не выводится, как и строка в подвале. */
.eah-soc{display:flex;flex-wrap:wrap;gap:10px 22px;margin:18px 0 22px}
.eah-soc a{display:inline-flex;align-items:center;gap:8px;min-height:44px;
  color:var(--accent);text-decoration:underline}
.eah-soc svg{width:20px;height:20px;flex:none}
.eah-footer__law{font:400 11.5px/1.5 var(--font-mono);color:rgba(255,255,255,.52);margin-top:34px;border-top:1px solid rgba(255,255,255,.16);padding-top:18px}
@media (max-width:900px){
  .eah-main.has-side .eah-main__grid{grid-template-columns:1fr}
  .eah-header__row{flex-wrap:wrap}
  .eah-shell{padding:0 18px}
}

/* ── блоки модулей витрины (template/eahypno/moduli/) ─── */
.eah-cards{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.eah-two{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
.eah-three{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.eah-card{border:1px solid var(--line);border-radius:var(--radius);padding:16px 18px;background:var(--card)}
.eah-card h3{margin:6px 0 6px;font-size:18px}
.eah-card h3 a{text-decoration:none}
.eah-card p{margin:0 0 10px;font-size:14px;color:var(--ink-2);max-width:none}
.eah-card .mono{color:var(--ink-3);display:block}
.eah-three p{font-size:14px;color:var(--ink-2);margin:6px 0 8px;max-width:none}
.eah-hero__lic{font:400 var(--t-micro)/1.35 var(--font-mono);letter-spacing:.05em;opacity:.72;margin:0 0 14px;max-width:none}
.eah-hero__lede{font-size:16px;opacity:.88;max-width:56ch;margin:0 0 20px}
.eah-hero .btn-primary.eah-hero__cta{background:#fff;color:var(--accent);--focus-color:#E0B84C}
.eah-hero .btn-primary.eah-hero__cta:hover{background:var(--inset);color:var(--accent-strong)}
.eah-section--accent .btn-primary{background:#fff;color:var(--accent)}
.eah-section--accent p{opacity:.9;max-width:60ch}
@media (max-width:760px){.eah-cards,.eah-two,.eah-three{grid-template-columns:1fr}}

/* ── раскладка «Витрина» (html/com_content/article/vitrina.php) ── */
.eah-vitrina__title{margin-bottom:calc(var(--step)*1.5)}
.eah-nabor{color:var(--status);font-size:14px;display:flex;gap:8px;align-items:baseline;margin:0 0 calc(var(--step)*2)}
.eah-vitrina__figure{margin:calc(var(--step)*4) 0}
.eah-vitrina__edit{font-size:13px;color:var(--ink-3)}

/* ── разбавители (см. razbavlenie-teksta) ─────────────── */
.term{border-left:3px solid var(--accent);background:var(--inset);padding:16px 20px;margin:calc(var(--step)*3) 0;font-size:15.5px;max-width:var(--measure)}
.term b{font-family:var(--font-display);font-size:16.5px;display:block;margin-bottom:5px}
.limit{background:var(--accent);color:#fff;--focus-color:#E0B84C;padding:22px 24px;border-radius:var(--radius-lg);margin:calc(var(--step)*3.5) 0;max-width:var(--measure)}
.limit h4{font:700 var(--t-micro)/1 var(--font-mono);letter-spacing:.09em;text-transform:uppercase;margin:0 0 10px;opacity:.72}
.limit p{margin:0;opacity:.94;font-size:15.5px}
.quote{margin:calc(var(--step)*3.5) 0;padding-left:22px;border-left:3px solid var(--status);font-family:var(--font-display);font-size:19px;line-height:1.45;max-width:var(--measure)}
.quote cite{display:block;margin-top:9px;font:400 13px/1.4 var(--font-text);color:var(--ink-3);font-style:normal}
.facts{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--line);border-bottom:1px solid var(--line);margin:calc(var(--step)*3.5) 0}
.facts div{padding:16px 18px}
.facts div+div{border-left:1px solid var(--line)}
.facts .n{font-family:var(--font-mono);font-size:24px;color:var(--accent);display:block;line-height:1.1}
.facts .t{font-size:13.5px;color:var(--ink-3);margin-top:5px;display:block}
/* Высота ограничена намеренно: без неё портрет 800x1200 разворачивается на всю
   колонку и страница превращается в ленту гигантских фотографий. width:auto не
   даёт растягивать мелкие файлы. */
.eah figure{margin:calc(var(--step)*4) 0}
.eah figure img{max-width:100%;width:auto;max-height:420px;display:block;margin-inline:auto;border-radius:var(--radius)}
.eah figcaption{font-size:13px;color:var(--ink-3);margin-top:9px;line-height:1.45;max-width:var(--measure);text-align:center}

/* Карточка отзыва: цитата и имя одним блоком. Портретов здесь нет намеренно —
   на боевом сайте они сгенерированы, а своих фотографий студентов нет. */
.otzyv{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:20px 22px;margin:0}
.otzyv blockquote{margin:0;border:0;padding:0;font-size:15.5px;line-height:1.62;color:var(--ink-2);max-width:none}
.otzyv .kto{margin:14px 0 0;font:400 11.5px/1.4 var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.otzyvy-setka{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin:calc(var(--step)*3) 0}
/* Видеоотзывы сняты вертикально на телефон, поэтому сетка из трёх узких
   колонок, а не привычных двух широких. aspect-ratio держит место до
   загрузки: без него постер подгружается позже и страница дёргается. */
.otzyvy-video{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin:calc(var(--step)*3) 0}
/* Вес поднят до (0,2,1): ролики лежат в figure, а правило `.eah figure video`
   для горизонтального видео весит (0,1,2) и иначе навязывает им 16:9 —
   вертикальный кадр обрезается по лицам. */
.eah .otzyvy-video video{
  display:block;width:100%;aspect-ratio:9/16;object-fit:cover;
  background:var(--ink);border:1px solid var(--line);border-radius:var(--radius);
}
/* Подпись есть не у всех роликов, поэтому figure без внешних отступов:
   иначе подписанный ролик уезжает вниз относительно соседних. */
.otzyvy-video figure{margin:0}
.otzyvy-video figcaption{text-align:left;margin-top:10px;max-width:none;font-size:var(--t-small);line-height:var(--lh-small);color:var(--ink-2)}
@media (max-width:760px){
  .otzyvy-setka{grid-template-columns:1fr}
  .otzyvy-video{grid-template-columns:1fr;max-width:340px}
}
ul.res{list-style:none;padding:0;margin:calc(var(--step)*2.5) 0;max-width:var(--measure)}
ul.res li{padding-left:26px;position:relative;margin-bottom:10px}
ul.res li:before{content:"";position:absolute;left:0;top:calc(.62em);width:11px;height:2px;background:var(--accent)}
.plashka{background:var(--inset);border-left:3px solid var(--status);padding:14px 18px;margin:calc(var(--step)*3) 0;font-size:14.5px;color:var(--ink-2);max-width:var(--measure)}
@media (max-width:760px){ .facts{grid-template-columns:1fr} .facts div+div{border-left:0;border-top:1px solid var(--line)} }

/* ── тёмные блоки: кольцо фокуса светлое ─────────────── */
.on-dark,.hero,footer.dark{--focus-color:#E0B84C}

/* ── печать: документы Академии печатают ──────────────── */
@media print{
  .eah-soc-blok{display:none}
  .eah-footer__soc{display:none}
  body{background:#fff;color:#000;font-size:11pt}
  /* .limit печатаем: это не декор, а сведения о том, чего программа не даёт. */
  .eah nav,.btn,.eah form,.no-print{display:none !important}
  .limit{background:transparent;color:#000;border:1pt solid #000;padding:8pt}
  .eah a{color:#000;text-decoration:none}
  .eah a[href^="http"]:after{content:" (" attr(href) ")";font-size:9pt;color:#444}
  .eah h2,.eah h3{page-break-after:avoid}
  .eah table,.eah figure{page-break-inside:avoid}
}
@media (max-width:900px){
 .eah-hero__grid{grid-template-columns:1fr;gap:34px}
 .eah-footer .mod-custom{grid-template-columns:1fr;gap:24px}
 .eah-nav,.eah-tel{display:none}
 .eah-header__row{height:64px;gap:14px}
 .eah-hero{padding:52px 0 56px}
}

/* Герой внутренней страницы приходит из раскладки статьи, то есть изнутри
   колонки содержимого. Отрицательные поля выносят его на всю ширину окна, а
   padding возвращает внутренности на сетку .eah-shell (1180/2 − 28 = 562).
   overflow-x:clip на html, а не на body: он гасит перелив от 100vw при видимой
   полосе прокрутки и при этом не ломает position:sticky у шапки. */
html{overflow-x:clip}
/* Страница витрины начинается героем встык с шапкой, поэтому снимается
   верхний отступ .eah-main — у остальных видов он остаётся. */
.eah-vitrina{margin-top:-30px}
.eah-vitrina__hero{margin-inline:calc(50% - 50vw);padding:72px max(28px,calc(50vw - 562px)) 78px;background:var(--accent);color:#fff}
.eah-vitrina__hero .eah-vitrina__title{color:#fff;max-width:16ch;font-size:clamp(34px,4.6vw,52px);line-height:1.08;margin:0 0 20px}
.eah-vitrina__hero .eah-hero__lede{font-size:18.5px;line-height:1.55;color:rgba(255,255,255,.86);max-width:34em;margin:0 0 30px}
.eah-vitrina__hero .eah-hero__lede p{margin:0}
.eah-vitrina__hero .eah-nabor{color:rgba(255,255,255,.82)}
.eah-vitrina__body{padding-top:34px}
/* Герой тёмный: главная кнопка становится белой, второстепенная — контурной. */
.eah-vitrina__hero .btn-primary{background:#fff;color:var(--accent);border-color:#fff}
.eah-vitrina__hero .btn-primary:hover{background:var(--inset);color:var(--accent-strong)}
.btn-ghost{border:1px solid rgba(255,255,255,.55);color:#fff;background:transparent}
.btn-ghost:hover{border-color:#fff;color:#fff}
@media (max-width:900px){ .eah-vitrina__hero{padding-top:44px;padding-bottom:48px} }

@media (max-width:560px){
  /* На узком экране название переносится, а кнопка из шапки убирается: в герое
     свой призыв, а вторая строка шапки налезала на героя. */
  .eah-logo__text{white-space:normal;font-size:16px}
  .eah-header__aside .btn{display:none}
}

/* ── формы RSForm ─────────────────────────────────────────
   RSForm выводит собственную разметку и о классе .field не знает, поэтому его
   классы приводятся к дизайн-системе здесь. Правила намеренно узкие: только те
   селекторы, которые компонент реально ставит. */
.eah .rsform-block{margin-bottom:calc(var(--step)*2.5);max-width:var(--measure)}
/* .formResponsive обязателен: у RSForm селектор той же силы, а его файл
   подключается позже нашего, поэтому без него побеждает он. */
.eah .formResponsive .formHorizontal .formControlLabel{display:block;float:none;width:auto;text-align:left;font-size:var(--t-small);color:var(--ink-2);margin-bottom:6px}
.eah .formResponsive .formHorizontal .formControls{margin-left:0;width:auto}
/* Селектор поднят до (0,3,1) намеренно. RSForm красит поля собственным
   .formResponsive input[type="text"] — это (0,2,1), и его responsive.min.css
   подключается позже нашего файла, поэтому прежнее .eah .rsform-input-box
   (0,2,0) проигрывало: поля оставались бутстраповскими — рамка #ccc,
   шрифт 13 px, отступ 4 px, height 18 px, ширина 210 px. Textarea при этом
   выглядела правильно, её RSForm красит более слабым селектором — из-за
   этого поля и текстовая область на одной форме различались. Здесь же
   гасятся остатки Bootstrap 2: фиксированная высота, content-box,
   внутренняя тень и собственный отступ снизу. */
.eah .formResponsive .formHorizontal input.rsform-input-box,
.eah .formResponsive .formHorizontal textarea.rsform-text-box,
.eah .formResponsive .formHorizontal select.rsform-select-box{
  display:block;width:100%;height:auto;box-sizing:border-box;box-shadow:none;margin:0;
  font:400 16px/1.4 var(--font-text);color:var(--ink);
  background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);
  padding:11px 13px;transition:border-color var(--transition);
}
.eah .formResponsive .formHorizontal textarea.rsform-text-box{min-height:132px;resize:vertical}
.eah .rsform-input-box:hover,.eah .rsform-text-box:hover,.eah .rsform-select-box:hover{border-color:var(--ink-3)}
.eah .rsform-input-box:focus-visible,.eah .rsform-text-box:focus-visible,.eah .rsform-select-box:focus-visible{border-color:var(--accent);outline:var(--focus);outline-offset:1px}
.eah .rsform-block-consent .formBody,.eah .rsform-type-checkboxgroup .formBody{display:flex;gap:10px;align-items:flex-start;font-size:var(--t-small);color:var(--ink-2)}
/* Флажок согласия лежит внутри fieldset > label, поэтому flex на .formBody
   до него не достаёт: выравнивать надо саму подпись. Размер задаётся с тем же
   весом, что и остальные поля, — правило RSForm на .formResponsive сильнее
   одноклассового, и прежние 16 px не применялись, флажок оставался 13 px. */
.eah .rsform .rsfp-fieldset{border:0;margin:0;padding:0;min-width:0}
/* Подпись остаётся обычной строкой: flex здесь делал каждое слово и ссылку
   отдельным элементом и растаскивал их зазором. Выравнивается только флажок. */
.eah .rsform-type-checkboxgroup .rsfp-fieldset label{
  display:block;margin:0;font-size:var(--t-small);line-height:var(--lh-small);color:var(--ink-2);
}
.eah .formResponsive .formHorizontal input.rsform-checkbox{
  width:16px;height:16px;margin:0 8px 0 0;vertical-align:-3px;accent-color:var(--accent);
}
/* Кнопку RSForm красит собственное правило .formResponsive button[type=submit]
   с силой выше нашей, поэтому селектор здесь такой же точный. Ещё у него
   градиент и тень текста из Bootstrap 2 — их надо гасить явно. */
.eah .formResponsive button[type=submit],
.eah .formResponsive input[type=submit]{
  font:700 15px/1 var(--font-text);background:var(--accent);background-image:none;
  color:#fff;text-shadow:none;border:1px solid transparent;
  border-radius:var(--radius);padding:14px 24px;cursor:pointer;
}
.eah .formResponsive button[type=submit]:hover,
.eah .formResponsive input[type=submit]:hover{background:var(--accent-strong);background-image:none}
.eah .formNoError{display:none}
.eah .formError{font-size:var(--t-small);line-height:1.45;color:var(--err);margin-top:6px;display:block}
/* Оболочка ошибки инлайновая, и даже со скрытым содержимым она создаёт после
   каждого поля пустую строку в высоту line-height родителя — около 28 px.
   Это и есть провалы между полями формы. Строку обнуляем; видимая ошибка
   возвращает свою собственную правилом выше. */
.eah .formResponsive .formHorizontal .formValidation{display:block;line-height:0}

/* Капча Aimy Captcha-Less невидима по устройству: свои поля она прячет
   собственным правилом display:none !important, и они продолжают отправляться.
   Место занимает пустая оболочка RSForm — блок, его отступы и пустая подпись
   (у неё нет id, поэтому правило плагина её не закрывает). Убираем только
   оболочку: сами поля и проверку ошибки не трогаем. */
/* Оболочка не скрывается целиком намеренно: у капчи может появиться видимая
   ошибка, а display:none на родителе её спрячет. Схлопываем отступы и прячем
   только заведомо пустые части; ловушки плагин прячет сам. */
.eah .formResponsive .formHorizontal .rsform-block-captcha{margin:0;padding:0;line-height:0}
.eah .formResponsive .formHorizontal .rsform-block-captcha > .formControlLabel,
.eah .rsform-block-captcha .formDescription{display:none}
.eah .rsform-block-captcha .formError{display:block;line-height:1.45;font-size:var(--t-small)}
.eah .formResponsive .formHorizontal .rsform-block-agreement > .formControlLabel,
.eah .formResponsive .formHorizontal .rsform-block-submit > .formControlLabel{display:none}   /* подписи здесь нет и не должно быть: у согласия подпись — текст рядом с флажком, у кнопки — её надпись. RSForm печатает пустой span на 5 px; скрываем по типу блока, а не по :empty — тот не ловит подпись из одних пробелов */
/* Пустые подписи и описания RSForm печатает всегда — они дают лишние
   десятки пикселей в каждом поле. */
.eah .formDescription:empty,.eah .formControlLabel:empty{display:none}

/* ── меню на узком экране ──────────────────────────────
   Флажок вместо скрипта: JS в шапке не нужен, а без раскрытия навигации на
   телефоне нет совсем. Сам флажок не hidden, чтобы оставался в порядке обхода
   с клавиатуры. */
/* На широком экране флажок скрыт полностью: иначе Tab попадал на невидимый
   переключатель, у которого и метка display:none, — остановка фокуса без
   всякого признака на экране. Фокусируемым он становится только там, где
   действительно управляет меню. */
.eah-nav__flazhok{display:none}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.eah-nav__knopka{display:none;font-size:22px;line-height:1;padding:8px 10px;margin-left:auto;cursor:pointer;color:var(--ink);border:1px solid var(--line);border-radius:var(--radius)}
.eah-nav__flazhok:focus-visible + .eah-nav__knopka{outline:var(--focus);outline-offset:2px}
@media (max-width:900px){
  .eah-nav__knopka{display:inline-block}
  .eah-nav__flazhok{display:block;position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
  .eah-nav{display:none;position:absolute;left:0;right:0;top:100%;margin-left:0;z-index:5;background:var(--card);border-bottom:1px solid var(--line);box-shadow:0 8px 24px rgba(20,24,29,.08);padding:8px 28px 16px}
  .eah-nav__flazhok:checked ~ .eah-nav{display:block}
  .eah-nav ul{flex-direction:column;gap:0}
  .eah-nav a{padding:12px 0;border-bottom:1px solid var(--line);border-left:2px solid transparent}
  .eah-nav a:hover,.eah-nav .current > a{border-bottom-color:var(--line);border-left-color:var(--accent);padding-left:10px}
  /* Панель отсчитывается от самой шапки — она уже sticky, то есть
     позиционирована. От строки нельзя: у строки своё внутреннее поле, и панель
     уезжала бы на его ширину. */
  .eah-nav__knopka{margin-left:auto}
  .eah-header__aside{margin-left:0}
}

/* Промокод — то, что человек копирует руками, поэтому он выделен рамкой и
   фоном: моноширинным шрифтом одного размера с текстом он читался как обычное
   слово и терялся во фразе. */
.kod{display:inline-block;font:700 15px/1 var(--font-mono);letter-spacing:.06em;color:var(--accent);background:var(--card);border:1px dashed var(--line-strong);border-radius:var(--radius);padding:5px 9px;margin:0 2px;user-select:all}

/* Вход для студентов. Держится в шапке и на узком экране: студенту он нужнее,
   чем меню, а меню там прячется под кнопку. */
.eah-vhod{font-size:14.5px;color:var(--ink-2);text-decoration:none;white-space:nowrap;padding:6px 0;border-bottom:2px solid transparent}
.eah-vhod:hover{color:var(--accent);border-bottom-color:var(--accent)}
@media (max-width:560px){ .eah-vhod{font-size:14px} }

@media (max-width:560px){
  /* На узком экране локап занимает всю строку, а кнопка меню и вход встают под
     ним: при фиксированной высоте они наезжали на герой. */
  .eah-header__row{flex-wrap:wrap;height:auto;min-height:0;padding:10px 28px;row-gap:6px}
  .eah-logo{flex:1 1 100%}
  .eah-nav__knopka{margin-left:0}
  .eah-header__aside{margin-left:auto}
}

/* ── страницы LMS (com_guru) ───────────────────────────────────────────
   Компонент приносит собственное оформление на UIkit: зелёная кнопка, синие
   вкладки, свои отступы. Переопределять его шаблон копией не стали — файл на
   семьсот строк разошёлся бы с компонентом при первом обновлении. Правила
   ниже узкие: только те классы, которые com_guru реально ставит. */

.eah .gru-course-detail{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:24px 26px;margin-bottom:calc(var(--step)*4)}
.eah .gru-course-title,.eah .gru-course-title h1,.eah .gru-course-title h2{font-family:var(--font-display);font-size:var(--t-h2);line-height:var(--lh-h2);color:var(--ink);margin:0 0 16px}
.eah .gru-course-media img{max-width:100%;height:auto;max-height:260px;object-fit:cover;border-radius:var(--radius);display:block}

/* Подписи в шапке курса — преподаватель, стоимость, документ. */
.eah .gru-course-info .uk-text-bold,.eah .gru-course-info .wk-text-bold{font:400 11.5px/1.4 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);display:block;margin-bottom:2px}

/* Кнопка записи. Селектор с #guru-component обязателен: компонент красит её
   правилом `#guru-component .uk-button-success`, а идентификатор сильнее любого
   набора классов — без него наше правило проигрывало. */
.eah #guru-component .uk-button-success,
.eah #guru-component .wk-button-success,
.eah #guru-component .gru-cover-purchase-btn .uk-button,
.eah .gru-cover-purchase-btn .uk-button,
.eah .gru-cover-purchase-btn .wk-button{
  background:var(--accent);background-image:none;color:#fff;text-shadow:none;
  border:1px solid transparent;border-radius:var(--radius);
  font:700 15px/1 var(--font-text);padding:14px 24px;box-shadow:none
}
.eah #guru-component .uk-button-success:hover,
.eah #guru-component .wk-button-success:hover,
.eah .gru-cover-purchase-btn .uk-button:hover{background:var(--accent-strong);background-image:none;color:#fff}

/* Полоса вкладок. */
.eah .guru-course-view ul.uk-tab{display:flex;flex-wrap:wrap;gap:0;margin:0 0 calc(var(--step)*3);padding:0;border-bottom:1px solid var(--line);list-style:none;background:none}
.eah .guru-course-view ul.uk-tab li{width:auto;margin:0;border:0;background:none}
.eah .guru-course-view ul.uk-tab li a{display:block;padding:12px 18px;font:400 13px/1.3 var(--font-text);color:var(--ink-2);text-decoration:none;border:0;border-bottom:2px solid transparent;background:none}
.eah .guru-course-view ul.uk-tab li a:hover{color:var(--accent);border-bottom-color:var(--line-strong)}
.eah .guru-course-view ul.uk-tab li.uk-active a,
.eah .guru-course-view ul.uk-tab li.wk-active a{color:var(--accent);border-bottom-color:var(--accent);font-weight:700;background:none}
.eah .guru-course-view ul.uk-tab li a i{display:none}

/* Список модулей и уроков. */
.eah .guru-tabs{border:1px solid var(--line);border-radius:var(--radius);margin-bottom:12px;background:var(--card)}
.eah .guru-tab-title{padding:14px 18px;font-weight:700;color:var(--ink);border-bottom:1px solid var(--line)}
.eah .guru-tab-title .day{cursor:pointer}

@media (max-width:760px){
  .eah .gru-course-detail{padding:18px 16px}
  .eah .guru-course-view ul.uk-tab li a{padding:10px 12px;font-size:12.5px}
}

/* Список курсов в категории. Селекторы с #guru-component там же, где компонент
   красит элемент правилом с идентификатором. Рамка — только у панели: ячейка
   сетки .gru-course-item шире её на поле сетки, и вторая рамка вокруг неё
   вылезала влево за колонку (23.09). */
.eah #guru-component .uk-panel-box:not(.gru-login-box):not(.gru-register-box){background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:0 0 18px;overflow:hidden}
/* Панель компонента красится его же `#guru-component .uk-panel-box{color:#444}`. */
.eah #guru-component .uk-panel-box{color:var(--ink)}
.eah .gru-course-item .uk-panel-title,
.eah .gru-course-item h3{font-family:var(--font-display);font-size:var(--t-h3);line-height:var(--lh-h3);margin:14px 18px 8px}
.eah .gru-course-item .uk-panel-title a,
.eah .gru-course-item h3 a{color:var(--accent);text-decoration:none}
.eah .gru-course-item .uk-panel-title a:hover,
.eah .gru-course-item h3 a:hover{text-decoration:underline;text-underline-offset:3px}
.eah .gru-course-cover img,.eah .gru-panel-teaser img{width:100%;height:auto;max-height:180px;object-fit:cover;display:block}
/* Каталог направлений (/courses-category/gurupcategs): карточка категории.
   У Guru там заголовок и кнопка без полей, оранжевая плашка числа курсов и тень —
   всё чужое витрине. Приводим к карточке курса выше (23.09). */
.eah #guru-component .gru-cat-item .uk-panel-box,
.eah #guru-component .gru-course-item .uk-panel-box{box-shadow:none}
.eah .gru-cat-item .uk-panel-title{font-family:var(--font-display);font-size:var(--t-h3);line-height:var(--lh-h3);margin:14px 18px 12px}
.eah .gru-cat-item .uk-panel-title a{color:var(--accent);text-decoration:none}
.eah .gru-cat-item .uk-panel-title a:hover{text-decoration:underline;text-underline-offset:3px}
.eah .gru-cat-item .description_guru:empty{display:none}
.eah .gru-cat-item .gru-readmore{margin:0 18px}
.eah #guru-component .gru-cat-item .uk-panel-badge{background:var(--card);color:var(--ink-2);font:400 11.5px/1.4 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;border:1px solid var(--line);border-radius:var(--radius);box-shadow:none;text-shadow:none;padding:3px 8px}
.eah .gru-course-item p{margin:0 18px 12px;font-size:14.5px;color:var(--ink-2)}
.eah .gru-author-list{margin:0 18px 10px;font:400 11.5px/1.4 var(--font-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.eah .gru-author-list a{color:var(--ink-3);text-decoration:none}
.eah .gru-author-list img,.eah .gru-author-list .guru-author-img{display:none}
.eah .gru-course-item .gru-readmore{margin:0 18px}
.eah .gru-course-item .gru-course-meta ul{margin:0;padding:12px 18px 0;list-style:none}
/* Заголовок страницы категории Guru кладёт в панель — без описания это пустая
   рамка вокруг h1. Вес не меньше общего правила панели выше. */
.eah #guru-component .gru-cat.uk-panel-box.wk-panel-box{background:none;border:0;border-radius:0;padding:0;margin:0}

/* Цена — ярлык поверх обложки; у компонента он зелёный. */
.eah #guru-component .uk-badge-success,
.eah #guru-component .wk-badge-success,
.eah .gru-course-item .uk-badge{background:var(--accent);color:#fff;border-radius:var(--radius);font:700 13px/1 var(--font-mono);letter-spacing:.02em;padding:8px 10px;box-shadow:none}

/* Кнопки списка: «Поиск» и «Подробнее». */
/* Селектор `.uk-form .uk-button` обязателен отдельно: правило компонента
   `div#guru-component .uk-form .uk-button` весит (1,2,1) и перебивает вариант
   без формы. Оно же задаёт высоту через line-height в 40px — вместе с полями
   кнопка «Войти» выходила 64 пикселя. Высоту собираем из полей, как у .btn. */
.eah #guru-component .uk-button,
.eah #guru-component .wk-button,
.eah #guru-component .uk-form .uk-button{background:var(--accent);background-image:none;color:#fff;text-shadow:none;border:1px solid transparent;border-radius:var(--radius);font:700 14px/1.15 var(--font-text);padding:12px 20px;min-height:0;box-shadow:none}
.eah #guru-component .uk-button:hover,
.eah #guru-component .wk-button:hover,
.eah #guru-component .uk-form .uk-button:hover{background:var(--accent-strong);color:#fff}
.eah #guru-component input[type="text"],
.eah #guru-component input[type="search"]{font:400 15px/1.4 var(--font-text);color:var(--ink);background:var(--card);border:1px solid var(--line-strong);border-radius:var(--radius);padding:10px 12px}

/* Якорь секции не должен уезжать под липкую шапку: её ряд 74px плюс поля.
   То же у заголовка с якорем внутри текста статьи — «Смотреть запись». */
.eah-section,.eah h2[id]{scroll-margin-top:7rem}
/* Полоса уже отбита сверху своими 64 px. Собственный отступ заголовка (40 px
   у `.eah h2`) добавлялся к ним и давал 104 px до первой строки — во всех
   полосах витрины разом. Первому заголовку полосы он не нужен. */
.eah-section h2:first-child{margin-top:0}
/* Полоса заявки без собственного заголовка — продолжение того, что стоит над
   ней: заголовок остаётся в теле статьи, а в полосе только поля. Фон у полосы
   тот же, что у страницы, поэтому её отбивка в 64 px читается не разделением,
   а дырой между заголовком и его же формой. Там, где у полосы заголовок есть
   (страницы программ), отбивка нужна и остаётся. */
#eah-zayavka:not(:has(h2)){padding-top:calc(var(--step)*3)}
/* aspect-ratio держит место до загрузки постера: у ролика с preload="none"
   размеров сразу нет, и без него страница дёргается при подгрузке. */
/* Ширина по полосе текста, а не по всей раскладке: без ограничения ролик
   растягивался на 1124 px против 729 px у абзацев рядом и выпадал из ритма
   страницы. Подпись ограничена тем же пределом, поэтому края совпадают. */
.eah figure video{display:block;width:100%;max-width:var(--measure);height:auto;aspect-ratio:16/9;border-radius:var(--radius);background:#000}
/* Под видео подпись — это описание в несколько строк, а не короткий ярлык к
   картинке: по центру такой абзац читается рвано. */
.eah figure video + figcaption{text-align:left}

/* ── вход в кабинет (com_guru 6.3) ─────────────────────────────────────
   У версии 6.3 своя система токенов: guru.css объявляет в :root переменные
   `--gru-*`, и его собственные правила ссылаются только на них. Поэтому здесь
   переопределяются ТОКЕНЫ, а не каждое правило по отдельности — состояния,
   мобильные раскладки и вариант справа-налево продолжают работать сами.
   Ниже токенов — только то, что токенами не выражается.
   Проверено на странице входа; кабинет после входа не проверялся. */
.eah #guru-component{
  --gru-primary:var(--accent);
  --gru-danger:var(--err);
  --gru-success:var(--ok);
  --gru-border-color:var(--line);
  --gru-text-black:var(--ink);
  --gru-link:var(--accent);
  --gru-link-hover:var(--accent-strong);
  --gru-link-title:var(--accent);
  --gru-link-title-hover:var(--accent-strong);
  --gru-panel-box-bg:var(--card);
  --gru-border-radius:var(--radius);
  --gru-border-radius-sm:var(--radius);
  --gru-border-radius-lg:var(--radius-lg);
  --gru-input-border-radius:var(--radius);
  --gru-input-height:46px;          /* 16px/1.4 плюс 11px сверху и снизу — поле .field */
  --gru-input-padding-x:13px;
  color:var(--ink);
}

/* Панели «уже есть аккаунт» и «нет аккаунта». Боковые поля были нулевыми:
   правило карточки списка курсов обнуляет их под обложку во всю ширину, и
   текст с полями упирался в рамку. Панели исключены из того правила выше. */
.eah #guru-component .gru-login-box,
.eah #guru-component .gru-register-box{background:var(--card);color:var(--ink);border:1px solid var(--line);border-radius:var(--radius);padding:22px 24px 24px;min-height:0;box-shadow:none}
/* Компонент помечает панель регистрации как `-primary` и красит её в свой
   голубой с синим текстом. Различение панелей сохраняем, цвет берём свой. */
.eah #guru-component .uk-panel-box-primary{background:var(--inset);color:var(--ink)}
.eah #guru-component .gru-login .uk-panel-title{font-family:var(--font-display);font-size:var(--t-h3);line-height:var(--lh-h3);font-weight:700;color:var(--ink);border-bottom:1px solid var(--line);padding-bottom:12px;margin:0 0 20px}

/* Поля приводятся к полю дизайн-системы. Токен `--gru-border-color` оставлен
   на `--line`, потому что он же красит рамки панелей, где нужна тонкая линия,
   а полю нужен контраст 3:1 — отсюда отдельное правило с `--line-strong`. */
.eah #guru-component .uk-form :is(input[type="text"],input[type="password"],input[type="email"],input[type="tel"],input[type="search"],select,textarea){font:400 16px/1.4 var(--font-text);color:var(--ink);background:var(--card);border:1px solid var(--line-strong)}
.eah #guru-component .uk-form :is(input,select,textarea):hover{border-color:var(--ink-3)}
/* Кольцо фокуса компонент гасит правилом `.uk-form input:focus{outline:0}`,
   которое сильнее глобального `:focus-visible`. Возвращаем его. */
.eah #guru-component .uk-form :is(input,select,textarea):focus-visible{border-color:var(--accent);outline:var(--focus);outline-offset:1px}
/* Показ пароля. Компонент считает кнопку с глазком частью поля, но рамку ей
   рисует своим цветом и скругляет правый край поля жёсткими 6 пикселями —
   глазок отрывался от поля. Собираем обратно в один элемент управления. */
.eah #guru-component .gru-login-box .input-group .input-group-addon{display:flex;align-items:center;padding:0 12px;border:1px solid var(--line-strong);border-left:0;border-radius:0 var(--radius) var(--radius) 0;background:var(--card);color:var(--ink-3)}
.eah #guru-component .gru-login-box .gru-psw-row .uk-form-controls.input-group input{border-top-right-radius:0;border-bottom-right-radius:0}

/* Подпись поля — мелкая и вторичная, как в `.field`; звёздочка обязательности
   тем же цветом, что и `.field .req`. */
.eah #guru-component .uk-form-label{font-size:var(--t-small);line-height:var(--lh-small);color:var(--ink-2);margin:0 0 6px}
/* Звёздочка обязательности. `!important` — не украшение: утилиты UIkit
   объявлены с ним, без него правило не срабатывает. Селектор сужен до подписи
   поля намеренно: тем же классом компонент помечает и текст ошибок, а ошибка
   не должна стать коричневой. */
.eah #guru-component .uk-form-label .uk-text-danger,
.eah #guru-component .uk-form-label .wk-text-danger{color:var(--status)!important}

/* «Забыли логин» и «Забыли пароль» компонент расталкивает по краям панели
   через justify-content:space-between — на широкой панели они оказываются в
   разных её концах. Ставим рядом. */
.eah #guru-component .gru-login-box .uk-list{justify-content:flex-start;gap:22px;font-size:var(--t-small);margin:0}
/* «Запомнить меня» — по образцу `.consent`. */
.eah #guru-component .gru-login-box label[for="guru-view-login-remember"]{display:flex;align-items:center;gap:6px;font-size:var(--t-small);color:var(--ink-2);margin:0}
.eah #guru-component .gru-login-box input[type="checkbox"]{width:16px;height:16px;margin:0;flex:none;accent-color:var(--accent)}

/* ── окно урока и прогресс кабинета ────────────────────────────────────
   Заголовок урока компонент печатает в одну строку с `overflow:visible`
   (custom.css, от 992px), поэтому длинное название уезжало под список
   уроков справа и обрывалось на полуслове. Даём ему ужиматься в своей
   колонке: `min-width:0` на гибком родителе — обязателен, иначе элемент
   не сжимается ниже длины содержимого. Полное название всё равно видно
   в списке уроков. Заодно кегль сводится к заголовку сайта: у компонента
   32px против 25px у h2. */
.eah .guru-lesson-header-l{min-width:0}
.eah .guru-lesson-header-label{overflow:hidden;text-overflow:ellipsis;font-family:var(--font-display);font-size:var(--t-h2);line-height:var(--lh-h2);color:var(--ink)}

/* Полоса прохождения курса у компонента бирюзовая (#009DD8). */
.eah #guru-component .uk-progress-bar,
.eah #guru-component .wk-progress-bar{background:var(--accent)}

/* ── вкладка «Модули/Уроки» до появления уроков ────────────────────────
   07.09 у программ профлинейки появились модули из учебных планов, а
   уроков у них ещё нет: учебные планы задают модуль и список тем, но не
   поурочный состав. Компонент этого случая не различает и печатает шапку
   таблицы уроков — «Тест/задание статус», «Просмотрен», «Уровень
   сложности» — над списком, в котором ни одного урока, плюс кнопки
   «Показать все» и «Скрыть все», которым нечего раскрывать.
   Признак пустоты структурный: блок уроков `.lessons_wrap` компонент
   выводит только при наличии уроков. Появятся уроки — правило перестанет
   применяться само, править ничего не придётся. */
.eah #tab1:not(:has(.lessons_wrap)) .table-of-contents .uk-hidden-small,
.eah #tab1:not(:has(.lessons_wrap)) .show_sub,
.eah #tab1:not(:has(.lessons_wrap)) .close_sub{display:none}
/* Стрелку раскрытия и курсор-палец компонент печатает у каждого модуля
   безусловно, поэтому заголовок выглядит нажимаемым, а нажатие ничего не
   делает. Убираем обещание вместе с шапкой. */
.eah #tab1:not(:has(.lessons_wrap)) .day{cursor:default}
.eah #tab1:not(:has(.lessons_wrap)) .day img{display:none}

/* ── строка урока: уровень сложности ──────────────────────────────────
   Уровень сложности урокам профлинейки не задан намеренно: учебные планы
   такого признака не вводят, а придумать его значит объявить программе
   свойство, которого в документах нет. Компонент этого случая не
   различает и печатает картинку с пустым именем файла — по битой иконке
   в каждой из 128 строк. Прячем саму картинку и заголовок колонки,
   которая под ним всегда пуста. Признак точный: путь оканчивается на
   каталог, потому что имени файла нет. */
.eah #tab1 img[src$="com_guru/images/"]{display:none}
.eah #tab1:not(:has(img[src$="_level.png"])) .table-of-contents .uk-hidden-small .col_title:nth-child(3){visibility:hidden}
