/* Публичный сайт «Венчурной братвы».
 *
 * Тот же язык, что у мини-апы: нулевые скругления, фаска вместо тени,
 * палитра из логотипа, системный шрифт. Токены продублированы, а не
 * подключены из app.css: сайт и приложение живут на разных страницах и
 * разной ширине, и связывать их одним файлом значит однажды сломать оба
 * правкой для одного.
 *
 * Библиотеки под этим больше нет. Раньше сайт стоял на @freedo/ui-lib с
 * классами fd-*, и половина из них тянула чужие скругления и тени — на
 * прямых углах и фаске это выглядело деталью из другого набора.
 */

:root {
  color-scheme: light;

  --ink: #0a1c4a;          /* холст вокруг панелей — контур логотипа */
  --bg: #dfe4ec;           /* панель — хром */
  --bg-2: #eef1f6;         /* второй план внутри панели */
  --line: #0a1c4a;
  --line-soft: #b6bdcb;

  --bevel-hi: #ffffff;
  --bevel-lo: #8b95a8;
  --bevel-out: inset 2px 2px 0 var(--bevel-hi), inset -2px -2px 0 var(--bevel-lo);
  --bevel-in:  inset 2px 2px 0 var(--bevel-lo), inset -2px -2px 0 var(--bevel-hi);

  /* Тёмная подложка под золотое кольцо фокуса. Ложится на 7 пикселей вокруг
     рамки, золото занимает из них с 2-го по 5-й — остаются два тёмных
     ободка, внутренний и внешний, и кольцо видно на любом фоне. */
  --focus-halo: 0 0 0 7px var(--ink);

  --text: #0d1220;
  --text-2: #4a5468;
  --accent: #0b2a86;
  --accent-ink: #ffffff;
  --accent-soft: #cdd8f2;
  --gold: #d8a52a;
  --gold-ink: #1a1204;
  --gold-soft: #f7e6b8;

  /* Смысловые: заливка, буквы, линия. Значения слово в слово те же, что в
     app.css: статус доступности показывают обе поверхности, и «Открыт» на
     личной странице обязан быть того же зелёного, что в приложении. */
  --ok-bg: #cfe9d5;   --ok-text: #0f3d20;   --ok-line: #4e8f63;
  --warn-bg: #f7e6b8; --warn-text: #5a3f00; --warn-line: #b78f1e;
  --bad-bg: #f4d0d0;  --bad-text: #7a1715;  --bad-line: #c06a68;

  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s7: 48px;

  /* Ступенчато: плавное на пиксельной сетке смазывает края. */
  --fast: .12s steps(3, end);

  --шрифт: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
           "Helvetica Neue", Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

img, svg { image-rendering: pixelated; max-width: 100%; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--шрифт);
  font-size: 17px;
  line-height: 1.55;
}

a { color: var(--accent); }

/* ═══════════════════════════════════════════════════════ каркас */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  max-width: 1000px;
  margin: 0 auto;
  padding: var(--s4);
  /* Запасной ход, а не расчёт на него. Ниже шапку поджимают так, чтобы на
     320 всё село в строку, но подпись на кнопке ещё поменяют, а системный
     шрифт на андроиде шире, чем здесь. Если места не хватит, вниз уедет
     кнопка, а не название: разорванное надвое «Венчурная братва» читается
     как опечатка, кнопка на своей строке — как решение. */
  flex-wrap: wrap;
}
/* Съезжая на свою строку, кнопка держится правого края: слева она выглядит
   вторым названием. */
.topbar .btn { margin-left: auto; }

.logo {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  color: #fff;
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -.01em;
  text-decoration: none;
  /* Название не переносится. На 320 оно ломалось на «Венчурная» и «братва»,
     шапка вырастала с 66 до 91 пикселя и съедала первый экран. */
  white-space: nowrap;
}
.logo img { width: 34px; height: 34px; flex: none; }
/* Своего кольца у названия не было, и с клавиатуры оно получало браузерное:
   синяя нитка в один пиксель, #005fcc поверх полотна #0a1c4a — 2.75:1. То
   есть первая же остановка табом была невидимой. Подложка здесь не нужна:
   полотно и так тёмное, золота хватает. */
.logo:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }

main {
  max-width: 1000px;
  margin: 0 auto;
  padding: 0 var(--s4) var(--s7);
  display: flex;
  flex-direction: column;
  gap: var(--s4);
}

section {
  background: var(--bg);
  border: 1px solid var(--line);
  box-shadow: var(--bevel-out);
  padding: var(--s5);
}

footer {
  max-width: 1000px;
  margin: 0 auto;
  padding: 0 var(--s4) var(--s6);
  color: #9fb0d6;
  font-size: 14px;
}
footer p { margin: 0 0 var(--s1); }
/* Вторая строка подвала. Класс .muted сюда не годится: он красит текст в
   --text-2, цвет для светлых панелей, а подвал лежит на тёмном полотне —
   получалось 1.7:1, то есть текст, который просто не виден. */
footer .footnote { color: #7488b5; }

/* ═══════════════════════════════════════════════════════ типографика */

h1 {
  margin: 0 0 var(--s3);
  font-size: clamp(28px, 5vw, 42px);
  line-height: 1.1;
  letter-spacing: -.02em;
  font-weight: 800;
  /* На странице встречи в заголовок попадает название, которое написал
     человек в боте. Одно длинное слово крупным кеглем шире экрана телефона,
     и без переноса оно уводит вбок всю страницу. */
  overflow-wrap: anywhere;
}
h2 { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -.01em; }
p { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

/* Подзаголовок и приглушённый текст на странице встречи — тоже чужие строки:
   место, ведущий, «как пройти». Ссылку на карту туда кладут регулярно. */
.lead { font-size: 19px; color: var(--text); overflow-wrap: anywhere; }
.muted { color: var(--text-2); overflow-wrap: anywhere; }
.small { font-size: 14px; }

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s3);
}

/* Надстрочная метка: «бета», «открытая встреча». */
.beta {
  display: inline-block;
  margin: 0 0 var(--s3);
  padding: var(--s1) var(--s2);
  background: var(--gold-soft);
  border: 1px solid var(--gold);
  color: var(--gold-ink);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* ═══════════════════════════════════════════════════════ кнопки */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 44px;
  padding: 0 var(--s4);
  border: 1px solid var(--line);
  box-shadow: var(--bevel-out);
  background: var(--bg-2);
  color: var(--text);
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--fast);
}
.btn:hover { background: #fff; }
.btn:active { box-shadow: var(--bevel-in); }
/* Кольцо двухцветное, и это не украшение. Одно золото стояло здесь раньше, и
   на панели --bg оно даёт 1.8:1 — полоса, которую видно только если знать,
   что она есть. Тёмный ободок кладётся под золото и вокруг него: на светлой
   панели работает ободок (12.9:1), на тёмном полотне шапки — золото (7.3:1).
   Порядок важен: `.btn:active` стоит выше и той же силы, поэтому нажатую и
   одновременно сфокусированную кнопку добирает отдельное правило ниже. */
.btn:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
  box-shadow: var(--bevel-out), var(--focus-halo);
}
.btn:focus-visible:active { box-shadow: var(--bevel-in), var(--focus-halo); }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.btn-primary:hover { background: #0d3099; }

.btn-lg { min-height: 52px; padding: 0 var(--s5); font-size: 18px; }
.btn-sm { min-height: 36px; padding: 0 var(--s3); font-size: 14px; }

/* Пальцем в 36 пикселей попадают через раз, а мелкие кнопки здесь несут
   главные действия: «Открыть в Telegram» в шапке и «Подробнее» на карточке
   встречи. На мыши 36 экономят место, на касании этой экономии не бывает. */
@media (pointer: coarse) {
  .btn-sm { min-height: 44px; padding: 0 var(--s4); }
  /* Название в шапке — это ссылка «на главную», и мимо неё пальцем попадали:
     строка высотой 34 пикселя при знаке в 34 пикселя. Ширины хватало и так,
     не хватало высоты. */
  .logo { min-height: 44px; }
}

/* ═══════════════════════════════════════════════════════ чипы и числа */

.chips { display: flex; flex-wrap: wrap; gap: var(--s2); margin: 0; }
/* Призыв под плашками стоял к ним вплотную и читался как ещё одна плашка,
   только другой ширины. Отступ возвращает ему статус отдельного действия. */
.numbers + .chips { margin-top: var(--s4); }

.chip {
  display: inline-flex;
  align-items: center;
  /* Промежуток между значком и словом — как у чипа в приложении. На витрине
     чип носит одно слово и промежутку нечего разделять, а на личной странице
     в нём кружок статуса и медальная эмодзи. */
  gap: var(--s1);
  min-height: 32px;
  padding: 0 var(--s3);
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  box-shadow: var(--bevel-out);
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  /* Темы каталога и имена ведущих пишут люди, и слово вроде
     «Интернационализациявнешнеэкономическойдеятельности» приезжает целиком.
     Плашка меряется по самому длинному слову, а перенести его нечем: на 320
     такая плашка уезжала на 170 пикселей вправо и тащила за собой прокрутку
     всей страницы. Предел ширины держит её в строке, перенос — внутри. */
  max-width: 100%;
  overflow-wrap: anywhere;
}
.chip-gold { background: var(--gold-soft); border-color: var(--gold); color: var(--gold-ink); }

.numbers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--s2);
  margin-top: var(--s4);
}
.numbers.few { grid-template-columns: repeat(auto-fit, minmax(160px, 210px)); }

