/* ══════════════════════════════════════════════════════════
   AGENT SUMMIT — общие стили прототипа
   ══════════════════════════════════════════════════════════ */

/* ══════════════ ШРИФТЫ ══════════════
   Брендовый Proxima Nova лицензируется через Adobe Fonts и в прототип вшит
   быть не может. Стек ниже пробует его первым: на проде, где кит Adobe
   подключён, страница возьмёт настоящий брендовый шрифт, а здесь молча
   уйдёт на Nunito Sans — ближайшую свободную замену с тем же геометрико-
   гуманистическим скелетом и высоким ростом строчных.
   Кириллические сабсеты убраны вместе с русской версией: интерфейс английский,
   грузить их не за чем. Файлы лежат в legacy/fonts-cyrillic — если русская
   версия вернётся, их и три правила @font-face надо будет вернуть тоже.
   Файлы локальные: без CDN и без единого внешнего запроса.            */
@font-face{
  font-family:'Nunito Sans'; font-style:normal; font-weight:300 900; font-display:swap;
  src:url('fonts/nunito-latin-300-900.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,
    U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/* ══════════════════════════════════════════════════════════
   TOKENS
   Палитра выведена из логотипа: тёмно-зелёная вершина (#0B4F2C)
   и изумрудная грань (#2E9E5B). Бирюза/розовый/бордо из текущей
   темы Squarespace не используются — см. ТЗ §2.4.
   Латунь (--brass) зарезервирована ИСКЛЮЧИТЕЛЬНО под дедлайн цены.
   ══════════════════════════════════════════════════════════ */
:root{
  /* brand-surface = сплошная зелёная заливка; accent-text = зелёный ДЛЯ ТЕКСТА
     (разделены: один и тот же зелёный не может пройти AA и как фон, и как текст);
     on-brand = текст поверх brand-surface. */
  --brand-surface:#0B4F2C; --accent-text:#1E7442; --on-brand:#F1F8F3;
  --emerald:#2E9E5B; --brass:#A8762F;
  --bg:#F1F3EE; --surface:#FFFFFF; --surface-2:#E9ECE5;
  --text:#0D1410; --text-2:#535E56; --text-3:#5C6860;
  --rule:#D8DDD4; --rule-2:#C2C9BE;
  /* wash — четвёртая поверхность: акцентная секция, которая раньше была
     тёмной полосой. Зелёный подмешан ровно настолько, чтобы отличаться
     от --bg и от --surface-2, но не спорить с фирменной заливкой. */
  --wash:#E7EFE8; --wash-rule:#D0DCD3;
  --band-bg:#07130C; --band-surface:#0F1E14; --band-text:#EAF0EB;
  --band-text-2:#93A398; --band-rule:#1E3325; --band-accent:#5FCE8B;

  /* ── ЦВЕТА ТРЕКОВ ──
     Одна и та же метка живёт и на светлой полосе программы, и (в тёмной
     теме) на тёмной. Поэтому это токены, а не хексы по месту: в :root они
     набраны для светлого фона, в тёмных блоках — осветлены. Точка фильтра,
     полоса слева у слота и чип .trk обязаны брать один и тот же токен,
     иначе фильтр перестаёт читаться как тот же язык, что и расписание. */
  --trk-main:#1B7040; --trk-reins:#1C6699; --trk-start:#6B45A0;
  --trk-ae:#8A5A16;   --trk-brk:#5C6860;
  /* EFI — четвёртый трек программы 2027: приехал из кабинета Cvent на место
     AE eXchange, которого в источнике больше нет. Свой цвет, а не чужой
     янтарь: вернётся AE — метки не сольются. */
  --trk-efi:#A5442E;
  /* Моноширинного шрифта на сайте больше нет: надзаголовки, метки, время и
     счётчики набирались IBM Plex Mono, и владелец попросил его убрать. Токен
     остался как ЕДИНАЯ точка для «служебного» начертания — тот же Nunito Sans,
     но с разрядкой и капителью, — чтобы не переписывать сорок с лишним
     правил и чтобы следующая замена снова была однострочной.
     Там, где цифры обязаны стоять в колонку (время в агенде, отсчёт до
     дедлайна, цены в таблице), включён font-variant-numeric:tabular-nums:
     моноширинность нужна была именно для этого, а не ради вида. */
  --label:var(--sans);
  --sans:'proxima-nova','Nunito Sans',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --maxw:1280px;
  /* Высота шапки. Точное значение ставит скрипт (зависит от кегля
     подгруженного шрифта); здесь запас на случай без JS. */
  --chrome:77px;

  /* ── РАДИУСЫ ──
     Скругление получают только приподнятые, интерактивные и медийные объекты.
     Хайрлайн-мозаики (.logos, .factlist, .steps, .gal, .opps, .acc) остаются
     прямоугольными: сетка из ячеек с зазором в 1px на скруглённых углах рвётся. */
  --r-xs:3px; --r-sm:5px; --r-md:8px; --r-lg:12px; --r-pill:999px;

  /* ── ВЫСОТА ──
     В светлой теме работает тень. В тёмной она не видна на #111811, поэтому
     к ней добавляется светлая линия сверху — так же, как это делает физика. */
  --e-1:0 1px 2px rgba(13,20,16,.05), 0 1px 3px -1px rgba(13,20,16,.09);
  --e-2:0 2px 4px rgba(13,20,16,.05), 0 10px 22px -14px rgba(13,20,16,.30);
  --e-3:0 4px 8px rgba(13,20,16,.06), 0 24px 52px -26px rgba(13,20,16,.42);
  --e-hover:0 3px 6px rgba(13,20,16,.06), 0 18px 36px -20px rgba(13,20,16,.38);
  --shadow:var(--e-2);   /* прежнее имя: не удалено, чтобы не ломать чужие правки */

  /* ── РИТМ ── */
  --sp-1:8px;  --sp-2:14px; --sp-3:22px; --sp-4:34px;
  --sp-5:52px; --sp-6:76px; --sp-7:104px; --sp-8:140px;
  --sec:clamp(56px,7.2vw,96px);        /* обычная секция */
  --sec-lead:clamp(72px,9vw,132px);    /* первая содержательная секция страницы */
  --sec-tight:clamp(36px,4.4vw,56px);

  /* ── ФОТО ──
     Намеренно НЕ переопределяются в тёмной теме: все фото лежат внутри полосы
     --band-*, а она тёмная в обеих темах. Осветлять их вслед за --bg нечего. */
  --photo-tint:#0B4F2C;
  /* Основа всех затемняющих масок. Отдельным токеном, а не хексом по месту:
     затемнение встречается в маске героя, в шапках страниц, в фотополосах,
     у кнопки паузы и подложки лайтбокса — и вторая светлая тема («paper»)
     делает их тёплыми одной строкой. Плотности при этом остаются в самих
     правилах: за читаемость текста поверх фотографии отвечают именно они. */
  --scrim-rgb:4,11,7;
  /* Список правок 10.09, всесайтовый п. 2: фотографии в шапках и полосах —
     в полном цвете. Обесцвечивание держало страницы в одной фактуре, но
     заказчик продаёт атмосферу события, а не графику: серое фото читается как
     архив. Читаемость текста держит затемняющая маска (--scrim-*), она и
     рассчитана под это. */
  --photo-filter:saturate(1.02) contrast(1.04) brightness(.78);
  --photo-filter-soft:saturate(1.02) contrast(1.02) brightness(.66);
  --scrim-band:linear-gradient(180deg, rgba(var(--scrim-rgb),.90) 0%, rgba(var(--scrim-rgb),.70) 46%, rgba(var(--scrim-rgb),.96) 100%);
  --scrim-side:linear-gradient(96deg, rgba(var(--scrim-rgb),.96) 0%, rgba(var(--scrim-rgb),.90) 44%, rgba(var(--scrim-rgb),.58) 78%, rgba(var(--scrim-rgb),.80) 100%);

  /* ── ПОВЕРХ ФИРМЕННОЙ ЗАЛИВКИ ──
     Считается ОТ --on-brand, а не светлым цветом наглухо: в тёмной теме
     --brand-surface становится светло-зелёным, и белый текст на нём исчезает. */
  --brand-grad:linear-gradient(152deg, var(--brand-surface) 0%,
    color-mix(in srgb, var(--brand-surface) 76%, var(--emerald)) 100%);
  --on-brand-2:color-mix(in srgb, var(--on-brand) 82%, transparent);
  --on-brand-3:color-mix(in srgb, var(--on-brand) 56%, transparent);
  --hair-on-brand:color-mix(in srgb, var(--on-brand) 16%, transparent);

  /* ── ДВИЖЕНИЕ ── */
  --ease:cubic-bezier(.2,.6,.2,1); --dur-1:.16s; --dur-2:.28s; --dur-3:.5s;

  /* ── МАСКИ ──
     Те же контуры, что в спрайте, но для мест, где иконка повторяется
     десятками (буллиты перечислений, наведение на плитку галереи).
     Ставить туда <svg><use> значило бы плодить узлы ради значка. */
  --m-check:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4.6 12.6 4.9 4.8L19.4 6.6'/%3E%3C/svg%3E");
  --m-zoom:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='10.8' cy='10.8' r='6.6'/%3E%3Cpath d='m15.6 15.6 4.8 4.8M8.2 10.8h5.2M10.8 8.2v5.2'/%3E%3C/svg%3E");
}
/* Тёмная тема описана ДВАЖДЫ: по системной настройке и по атрибуту. Блоки —
   пара, их содержимое обязано совпадать дословно. Токен, дописанный только
   в один, даёт сайт, который верен при системной тёмной и сломан при ручном
   переключении (или наоборот). */
@media (prefers-color-scheme:dark){
  /* :not([data-theme]) — любое ЯВНОЕ значение темы отменяет системную.
     Раньше здесь стояло :not([data-theme="light"]), и добавление третьей
     светлой темы («paper») тихо накладывало бы на неё тёмные токены. */
  :root:not([data-theme]){
    --bg:#0A0F0B; --surface:#111811; --surface-2:#161E17;
    --text:#E8EDE8; --text-2:#9CA89E; --text-3:#828E85;
    --rule:#212A22; --rule-2:#334036;
    --wash:#0E1811; --wash-rule:#1F2C23;
    --band-bg:#040B07; --band-surface:#0D1710; --band-rule:#1C2C21;
    --brand-surface:#63CE91; --accent-text:#4FBF7F; --on-brand:#04140A;
    --emerald:#4FBF7F; --brass:#D2A05C;
    --trk-main:#5FCE8B; --trk-reins:#7FB7E8; --trk-start:#C79BE0;
    --trk-ae:#D9A45F;   --trk-brk:#93A398; --trk-efi:#E8927A;
    --e-1:0 1px 2px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.03);
    --e-2:0 2px 6px rgba(0,0,0,.60), inset 0 1px 0 rgba(255,255,255,.045);
    --e-3:0 10px 32px rgba(0,0,0,.72), inset 0 1px 0 rgba(255,255,255,.06);
    --e-hover:0 6px 18px rgba(0,0,0,.66), inset 0 1px 0 rgba(255,255,255,.07);
  }
}
:root[data-theme="dark"]{
  --bg:#0A0F0B; --surface:#111811; --surface-2:#161E17;
  --text:#E8EDE8; --text-2:#9CA89E; --text-3:#828E85;
  --rule:#212A22; --rule-2:#334036;
  --wash:#0E1811; --wash-rule:#1F2C23;
  --band-bg:#040B07; --band-surface:#0D1710; --band-rule:#1C2C21;
  --brand-surface:#63CE91; --accent-text:#4FBF7F; --on-brand:#04140A;
  --emerald:#4FBF7F; --brass:#D2A05C;
  --trk-main:#5FCE8B; --trk-reins:#7FB7E8; --trk-start:#C79BE0;
  --trk-ae:#D9A45F;   --trk-brk:#93A398; --trk-efi:#E8927A;
  --e-1:0 1px 2px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.03);
  --e-2:0 2px 6px rgba(0,0,0,.60), inset 0 1px 0 rgba(255,255,255,.045);
  --e-3:0 10px 32px rgba(0,0,0,.72), inset 0 1px 0 rgba(255,255,255,.06);
  --e-hover:0 6px 18px rgba(0,0,0,.66), inset 0 1px 0 rgba(255,255,255,.07);
}

/* ══════════════════════════════════════════════════════════
   ВТОРАЯ СВЕТЛАЯ ТЕМА — «PAPER»
   Тот же макет, другой материал: не белая бумага с холодным серым, а
   тёплый картон с латунными линейками и чернильным текстом. Зачем вторая:
   первая светлая — нейтральная и «цифровая», эта читается как печатная
   программа конференции, которой шестнадцать лет. Меняются ТОЛЬКО токены,
   ни одного правила вёрстки: если тема требует правки разметки, значит
   она не тема, а другой макет.
   Открывается по адресу ?theme=paper.
   ══════════════════════════════════════════════════════════ */
:root[data-theme="paper"]{
  --brand-surface:#0A4527; --accent-text:#1A6B3C; --on-brand:#FBF7EE;
  --emerald:#2B8F52; --brass:#8A6224;
  --bg:#F5F0E4; --surface:#FFFCF4; --surface-2:#EDE6D6;
  --text:#171410; --text-2:#544C40; --text-3:#5E5648;
  --rule:#E0D7C4; --rule-2:#C9BCA4;
  --wash:#ECE7D8; --wash-rule:#D7CDB7;
  --band-bg:#141009; --band-surface:#1F1810; --band-text:#F4EEE1;
  --band-text-2:#A0947F; --band-rule:#33291B; --band-accent:#6FD094;
  /* тени тёплые: серая тень на кремовом фоне выглядит грязным пятном */
  --e-1:0 1px 2px rgba(60,44,20,.06), 0 1px 3px -1px rgba(60,44,20,.10);
  --e-2:0 2px 4px rgba(60,44,20,.06), 0 10px 22px -14px rgba(60,44,20,.32);
  --e-3:0 4px 8px rgba(60,44,20,.07), 0 24px 52px -26px rgba(60,44,20,.44);
  --e-hover:0 3px 6px rgba(60,44,20,.07), 0 18px 36px -20px rgba(60,44,20,.40);
  /* Дуотон фотографий уходит из зелени в сепию — иначе тёплая рама и
     холодное фото спорят на каждом стыке. Вместе с тоном приподнята и
     яркость: при brightness .72 кадр сжат почти до чёрного, и подкрашивать
     там нечего — тон не виден ни в зелёном, ни в коричневом. Затемняющая
     маска (--scrim-*) не тронута: за читаемость текста поверх фотографии
     отвечает именно она, и трогать её ради оттенка нельзя. */
  --photo-tint:#4A3218;
  --photo-filter:sepia(.28) saturate(1.05) contrast(1.06) brightness(.9);
  --photo-filter-soft:sepia(.24) saturate(1.05) contrast(1.04) brightness(.76);
  /* Затемнение тоже тёплое — иначе вся затея с сепией бессмысленна: маска
     идёт поверх подкрашенного кадра с плотностью .70–.96, и её собственный
     зелёно-чёрный тон перебивал подкраску под собой (замеренный тон полосы
     оставался 145° при заданных 28°). Меняется ТОЛЬКО основа: плотности
     живут в правилах и отвечают за читаемость текста поверх фотографии. */
  --scrim-rgb:16,12,6;
}

/* ══════════════════════════════════════════════════════════
   СВЕТЛАЯ РАМА
   Тёмным на сайте остаётся только то, под чем лежит фотография:
   .hero, .phero, .photoband и лайтбокс. Всё остальное — шапка, баннер
   прототипа, мобильное меню, липкий бар, полосы .band, подписка, футер —
   светлое. Переопределяются не сами правила, а слой --band-*: полос,
   таблиц, чипов и кнопок, завязанных на эти токены, около восьмидесяти,
   и переписывать их поимённо значило бы завести вторую тему.
   Значения берутся из тем (--surface, --text, --rule), а не хексами:
   в тёмной теме та же рама автоматически становится тёмной.
   ══════════════════════════════════════════════════════════ */
header.site, #mobnav, #sticky, footer.site,
section.band:not(.photoband), .signup, .statband{
  --band-text:var(--text);
  --band-text-2:var(--text-2);
  --band-accent:var(--accent-text);
  /* латунь идёт по светлому фону только здесь (часы в липком баре и
     подсветка демо-данных); базовый #A8762F на #E9ECE5 не добирает до AA */
  --brass:#8A6224;
}
/* шапка и всё, что из неё выпадает */
header.site, #mobnav, #sticky{
  --band-bg:var(--surface); --band-surface:var(--surface-2); --band-rule:var(--rule);
}
/* служебная полоса по нижнему краю страницы */
footer.site{
  --band-bg:var(--surface-2); --band-surface:var(--surface-2); --band-rule:var(--rule-2);
}
/* акцентные секции: ячейки внутри них белые, поэтому --band-surface светлее фона */
section.band:not(.photoband), .signup, .statband{
  --band-bg:var(--wash); --band-surface:var(--surface); --band-rule:var(--wash-rule);
}

/* ══════════════ BASE ══════════════ */
/* Видно только скринридеру: заголовок, который в макете не нужен, но без
   которого уровни h1→h3 идут через ступеньку. */
.sr-only{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}
*{box-sizing:border-box}
/* Правило браузера [hidden]{display:none} живёт в user-agent-таблице, и любой
   display на классе его перебивает. Из-за этого зелёная реплика об отправке
   формы (.fine display:flex) висела на странице всегда, а кнопка паузы
   (.vidtoggle display:inline-flex) показывалась даже там, где видео не идёт.
   Атрибут hidden должен побеждать любой класс — иначе им нельзя пользоваться. */
[hidden]{display:none !important}
/* Якорные переходы должны останавливаться ПОД липкой шапкой, а не за ней:
   без этого «Reinsurance Symposium» из футера уводил на заголовок, накрытый
   шапкой. Высоту шапки меряет скрипт (--chrome), запас — на случай без JS. */
html{scroll-behavior:smooth; scroll-padding-top:calc(var(--chrome, 77px) + 14px)}
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:var(--sans); font-size:18px; line-height:1.6;   /* 18px — ТЗ §8, возраст аудитории */
  -webkit-font-smoothing:antialiased;
  /* колонка на всю высоту: на короткой странице (404) иначе под футером
     остаётся полоса фона body — выглядит как обрыв вёрстки */
  display:flex; flex-direction:column; min-height:100vh;
}
main{flex:1 0 auto}
img{max-width:100%; display:block}
.shell{max-width:var(--maxw); margin:0 auto; padding:0 32px}
@media (max-width:640px){ .shell{padding:0 20px} body{font-size:17px} }

/* ══════════════ ИКОНКИ ══════════════
   Спрайт из src/icons.svg инлайнится в начало <body>; здесь только размер.
   Размер задан в em, а не в пикселях: иконка обязана ехать за кеглем строки,
   в которую поставлена, иначе в мелком моно-тексте она вырастает в кляксу.
   vertical-align подобран под срез строчных, а не под базовую линию —
   у иконок оптический центр ниже, чем у букв.                            */
.ic{
  width:1.05em; height:1.05em; flex:none; display:inline-block;
  vertical-align:-.16em; fill:none; stroke-linecap:round; stroke-linejoin:round;
}
.ic-lg{width:1.5em; height:1.5em; vertical-align:-.32em}
.ic-xl{width:2.2em; height:2.2em; vertical-align:-.5em}
/* иконка в строке текста без flex-контейнера: без зазора она липнет к слову */
:where(p, li, span, a, h4, dfn, figcaption, summary, b) > .ic:not(:only-child){margin-right:.42em}
:where(p, li, span, a, h4, dfn, figcaption, summary, b) > .ic:last-child:not(:only-child){margin-right:0; margin-left:.42em}
/* контейнеры, которые уже раскладывают детей флексом, зазор задают сами */
:where(.btn, .ilist li, .fmeta li, .facts span, .when span, .roles button, #mobnav a) > .ic{margin:0}

/* значок в кружке — для мест, где иконка стоит не в строке, а как метка блока */
.icbox{
  flex:none; display:grid; place-items:center; width:44px; height:44px;
  border-radius:var(--r-md); background:color-mix(in srgb, var(--accent-text) 11%, transparent);
  color:var(--accent-text); margin-bottom:16px;
}
.icbox .ic{width:22px; height:22px; vertical-align:0}
.band .icbox, .photoband .icbox{
  background:color-mix(in srgb, var(--band-accent) 15%, transparent); color:var(--band-accent);
}

/* список «иконка + строка»: тем же набором собраны факты в шапках,
   реквизиты в футере и перечисления в тексте */
.ilist{list-style:none; margin:0; padding:0; display:grid; gap:10px}
.ilist li{display:flex; align-items:flex-start; gap:11px; font-size:15.5px; color:var(--text-2)}
.ilist .ic{color:var(--accent-text); margin-top:.16em}

.eyebrow{
  font-family:var(--label); font-size:11.5px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--accent-text); margin:0 0 18px; font-weight:500;
  display:flex; align-items:center; gap:8px;
}
.eyebrow .ic{width:14px; height:14px; vertical-align:0}
/* линейка после надзаголовка: секция получает начало, а не просто отступ */
.eyebrow::after{content:''; flex:1 1 auto; height:1px; max-width:64px; background:currentColor; opacity:.38}
.band .eyebrow{color:var(--band-accent)}
h1{font-size:clamp(36px,5.4vw,60px); line-height:1.02; letter-spacing:-.036em; font-weight:800; margin:0 0 18px; text-wrap:balance}
h2{
  font-size:clamp(30px,4.4vw,50px); line-height:1.05; letter-spacing:-.032em;
  font-weight:800; margin:0 0 16px; text-wrap:balance; max-width:24ch;
}
h3{font-size:20px; line-height:1.28; letter-spacing:-.012em; font-weight:700; margin:0 0 8px; text-wrap:balance}
p{margin:0 0 16px; max-width:68ch}
.lede{font-size:19px; color:var(--text-2); max-width:60ch}
.band .lede{color:var(--band-text-2)}
a{color:inherit}
:focus-visible{outline:2px solid var(--emerald); outline-offset:3px; border-radius:var(--r-xs)}
/* внутри тёмных полос --emerald почти не читается: там своя, светлая версия */
.hero :focus-visible, .phero :focus-visible, section.band :focus-visible,
.photoband :focus-visible, footer.site :focus-visible,
#mobnav :focus-visible, #sticky :focus-visible, #lb :focus-visible{
  outline-color:var(--band-accent);
}
/* Размеры задаются в базовом правиле, а не только в :focus: проверка меряет
   элемент в обычном состоянии и иначе видит прежние 27 px. */
.skip{position:absolute; left:-9999px; display:inline-flex; align-items:center;
  min-height:44px; padding:13px 18px}
/* Высота цели касания: аудит считает её и у клавиатурной ссылки — 44 px
   стоит недорого и снимает единственное замечание, которое повторялось на
   каждой странице в обеих темах. */
.skip:focus{left:8px; top:8px; z-index:99; background:var(--emerald); color:#04140A;
  padding:13px 18px; min-height:44px; display:inline-flex; align-items:center;
  font-weight:700; border-radius:var(--r-xs)}

/* ══════════════ ПОЯВЛЕНИЕ ПРИ СКРОЛЛЕ ══════════════
   Класс .rv навешивает ТОЛЬКО скрипт. Писать его в разметке нельзя: без JS
   или без IntersectionObserver страница осталась бы с opacity:0, то есть
   пустой. Задержка по --d делает лесенку внутри одной сетки.            */
.rv{
  opacity:0; transform:translateY(14px);
  transition:opacity var(--dur-3) var(--ease), transform var(--dur-3) var(--ease);
  transition-delay:calc(var(--d,0) * 55ms);
}
.rv.in{opacity:1; transform:none}
@media (prefers-reduced-motion:reduce){
  .rv, .rv.in{opacity:1; transform:none; transition:none}
}

/* ══════════════ BUTTONS ══════════════ */
.btn{
  display:inline-flex; align-items:center; gap:9px; font-family:var(--sans);
  font-size:15px; font-weight:700; letter-spacing:.02em; text-decoration:none;
  padding:15px 26px; border:1.5px solid transparent; cursor:pointer;
  border-radius:var(--r-sm);
  transition:background var(--dur-1), color var(--dur-1), border-color var(--dur-1),
             transform var(--dur-1) var(--ease), box-shadow var(--dur-1), filter var(--dur-1);
}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:translateY(0)}
@media (prefers-reduced-motion:reduce){
  .btn{transition:none}
  .btn:hover, .btn:active{transform:none}
}
.btn-primary{background:var(--emerald); color:#04140A; border-color:var(--emerald); box-shadow:var(--e-1)}
.btn-primary:hover{filter:brightness(1.10); box-shadow:var(--e-hover)}
/* Раньше цвет рамки был набран как rgba(234,240,235,.34) — светлым наглухо.
   Кнопка стоит и в тёмном герое, и в светлых полосах .band, поэтому обе
   величины считаются от --band-text: в герое это та же самая рамка, что
   и была, в светлой полосе — тёмная. */
.btn-ghost{
  background:transparent; color:var(--band-text);
  border-color:color-mix(in srgb, var(--band-text) 34%, transparent);
}
.btn-ghost:hover{border-color:var(--band-text); background:color-mix(in srgb, var(--band-text) 7%, transparent)}
.btn .ic{width:17px; height:17px; vertical-align:0}
.btn-outline{background:transparent; color:var(--text); border-color:var(--rule-2)}
.btn-outline:hover{border-color:var(--text); background:var(--surface)}
/* кнопка ПОВЕРХ фирменной заливки (.card.hi, .signup). Белым наглухо её задавать
   нельзя: в тёмной теме --brand-surface светло-зелёный и белая кнопка пропадает. */
.btn-on-brand{background:var(--on-brand); color:var(--brand-surface); border-color:var(--on-brand)}
.btn-on-brand:hover{background:color-mix(in srgb, var(--on-brand) 88%, var(--emerald))}
.btn .arw{font-family:var(--label); font-size:15px}
.btnrow{display:flex; flex-wrap:wrap; gap:12px}
/* На телефоне кнопки всё равно встают в колонку, но каждая по своей ширине —
   получается лесенка из разной длины подписей. Ширина одна на всех. */
@media (max-width:520px){
  .btnrow{flex-direction:column; align-items:stretch}
  .btnrow .btn{justify-content:center; text-align:center}
}

/* страница одного спикера: монограмма слева, его сессии справа */
.spk-one{display:grid; grid-template-columns:minmax(180px,240px) 1fr; gap:var(--sp-4) var(--sp-5); align-items:start}
.spk-one > .frame{margin-bottom:0}
.spk-one .agenda{border-top:1px solid var(--rule); margin-top:14px}
.spk-one .slot{margin-inline:0; padding-inline:0 16px}
.spk-one .callout h2{margin:0 0 10px; font-size:18px; max-width:none; line-height:1.28; letter-spacing:-.012em}
@media (max-width:760px){
  .spk-one{grid-template-columns:1fr; gap:var(--sp-3)}
  .spk-one > .frame{max-width:180px}
}

/* ══════════════ ВСТРОЕННАЯ ЧУЖАЯ ФОРМА ══════════════
   Рамка своя, содержимое чужое. Высота задана в vh с потолком: внутри
   скроллится сама форма, и растягивать блок под её содержимое нечем —
   кросс-доменный iframe своей высоты наружу не сообщает. */
.embed{
  position:relative; background:var(--surface); border:1px solid var(--rule-2);
  border-radius:var(--r-md); box-shadow:var(--e-2); overflow:hidden;
  height:clamp(560px, 76vh, 900px);
}
.embed iframe{display:block; width:100%; height:100%; border:0}
.embed-fallback{
  display:flex; gap:9px; align-items:flex-start; margin:16px 0 0;
  font-size:14px; color:var(--band-text-2); max-width:74ch;
}
.embed-fallback .ic{width:16px; height:16px; flex:none; margin-top:.16em; color:var(--brass)}
.embed-fallback a{font-weight:650; color:var(--band-accent)}
@media (max-width:640px){ .embed{height:clamp(520px, 82vh, 760px)} }
/* печать чужой формы бессмысленна — во фрейме нечего печатать */
@media print{ .embed{display:none} }

/* ══════════════ ПРЕЛОАДЕР ══════════════
   Задача — закрыть промежуток между первой отрисовкой и подгрузкой шрифта
   с фоновым видео, а не развлекать. Поэтому: фон ровно цвета страницы
   (без вспышки), собственная анимация в 1,1 секунды, уход за 0,45.
   Скрывается классом .done, а затем удаляется из DOM: оставлять во весь
   экран элемент, пусть и прозрачный, нельзя — он перехватывал бы клики. */
#preloader{
  position:fixed; inset:0; z-index:200; background:var(--bg);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:22px;
  transition:opacity .45s var(--ease), visibility 0s linear .45s;
}
#preloader.done{opacity:0; visibility:hidden}
/* знак собирается из двух половин шеврона — того же, что в логотипе */
#preloader .mk{position:relative; width:76px; height:60px}
#preloader .mk span{
  position:absolute; inset:0; background:var(--brand-surface);
  animation:pl-in .7s var(--ease) both;
}
#preloader .mk .l{clip-path:polygon(50% 0%, 50% 52%, 28% 100%, 0% 100%)}
#preloader .mk .r{clip-path:polygon(50% 0%, 100% 100%, 72% 100%, 50% 52%); animation-delay:.12s}
@keyframes pl-in{
  from{opacity:0; transform:translateY(10px) scale(.94)}
  to  {opacity:1; transform:none}
}
#preloader .wd{
  margin:0; font-family:var(--label); font-size:12px; letter-spacing:.28em;
  text-transform:uppercase; color:var(--text-3); animation:pl-in .7s var(--ease) .22s both;
}
#preloader .bar{
  width:132px; height:2px; background:var(--rule); border-radius:2px; overflow:hidden;
}
#preloader .bar i{
  display:block; width:40%; height:100%; background:var(--emerald); border-radius:2px;
  animation:pl-run 1.1s var(--ease) infinite;
}
@keyframes pl-run{
  0%  {transform:translateX(-110%)}
  100%{transform:translateX(360%)}
}
/* При выключенных анимациях остаётся статичный знак: сам экран нужен,
   движение — нет. */