.number {
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  box-shadow: var(--bevel-out);
  padding: var(--s3);
  text-align: center;
}
/* Подпись под числом длиной в слово («человекпредпринимателей») распирала
   плашку изнутри: на 320 две плашки в ряду вылезали за правый край панели. */
.number strong { display: block; font-size: 26px; line-height: 1.15; font-weight: 800; overflow-wrap: anywhere; }
.number small { display: block; color: var(--text-2); font-size: 13px; margin-top: 2px; overflow-wrap: anywhere; }

/* ═══════════════════════════════════════════════════════ лица и встречи */

.faces { display: flex; flex-wrap: wrap; gap: var(--s1); margin-top: var(--s4); }

.face.more { background: var(--accent-soft); color: var(--accent); }

/* Фотография внутри кружка. Правила не было вовсе: картинка держалась только
   на общем `img { max-width: 100% }`, то есть подгонялась по ширине, а высота
   оставалась своей. Квадратная аватарка попадала в плитку случайно, любая
   другая вылезала за неё и ломала ряд. В мини-апе это правило есть с самого
   начала, на витрину его просто не перенесли. */
.face img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.face {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  box-shadow: var(--bevel-out);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 800;
  font-size: 14px;
  /* Обрезает фотографию по квадрату плитки. Раньше стояло вторым правилом
     `.face` отдельной строкой выше — то же имя, то же место, а искать
     свойство приходилось в двух местах. */
  overflow: hidden;
}

/* Портреты. Блок собирает _portraits_block в web.py и отдаёт разметку
   .portraits > .portrait-grid > .portrait > (img, .who > (b, small)).
   Правил на него не было ни одного, и это видно только на живой базе: в
   тестах блок не появляется, потому что его показывают лишь тем, у кого есть
   настоящая фотография, а в засеве фотографий нет. На боевой витрине из-за
   этого карточки рисовались строчными ссылками высотой в двадцать пикселей,
   аватарки растягивались во всю ширину панели, а два человека наезжали друг
   на друга в одной строке. */

.portrait-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: var(--s2);
  margin-top: var(--s4);
}

.portrait {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3);
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  box-shadow: var(--bevel-out);
  color: var(--text);
  text-decoration: none;
  /* Ячейка сетки по умолчанию не уже своего содержимого, а содержимое тут —
     чужая подпись в одну строку. Без этого длинная подпись раздвигала бы
     колонку вместо того, чтобы обрезаться. */
  min-width: 0;
}
.portrait img {
  width: 52px;
  height: 52px;
  flex: none;
  object-fit: cover;
  display: block;
  border: 1px solid var(--line);
}
.who { display: flex; flex-direction: column; min-width: 0; }
.who b { font-weight: 800; font-size: 16px; line-height: 1.25; overflow-wrap: anywhere; }
/* Подпись человек пишет сам, и пишет сколько хочет: в базе лежат строки на
   полтораста знаков. Две строки — столько же, сколько занимает имя с полем,
   и карточки в ряду остаются одной высоты. */
.who small {
  color: var(--text-2);
  font-size: 13px;
  line-height: 1.3;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

a.portrait:hover { background: #fff; }
a.portrait:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
  box-shadow: var(--bevel-out), var(--focus-halo);
}
a.portrait:active { box-shadow: var(--bevel-in); }
a.portrait:focus-visible:active { box-shadow: var(--bevel-in), var(--focus-halo); }

/* Встречи. Классы взяты из разметки, которую собирает _event_card в web.py:
   .event-list > .event > (h3, .when, .text, .row). Раньше здесь стояли
   выдуманные .cards/.card, и список рисовался браузерным по умолчанию — с
   точками и без рамок. */

/* `min(300px, 100%)` вместо голых 300px. Голые 300 — это не «не уже трёхсот»,
   а «ровно триста, даже если места 254»: на 320 колонка вылезала за панель, и
   вся страница ехала вбок на 13 пикселей. Ниже трёхсот колонка теперь просто
   сжимается до ширины родителя, а выше ведёт себя как раньше. */
.event-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: var(--s3);
  margin: 0;
  padding: 0;
  list-style: none;   /* точки маркеров: список тут плитками, а не перечнем */
}

.event {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding: var(--s4);
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  box-shadow: var(--bevel-out);
}
/* Название и описание встречи набирает человек в боте. Туда попадают ссылки
   на регистрацию и слова без пробелов, длиннее плитки: без переноса они
   распирали плитку и выталкивали афишу за экран. */
.event h3 { margin: 0; font-size: 18px; font-weight: 800; line-height: 1.25; overflow-wrap: anywhere; }
.event .when { margin: 0; color: var(--text-2); font-size: 14px; overflow-wrap: anywhere; }
.event .text { margin: 0; font-size: 15px; overflow-wrap: anywhere; }

/* Чипы и кнопка в подвале плитки. margin-top:auto прижимает их вниз, чтобы у
   соседних плиток разной высоты кнопки стояли на одной линии. */
.event .row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  margin-top: auto;
  padding-top: var(--s1);
}

/* Прошедшие приглушены: они на странице как доказательство, что встречи
   вправду были, а не как то, куда сейчас идти. */
.events.past .event { opacity: .78; }
.events.past .event:hover { opacity: 1; }

/* Строка вместо пустой рамки, когда афиша пуста. */
.empty { margin: 0; color: var(--text-2); }

/* ═══════════════════════════════════════════════════════ личная страница */

/* Страница человека, /u/{slug}. Она одна из четырёх поверхностей стояла на
 * @freedo/ui-lib со слоем landing.css поверх: круглые пилюли, фиолетовый
 * акцент, мягкие тени, своя тёмная тема и никакой шапки. С витрины сюда ведут
 * портреты из блока «Кто здесь есть», и человек, кликнув по лицу, попадал в
 * другой продукт, из которого некуда вернуться.
 *
 * Ниже только то, чего на витрине ещё не было: чужой текст из анкеты, чип
 * доступности, строка «сейчас ищу», рекомендации и контакты. Всё остальное на
 * этой странице собрано из тех же section, .section-head, .chip и .btn.
 */

/* Текст, который человек написал о себе сам. Переводы строк он ставил
 * осмысленно: без pre-line абзацы слипались в один. Класс назван так же, как
 * в приложении, — это ровно тот же кусок текста, показанный в другом месте. */