@media (prefers-reduced-motion:reduce){
  #preloader .mk span, #preloader .wd{animation:none}
  #preloader .bar i{animation:none; width:100%}
  #preloader{transition:opacity .2s}
}

/* ══════════════ СЛУЖЕБНЫЙ УГОЛ ПРОТОТИПА ══════════════
   Записка и подсветка демо-данных. Обе — инструменты разбора, а не часть
   сайта, поэтому лежат накладкой в левом нижнем углу, а не полосой над
   шапкой: полоса отнимала у первого экрана 82px, хотя нужна раз за просмотр.
   Правый нижний угол занят стоп-краном фонового видео. */
#tools{
  position:fixed; left:16px; bottom:16px; z-index:41;
  display:flex; flex-direction:column; align-items:flex-start; gap:10px;
  max-width:min(420px, calc(100vw - 32px));
  transition:transform var(--dur-2) var(--ease);
}
/* липкая полоса регистрации приходит снизу во всю ширину и накрыла бы угол;
   её высоту меряет скрипт — на телефоне она вдвое выше */
body.sticky-on #tools{transform:translateY(calc(-1 * var(--sticky-h, 64px)))}
/* свёрнутое состояние — один значок; подпись у него в aria-label */
#tools > #noteBtn{width:38px; padding:0; justify-content:center}
#tools > #noteBtn .ic{width:17px; height:17px}
#tools button{
  display:inline-flex; align-items:center; gap:8px; height:38px; padding:0 15px;
  border:1px solid var(--rule-2); border-radius:var(--r-pill);
  background:color-mix(in srgb, var(--surface) 88%, transparent);
  color:var(--text-2); cursor:pointer; box-shadow:var(--e-2);
  font-family:var(--label); font-size:11px; letter-spacing:.11em; text-transform:uppercase;
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  transition:color var(--dur-1), border-color var(--dur-1), background var(--dur-1);
}
#tools button .ic{width:14px; height:14px; vertical-align:0; flex:none}
#tools button:hover{color:var(--text); border-color:var(--text-3)}
#tools button[aria-pressed="true"], #tools button[aria-expanded="true"]{
  background:var(--brand-surface); background-image:var(--brand-grad);
  color:var(--on-brand); border-color:transparent;
}
#protonote{
  background:color-mix(in srgb, var(--surface) 96%, transparent);
  border:1px solid var(--rule-2); border-radius:var(--r-md); box-shadow:var(--e-3);
  padding:16px 18px; font-size:13.5px; line-height:1.5; color:var(--text-2);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
}
#protonote p{margin:0 0 14px; max-width:none}
#protonote p:last-of-type{margin-bottom:16px}
/* подсветка демо-данных живёт внутри записки: это инструмент того же разбора,
   и держать под него отдельную кнопку в углу не за что */
#protonote #phToggle{width:100%; justify-content:center}
#protonote .lbl{
  font-family:var(--label); font-size:11px; letter-spacing:.13em; text-transform:uppercase;
  color:var(--accent-text); margin-bottom:8px; display:flex; align-items:center; gap:6px;
}
#protonote .lbl .ic{width:13px; height:13px; vertical-align:0}
@media (max-width:520px){
  #tools{left:12px; bottom:12px; max-width:calc(100vw - 24px)}
  #tools button{padding:0 12px; letter-spacing:.06em}
}
@media (prefers-reduced-motion:reduce){ #tools{transition:none} #tools button{transition:none} }

/* плейсхолдеры — данные, которых у нас нет */
.ph{}  /* по умолчанию не маркируем: включается кнопкой в левом нижнем углу */
/* Разбор источника — для заказчика, а не для участника события: сайт вот-вот
   станет боевым, и посетителю незачем читать, что на старом сайте телефон
   расходится с почтой. Показывается той же кнопкой, что подсвечивает данные-
   заглушки. */
.devnote{display:none}
body.show-ph .devnote{display:block; border-left:3px solid var(--amber, #C9922B); padding-left:14px}
body.show-ph .devnote::before{
  content:'Заметка для заказчика'; display:block; font-family:var(--label);
  font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--text-3);
  margin-bottom:6px;
}
body.show-ph .ph{
  background:color-mix(in srgb, var(--brass) 20%, transparent);
  box-shadow:inset 0 -2px 0 var(--brass);
}

/* ══════════════ HEADER ══════════════ */
header.site{
  position:relative; z-index:30; background:var(--band-bg); color:var(--band-text);
  border-bottom:1px solid var(--band-rule);
}
/* Липкая шапка. Фон непрозрачный (--band-bg у шапки = --surface): под ней
   проезжает контент, и полупрозрачная полоса читалась бы как грязь.
   Тень появляется только когда шапка действительно «оторвалась» от верха —
   в покое линия под ней ни к чему. */
#topbar{position:sticky; top:0; z-index:50}
#topbar.stuck header.site{box-shadow:var(--e-2); border-bottom-color:transparent}
header.site{transition:box-shadow var(--dur-2), border-color var(--dur-2)}
@media (prefers-reduced-motion:reduce){ header.site{transition:none} }
@media print{ #topbar{position:static} }
header.site .shell{display:flex; align-items:center; gap:28px; height:76px}
header.site img.logo{height:44px; width:auto} /* правки 10.09, п. 2 */
header.site .brand{display:flex; align-items:center}
header.site nav{display:flex; gap:26px; margin-left:auto}
header.site nav a{
  font-size:14.5px; font-weight:600; text-decoration:none; color:var(--band-text);
  opacity:.78; letter-spacing:.005em; position:relative; padding:6px 0;
}
header.site nav a:hover{opacity:1; color:var(--band-accent)}
header.site nav a.on{opacity:1; color:var(--band-accent)}
/* активный пункт подчёркнут отдельным элементом, а не box-shadow: линия
   должна быть по ширине слова и не залезать в клик-зону соседа */
header.site nav a.on::after{
  content:''; position:absolute; left:0; right:0; bottom:-2px; height:2px;
  background:var(--band-accent); border-radius:2px;
}
header.site .btn{padding:11px 18px; font-size:14px}

/* кнопка-значок в шапке (сейчас одна — переключатель темы) */
.iconbtn{
  flex:none; width:38px; height:38px; display:inline-flex; align-items:center; justify-content:center;
  background:none; border:1px solid var(--band-rule); color:var(--band-text-2); cursor:pointer;
  border-radius:var(--r-sm); transition:color var(--dur-1), border-color var(--dur-1), background var(--dur-1);
}
.iconbtn:hover{color:var(--band-accent); border-color:var(--band-accent); background:var(--band-surface)}
.iconbtn .ic{width:18px; height:18px; vertical-align:0}
@media (prefers-reduced-motion:reduce){ .iconbtn{transition:none} }
/* в шапке кнопка стоит между навигацией и «Register»; на узком экране
   навигация уходит в бургер, и значок остаётся рядом с ним */
header.site nav + .iconbtn{margin-left:0}
@media (max-width:900px){ .iconbtn{margin-left:auto} #burger{margin-left:0} }

/* выбор темы в мобильном меню: там есть место на подписи, и три состояния
   видны сразу — в шапке кнопка их только перебирает по кругу */
.themerow{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px 16px;
  padding:16px 0 4px; border-top:1px solid var(--band-rule); margin-top:6px;
}
.themerow > span{
  font-family:var(--label); font-size:11px; letter-spacing:.13em; text-transform:uppercase;
  color:var(--band-text-2);
}
.seg{display:inline-flex; border:1px solid var(--band-rule); border-radius:var(--r-sm); overflow:hidden}
.seg button{
  display:inline-flex; align-items:center; gap:7px; background:none; border:none; cursor:pointer;
  font-family:var(--sans); font-size:13px; font-weight:600; color:var(--band-text-2);
  padding:10px 13px; border-right:1px solid var(--band-rule);
}
.seg button:last-child{border-right:none}
.seg button .ic{width:15px; height:15px; vertical-align:0}
.seg button[aria-checked="true"]{background:var(--band-accent); color:var(--on-brand)}
.seg button:hover:not([aria-checked="true"]){color:var(--band-text)}

/* бургер: на многостраничнике мобильная навигация обязательна —
   без неё внутренние страницы с телефона недостижимы */
#burger{
  display:none; margin-left:auto; background:none; border:1px solid var(--band-rule);
  color:var(--band-text); padding:9px 12px; cursor:pointer; font-family:var(--label);
  font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  align-items:center; gap:8px; border-radius:var(--r-sm);
}
#burger .ic{width:15px; height:15px; vertical-align:0}
/* Меню раскрывается, а не появляется скачком. grid-template-rows 0fr→1fr —
   единственный способ анимировать высоту по СОДЕРЖИМОМУ, без вбитого
   max-height, который пришлось бы подгонять под число пунктов.
   visibility:hidden в закрытом состоянии обязателен: display:none нельзя
   (анимации не будет), а просто opacity:0 оставил бы пункты в порядке
   табуляции — с клавиатуры фокус уходил бы в невидимое меню. */
#mobnav{
  display:grid; grid-template-rows:0fr; visibility:hidden; opacity:0;
  background:var(--band-surface); border-bottom:1px solid transparent;
  transition:grid-template-rows .34s var(--ease), opacity .22s var(--ease),
             visibility 0s linear .34s, border-color .34s;
}
#mobnav.open{
  grid-template-rows:1fr; visibility:visible; opacity:1;
  border-bottom-color:var(--band-rule);
  transition:grid-template-rows .34s var(--ease), opacity .18s var(--ease),
             visibility 0s, border-color .1s;
}
#mobnav > .shell{min-height:0; overflow:hidden}
#mobnav a{
  display:flex; align-items:center; gap:13px; padding:15px 0; text-decoration:none;
  color:var(--band-text); border-bottom:1px solid var(--band-rule); font-weight:600;
  /* пункты выезжают лесенкой — открытие читается как одно движение,
     а не как мгновенная простыня из десяти строк */
  opacity:0; transform:translateY(-7px);
  transition:opacity .26s var(--ease), transform .26s var(--ease), color var(--dur-1);
}
#mobnav.open a{opacity:1; transform:none}
#mobnav.open a:nth-child(1){transition-delay:.05s}
#mobnav.open a:nth-child(2){transition-delay:.08s}
#mobnav.open a:nth-child(3){transition-delay:.11s}
#mobnav.open a:nth-child(4){transition-delay:.14s}
#mobnav.open a:nth-child(5){transition-delay:.17s}
#mobnav.open a:nth-child(6){transition-delay:.20s}
#mobnav.open a:nth-child(7){transition-delay:.23s}
#mobnav.open a:nth-child(8){transition-delay:.26s}
#mobnav.open a:nth-child(9){transition-delay:.29s}
#mobnav.open a:nth-child(10){transition-delay:.32s}
#mobnav.open .themerow{opacity:1; transform:none; transition-delay:.35s}
#mobnav .themerow{opacity:0; transform:translateY(-7px); transition:opacity .26s var(--ease), transform .26s var(--ease)}
/* значок пункта подъезжает вместе со строкой, но чуть живее */
#mobnav a:hover{color:var(--band-accent)}
#mobnav a:hover .ic{transform:translateX(2px)}
#mobnav a .ic{transition:transform var(--dur-1) var(--ease)}
@media (prefers-reduced-motion:reduce){
  #mobnav, #mobnav a, #mobnav .themerow, #mobnav a .ic{transition:none}
  #mobnav a, #mobnav .themerow{opacity:1; transform:none}
}
#mobnav a .ic{width:18px; height:18px; color:var(--band-accent)}
#mobnav a:last-child{border-bottom:none}
@media (max-width:900px){
  header.site nav{display:none}
  header.site>.shell>.btn{display:none}
  #burger{display:inline-flex}
}

/* ══════════════ HERO (главная) ══════════════ */
/* Герой занимает ровно остаток экрана: на 13-дюймовом ноутбуке (рабочая
   область около 780px) прежняя вёрстка выходила за нижнюю кромку, и кнопки
   «Register» на первом экране не было видно.
   svh, а не vh: на мобильных vh считается по экрану БЕЗ адресной строки, и
   первый экран уезжал под неё. Единица новая, поэтому строкой выше остаётся
   запись на vh — старый браузер возьмёт её и просто не досчитает 60 пикселей.
   Высота — min-height, а не height: если текст всё же не помещается (узкий
   телефон, крупный системный шрифт), блок обязан вырасти, а не обрезать себя. */
.hero{
  position:relative; background:var(--band-bg); color:var(--band-text); overflow:hidden;
  min-height:calc(100vh - var(--chrome));
  min-height:calc(100svh - var(--chrome));
  display:flex; flex-direction:column;
}
.hero .photo{position:absolute; inset:0}
.hero .photo img, .hero .photo video{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:52% 42%;
}
/* Ролик проявляется поверх фото, а не заменяет его: пока файл не готов
   (или не поедет вовсе), на месте героя стоит кадр, а не чёрный прямоугольник.
   Лёгкая десатурация — чтобы тёплая плёнка не спорила с зелёным акцентом. */
.hero .photo video{opacity:0; transition:opacity 1s ease; filter:saturate(.9) contrast(1.02) brightness(1.18)} /* правки 10.09, п. 1: ролик светлее */
.hero .photo video.on{opacity:1}
.hero .scrim{
  position:absolute; inset:0;
  background:
    linear-gradient(96deg, rgba(var(--scrim-rgb),.96) 0%, rgba(var(--scrim-rgb),.90) 40%, rgba(var(--scrim-rgb),.58) 70%, rgba(var(--scrim-rgb),.74) 100%),
    linear-gradient(0deg, rgba(var(--scrim-rgb),.9) 0%, rgba(var(--scrim-rgb),0) 42%);
}
/* Под видео маска плотнее: кадры светлее и намного пестрее статичного фото,
   и на «коридорных» планах заголовок по прежнему градиенту читался с трудом.
   Сверху добавлена шапка-затемнение (под шапкой сайта кадр не должен быть
   ярче полосы) и фирменный зелёный подсвет справа, чтобы тёплый ролик
   не выпадал из палитры. Класс vid-on вешает скрипт — на статичном фото
   такая плотность лишняя. */