.about-text {
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* Доступность. Чип из тех же деталей, что остальные, плюс цвет. Цвет несёт
 * смысл, но не в одиночку: рядом всегда слово, и на бумаге, где заливка не
 * печатается, остаётся оно. Заголовки статусов короткие и заданы в коде,
 * поэтому строку не переносим: «В завале» в две строки читается как сбой. */
.status { white-space: nowrap; }
.status .dot { width: 14px; height: 14px; flex: none; }

/* Порядок важен: правила стоят после .chip и той же силы, иначе заливку чипа
   не перебить. Свойства лежат в своих правилах, а не в общем селекторе. */
.status-open     { background: var(--ok-bg);   color: var(--ok-text);   border-color: var(--ok-line); }
.status-business { background: var(--warn-bg); color: var(--warn-text); border-color: var(--warn-line); }
.status-busy     { background: var(--bad-bg);  color: var(--bad-text);  border-color: var(--bad-line); }

/* «Сейчас ищу» — строка, которую человек меняет чаще всего остального на
 * странице, и единственная с сегодняшним сроком годности. Отбита слева
 * акцентом: в приложении она отбита им же. */
.seeking {
  margin: var(--s4) 0 0;
  padding: var(--s3);
  border: 1px solid var(--line-soft);
  border-left: 4px solid var(--accent);
  background: var(--bg-2);
  box-shadow: var(--bevel-out);
  overflow-wrap: anywhere;
}

/* Рекомендации. Чужие слова весомее собственного описания, поэтому им плитка
 * и кавычка, а не строка перечня. */
.recs { display: grid; gap: var(--s3); }

.rec {
  margin: 0;
  padding: var(--s4);
  border: 1px solid var(--line-soft);
  border-left: 4px solid var(--accent);
  background: var(--bg-2);
  box-shadow: var(--bevel-out);
}
.rec blockquote { margin: 0; overflow-wrap: anywhere; }

/* Подпись под цитатой: имя, чем занимается, откуда знает. Три куска в строку,
   на узком переносятся по одному. */
.rec figcaption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s1) var(--s3);
  margin-top: var(--s2);
  font-size: 14px;
}
.rec figcaption b { font-weight: 800; overflow-wrap: anywhere; }
.rec figcaption span { color: var(--text-2); overflow-wrap: anywhere; }
.rec figcaption em { font-style: normal; color: var(--text-2); }

/* Контакты. Строка кликается целиком: подпись слева и значение справа по
 * отдельности — две мишени вместо одной, и обе уже пальца. */
.links { display: grid; gap: var(--s2); }

.links a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  min-height: 44px;
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line-soft);
  box-shadow: var(--bevel-out);
  background: var(--bg-2);
  color: var(--text);
  text-decoration: none;
  /* Адрес человек вписывает сам, и в поле приезжает строка без пробелов
     длиннее экрана: на 320 она уводила вбок всю страницу. */
  overflow-wrap: anywhere;
}
.links a:hover { background: #fff; }
.links a:active { box-shadow: var(--bevel-in); }
.links a:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
  box-shadow: var(--bevel-out), var(--focus-halo);
}
.links a:focus-visible:active { box-shadow: var(--bevel-in), var(--focus-halo); }

/* Подпись слева: «Телефон», «Почта», «Сайт». Не сжимается, иначе длинное
   значение справа выдавливает её в столбик из букв. */
.links .k { flex: none; color: var(--text-2); font-size: 14px; font-weight: 700; }

/* ═══════════════════════════════════════════════════════ карта встречи */

/* Рамка держит пропорцию сама, без скрипта: отступ снизу в процентах считается
   от ширины родителя, и карта не прыгает при загрузке. */
.map {
  position: relative;
  height: 0;
  padding-bottom: 56%;
  margin: var(--s3) 0;
  border: 1px solid var(--line);
  box-shadow: var(--bevel-out);
  background: var(--bg-2);
  overflow: hidden;
}
.map iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  /* Карта единственная картинка на сайте, которой пиксельность во вред:
     подписи улиц от неё рассыпаются. */
  image-rendering: auto;
}

/* На телефоне карта выше по пропорции: узкая и плоская показывает две улицы
   и ничего вокруг. */
@media (max-width: 640px) {
  .map { padding-bottom: 75%; }
}

/* Печатать карту бессмысленно: серый прямоугольник на полстраницы. Адрес и
   ссылки рядом остаются. */
@media print {
  .map { display: none; }
}

.where .lead { margin-bottom: 0; }
.chips.calendar { margin-top: var(--s3); }

/* ═══════════════════════════════════════════════════════ как попасть */

.join ol { margin: 0 0 var(--s4); padding-left: 1.3em; }
.join li { margin-bottom: var(--s2); }

.wide-only { display: none; }
@media (min-width: 560px) { .wide-only { display: inline; } }