.hero.vid-on .scrim{
  background:
    linear-gradient(180deg, rgba(var(--scrim-rgb),.45) 0%, rgba(var(--scrim-rgb),0) 22%),
    radial-gradient(120% 88% at 88% 12%, rgba(11,79,44,.22) 0%, rgba(11,79,44,0) 62%),
    linear-gradient(96deg, rgba(var(--scrim-rgb),.90) 0%, rgba(var(--scrim-rgb),.72) 42%, rgba(var(--scrim-rgb),.30) 72%, rgba(var(--scrim-rgb),.45) 100%),
    linear-gradient(0deg, rgba(var(--scrim-rgb),.85) 0%, rgba(var(--scrim-rgb),0) 48%);
}

/* На телефоне боковой градиент бессмысленен: колонка одна и «светлая»
   правая треть, ради которой он рисовался, физически не помещается —
   ролик уходил под сплошную заливку и его не было видно вовсе.
   Здесь маска вертикальная: кадр открыт сверху, к низу уходит в фон. */
@media (max-width:760px){
  .hero.vid-on .scrim{
    background:
      linear-gradient(180deg, rgba(var(--scrim-rgb),.80) 0%, rgba(var(--scrim-rgb),.46) 26%,
                              rgba(var(--scrim-rgb),.72) 58%, rgba(var(--scrim-rgb),.93) 88%, rgba(var(--scrim-rgb),.97) 100%),
      radial-gradient(120% 50% at 76% 6%, rgba(11,79,44,.40) 0%, rgba(11,79,44,0) 70%);
  }
  /* кадр смещён к центру: при узком кропе люди с краёв уезжают за границу */
  .hero .photo video{object-position:56% 38%}
}

@media (prefers-reduced-motion:reduce){
  /* если настройку сменили уже на открытой странице, ролик обязан пропасть
     сам, не дожидаясь перезагрузки */
  .hero .photo video{display:none}
  .hero.vid-on .scrim{background:
    linear-gradient(96deg, rgba(var(--scrim-rgb),.96) 0%, rgba(var(--scrim-rgb),.90) 40%, rgba(var(--scrim-rgb),.58) 70%, rgba(var(--scrim-rgb),.74) 100%),
    linear-gradient(0deg, rgba(var(--scrim-rgb),.9) 0%, rgba(var(--scrim-rgb),0) 42%)}
}

/* стоп-кран фонового видео: неброский, но досягаемый — правый нижний угол
   героя, над скосом .edge */
.vidtoggle{
  position:absolute; z-index:2; bottom:clamp(46px,5.6vw,84px);
  /* по правому краю колонки .shell, а не окна */
  right:max(32px, calc((100vw - var(--maxw))/2 + 32px));
  display:inline-flex; align-items:center; gap:8px; height:38px; padding:0 14px;
  border:1px solid rgba(232,237,232,.28); border-radius:999px;
  background:rgba(var(--scrim-rgb),.52); color:#E8EDE8; cursor:pointer;
  font:inherit; font-size:12.5px; letter-spacing:.02em;
  backdrop-filter:blur(6px); transition:background .2s, border-color .2s;
}
.vidtoggle:hover{background:rgba(var(--scrim-rgb),.78); border-color:rgba(232,237,232,.5)}
.vidtoggle .ic{width:17px; height:17px; flex:none}
@media (max-width:760px){
  /* на телефоне подпись съедает полосу вдоль всего экрана — остаётся значок,
     имя кнопки уходит в aria-label (его ставит скрипт) */
  .vidtoggle .vt-lbl{position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%)}
  .vidtoggle{width:38px; padding:0; justify-content:center; right:16px; bottom:clamp(40px,7vw,64px)}
}
/* margin:auto вместо justify-content:center — при переполнении flex-контейнера
   центрирование обрезает содержимое сверху, а автоматические поля нет. */
.hero .shell{
  position:relative; width:100%; margin:auto;
  padding-top:clamp(26px,4.6vh,92px); padding-bottom:clamp(26px,4.4vh,88px);
}
.hero .inner{max-width:760px}
.hero h1{
  /* кегль ограничен и высотой окна: на широком, но низком экране (ноутбук,
     развёрнутый браузер с панелями) три строки по 92px не оставляли места
     ни подзаголовку, ни кнопкам. 8.6vh подобрано по рабочей области
     13-дюймового ноутбука: три строки заголовка занимают там 200px. */
  font-size:clamp(38px,min(7.6vw,8.6vh),92px); line-height:.98; letter-spacing:-.042em; font-weight:800;
  margin:0 0 clamp(14px,2.2vh,26px); text-wrap:balance;
}
.hero h1 em{font-style:normal; color:var(--band-accent)}
.hero .when{
  font-family:var(--label); font-size:clamp(13px,1.8vw,15.5px); letter-spacing:.11em;
  text-transform:uppercase; color:var(--band-text); margin:0 0 clamp(14px,2.2vh,22px);
  display:flex; flex-wrap:wrap; gap:8px 14px; align-items:center;
}
.hero .when i{font-style:normal; color:var(--band-accent)}
.hero .sub{font-size:clamp(17px,1.9vh,19px); line-height:1.55; color:#C8D4CB; max-width:62ch; margin:0 0 clamp(16px,2.8vh,34px)}
.hero .cta{display:flex; flex-wrap:wrap; gap:13px; margin-bottom:clamp(18px,3.4vh,44px)}
@media (max-width:520px){
  /* две кнопки в ряд вместо переноса в столбик: в столбик они занимали
     125px — четверть того, что вообще остаётся герою на телефоне */
  .hero .cta{display:grid; grid-template-columns:1fr 1fr; gap:10px}
  .hero .cta .btn{padding:14px 12px; justify-content:center; text-align:center}
  /* пояснение к дедлайну — единственная в блоке строка, которую можно снять:
     и срок, и сам отсчёт, и «+$100» остаются в теге и в часах */
  .deadline .note{display:none}
  .deadline{width:100%; padding:10px 14px; gap:4px 14px; margin-bottom:clamp(14px,2.4vh,34px)}
  .hero .when{gap:4px 12px; margin-bottom:clamp(10px,1.8vh,22px)}
  .hero h1{margin-bottom:clamp(12px,1.8vh,26px)}
  .hero .sub{line-height:1.45; margin-bottom:clamp(14px,2.4vh,34px)}
}
/* Телефон с низким экраном (iPhone SE и его ровесники): описание события
   уходит, чтобы на первом экране целиком помещались дата, заголовок, отсчёт
   и обе кнопки. Кегль при этом НЕ уменьшается: аудитория сайта — люди,
   которым мелкий текст читать тяжело, и жать шрифт ради строчки нельзя.
   Тот же текст лежит в описании страницы и открывает раздел «About». */
@media (max-width:520px) and (max-height:640px){
  .hero .sub{display:none}
}
.hero .est{
  font-family:var(--label); font-size:12px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--band-text-2); border-top:1px solid var(--band-rule);
  padding-top:clamp(12px,1.8vh,18px); margin-bottom:0;
}
/* На совсем невысоком окне строка «16-й год подряд» уходит: это единственное
   в герое, без чего первый экран не теряет ни даты, ни цены, ни кнопки. */
@media (max-height:640px){ .hero .est{display:none} }

/* обратный отсчёт до повышения цены — ТЗ §5.05 */
.deadline{
  display:inline-flex; flex-wrap:wrap; align-items:center; gap:10px 18px;
  border:1px solid rgba(210,160,92,.42); background:rgba(168,118,47,.13);
  padding:13px 18px; margin:0 0 clamp(20px,3.4vh,34px); border-radius:var(--r-md);
}
.deadline .tag{
  font-family:var(--label); font-size:11.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--brass); font-weight:600;
}
.deadline .clock{
  font-family:var(--label); font-size:17px; font-variant-numeric:tabular-nums;
  letter-spacing:.02em; color:#F0DFC4;
}
.deadline .clock b{font-weight:700}
/* Единицы отсчёта набирает скрипт (#clock), а сам счётчик стоит и в героe
   главной, и в шапке /register/. Раньше правило висело только на .deadline,
   и на второй странице <small> падал до браузерных 0.83em — 10,4px. */
.deadline .clock small, #clock small{font-size:11.5px; letter-spacing:.1em; color:var(--brass); margin-left:2px; text-transform:uppercase}
.deadline .note{font-size:13px; color:#C6B79C}

/* водяной знак: та же вершина, что в логотипе, крупно и почти незаметно */
.hero .mark{
  position:absolute; right:-8%; bottom:-22%; width:clamp(280px,36vw,580px); aspect-ratio:1;
  pointer-events:none; z-index:0;
  background:color-mix(in srgb, var(--band-accent) 6%, transparent);
  clip-path:polygon(50% 0%,100% 100%,72% 100%,50% 52%,28% 100%,0% 100%);
}
.hero .shell{z-index:1}

/* диагональ логотипа на стыке со следующей секцией.
   Клин обязан быть залит цветом СЛЕДУЮЩЕЙ секции, иначе на стыке ложится
   треугольник чужого фона. Раньше здесь стоял --bg и совпадение было
   случайным; после перевода рамы на светлые поверхности за героем идут
   разные фоны, поэтому цвет выбирается по соседу. */
.hero .edge, .phero .edge{
  position:absolute; left:0; right:0; bottom:-1px; height:clamp(28px,4vw,64px);
  background:var(--bg); clip-path:polygon(0 100%, 100% 0, 100% 100%);
}
.hero:has(+ .produced) .edge{background:var(--surface)}
.hero:has(+ section.alt) .edge, .phero:has(+ section.alt) .edge{background:var(--surface-2)}
.hero:has(+ section.band:not(.photoband)) .edge,
.phero:has(+ section.band:not(.photoband)) .edge{background:var(--wash)}
/* На 404 за шапкой сразу футер, а он лежит вне <main> — соседним селектором
   его не достать. Поэтому цвет клина задан по классу самой страницы. */
.phero.nf .edge{background:var(--surface-2)}

/* Обратный скос: светлая секция входит в тёмную. Раньше мотив работал только
   сверху вниз, из-за чего половина стыков на сайте была просто прямой линией.
   Рисуется цветом ПРЕДЫДУЩЕЙ секции и живёт внутри тёмной. */
.edge.up{
  position:absolute; left:0; right:0; top:-1px; bottom:auto; z-index:1;
  height:clamp(22px,3vw,44px); background:var(--bg);
  clip-path:polygon(0 0, 100% 0, 0 100%);
}
section.alt + section.band > .edge.up{background:var(--surface-2)}

/* ══════════════ PAGE HERO (внутренние) ══════════════ */
.phero{position:relative; background:var(--band-bg); color:var(--band-text); overflow:hidden}
.phero .shell{position:relative; z-index:1; padding-top:56px; padding-bottom:64px}

/* ── фото-подложка внутренних шапок ──
   Обесцвеченный кадр + заливка бренда через mix-blend-mode:color = дуотон,
   в котором любое фото ложится в палитру. isolation:isolate обязателен:
   без него смешивание уходит на страницу за секцией. Прозрачность держим
   на <img>, а не на .photo — контейнер с opacity<1 меняет режим смешивания. */
.phero.has-photo .photo{position:absolute; inset:0; z-index:0; isolation:isolate}
.phero.has-photo .photo img{
  width:100%; height:100%; object-fit:cover; opacity:.86; filter:var(--photo-filter-soft);
}
/* Дуотон остаётся только там, где он и был затеей, — в «бумажной» теме с её
   сепией. В обычных темах заливка снята: она перекрашивала фотографию в
   палитру и съедала цвет, ради которого правка и делалась. */
.phero.has-photo .photo::before{content:none}
[data-theme='paper'] .phero.has-photo .photo::before{
  content:''; position:absolute; inset:0; background:var(--photo-tint); mix-blend-mode:color;
}
/* Общий пункт 2 списка правок от 10.09: в шапках стояли тёмные кадры с
   обрезанными лицами. Кадр теперь виден в цвете, а маска держит плотность
   только слева, под текстом, и отпускает правую треть. */
.phero.has-photo .photo::after{content:''; position:absolute; inset:0; background:
  linear-gradient(96deg, rgba(var(--scrim-rgb),.94) 0%, rgba(var(--scrim-rgb),.86) 38%,
                  rgba(var(--scrim-rgb),.34) 68%, rgba(var(--scrim-rgb),.52) 100%)}
/* Кадр со сцены снят на чёрном фоне: при общей маске он уходил в грязь, хотя
   сам человек освещён. Для таких полос маска отпускается раньше, а снимок
   осветляется — герой читается, текст слева по-прежнему лежит на плотном. */
.phero.has-photo.lit .photo img{opacity:.97; filter:brightness(1.28) contrast(1.04)}
.phero.has-photo.lit .photo::after{background:
  linear-gradient(96deg, rgba(var(--scrim-rgb),.93) 0%, rgba(var(--scrim-rgb),.72) 30%,
                  rgba(var(--scrim-rgb),.18) 58%, rgba(var(--scrim-rgb),.34) 100%)}
@media (max-width:640px){
  /* Кроп подобран под широкий экран; на узком он режет кадр по случайному месту.
     И главное: маска в шапках горизонтальная, а на телефоне колонка одна на всю
     ширину — текст ложился прямо на лицо. Поэтому на узком экране маска
     вертикальная, а снимок уходит в фактуру, а не спорит с набором. */
  .phero.has-photo .photo img{object-position:50% 30% !important; opacity:.38}
  .phero.has-photo.lit .photo img{opacity:.46; filter:brightness(1.2) contrast(1.02)}
  .phero.has-photo .photo::after,
  .phero.has-photo.lit .photo::after{background:
    linear-gradient(180deg, rgba(var(--scrim-rgb),.93) 0%, rgba(var(--scrim-rgb),.82) 42%,
                    rgba(var(--scrim-rgb),.90) 100%)}
}
.phero h1{max-width:20ch}
.phero .lede{color:var(--band-text-2); font-size:19px; max-width:62ch}
.phero .edge{height:clamp(22px,3vw,44px)}
/* Скос гасится, только если следом идёт фото-полоса: она тёмная в обеих
   темах, и светлый клин лёг бы поперёк тёмного экрана. Прежний режим
   .phero.flat (program.html) не нужен — полоса программы стала светлой,
   и шапка входит в неё обычной диагональю, как на остальных страницах. */
.phero:has(+ .photoband) .edge{display:none}
.crumbs{
  font-family:var(--label); font-size:11px; letter-spacing:.13em; text-transform:uppercase;
  color:var(--band-text-2); margin:0 0 20px; display:flex; gap:9px; flex-wrap:wrap;
}
.crumbs a{text-decoration:none; color:var(--band-text-2)}
.crumbs a:hover{color:var(--band-accent)}
.phero .facts{
  display:flex; flex-wrap:wrap; gap:10px 30px; margin:26px 0 0; padding-top:20px;
  border-top:1px solid var(--band-rule); font-family:var(--label); font-size:12.5px;
  letter-spacing:.08em; text-transform:uppercase; color:var(--band-text-2);
}
.phero .facts b{color:var(--band-text); font-weight:500}

/* ══════════════ PRODUCED BY ══════════════ */
.produced{background:var(--surface); border-bottom:1px solid var(--rule)}
.produced .shell{
  display:flex; flex-wrap:wrap; align-items:center; gap:12px 26px;
  padding-top:20px; padding-bottom:20px;
}
.produced span{
  font-family:var(--label); font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--text-3);
}
.produced strong{font-size:15px; font-weight:700; letter-spacing:-.01em}
.produced em{font-style:italic; color:var(--text-2); font-size:15px}

/* ══════════════ SECTIONS ══════════════
   Отступ был жёсткими 88px на всех двенадцати страницах — от этого они
   выглядели одним и тем же документом с разным текстом. Теперь это шкала,
   а модификаторы задают вес секции.                                      */
section{padding:var(--sec) 0; position:relative}
section.lead{padding:var(--sec-lead) 0}      /* первая содержательная секция */
section.tight{padding:var(--sec-tight) 0}
section.flush-top{padding-top:0}             /* продолжение предыдущей секции */
section.flush-bottom{padding-bottom:0}
section.alt{background:var(--surface-2)}
section.rule-top{border-top:1px solid var(--rule)}
section.band{background:var(--band-bg); color:var(--band-text)}
section.band h2, section.band h3{color:var(--band-text)}
/* ── ФАКТУРА АКЦЕНТНЫХ ПОЛОС ──
   Тёмная полоса отделялась от страницы сама, светлая — почти нет: разница
   между --wash и --bg меньше трёх процентов яркости. Решётка в 4% из двух
   встречных штриховок даёт поверхности материал, но не рисунок: на
   расстоянии вытянутой руки её не видно, а край секции уже читается.
   Только background-image, без ::before — псевдоэлемент пришлось бы
   вытаскивать из-под содержимого секции z-index'ом.                     */
section.band:not(.photoband), .statband, .signup{
  background-image:
    repeating-linear-gradient(45deg,  color-mix(in srgb, var(--accent-text) 4%, transparent) 0 1px, transparent 1px 22px),
    repeating-linear-gradient(-45deg, color-mix(in srgb, var(--accent-text) 4%, transparent) 0 1px, transparent 1px 22px);
}
/* две тёмные секции подряд читаются как одна: двойной отступ на стыке лишний.
   Фото-полоса из правила исключена — её отступ держит кадр, а не текст. */
section.band:not(.photoband) + section.band:not(.photoband){padding-top:0}
.sec-head{margin-bottom:var(--sp-5)}
.sec-head.compact{margin-bottom:var(--sp-3)}
.sec-head.row{display:flex; flex-wrap:wrap; gap:24px; align-items:flex-end; justify-content:space-between}

/* ══════════════ ФОТО-ПОЛОСА ══════════════
   Передышка посреди страниц, которые иначе идут стеной текста. Тот же дуотон,
   что и в шапках: grayscale + mix-blend-mode:color по --photo-tint. */
.photoband{position:relative; overflow:hidden; background:var(--band-bg); padding:clamp(72px,9vw,124px) 0}
.photoband .photo{position:absolute; inset:0; z-index:0; isolation:isolate}
.photoband .photo img{width:100%; height:100%; object-fit:cover; filter:var(--photo-filter)}
.photoband .photo::before{content:''; position:absolute; inset:0; background:var(--photo-tint); mix-blend-mode:color}
.photoband .photo::after{content:''; position:absolute; inset:0; background:var(--scrim-band)}
.photoband .shell{position:relative; z-index:1}
.photoband .inner{max-width:56ch}
.photoband figcaption{
  font-family:var(--label); font-size:12px; letter-spacing:.06em; line-height:1.5;
  color:var(--band-text-2); margin:18px 0 0; max-width:60ch;
}
/* на узком экране фон должен уступить тексту */
@media (max-width:640px){ .photoband .photo img{opacity:.7} }

/* ══════════════ ROLE SWITCHER — ТЗ §5.07 ══════════════ */
.roles{display:flex; flex-wrap:wrap; gap:0; border:1px solid var(--rule-2); margin-bottom:40px; background:var(--surface)}
.roles button{
  flex:1 1 auto; min-width:132px; background:none; border:none; cursor:pointer;
  padding:15px 18px; font-family:var(--sans); font-size:14.5px; font-weight:650; color:var(--text-2);
  border-right:1px solid var(--rule); transition:background .15s, color .15s;
}
.roles button:last-child{border-right:none}
.roles button:hover{background:var(--surface-2); color:var(--text)}
.roles button[aria-selected="true"]{background:var(--brand-surface); color:var(--on-brand)}

.reasons{display:grid; grid-template-columns:repeat(auto-fit,minmax(258px,1fr)); gap:var(--sp-3)}
.reasons article{
  background:var(--surface); padding:30px 26px; border:1px solid var(--rule);
  border-radius:var(--r-md); box-shadow:var(--e-1);
  transition:transform var(--dur-2) var(--ease), box-shadow var(--dur-2), border-color var(--dur-2);
}
.reasons article:hover{transform:translateY(-3px); box-shadow:var(--e-hover); border-color:var(--rule-2)}
@media (prefers-reduced-motion:reduce){
  .reasons article{transition:none}
  .reasons article:hover{transform:none}
}
.reasons .n{
  font-family:var(--label); font-size:11.5px; letter-spacing:.13em; color:var(--accent-text);
  display:block; margin-bottom:14px;
}
.reasons p{margin:0; font-size:16px; color:var(--text-2); max-width:none}

/* ══════════════ ПРОГРАММА — ТЗ §5.01 ══════════════ */
.tracks{display:flex; flex-wrap:wrap; gap:9px; margin-bottom:8px}
.tracks button{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--label); font-size:11.5px; letter-spacing:.09em; text-transform:uppercase;
  background:none; border:1px solid var(--band-rule); color:var(--band-text-2);
  padding:8px 15px 8px 12px; border-radius:var(--r-pill); cursor:pointer; transition:all .15s;
}
/* точка в цвете трека: фильтр и полоса слева у слота говорят на одном языке */
.tracks button::before{content:''; width:7px; height:7px; border-radius:50%; flex:none}
.tracks button[data-trk="all"]{padding-left:15px}
.tracks button[data-trk="all"]::before{display:none}
.tracks button[data-trk="main"]::before {background:var(--trk-main)}
.tracks button[data-trk="reins"]::before{background:var(--trk-reins)}
.tracks button[data-trk="start"]::before{background:var(--trk-start)}
.tracks button[data-trk="ae"]::before   {background:var(--trk-ae)}
.tracks button[data-trk="efi"]::before  {background:var(--trk-efi)}
.tracks button:hover{color:var(--band-text); border-color:var(--band-text-2)}
.tracks button[aria-pressed="true"]{background:var(--band-accent); color:var(--on-brand); border-color:var(--band-accent); font-weight:600}
.tracks button[aria-pressed="true"]::before{box-shadow:0 0 0 2px color-mix(in srgb, var(--on-brand) 30%, transparent)}

/* переключатель дней */
.daytabs{
  display:flex; flex-wrap:wrap; gap:1px; background:var(--band-rule);
  border:1px solid var(--band-rule); border-radius:var(--r-md); overflow:hidden; margin-bottom:30px;
}
.daytabs button{
  flex:1 1 180px; background:var(--band-bg); border:none; cursor:pointer; color:var(--band-text);
  padding:16px 18px; text-align:left; font-family:var(--sans); transition:background .15s, color .15s;
}
.daytabs button:hover{background:var(--band-surface)}
.daytabs button[aria-selected="true"]{background:var(--band-accent); color:var(--on-brand); box-shadow:inset 0 -3px 0 color-mix(in srgb, var(--on-brand) 24%, transparent)}
.daytabs .d{display:flex; align-items:center; gap:7px; font-family:var(--label); font-size:11px; letter-spacing:.14em; text-transform:uppercase; margin-bottom:5px; color:var(--band-text-2)}
.daytabs .d .ic{width:13px; height:13px; vertical-align:0}
/* 74% выворотки по фирменной зелени давали 3,6:1 — для 11px мало (нужно 4,5).
   88% дают 4,6 и при этом всё ещё читаются как подпись, а не как заголовок. */
.daytabs button[aria-selected="true"] .d{color:color-mix(in srgb, var(--on-brand) 88%, transparent)}
.daytabs .t{display:block; font-size:17px; font-weight:700; letter-spacing:-.015em}
/* сколько сессий в этом дне — подставляется скриптом из той же агенды */
.daytabs .c{
  display:block; margin-top:4px; font-family:var(--label); font-size:11px;
  color:var(--band-text-2); font-variant-numeric:tabular-nums;
}
.daytabs button[aria-selected="true"] .c{color:color-mix(in srgb, var(--on-brand) 88%, transparent)}
/* счётчик у фильтра треков: показывает, есть ли вообще что смотреть */
.tracks button .n{opacity:.72; font-variant-numeric:tabular-nums; margin-left:2px}
.tracks button[disabled]{opacity:.42; cursor:default}
.tracks button[disabled]:hover{background:none}

.agenda{border-top:1px solid var(--band-rule); margin-top:26px}
/* Полоса слева окрашена по треку — те же цвета, что у точек в фильтре и у .trk.
   33 одинаковые строки так получают структуру без единой новой картинки.
   Отрицательный margin возвращает текст на прежнюю сетку, несмотря на padding. */
.slot{
  display:grid; grid-template-columns:104px 1fr auto; gap:22px; align-items:start;
  padding:22px 16px; margin-inline:-16px; border-bottom:1px solid var(--band-rule);
  border-left:3px solid transparent; border-radius:var(--r-sm);
  transition:background var(--dur-1), border-left-color var(--dur-1);
}
.slot[data-trk="main"] {border-left-color:var(--trk-main)}
.slot[data-trk="reins"]{border-left-color:var(--trk-reins)}
.slot[data-trk="start"]{border-left-color:var(--trk-start)}
.slot[data-trk="ae"]   {border-left-color:var(--trk-ae)}
.slot[data-trk="efi"]  {border-left-color:var(--trk-efi)}
/* перерывы и регистрация — фон программы, а не её содержание: отступают */
.slot[data-trk="brk"]{border-left-color:var(--band-rule); opacity:.72}
.slot:hover{background:color-mix(in srgb, var(--band-text) 5%, transparent)}
.slot[data-trk="brk"]:hover{opacity:1}
@media (prefers-reduced-motion:reduce){ .slot{transition:none} }
.slot .time{
  font-family:var(--label); font-size:13.5px; font-variant-numeric:tabular-nums;
  color:var(--band-text-2); letter-spacing:.02em; padding-top:3px; white-space:nowrap;
  border-right:1px solid var(--band-rule); padding-right:14px; align-self:stretch;
}
.slot h3{font-size:18.5px; margin:0 0 7px}
.slot .meta{display:flex; flex-wrap:wrap; gap:8px 12px; align-items:center; font-size:13.5px; color:var(--band-text-2)}
.slot .who{margin:8px 0 0; font-size:14.5px; color:var(--band-text); max-width:60ch}
.slot .who i{font-style:normal; color:var(--band-text-2)}
.slot .desc{margin:10px 0 0; font-size:15px; line-height:1.55; color:var(--band-text-2); max-width:72ch}
.slot .more{
  background:none; border:none; padding:0; margin-top:8px; cursor:pointer; font-family:var(--label);
  font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--band-accent);
}
.trk{
  font-family:var(--label); font-size:11.5px; letter-spacing:.1em; text-transform:uppercase;
  padding:2.5px 8px; border:1px solid currentColor; white-space:nowrap; border-radius:var(--r-xs);
  display:inline-flex; align-items:center; gap:6px;
  background:color-mix(in srgb, currentColor 9%, transparent);
}
.trk .ic{width:12px; height:12px; vertical-align:0}
/* длительность слота: время начала и конца уже стоит слева, но «45 min»
   читается быстрее, чем разница двух меток, — а выбирают между
   параллельными сессиями именно по ней */
.slot .dur{
  font-family:var(--label); font-size:11px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--band-text-2); display:inline-flex; align-items:center; gap:5px;
}
.slot .dur .ic{width:12px; height:12px; vertical-align:0}
.trk.t-main{color:var(--trk-main)}
.trk.t-reins{color:var(--trk-reins)}
.trk.t-ae{color:var(--trk-ae)}
.trk.t-efi{color:var(--trk-efi)}
.trk.t-start{color:var(--trk-start)}
.trk.t-break{color:var(--trk-brk)}
.slot .add{
  background:none; border:1px solid var(--band-rule); color:var(--band-text-2); cursor:pointer;
  font-family:var(--label); font-size:11px; letter-spacing:.09em; text-transform:uppercase;
  padding:8px 12px; white-space:nowrap; transition:all .15s; border-radius:var(--r-sm);
  display:inline-flex; align-items:center; gap:7px;
}
.slot .add .ic{width:13px; height:13px; vertical-align:0}
.slot .add:hover{color:var(--band-text); border-color:var(--band-text-2)}
.slot .add[aria-pressed="true"]{background:var(--band-accent); color:var(--on-brand); border-color:var(--band-accent); font-weight:600}
.slot[hidden]{display:none}
@media (max-width:720px){
  .slot{grid-template-columns:1fr; gap:10px}
  .slot .add{justify-self:start}
  /* в одну колонку линейка справа от времени превращается в черту поперёк строки */
  .slot .time{border-right:none; padding-right:0}
}
.agenda-foot{
  display:flex; flex-wrap:wrap; gap:18px; align-items:center; justify-content:space-between;
  padding-top:26px;
}
/* Цвета полосы (--band-*) рассчитаны на тёмный фон. Эта строка стоит и на
   светлых секциях — там она давала 2.6:1, а число в ней 1.7:1. Поэтому по
   умолчанию обычный текст, а цвета полосы включаются только внутри неё. */
.mycount{font-family:var(--label); font-size:13px; color:var(--text-2); font-variant-numeric:tabular-nums}
.mycount b{color:var(--text)}
.band .mycount, .phero .mycount, .on-band .mycount{color:var(--band-text-2)}
.band .mycount b, .phero .mycount b, .on-band .mycount b{color:var(--band-accent)}
.icsnote{flex:1 1 100%; margin:0; font-size:13px; color:var(--band-text-2); max-width:60ch}
.icsnote b{color:var(--band-accent)}

/* ══════════════ SPEAKERS ══════════════
   Рамка — монограмма на фирменной заливке (почему именно так — см. site.js).
   Оттенок берётся из --i: шесть ступеней подмешивания --surface в --brand-surface.
   Первая строка background — плоский фолбэк: Safari < 16.2 роняет всю
   декларацию с color-mix, и без неё рамка осталась бы прозрачной.        */
.spk-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(178px,1fr)); gap:var(--sp-3)}
/* На телефоне auto-fill с минимумом в 178px давал ОДНУ колонку: рамка 4:5
   растягивалась на всю ширину экрана, и шесть спикеров занимали две с
   половиной тысячи пикселей монограмм. Две колонки и квадрат вместо
   портрета укладывают ту же шестёрку примерно в 560px. Кегль подписей
   при этом не трогаем — аудитория возрастная. */