@media (max-width: 640px) {
  body { font-size: 16px; }
  section { padding: var(--s4); }
  .lead { font-size: 17px; }
  /* По одному числу в строке четыре плашки съедали весь экран, и до афиши
     приходилось листать. Два в ряд читаются так же и занимают вдвое меньше. */
  .numbers, .numbers.few { grid-template-columns: 1fr 1fr; }
  .number strong { font-size: 22px; }
  /* Плитки с инициалами — украшение, а не содержание: на узком они не
     должны отжимать вниз всё остальное. */
  .face { width: 36px; height: 36px; font-size: 12px; }
  /* Главное действие на телефоне во всю ширину: мимо не промахнёшься, и
     видно, что оно тут одно, а не первое из нескольких. */
  .chips .btn-lg { width: 100%; }
  h1 { font-size: clamp(24px, 7vw, 32px); }
}

/* Самые узкие телефоны, 320 и 360. Здесь шапка не сходится: название в
   полном размере плюс кнопка «Telegram» шире, чем 288 пикселей между
   полями, и название ломалось надвое. Поджимаем поля, промежуток и сам
   знак — в строку садится всё, включая кнопку в 44 пикселя для пальца.
   Порог 365, а не 400: на 375 и 414 полный размер помещается сам. */
@media (max-width: 365px) {
  .topbar { padding: var(--s3); gap: var(--s2); }
  .logo { font-size: 16px; gap: var(--s1); }
  .logo img { width: 30px; height: 30px; }
  main { padding: 0 var(--s3) var(--s6); }
  footer { padding: 0 var(--s3) var(--s5); }
}

/* Сайт открывают и с тёмной темой в системе. Полотно у нас и так тёмное,
 * а панели остаются светлыми намеренно: это хром из логотипа, и в тёмном
 * исполнении он перестаёт быть хромом. Меняем только то, что читается
 * поверх холста. */
@media (prefers-color-scheme: dark) {
  footer { color: #93a6cf; }
}

/* ═══════════════════════════════════════════════════════ бумага */

/* Правил для печати не было вовсе, а страницу встречи распечатывают: её
 * вешают в баре и приносят на саму встречу. Браузер по умолчанию не печатает
 * фоны, и на бумагу уходило вот что: тёмное полотно исчезает, а поверх белого
 * остаётся белое название в шапке, белые подписи на кнопках и подвал цветом
 * #9fb0d6, который на белом даёт 2.2:1. То есть ровно те строки, ради которых
 * лист и печатали, оказывались пустыми местами.
 *
 * Свойства разложены по правилам самих компонентов, а не собраны в один
 * групповой селектор: в этом файле уже дважды такой селектор перебивал
 * правило компонента, и оба раза это находили не сразу.
 */
@media print {
  body { background: #fff; }

  /* Название рисовалось белым по тёмному полотну. Полотна на бумаге нет. */
  .logo { color: var(--ink); }

  /* Подвал набран под тёмный фон: на белом это 2.2:1 и 3.0:1. */
  footer { color: var(--text); }
  footer .footnote { color: var(--text-2); }

  /* Синяя заливка кнопки не печатается, а белые буквы на ней — печатаются
     белым. Оставляем рамку и тёмный текст. */
  .btn {
    background: none;
    color: var(--ink);
    border-color: var(--ink);
    max-width: 100%;
    overflow-wrap: anywhere;
  }
  .btn-primary { background: none; color: var(--ink); border-color: var(--ink); }
  /* На бумаге по кнопке не щёлкнешь: дописываем адрес, ради которого она тут
     и стоит. */
  .btn[href^="http"]::after { content: " " attr(href); font-weight: 400; }

  /* Мозаика инициалов — украшение, и цвет плитки задан прямо в разметке.
     Заливка не печатается, буквы на ней белые: вышел бы ряд пустых квадратов. */
  .faces { display: none; }

  /* Плитку не режем между листами: половина встречи на одной странице, вторая
     на другой — это уже не афиша. */
  .event { break-inside: avoid; }
  .portrait { break-inside: avoid; }
  .number { break-inside: avoid; }
  /* Цитату не режем: половина рекомендации на одном листе, вторая на другом —
     это уже не рекомендация. Разделу целиком «не резать» тут мало: когда
     рекомендаций много, раздел выше листа, и запрет браузер игнорирует. */
  .rec { break-inside: avoid; }
  .links a { break-inside: avoid; }
  section { break-inside: avoid; }
}