@media (max-width:520px){
  .spk-grid{grid-template-columns:repeat(2,1fr); gap:var(--sp-2)}
  .spk .frame{aspect-ratio:1; margin-bottom:10px}
  .spk .frame .ini{font-size:clamp(26px,9vw,34px)}
}
/* Колонка с прижатой к низу подписью: у спикеров должность занимает от одной
   до трёх строк, и «1 session» гулял по ряду на три разные высоты. */
.spk{text-decoration:none; display:flex; flex-direction:column}
.spk .frame{
  position:relative; isolation:isolate; aspect-ratio:4/5; overflow:hidden;
  margin-bottom:14px; border:1px solid var(--rule); border-radius:var(--r-md);
  display:grid; place-items:center; box-shadow:var(--e-1);
  background:var(--brand-surface);
  /* Оттенок различает спикеров в сетке, но раньше он различал их ЯРКОСТЬЮ:
     заливка подмешивалась к --surface, и у дальних значений хеша инициалы
     на ней падали до 2,6:1 при норме 3. Разница теперь в НАКЛОНЕ градиента
     и лёгком сдвиге к --emerald — светлота одна на все карточки, и контраст
     инициалов не зависит от того, как зовут человека. */
  background:linear-gradient(calc(132deg + var(--i,0) * 23deg),
    var(--brand-surface) 0%,
    color-mix(in srgb, var(--brand-surface) 72%, var(--emerald)) 100%);
  transition:transform var(--dur-2) var(--ease), box-shadow var(--dur-2);
}
/* шеврон логотипа: единственный, кроме .edge, случай использования мотива */
.spk .frame::after{
  content:''; position:absolute; right:-10%; bottom:-12%; width:78%; aspect-ratio:1;
  background:color-mix(in srgb, var(--on-brand) 13%, transparent);
  clip-path:polygon(50% 0%,100% 100%,72% 100%,50% 52%,28% 100%,0% 100%);
}
.spk .frame .ini{
  position:relative; z-index:1; font-family:var(--label); font-weight:500;
  font-size:clamp(30px,4.2vw,42px); letter-spacing:.05em; color:var(--on-brand);
}
/* настоящее фото ложится поверх монограммы — с переходом на кабинет Cvent
   оно есть у каждого спикера; страница одного спикера рисует ту же рамку, но
   вне .spk, поэтому селектор перечисляет оба места */
.spk .frame img,
.spk-one > .frame img{position:absolute; inset:0; z-index:2; width:100%; height:100%;
  object-fit:cover; object-position:50% 22%}
.spk:hover .frame{transform:translateY(-3px); box-shadow:var(--e-hover)}
@media (prefers-reduced-motion:reduce){
  .spk .frame{transition:none}
  .spk:hover .frame{transform:none}
}
.spk h3{font-size:16px; margin:0 0 3px}
.spk p{font-size:13.5px; color:var(--text-2); margin:0; line-height:1.4}
.spk .role{font-family:var(--label); font-size:11.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--accent-text); margin-top:auto; padding-top:6px}

/* тот же знак размером с аватар — в полном списке спикеров */
#spkFull .head{display:flex; gap:14px; align-items:flex-start; margin-bottom:14px}
#spkFull .head h3{margin:0 0 3px}
#spkFull .head .tagline{margin:0}
.chip{
  flex:none; position:relative; isolation:isolate; width:46px; height:46px; overflow:hidden;
  display:grid; place-items:center; border-radius:var(--r-sm);
  background:var(--brand-surface);
  background:linear-gradient(calc(132deg + var(--i,0) * 23deg),
    var(--brand-surface) 0%,
    color-mix(in srgb, var(--brand-surface) 72%, var(--emerald)) 100%);
}
.chip .ini{font-family:var(--label); font-weight:500; font-size:15px; letter-spacing:.04em; color:var(--on-brand)}
/* Портрет в миниатюре. Правила для него не было вовсе: картинка ложилась
   натуральным размером в ячейку 46×46 и обрезалась случайным куском —
   из кадра оставалась полоска лба или подбородка. Кадрируем по центру со
   сдвигом вверх: в портретах лицо всегда в верхней трети. */
.chip img{position:absolute; inset:0; z-index:2; width:100%; height:100%;
  object-fit:cover; object-position:50% 22%}

/* ══════════════ STATS ══════════════
   Полоса на фирменной заливке — единственный насыщенный блок главной.
   Ячейки непрозрачные, зазор в 1px показывает --hair-on-brand: тот же приём
   хайрлайн-сетки, но внутри цвета, а не поверх страницы. Градиент секции
   виден в её внешних отступах и даёт полосе объём.                        */
.statband{background:var(--wash)}
.stats{display:grid; grid-template-columns:repeat(auto-fit,minmax(168px,1fr)); gap:1px; background:var(--rule); border:1px solid var(--rule)}
.stats div{background:var(--surface); padding:24px 22px 26px}
.stats dt{
  font-family:var(--label); font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--text-3); margin:0 0 12px; display:flex; align-items:center; gap:8px;
}
.stats dt .ic{width:15px; height:15px; vertical-align:0; color:var(--accent-text)}
.stats dd{
  margin:0; font-size:clamp(32px,4vw,46px); font-weight:800; letter-spacing:-.035em;
  line-height:1; font-variant-numeric:tabular-nums; color:var(--accent-text);
}
.stats dd small{font-size:16px; font-weight:600; letter-spacing:-.01em; color:var(--text-2)}
/* подпись под числом: без неё полоса читается как набор цифр без единиц */
.stats .cap{
  display:block; margin-top:9px; font-size:13px; line-height:1.4; color:var(--text-2);
}
.statband .stats{background:var(--wash-rule); border-color:var(--wash-rule)}
/* пять ячеек в одну колонку дают экран высотой в 700px — прижимаем к двум */
@media (max-width:640px){
  .stats{grid-template-columns:repeat(2,1fr)}
  .stats > div:last-child{grid-column:1 / -1}
}

/* вместо плоской левой линейки — шеврон логотипа: тот же мотив, что у .edge
   и у монограмм спикеров, третье и последнее его применение */
.quote{position:relative; padding:42px 0 6px; margin:44px 0 0; max-width:64ch}
.quote::before{
  content:''; position:absolute; top:0; left:0; width:26px; height:22px; background:var(--accent-text);
  clip-path:polygon(50% 0%,100% 100%,74% 100%,50% 48%,26% 100%,0% 100%);
}
.band .quote::before, .photoband .quote::before{background:var(--band-accent)}
.quote blockquote{margin:0 0 14px; font-size:22px; line-height:1.42; letter-spacing:-.014em; font-weight:600}
.quote figcaption{font-family:var(--label); font-size:12.5px; letter-spacing:.06em; color:var(--text-3)}
.quotes{display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:var(--sp-3); margin-top:8px}
.quotes .quote{
  margin:0; padding:26px 24px; background:var(--surface); border:1px solid var(--rule);
  border-radius:var(--r-md); box-shadow:var(--e-1);
  /* подпись прижата к низу: цитаты разной длины, и без этого имена стояли
     на трёх разных высотах в одном ряду */
  display:flex; flex-direction:column;
}
.quotes blockquote{margin-bottom:18px}
.quotes figcaption{margin-top:auto}
.quotes .quote::before{top:26px; left:24px}
.quotes blockquote{margin-top:34px; font-size:18px; font-weight:600; line-height:1.45}

/* ══════════════ SPONSORS — ТЗ §5.04 ══════════════ */
.tier{margin-bottom:38px}
.tier :is(h2,h3){
  font-family:var(--label); font-size:11px; letter-spacing:.15em; text-transform:uppercase;
  color:var(--text-3); font-weight:500; margin:0 0 16px; padding-bottom:10px; border-bottom:1px solid var(--rule);
}
/* Хайрлайн-стена (gap:1px по общему фону) для логотипов не подошла: в неполном
   последнем ряду flex-grow растягивал хвост, и один логотип Symposium занимал
   плашку во всю ширину экрана. С текстовыми названиями это было незаметно,
   со знаками — нет. Поэтому здесь настоящий зазор и потолок ширины: короткий
   ряд просто заканчивается слева, без растянутых плашек и серых прогалин. */
/* Сетка, а не flex-wrap: при переносе flex-grow делал плашки последнего
   ряда шире плашек первого, и стена шла ступенькой. В grid колонка одна
   на всю секцию, неполный ряд просто заканчивается слева. */
.logos{display:grid; gap:10px; grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.tier-1 .logos{grid-template-columns:repeat(auto-fill,minmax(176px,1fr))}
.tier-1 .logos a{min-height:112px}
.tier-2 .logos{grid-template-columns:repeat(auto-fill,minmax(156px,1fr))}
.tier-2 .logos a{min-height:96px}
.tier-3 .logos{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}
.tier-3 .logos a{min-height:88px}
/* Плашка белая в ОБЕИХ темах и не перекрашивается на hover. Логотип —
   чужой товарный знак: его цвета трогать нельзя, а прежняя заливка бренда
   по наведению превращала бы их в зелёные пятна. В тёмной теме белая плашка
   тоже обязательна: половина исходников — JPEG с белым фоном, на тёмном они
   всё равно встали бы белыми прямоугольниками, только криво обрезанными. */
.logos a{
  background:#FFFFFF; display:flex; align-items:center; justify-content:center;
  padding:10px 12px; text-decoration:none;   /* поля уже заложены в холст файла */
  border:1px solid var(--rule); border-radius:var(--r-sm);
  transition:box-shadow var(--dur-1), border-color var(--dur-1);
}
/* все файлы уже приведены к общему холсту 600×240 (assets/logos/README.md),
   поэтому размеров под конкретный логотип здесь нет и быть не должно */
.logos img{width:100%; height:auto; display:block}
.logos a:hover{border-color:var(--emerald); box-shadow:inset 0 0 0 2px var(--emerald)}
/* Стена 2026 собрана из логотипов Cvent (build.py, data/sponsors-2026.json):
   они не приведены к холсту 600×240 и приходят в любых пропорциях, поэтому
   рамка задаётся здесь, а знак вписывается в неё целиком. Плашка без ссылки
   (страница спонсоров) — span.lg, выглядит так же, как ссылка на главной. */
.logos img.cv{aspect-ratio:5/2; height:auto; object-fit:contain}
.logos span.lg{
  background:#FFFFFF; display:flex; align-items:center; justify-content:center;
  padding:10px 12px; border:1px solid var(--rule); border-radius:var(--r-sm);
}
.tier-1 .logos span.lg{min-height:112px}
.tier-2 .logos span.lg{min-height:96px}
.tier-3 .logos span.lg{min-height:88px}
@media (prefers-reduced-motion:reduce){ .logos a{transition:none} }
@media (max-width:640px){
  .logos{gap:8px}
  .logos a{padding:12px 14px}
  .tier-1 .logos a, .tier-2 .logos a, .tier-3 .logos a{flex:1 1 120px; max-width:none; min-height:74px}
}

/* карточка спонсора на странице спонсоров */
.sponsor-cards{display:grid; grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); gap:var(--sp-3)}
.sponsor-cards article{
  background:var(--surface); padding:24px 22px; border:1px solid var(--rule);
  border-radius:var(--r-md); box-shadow:var(--e-1);
  transition:transform var(--dur-2) var(--ease), box-shadow var(--dur-2), border-color var(--dur-2);
}
.sponsor-cards article:hover{transform:translateY(-3px); box-shadow:var(--e-hover); border-color:var(--rule-2)}
@media (prefers-reduced-motion:reduce){
  .sponsor-cards article{transition:none}
  .sponsor-cards article:hover{transform:none}
}
.sponsor-cards :is(h3,h4){margin:0 0 6px; font-size:17px; font-weight:700; letter-spacing:-.015em}
.sponsor-cards .cat{font-family:var(--label); font-size:11.5px; letter-spacing:.12em; text-transform:uppercase; color:var(--accent-text); margin:0 0 10px}
.sponsor-cards p{margin:0; font-size:14.5px; color:var(--text-2); max-width:none}
.sponsor-cards .booth{font-family:var(--label); font-size:12px; color:var(--text-3); margin-top:12px; display:block}

/* ══════════════ КАРТОЧКИ / ЦЕНЫ ══════════════ */
.cards{display:grid; grid-template-columns:repeat(auto-fit,minmax(290px,1fr)); gap:var(--sp-3)}
.card{
  background:var(--surface); padding:32px 28px; display:flex; flex-direction:column;
  border:1px solid var(--rule); border-radius:var(--r-md); box-shadow:var(--e-1);
  transition:transform var(--dur-2) var(--ease), box-shadow var(--dur-2), border-color var(--dur-2);
}
.card:hover{transform:translateY(-3px); box-shadow:var(--e-hover); border-color:var(--rule-2)}
@media (prefers-reduced-motion:reduce){
  .card{transition:none}
  .card:hover{transform:none}
}
.card.hi{background:var(--brand-surface); background:var(--brand-grad); color:var(--on-brand); border-color:transparent; box-shadow:var(--e-2)}
.card.hi:hover{border-color:transparent}
.card.hi :is(h2,h3), .card.hi .price{color:var(--on-brand)}
/* приглушённый текст на фирменной заливке считается ОТ --on-brand, а не
   светлым цветом наглухо: в тёмной теме заливка становится светло-зелёной,
   и жёстко заданный светлый текст на ней исчезает */
.card.hi .tagline, .card.hi li, .card.hi .until, .card.hi p{color:var(--on-brand-2)}
/* Уровень заголовка в карточке диктует структура страницы: там, где над
   сеткой карточек нет заголовка секции, карточка обязана быть h2, иначе
   после h1 сразу идёт h3. Набор при этом всегда одинаковый — как у h3. */
.card h2{font-size:20px; line-height:1.28; letter-spacing:-.012em; font-weight:700; margin:0 0 8px; max-width:none}
.tier :is(h2,h3){line-height:1.3; max-width:none}
.card .tagline{font-family:var(--label); font-size:11px; letter-spacing:.13em; text-transform:uppercase; color:var(--text-3); margin:0 0 14px}
.card .price{font-size:38px; font-weight:800; letter-spacing:-.035em; line-height:1; color:var(--accent-text); font-variant-numeric:tabular-nums; margin:6px 0 4px}
.card .price s{font-size:19px; font-weight:600; color:var(--text-3); margin-left:10px; letter-spacing:-.01em}
.card .until{font-family:var(--label); font-size:11.5px; letter-spacing:.08em; color:var(--text-3); margin:0 0 20px}
.card ul{list-style:none; margin:18px 0 0; padding:0; display:grid; gap:10px; font-size:15px; color:var(--text-2)}
.card ul li{padding-left:26px; position:relative; line-height:1.45}
/* Галочка вместо тире. Иконка рисуется маской, а не элементом <svg> в
   разметке: перечислений в пакетах спонсорства и билетах под сотню строк,
   и каждой прописывать спрайт — это сто лишних узлов в DOM ради буллита.
   currentColor через background сохраняет перекраску на фирменной заливке. */
.card ul li::before{
  content:''; position:absolute; left:0; top:.42em; width:15px; height:15px;
  background:var(--accent-text);
  -webkit-mask:var(--m-check) center/contain no-repeat; mask:var(--m-check) center/contain no-repeat;
}
.card.hi ul li::before{background:var(--on-brand)}
.card .foot{margin-top:auto; padding-top:24px}

/* ── КАРТОЧКА МЕРОПРИЯТИЯ ──
   Собрана на общей .card: фон, рамка, тень, поведение при наведении и вся
   тёмная тема достаются от неё — поэтому ни одного нового токена здесь нет
   и появиться не должно. Своё только раскладка: плашка даты, метаданные
   со значками и подвал с двумя ссылками. */
.evcard{padding:24px; gap:0; overflow:hidden}

/* Ровно четыре мероприятия общая сетка раскладывает как 3 + 1, и второй ряд
   выглядит брошенным. В этом единственном случае переходим на 2×2 и не даём
   паре карточек растянуться во всю ширину: на 1400px колонка вышла бы под
   600px, а в карточке три строки текста. Условие на количество — через
   :has(), он в этом файле уже используется; при любом другом числе карточек
   правило не срабатывает и работает обычный auto-fit. Класс .cards не
   трогаем: он стоит ещё на пяти страницах. */
@media (min-width:900px){
  #evGrid:has(> .evcard:nth-child(4):last-child){
    grid-template-columns:repeat(2,1fr);
    max-width:1000px;
  }
}

/* Обложка тянется от края до края карточки — отсюда отрицательные поля на
   ширину её padding. Соотношение задано жёстко: картинки в Cvent грузят
   какие угодно, а сетка карточек не должна от них разъезжаться. */
.evimg{display:block; margin:-24px -24px 18px; background:var(--surface-2)}
.evimg img{display:block; width:100%; aspect-ratio:16/9; object-fit:cover}

.evhead{display:flex; gap:14px; align-items:flex-start; margin:0 0 14px}
.evhtxt{min-width:0}
/* Плашка даты — единственный акцент карточки: в сетке глаз ищет сначала
   число. Цифры табличные, иначе колонка дат пляшет от карточки к карточке. */
.evdate{
  flex:0 0 auto; text-align:center; padding:9px 11px; min-width:62px;
  background:var(--wash); border:1px solid var(--wash-rule); border-radius:var(--r-md);
}
.evdate b{
  display:block; font-size:23px; font-weight:800; line-height:1; letter-spacing:-.03em;
  color:var(--accent-text); font-variant-numeric:tabular-nums;
}
.evdate span{
  display:block; margin-top:4px; font-family:var(--label); font-size:10.5px; font-weight:700;
  letter-spacing:.1em; text-transform:uppercase; color:var(--text-3); white-space:nowrap;
}
.evcard .tagline{margin:0 0 6px}
.evcard h3{font-size:18.5px; line-height:1.28; letter-spacing:-.012em; font-weight:700; margin:0; max-width:none}
/* Названия приходят из чужой системы: там встречаются и составные слова без
   пробелов, и вставленные адреса. Такое слово шире колонки не переносится
   само и уезжает под край карточки, а overflow:hidden выше это молча
   обрезает — поэтому перенос разрешён в любом месте. */
.evcard h3, .evdesc, .evmeta li{overflow-wrap:anywhere}

.evmeta{list-style:none; margin:0; padding:0; display:grid; gap:7px; font-size:14.5px; color:var(--text-2)}
/* .card ul li рисует галочку-буллит и отступ под неё — у метаданных свой
   значок в каждой строке. Селектор с .card обязателен: без него правило
   .card ul li::before весит больше и галочка остаётся. */
.card .evmeta li{display:flex; gap:9px; align-items:flex-start; padding-left:0; line-height:1.45}
.card .evmeta li::before{content:none; display:none}
.evmeta .ic{flex:0 0 auto; margin-top:.16em; opacity:.72}
.evdesc{font-size:14.5px; line-height:1.55; color:var(--text-2); margin:14px 0 0}

/* Подвал: главная кнопка и негромкая ссылка на повестку. Прижат к низу
   (.foot из .card), чтобы кнопки стояли в одну линию у карточек разной
   высоты — иначе сетка выглядит рваной. */
.evcard .foot{padding-top:20px; display:flex; flex-wrap:wrap; gap:10px 16px; align-items:center}
.evlink{
  display:inline-flex; align-items:center; gap:6px; text-decoration:none;
  font-family:var(--label); font-size:12px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--text-3); border-bottom:1px solid transparent;
  transition:color var(--dur-1) var(--ease), border-color var(--dur-1);
}
.evlink:hover{color:var(--accent-text); border-color:currentColor}
.evlink .ic{width:13px; height:13px}

/* таблица дополнительных возможностей */
.opps{width:100%; border-collapse:collapse; font-size:15.5px; margin-top:10px}
.opps caption{text-align:left; font-family:var(--label); font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--text-3); padding-bottom:12px}
.opps th, .opps td{text-align:left; padding:14px 16px; border-bottom:1px solid var(--rule); vertical-align:top}
.opps thead th{
  font-family:var(--label); font-size:11.5px; letter-spacing:.13em; text-transform:uppercase;
  color:var(--text-3); font-weight:500; border-bottom:1px solid var(--rule-2);
}
.opps tbody tr:hover{background:var(--surface)}
.opps .num{font-variant-numeric:tabular-nums; white-space:nowrap; font-weight:700}
.opps small{display:block; color:var(--text-3); font-size:13.5px; font-weight:400; margin-top:4px; max-width:52ch}
.status{
  font-family:var(--label); font-size:11.5px; letter-spacing:.1em; text-transform:uppercase;
  padding:3px 9px; border:1px solid currentColor; white-space:nowrap; display:inline-block;
  border-radius:var(--r-xs);
}
.status.free{color:var(--accent-text)}
.status.sold{color:var(--text-3)}
.tablewrap{overflow-x:auto; border:1px solid var(--rule); background:var(--surface); padding:0 22px 6px; border-radius:var(--r-md)}

/* На телефоне таблица из трёх колонок не помещается: описание сжималось до
   колонки в семь символов и уползало на восемь строк, а «Availability»
   вообще уходил за правый край в горизонтальную прокрутку — то есть цена и
   наличие, ради которых в таблицу и смотрят, были не видны. Здесь строка
   разворачивается в карточку: название с описанием во всю ширину, под ними
   цена и статус в одну линию. Шапка колонок при этом теряет смысл и уходит
   из потока (но остаётся скринридеру — заголовки ячеек в ней). */
@media (max-width:640px){
  .tablewrap{overflow-x:visible; padding:0}
  .opps{display:block; margin-top:0; font-size:16px}
  .opps caption{display:block; padding:16px 18px 4px}
  .opps thead{position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%)}
  .opps tbody{display:block}
  .opps tr{
    display:grid; grid-template-columns:1fr auto; align-items:center;
    gap:6px 14px; padding:16px 18px; border-bottom:1px solid var(--rule);
  }
  .opps tbody tr:last-child{border-bottom:none}
  .opps td{display:block; padding:0; border:none}
  .opps td:first-child{grid-column:1 / -1; font-weight:650}
  .opps small{margin-top:5px; max-width:none}
  .opps .num{font-size:19px; color:var(--accent-text)}
  .opps td:last-child{justify-self:end}
}

/* ══════════════ АККОРДЕОН ══════════════ */
.acc{border:1px solid var(--rule); background:var(--surface); border-radius:var(--r-md); overflow:hidden}
.acc details{border-bottom:1px solid var(--rule)}
.acc details:last-child{border-bottom:none}
.acc summary{
  cursor:pointer; padding:20px 24px; font-weight:700; font-size:17px; letter-spacing:-.01em;
  list-style:none; display:flex; justify-content:space-between; gap:20px; align-items:center;
}
.acc summary::-webkit-details-marker{display:none}
.acc summary::after{
  content:'+'; font-family:var(--label); color:var(--accent-text); font-size:20px; flex:none;
  transition:transform var(--dur-2) var(--ease);
}
.acc details[open] summary::after{transform:rotate(45deg)}
@media (prefers-reduced-motion:reduce){ .acc summary::after{transition:none} }
.acc summary:hover{background:var(--surface-2)}
.acc .body{padding:0 24px 24px; color:var(--text-2); font-size:16px}
.acc .body p:last-child{margin-bottom:0}

/* ══════════════ ПРОЧЕЕ ══════════════ */
.prose{max-width:72ch}
.prose h3{margin-top:34px}
.prose ul{padding-left:22px; color:var(--text-2)}
.prose li{margin-bottom:9px}
.prose strong{color:var(--text)}

/* Текст и выноска в одной полосе: колонка чтения остаётся узкой, а вторая
   половина ширины перестаёт быть пустым фоном. */
.proserow{display:grid; grid-template-columns:1fr minmax(240px,.6fr); gap:var(--sp-4) var(--sp-5); align-items:start}
@media (max-width:860px){ .proserow{grid-template-columns:1fr} }
.pull{
  margin:0; border-left:3px solid var(--band-accent); padding:2px 0 2px 22px; max-width:24ch;
  font-size:clamp(19px,2vw,23px); line-height:1.34; font-weight:700; letter-spacing:-.018em;
  /* --text, а НЕ --band-text: последний объявлен глобально и означает текст
     поверх ТЁМНОЙ полосы. В обычной светлой секции выноска им красилась в
     почти белый по почти белому (1:1). Внутри светлых полос --text и так
     верен, внутри тёмных его переопределяет сама полоса. */
  color:var(--text); text-wrap:balance;
}

/* Заглушка для блоков, которые рисует скрипт. Без неё страница со
   отключённым JS показывала три пустых проёма подряд и ничего не объясняла:
   выглядело как сломанная вёрстка, а не как отключённый скрипт. */
.nojs{
  display:flex; gap:10px; align-items:flex-start; margin:0;
  border:1px dashed var(--band-rule, var(--rule-2)); border-radius:var(--r-md);
  padding:18px 20px; color:var(--band-text-2, var(--text-2)); font-size:15px; max-width:70ch;
}
.nojs .ic{width:18px; height:18px; flex:none; margin-top:.15em; color:var(--brass)}

.callout{
  border:1px solid var(--rule-2); border-left:3px solid var(--brass); background:var(--surface);
  padding:24px 26px; margin:32px 0 0; border-radius:var(--r-md); box-shadow:var(--e-1);
}
.callout :is(h2,h3){margin:0 0 10px; font-size:18px; max-width:none; line-height:1.28; letter-spacing:-.012em}
.callout p{margin:0; color:var(--text-2); font-size:16px}
.callout p + p{margin-top:12px}

.split{display:grid; grid-template-columns:1fr 1fr; gap:0; align-items:stretch}
@media (max-width:860px){ .split{grid-template-columns:1fr} }
.split .pane{padding:56px 48px; background:var(--surface); border:1px solid var(--rule); border-radius:var(--r-md) 0 0 var(--r-md)}
.split .pic{border:1px solid var(--rule); border-left:none; overflow:hidden; min-height:340px; border-radius:0 var(--r-md) var(--r-md) 0}
@media (max-width:860px){
  .split{border-radius:var(--r-md); overflow:hidden}
  .split .pic{border-left:1px solid var(--rule); min-height:260px; border-radius:0}
  .split .pane{padding:40px 28px; border-radius:0}
}
.split .pic img{width:100%; height:100%; object-fit:cover}
.factlist{list-style:none; margin:24px 0 0; padding:0; display:grid; gap:1px; background:var(--rule); border:1px solid var(--rule)}
.factlist li{background:var(--surface); padding:14px 18px; display:flex; gap:18px; justify-content:space-between; align-items:baseline; font-size:15px}
.factlist dfn{
  font-family:var(--label); font-size:11px; letter-spacing:.11em; text-transform:uppercase;
  color:var(--text-3); font-style:normal; white-space:nowrap;
}
.factlist b{font-weight:650; text-align:right}

/* контакты */
.contacts{display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:var(--sp-3)}
.contacts article{
  background:var(--surface); padding:30px 28px; border:1px solid var(--rule);
  border-radius:var(--r-md); box-shadow:var(--e-1);
  transition:transform var(--dur-2) var(--ease), box-shadow var(--dur-2), border-color var(--dur-2);
}
.contacts article:hover{transform:translateY(-3px); box-shadow:var(--e-hover); border-color:var(--rule-2)}
@media (prefers-reduced-motion:reduce){
  .contacts article{transition:none}
  .contacts article:hover{transform:none}
}
.contacts h3{margin:0 0 4px; font-size:21px}
.contacts .pos{font-family:var(--label); font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:var(--accent-text); margin:0 0 16px}
.contacts a{display:block; text-decoration:none; font-weight:650; margin-bottom:6px}
@media (max-width:760px){ .contacts a{padding:6px 0; margin-bottom:0} }
.contacts a:hover{color:var(--accent-text)}

/* нумерованные шаги */
.steps{list-style:none; counter-reset:s; margin:26px 0 0; padding:0; display:grid; gap:1px; background:var(--rule); border:1px solid var(--rule)}
.steps li{background:var(--surface); padding:22px 26px 22px 68px; position:relative; counter-increment:s; color:var(--text-2); font-size:16px}
.steps li::before{
  content:counter(s,decimal-leading-zero); position:absolute; left:26px; top:22px;
  font-family:var(--label); font-size:12px; color:var(--accent-text); letter-spacing:.1em;
}
.steps b{color:var(--text); display:block; margin-bottom:4px; font-size:17px}
/* тот же список внутри тёмной полосы */
section.band .steps{background:var(--band-rule); border-color:var(--band-rule)}
section.band .steps li{background:var(--band-surface); color:var(--band-text-2)}
section.band .steps li::before{color:var(--band-accent)}
section.band .steps b{color:var(--band-text)}
/* поверх фото ячейки полупрозрачные, иначе десять плашек закрывают весь кадр */
.photoband .steps li{background:color-mix(in srgb, var(--band-bg) 74%, transparent)}

/* ══════════════ ГАЛЕРЕЯ ══════════════ */
.gal{display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:1px; background:var(--rule); border:1px solid var(--rule)}
.gal button{
  padding:0; border:none; background:var(--surface-2); cursor:zoom-in; display:block;
  aspect-ratio:3/2; overflow:hidden; position:relative;
}
.gal img{width:100%; height:100%; object-fit:cover; transition:transform .3s ease}
.gal button:hover img{transform:scale(1.03)}
.gal button::after{
  content:''; position:absolute; inset:0; box-shadow:inset 0 0 0 0 var(--emerald);
  transition:box-shadow var(--dur-2); pointer-events:none;
}
.gal button:hover::after{box-shadow:inset 0 0 0 3px var(--emerald)}
@media (prefers-reduced-motion:reduce){
  .gal img{transition:none} .gal button:hover img{transform:none}
  .gal button::after{transition:none}
}

/* лайтбокс: <dialog> вместо самодельного оверлея — фокус, Esc и подложка
   уже реализованы браузером и работают со скринридером */
#lb{
  border:none; padding:0; max-width:min(1180px,94vw); max-height:92vh; width:100%;
  background:var(--band-bg); color:var(--band-text); border-radius:var(--r-lg); overflow:hidden;
}
#lb::backdrop{background:rgba(var(--scrim-rgb),.88)}
#lb img{width:100%; height:auto; max-height:78vh; object-fit:contain; background:#000}
#lb .bar{
  display:flex; align-items:center; gap:16px; justify-content:space-between;
  padding:12px 16px; border-top:1px solid var(--band-rule);
  font-family:var(--label); font-size:12px; letter-spacing:.1em; text-transform:uppercase;
  color:var(--band-text-2);
}
#lb .bar button{
  background:none; border:1px solid var(--band-rule); color:var(--band-text);
  font-family:var(--label); font-size:12px; padding:8px 14px; cursor:pointer; letter-spacing:.1em;
  border-radius:var(--r-sm);
}
#lb .bar button:hover{border-color:var(--band-accent); color:var(--band-accent)}
#lb .nav{display:flex; gap:8px}

/* ══════════════ 404 ══════════════ */
.nf{min-height:56vh; display:flex; align-items:center}
.nf .code{
  font-family:var(--label); font-size:13px; letter-spacing:.2em; text-transform:uppercase;
  color:var(--band-accent); margin:0 0 20px;
}
.nf h1{max-width:16ch}
.nf ul{list-style:none; margin:30px 0 0; padding:0; display:flex; flex-wrap:wrap; gap:10px}
.nf ul a{
  display:inline-block; text-decoration:none; border:1px solid var(--band-rule);
  padding:11px 18px; font-size:15px; font-weight:650; color:var(--band-text);
  border-radius:var(--r-sm); transition:border-color var(--dur-1), color var(--dur-1), transform var(--dur-1) var(--ease);
}
.nf ul a:hover{border-color:var(--band-accent); color:var(--band-accent); transform:translateY(-1px)}
@media (prefers-reduced-motion:reduce){ .nf ul a{transition:none} .nf ul a:hover{transform:none} }

/* ══════════════ NEWSLETTER ══════════════
   Раньше блок был тёмно-зелёной заливкой с набранными вручную светлыми
   цветами. Теперь это такая же светлая акцентная полоса, как .band, и все
   цвета берутся из темы — иначе в тёмной теме белый ввод остался бы белым. */
.signup{background:var(--wash)}
.signup .shell{display:grid; grid-template-columns:1fr minmax(320px,.9fr); gap:26px 56px; align-items:start}
@media (max-width:860px){ .signup .shell{grid-template-columns:1fr} }
.signup h2{max-width:16ch}
.signup .lede{margin-bottom:0}
.signup .act{display:grid; gap:14px; align-content:start}
.signup form{display:flex; flex-wrap:wrap; gap:11px; margin:0 0 14px}
.signup .field{position:relative; flex:1 1 240px; display:flex; align-items:center}
.signup .field .ic{position:absolute; left:15px; width:18px; height:18px; color:var(--text-3); pointer-events:none}
.signup input{
  width:100%; font-family:var(--sans); font-size:16px; padding:15px 16px 15px 44px;
  border:1.5px solid var(--rule-2); background:var(--surface); color:var(--text);
  border-radius:var(--r-sm);
}
.signup input::placeholder{color:var(--text-3)}
.signup input:focus{outline:2px solid var(--emerald); outline-offset:1px; border-color:var(--emerald)}
.signup .fine{font-size:13px; color:var(--text-3); max-width:56ch; margin:0; display:flex; gap:8px; align-items:flex-start}
.signup .fine .ic{margin-top:.16em}
.signup .fine.ok{color:var(--accent-text); font-weight:600}

/* ══════════════ FOOTER ══════════════ */
footer.site{
  background:var(--band-bg); color:var(--band-text-2); padding:64px 0 34px; font-size:14.5px;
  border-top:1px solid var(--band-rule);
}
footer.site .cols{display:grid; grid-template-columns:1.4fr repeat(3,1fr); gap:40px; margin-bottom:48px}
@media (max-width:820px){ footer.site .cols{grid-template-columns:1fr 1fr; gap:32px} }
footer.site img.logo{height:32px; width:auto; margin-bottom:20px}
footer.site h4{
  font-family:var(--label); font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--band-text); font-weight:500; margin:0 0 14px;
  display:flex; align-items:center; gap:8px;
}
footer.site h4 .ic{width:14px; height:14px; vertical-align:0; color:var(--band-accent)}
footer.site ul{list-style:none; margin:0; padding:0; display:grid; gap:9px}
footer.site a{text-decoration:none; color:var(--band-text-2)}
footer.site a:hover{color:var(--band-accent)}
/* реквизиты в первой колонке: те же иконки, что в шапках страниц —
   дата, город и размер зала повторяются на сайте всюду одним набором */
footer.site .fmeta{list-style:none; margin:0; padding:0; display:grid; gap:9px}
footer.site .fmeta li{display:flex; align-items:flex-start; gap:10px; line-height:1.45}
footer.site .fmeta .ic{width:16px; height:16px; margin-top:.14em; color:var(--band-accent)}
footer.site .legal{
  border-top:1px solid var(--band-rule); padding-top:22px; display:flex; flex-wrap:wrap;
  gap:10px 22px; font-size:13px; color:var(--band-text-2); align-items:center;
}
footer.site .legal .ic{width:12px; height:12px; opacity:.6}
footer.site .legal .totop{margin-left:auto; font-weight:650; color:var(--band-text)}
footer.site .legal .totop:hover{color:var(--band-accent)}
/* На телефоне ссылки футера и юридической строки были высотой в свои 20px —
   в палец такая цель не попадает. Padding вместо gap: сама сетка не растёт,
   растёт только кликабельная область, и колонки остаются той же длины. */
@media (max-width:760px){
  footer.site ul{gap:0}
  footer.site ul a{display:block; padding:11px 0}
  footer.site .fmeta{gap:12px}
  footer.site .legal{gap:2px 22px}
  /* Ссылки подвала — самостоятельные цели, а не слова внутри предложения:
     на телефоне им положены те же 44 px по высоте. */
  footer.site .legal > *{padding:9px 0}
  footer.site .legal a{display:inline-flex; align-items:center; min-height:44px}
  footer.site .built a{min-height:44px}
  .crumbs a{display:inline-block; padding:7px 0}
}

/* ══════════════ STICKY REGISTER BAR — ТЗ §5.05 ══════════════ */
#sticky{
  position:fixed; left:0; right:0; bottom:0; z-index:40; background:var(--band-surface);
  border-top:1px solid var(--band-rule); color:var(--band-text);
  transform:translateY(105%); transition:transform .28s ease; box-shadow:var(--e-3);
}
#sticky.on{transform:translateY(0)}
@media (prefers-reduced-motion:reduce){ #sticky{transition:none} }
#sticky .shell{display:flex; flex-wrap:wrap; align-items:center; gap:14px 24px; padding-top:13px; padding-bottom:13px}
#sticky .w{
  font-family:var(--label); font-size:12.5px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--band-text-2); font-variant-numeric:tabular-nums;
  display:inline-flex; align-items:center; gap:9px;
}
#sticky .w .ic{width:15px; height:15px; vertical-align:0; color:var(--brass)}
#sticky .w b{color:var(--brass)}
#sticky .btn{margin-left:auto; padding:11px 22px; font-size:14px}
@media (max-width:560px){ #sticky .btn{margin-left:0; width:100%; justify-content:center} }

/* ══════════════ ПЕЧАТЬ ══════════════
   Появилась вместе со scroll-reveal и обязательна из-за него: блок, до
   которого читатель не долистал, ушёл бы в печать с opacity:0, то есть
   страница печаталась бы наполовину пустой.                            */
@media print{
  /* transition тоже гасим: без него блок «проявляется» полсекунды и успевает
     уехать в печать полупрозрачным */
  .rv, .rv.in{opacity:1 !important; transform:none !important; transition:none !important}
  #sticky, #mobnav, #burger, #themeBtn, .skip,
  .hero .photo, .hero .scrim, .phero .photo, .photoband .photo, .edge,
  .vidtoggle, #tools{display:none !important}
  body{font-size:11pt; background:#fff; color:#000; display:block}
  .hero, .phero, section.band, .photoband, .statband, .signup, footer.site{
    background:#fff !important; color:#000 !important;
  }
  .hero h1, .phero h1, section.band h2, section.band h3, .photoband h2,
  .statband .stats dd, .signup h2{color:#000 !important}
  .lede, .band .lede, .slot .desc, .slot .meta, footer.site{color:#333 !important}
  section{padding:18pt 0}
  .card, .spk .frame, .callout, .reasons article, .contacts article,
  .sponsor-cards article{box-shadow:none !important; break-inside:avoid}
  .slot, .acc details, .steps li, .factlist li{break-inside:avoid}
  .acc details{display:block}
  .acc .body{display:block !important}
  a[href^="http"]::after{content:" (" attr(href) ")"; font-size:9pt; word-break:break-all}
}

/* Подпись разработчика в юридической строке: тише соседних ссылок, чтобы не
   спорить с копирайтом организатора, но кликабельная. */
/* Прозрачность 0.75 на светлом подвале давала 3.33:1 при кегле 12 px: axe
   считает это нечитаемым, и он прав — подпись сливалась с фоном. Полный цвет
   даёт 5.1:1 и на глаз остаётся такой же негромкой. */
footer.site .built{
  /* flex-basis на всю строку: иначе подпись становится узким элементом
     контейнера, и линия-разделитель обрывается на середине подвала */
  /* общий стиль абзаца режет ширину до 68ch, и линия-разделитель
     обрывалась на середине подвала */
  width:100%; max-width:none; flex-basis:100%;
  margin:16px 0 0; padding-top:14px; font-size:12px; color:var(--band-text-2);
  border-top:1px solid var(--band-rule);
}
footer.site .built a{text-decoration:underline; text-underline-offset:2px;
  font-weight:600; color:var(--band-text);
  text-decoration-color:color-mix(in srgb, var(--band-accent) 60%, transparent)}

/* #sticky прижат к нижней кромке и перекрывает конец страницы: без запаса
   юридическая строка (условия, приватность, подпись разработчика) остаётся
   недосягаемой даже при полной прокрутке. Высота панели — 75px на десктопе
   и 109px там, где кнопка занимает всю ширину; берём с небольшим полем. */
footer.site .legal{padding-bottom:92px}
@media (max-width:560px){ footer.site .legal{padding-bottom:126px} }

/* ══════════════ КАТАЛОГ ЭКСПОНЕНТОВ ══════════════
   Список из кабинета Cvent: сотня с лишним компаний, поэтому карточка
   плотная — логотип, название, одна строка позиционирования и категории.
   Логотипы приходят с прозрачным фоном и тёмными начертаниями, так что
   плитка под ними белая в обеих темах: иначе половина каталога пропадает
   на тёмной странице. */
.expo-grid{
  display:grid; gap:1px; background:var(--rule);
  border:1px solid var(--rule); margin-top:var(--sp-3);
  grid-template-columns:repeat(auto-fill, minmax(240px, 1fr));
}
.expo-card{
  background:var(--surface); padding:20px 20px 22px;
  display:flex; flex-direction:column; gap:8px;
}
.expo-logo{
  display:flex; align-items:center; justify-content:flex-start;
  height:64px; margin-bottom:4px;
}
.expo-logo img{
  max-height:56px; max-width:150px; width:auto; object-fit:contain;
  background:#fff; padding:6px; border-radius:4px;
}
.expo-card h3{
  font-size:17px; line-height:1.25; margin:0; letter-spacing:-.01em;
}
.expo-card p{ margin:0; font-size:14px; color:var(--text-2); line-height:1.45 }
.expo-card .cat{
  margin-top:auto; padding-top:6px;
  font-family:var(--label); font-size:10.5px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--accent-text);
}
/* спонсор без логотипа — не дыра в стене, а его имя набором */
.logos .noimg{
  display:flex; align-items:center; justify-content:center; padding:14px 18px;
  border:1px solid var(--rule); font-family:var(--label);
  font-size:13px; letter-spacing:.06em; text-transform:uppercase; color:var(--text-2);
}

/* ── правки 10.09.2026 ─────────────────────────────────────────────── */
/* п. 4: лента кадров под героем */
.strip{overflow:hidden; background:var(--surface-2); padding:14px 0; border-bottom:1px solid var(--line)}
.strip-track{display:flex; gap:10px; width:max-content; animation:strip 70s linear infinite}
.strip-track img{height:170px; width:255px; object-fit:cover; border-radius:6px; display:block}
@keyframes strip{from{transform:translateX(0)} to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){ .strip-track{animation:none} }
@media (max-width:760px){ .strip-track img{height:120px; width:180px} }
/* п. 7, 20: программа 2027 ещё не собрана */
.coming{margin:8px 0 18px; padding:14px 18px; border-left:4px solid #1e7442; background:var(--surface-2); border-radius:6px; font-size:.95rem}
.coming.on-dark{background:rgba(255,255,255,.08); color:inherit}
/* п. 14: спонсоры на белом — логотипы без белых коробок на тёмном */
#sponsors.alt{background:#fff; color:#111}
#sponsors .eyebrow{color:#1e7442} #sponsors h2,#sponsors h3{color:#111} #sponsors .lede{color:#555}
#sponsors .logos a{background:#fff; border:1px solid #e5e7eb; box-shadow:none}
/* п. 3: Powered by BBM в подвале */
footer.site .legal .bbm img{height:34px; width:auto; display:block}


/* ── баннер согласия ───────────────────────────────────────────────────
   Правило кластера: всплывающее не перекрывает первый экран, поэтому баннер
   выезжает снизу только после героя. На узком экране — во всю ширину: угловая
   карточка на телефоне закрывает как раз кнопку регистрации. */
.consent{
  position:fixed; left:0; right:0; bottom:0; z-index:75;
  background:var(--surface); border-top:1px solid var(--rule);
  padding:16px 18px; box-shadow:0 -8px 32px rgba(0,0,0,.18);
}
.consent p{margin:0 0 12px; font-size:.94rem; line-height:1.5; max-width:60ch}
.consent-btns{display:flex; flex-wrap:wrap; gap:10px}
@media (min-width:760px){
  .consent{left:18px; right:auto; bottom:18px; max-width:420px;
           border:1px solid var(--rule); border-radius:var(--r-md)}
}
@media (prefers-reduced-motion:no-preference){
  .consent{animation:consent-in .32s ease both}
}
@keyframes consent-in{from{opacity:0; transform:translateY(12px)} to{opacity:1; transform:none}}
