/* Посадочные страницы под сценарии.

   ЗАЧЕМ ОТДЕЛЬНЫЙ ФАЙЛ. Набор живёт не в `_legal_template.html`, а инлайнится
   в <head> только тех шести страниц, которым он нужен: общий шаблон обслуживает
   241 страницу (правовые, лента, статьи), и возить на них неиспользуемые
   килобайты незачем. Плюс изоляция: прошлая попытка добавила в общий шаблон
   правило `.art .faq`, и блок вопросов поехал во ВСЕХ статьях блога.

   ИЗОЛЯЦИЯ. Каждый селектор начинается с `.sol` — корневого класса посадочной.
   Ни одного правила без этого префикса здесь быть не должно: `.art`,
   `.legal-content` и общие компоненты (`.btn`, `.callout`, `.art-tbl`) страница
   либо использует как есть, либо не трогает вовсе.

   ЖЁЛТЫЙ — СОСТОЯНИЕ, А НЕ УКРАШЕНИЕ. Одно правило на все три страницы: жёлтым
   отмечено то, ради чего человек пришёл. На собеседовании — подсказка, на
   совещании — то, что осталось после разговора, на переводе — дорожка, которую
   человек читает. Поэтому жёлтого на странице мало и он всегда значит одно.  */

/* ── Оболочка ────────────────────────────────────────────────────────────── */
/* Мелкие подписи набраны --muted, а не --faint: 10-11 пунктов моноширинного
   с #767676 на бумажном фоне дают 4.0:1 — ниже порога AA для обычного текста. */
.sol { --sol-gutter:104px; }
.sol-wrap { max-width:1120px; margin:0 auto; padding:0 24px; }

/* Секция — полоса во всю ширину с жёсткой нижней границей: тот же приём, что
   держит ритм главной страницы. Фон задаётся модификатором, а не инлайном. */
.sol-sec { padding:64px 0; border-bottom:2px solid var(--ink); }
.sol-sec--soft { background:var(--y-soft); }
.sol-sec--raised { background:var(--raised); }
.sol-sec--dark { background:var(--band-bg); color:var(--band-fg); border-bottom:none; }
/* В тёмной теме --band-bg (#0A0A0A) почти сливается со страницей (#0E0E0E),
   и полоса перестаёт быть полосой — а на странице про совещания на ней стоит
   блок ограничений, ради заметности и вынесенный отдельно. Поднимаем фон:
   отношение «этот кусок другой» остаётся, только теперь полоса светлее
   страницы, а не темнее. */
[data-theme="dark"] .sol-sec--dark { background:var(--raised); }
.sol-sec--last { border-bottom:none; }

/* Шапка секции: слева узкая колонка данных, справа заголовок. Колонка несёт
   ЗНАЧЕНИЕ, своё у каждой страницы (отметка времени, «до/после», пара языков),
   а не декоративную надпись над каждым заголовком. */
.sol-sec-head { display:grid; grid-template-columns:var(--sol-gutter) minmax(0,1fr); gap:24px; align-items:baseline; }
.sol .sol-kicker { font-family:"JetBrains Mono",monospace; font-size:11px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted); line-height:1.5;
  border-top:2px solid var(--ink); padding-top:8px; }
.sol .sol-sec--dark .sol-kicker { color:var(--band-accent); border-top-color:var(--band-accent); }
.sol h2 { font-family:"Unbounded","Unbounded Fallback",sans-serif; font-size:clamp(23px,3.1vw,36px); font-weight:800;
  letter-spacing:-0.03em; line-height:1.1; }
.sol h3 { font-size:16px; font-weight:800; letter-spacing:-0.01em; }
/* Базовая типографика намеренно задана через элемент: разметка страницы и так
   плотная классами. Обратная сторона — специфичность (0,1,1) выше, чем у
   одноклассового правила компонента, поэтому у всех правил для <p> ниже стоит
   префикс `.sol`. Без него лид и подписи молча получали базовый размер. */
.sol p { font-size:15.5px; line-height:1.66; color:var(--muted); }
.sol p + p { margin-top:12px; }
/* Абзац в ТЁМНОЙ полосе. Правило стоит здесь, сразу за `.sol p`, и намеренно
   на класс длиннее его: `--muted` — это серый для светлой страницы, и на фоне
   #0A0A0A он даёт контраст 2.2:1 при норме 4.5:1. Текст был читаем с трудом на
   640 страницах.

   ПОЧЕМУ ОДНОЙ ОБЪЯВЛЕННОЙ ПРАВКИ БЫЛО МАЛО. Она существовала — рядом с
   `.sol-sec--dark` в начале файла, — но у обеих селекторов одна специфичность
   (0,1,1), а при равной побеждает ТОТ, ЧТО НИЖЕ. `.sol p` объявлен ниже и молча
   отменял её. Отсюда и лишний `.sol` впереди: (0,2,1) выигрывает независимо от
   того, куда правило переедет при следующей правке файла. */
.sol .sol-sec--dark p { color:rgba(242,239,230,.78); }
.sol b { font-weight:700; color:var(--ink); }
/* Тот же приём и по той же причине, что у абзаца выше. Сегодня это правило
   выигрывает у `.sol b` одним лишь порядком, но проигрывает `.sol-lede b` и
   `.sol-ledger li b`: поставь кто-нибудь лид или книгу в тёмную полосу — и
   жирное слово покрасилось бы чернилами светлой страницы. Такой разметки
   сейчас нет ни на одной из 640 страниц, поэтому правка ничего не меняет на
   вид; она убирает ловушку, которая иначе ждала бы своего фрагмента. */
.sol .sol-sec--dark b { color:var(--band-fg); }
.sol-body { margin-top:22px; max-width:64ch; }
.sol-body p + p { margin-top:14px; }
/* `:not(.btn)` здесь не косметика. Без него правило (0,1,1) перебивало `.btn-y`
   (0,1,0), кнопка наследовала цвет секции — и в тёмной полосе призыв оказался
   светлым текстом по жёлтому фону. */
.sol a:not(.btn) { color:inherit; text-decoration:underline; text-decoration-color:var(--y);
  text-decoration-thickness:2px; text-underline-offset:3px; }
.sol a:not(.btn):hover { background:var(--y-soft); }
.sol .sol-sec--dark a:not(.btn):hover { background:transparent; color:var(--y); }

/* ── Первый экран ────────────────────────────────────────────────────────── */
.sol-hero { padding:44px 0 56px; border-bottom:2px solid var(--ink); }
.sol-hero .crumbs { margin-bottom:20px; }
.sol-hero-grid { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:44px; align-items:center; }
/* min-width у грид-элемента по умолчанию auto: «собеседования,» в заголовке
   шире колонки, и без этого слово вылезало под соседнюю панель. */
.sol-hero-grid > * { min-width:0; }
.sol h1 { font-family:"Unbounded","Unbounded Fallback",sans-serif; font-size:clamp(29px,4vw,46px); font-weight:900;
  letter-spacing:-0.035em; line-height:1.02; overflow-wrap:break-word; }
.sol .sol-lede { margin-top:20px; font-size:17.5px; line-height:1.55; color:var(--muted); max-width:44ch; }
.sol-lede b { color:var(--ink); font-weight:700; }
.sol-actions { display:flex; flex-wrap:wrap; gap:12px; align-items:center; margin-top:28px; }
.sol-actions .btn { padding:15px 28px; font-size:14.5px; }
/* У общей `.btn` видимой обводки фокуса нет; добавляем её локально, не трогая
   компонент, которым пользуются ещё 241 страница. */
.sol .btn:focus-visible { outline:2px solid var(--ink); outline-offset:3px; }
.sol-sec--dark .btn:focus-visible { outline-color:var(--y); }
.sol .sol-fine { margin-top:14px; font-family:"JetBrains Mono",monospace; font-size:11px; font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }

/* ── Живой оверлей: первый экран страницы про собеседование ──────────────── */
/* Панель повторяет оверлей продукта и остаётся тёмной в обеих темах: в
   приложении он тёмный всегда. Цвета поэтому числами, как у `.ovd`. */
.sol-cue-panel { background:#0E1014; border:2px solid var(--ink); border-radius:18px;
  box-shadow:var(--shadow-hard); padding:14px 16px 16px; }
.sol-cue-bar { display:flex; align-items:center; gap:12px; }
.sol-cue-play { border:1.5px solid #E7AE46; border-radius:999px; background:transparent; color:#E7AE46;
  font:inherit; font-size:11px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  padding:7px 15px; cursor:pointer; flex:none; }
.sol-cue-play:hover { background:#E7AE46; color:#0E1014; }
.sol-cue-play:focus-visible { outline:2px solid #E7AE46; outline-offset:2px; }
.sol-cue-wave { display:inline-flex; align-items:flex-end; gap:3px; height:20px; flex:none; }
.sol-cue-wave i { width:3px; height:38%; background:#E7AE46; border-radius:2px; }
.sol-cue-wave i:nth-child(2) { height:70%; }
.sol-cue-wave i:nth-child(4) { height:56%; }
.sol-cue.on .sol-cue-wave i { animation:sol-wave 900ms ease-in-out infinite; }
.sol-cue.on .sol-cue-wave i:nth-child(2) { animation-delay:.10s; }
.sol-cue.on .sol-cue-wave i:nth-child(3) { animation-delay:.20s; }
.sol-cue.on .sol-cue-wave i:nth-child(4) { animation-delay:.30s; }
.sol-cue.on .sol-cue-wave i:nth-child(5) { animation-delay:.15s; }
@keyframes sol-wave { 0%,100% { height:24%; } 50% { height:100%; } }
.sol-cue-tag { font-family:"JetBrains Mono",monospace; font-size:9.5px; font-weight:800;
  letter-spacing:.12em; text-transform:uppercase; color:rgba(255,255,255,.45); }
.sol-cue-step { margin-inline-start:auto; font-family:"JetBrains Mono",monospace; font-size:10.5px;
  font-weight:700; color:#E7AE46; font-variant-numeric:tabular-nums; white-space:nowrap; }
.sol-cue-body { margin-top:12px; min-height:216px; border-radius:14px; background:rgba(255,255,255,.05);
  padding:14px 15px; display:flex; flex-direction:column; gap:11px; }
/* Реплика: подпись говорящего сверху, текст под ней. Своя реплика и чужая
   различаются подписью, а не цветом, — цвет здесь занят подсказкой. */
.sol-cue-turn { color:#F2EFE6; }
.sol-cue-who { display:block; font-family:"JetBrains Mono",monospace; font-size:9px; font-weight:800;
  letter-spacing:.14em; text-transform:uppercase; color:rgba(255,255,255,.42); margin-bottom:4px; }
.sol-cue-said { font-size:14.5px; line-height:1.55; }
/* Подсказка — единственное жёлтое пятно в панели: ради неё всё и происходит. */
.sol-cue-hint { border:2px solid var(--y); border-radius:12px; background:rgba(255,224,0,.09);
  padding:11px 13px; }
.sol-cue-hint .sol-cue-who { color:var(--y); }
.sol-cue-hint .sol-cue-said { color:#FFF6C4; }
.sol-cue-caret { display:inline-block; width:2px; height:1em; background:#E7AE46;
  vertical-align:-2px; margin-inline-start:2px; animation:sol-caret 900ms steps(1) infinite; }
@keyframes sol-caret { 0%,50% { opacity:1; } 51%,100% { opacity:0; } }
.sol .sol-cue-foot { margin-top:12px; font-family:"JetBrains Mono",monospace; font-size:10.5px;
  font-weight:700; letter-spacing:.05em; color:var(--muted); }

/* ── Такты разговора: горизонтальная шкала времени ───────────────────────── */
/* Шаги неравные намеренно: между вопросом и слышимостью разрыва нет, а между
   контекстом и подсказкой он есть. Шкала показывает время, а не рисует его. */
.sol-beats { list-style:none; margin:30px 0 0; padding:0;
  display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:0; }
.sol-beat { position:relative; padding:26px 22px 0 0; }
/* Связка рисуется КАЖДЫМ тактом до следующего, а не одной линией через весь
   блок: у последнего её просто нет, и линия не обещает пятый такт. Тот же приём
   работает и когда шкала встаёт вертикально на телефоне. */
.sol-beat::after { content:""; position:absolute; top:9px; inset-inline-start:20px;
  inset-inline-end:0; height:2px; background:var(--ink); }
.sol-beat:last-child::after { content:none; }
.sol-beat::before { content:""; position:absolute; top:0; inset-inline-start:0; width:20px; height:20px;
  border:2px solid var(--ink); border-radius:50%; background:var(--bg); }
.sol-beat--now::before { background:var(--y); }
.sol-beat-t { display:block; font-family:"JetBrains Mono",monospace; font-size:11px; font-weight:800;
  letter-spacing:.06em; color:var(--muted); font-variant-numeric:tabular-nums; }
.sol-beat b { display:block; margin-top:7px; font-size:16px; font-weight:800; letter-spacing:-0.01em; }
.sol-beat span.sol-beat-d { display:block; margin-top:6px; font-size:13.5px; line-height:1.5; color:var(--muted); }

/* ── Ведомость «где черта»: две колонки без победителя ───────────────────── */
.sol-ledger { display:grid; grid-template-columns:1fr 1fr; gap:0; margin-top:26px;
  border:2px solid var(--ink); border-radius:var(--r); background:var(--paper); overflow:hidden; }
.sol-ledger-col { padding:20px 22px 22px; }
.sol-ledger-col + .sol-ledger-col { border-inline-start:2px solid var(--ink); }
.sol-ledger-cap { display:block; font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; padding-bottom:9px; border-bottom:2px solid var(--ink); }
/* Семантические зелёный и красный берём из системы, но подкручиваем яркость
   ЛОКАЛЬНО: сами токены --grn/--red живут ещё и в статьях блога, а на белой
   карточке 10-пунктовый --grn даёт 4.3:1 — ниже порога AA. В тёмной теме та же
   беда у --red (3.9:1 на #161616), поэтому пары свои для каждой темы.
   Цвет здесь — не единственный признак: что где, сказано словами в самой метке. */
.sol-ledger-col--ok .sol-ledger-cap { color:#15702F; }
.sol-ledger-col--no .sol-ledger-cap { color:var(--red); }
[data-theme="dark"] .sol-ledger-col--ok .sol-ledger-cap { color:#4FBF6E; }
[data-theme="dark"] .sol-ledger-col--no .sol-ledger-cap { color:#F5766C; }
.sol-ledger ul { list-style:none; margin:0; padding:0; }
.sol-ledger li { margin-top:13px; font-size:14.5px; line-height:1.5; color:var(--muted); }
.sol-ledger li b { display:block; color:var(--ink); font-weight:700; margin-bottom:2px; }

/* ── Границы продукта ─────────────────────────────────────────────────────
   Блок обязателен на всех трёх страницах: человек должен узнать про потоковую
   транскрипцию и системный звук ДО регистрации, а не после оплаты. Оформлен
   как обычная часть страницы, без интонации извинения. */
.sol-limits { display:grid; grid-template-columns:1fr 1fr; gap:18px; margin-top:26px; }
/* Вариант в строку: ограничения идут теми же двумя колонками, что и дорожки
   перевода выше, — страница про перевод держит одну сетку сверху донизу. */
.sol-limits--rows { grid-template-columns:1fr; list-style:none; padding:0; gap:0;
  border:2px solid var(--ink); border-radius:var(--r); }
.sol-limits--rows .sol-limit { border:none; display:grid; grid-template-columns:var(--sol-gutter) minmax(0,1fr);
  gap:0 24px; align-items:start; }
.sol-limits--rows .sol-limit + .sol-limit { border-top:2px solid var(--ink); }
.sol-limits--rows .sol-limit b, .sol-limits--rows .sol-limit p { grid-column:2; margin-top:0; }
.sol-limits--rows .sol-limit p { margin-top:9px; }
.sol-limit { border:2px solid currentColor; border-radius:var(--r); padding:20px 22px 22px; }
.sol-limit-n { font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; opacity:.65; }
.sol-limit b { display:block; margin-top:10px; font-size:17px; font-weight:800; letter-spacing:-0.01em; }
.sol-limit p { margin-top:9px; font-size:14.5px; }

/* ── Карточки-шаги (подготовка, режимы) ──────────────────────────────────── */
.sol-cards { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; margin-top:26px; }
.sol-cards--two { grid-template-columns:repeat(2,minmax(0,1fr)); }
.sol-card { border:2px solid var(--ink); border-radius:var(--r-lg); background:var(--paper);
  padding:20px 22px 22px; }
.sol-card--mark { background:var(--y-soft); }
.sol-card-cap { display:block; font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.sol-card h3 { margin-top:10px; }
.sol-card p { margin-top:8px; font-size:14px; }

/* ── Конвертер «сказано → осталось»: страница про совещания ──────────────── */
.sol-cast { margin-top:28px; border:2px solid var(--ink); border-radius:var(--r-lg);
  background:var(--paper); box-shadow:var(--shadow-hard); overflow:hidden; }
.sol-cast-bar { display:flex; flex-wrap:wrap; align-items:center; gap:14px;
  padding:12px 18px; background:var(--ink); color:var(--bg); }
.sol-cast-bar .sol-cast-cap { font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; }
.sol-cast-btn { margin-inline-start:auto; border:1.5px solid var(--bg); border-radius:var(--r-sm);
  background:transparent; color:var(--bg); font:inherit; font-size:11px; font-weight:800;
  letter-spacing:.06em; text-transform:uppercase; padding:7px 15px; cursor:pointer; }
.sol-cast-btn:hover { background:var(--y); color:var(--y-ink); border-color:var(--y); }
.sol-cast-btn:focus-visible { outline:2px solid var(--y); outline-offset:2px; }
.sol-cast-cols { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
.sol-cast-col { padding:20px 22px 24px; display:flex; flex-direction:column; }
.sol-cast-col + .sol-cast-col { border-inline-start:2px solid var(--ink); background:var(--raised); }
.sol-cast-col > .sol-cast-cap { display:block; font-family:"JetBrains Mono",monospace; font-size:10px;
  font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-bottom:14px; }
/* Реплики: спикер отдельной строкой, чтобы длинное имя не съедало ширину. */
.sol-said { list-style:none; margin:0; padding:0; }
.sol-said li { margin-top:12px; font-size:14.5px; line-height:1.55; color:var(--muted);
  padding-inline-start:12px; border-inline-start:2px solid var(--line-soft);
  transition:border-color 140ms var(--ease), color 140ms var(--ease); }
.sol-said li:first-child { margin-top:0; }
.sol-said li.on { border-inline-start-color:var(--y); color:var(--ink); }
.sol-said-who { display:block; font-family:"JetBrains Mono",monospace; font-size:9px; font-weight:800;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin-bottom:3px; }
/* Итог: карточки того, что осталось. До разбора здесь честная пустота, а не
   заранее нарисованный результат. */
.sol-kept { list-style:none; margin:0; padding:0; display:grid; gap:10px; }
/* Пустое начальное состояние включает СКРИПТ (класс `armed`), а не разметка:
   без JS кнопка «разобрать» не появляется, и результат обязан быть виден сразу,
   иначе половина блока просто не существует для читателя.
   Карточки именно УБИРАЮТСЯ из потока, а не гасятся прозрачностью: погашенные,
   они держали полколонки пустоты, и рамка «место под результат» висела в
   верхнем углу дыры вместо того, чтобы её занять. */
.sol-cast.armed:not(.done) .sol-kept { display:none; }
.sol-cast.armed.done .sol-kept li { animation:sol-rise 300ms var(--ease) backwards; }
.sol-cast.armed.done .sol-kept li:nth-child(2) { animation-delay:110ms; }
.sol-cast.armed.done .sol-kept li:nth-child(3) { animation-delay:220ms; }
.sol-cast.armed.done .sol-kept li:nth-child(4) { animation-delay:330ms; }
@keyframes sol-rise { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }
.sol-keep { display:block; width:100%; text-align:start; border:2px solid var(--ink); border-radius:var(--r);
  background:var(--paper); color:var(--ink); font:inherit; padding:12px 14px; cursor:pointer;
  transition:box-shadow 120ms var(--ease), transform 120ms var(--ease); }
.sol-keep:hover, .sol-keep[aria-pressed="true"] { box-shadow:3px 3px 0 0 var(--ink); transform:translate(-1px,-1px); }
.sol-keep:focus-visible { outline:2px solid var(--ink); outline-offset:2px; }
.sol-keep-kind { display:inline-block; font-family:"JetBrains Mono",monospace; font-size:9px;
  font-weight:800; letter-spacing:.12em; text-transform:uppercase; background:var(--y);
  color:var(--y-ink); border-radius:999px; padding:3px 9px; }
.sol-keep-kind--task { background:var(--ink); color:var(--bg); }
/* Третий вид итога — открытый вопрос: не решение и не задача. Контур вместо
   заливки, потому что владельца у него ещё нет. Рамка нарисована внутренней
   тенью — border сдвинул бы метку относительно двух соседних. */
.sol-keep-kind--open { background:var(--raised); color:var(--ink);
  box-shadow:inset 0 0 0 1.5px var(--ink); }
/* Стопка итогов в первом экране — иллюстрация, а не орган управления: те же
   карточки, что соберёт разбор ниже, но нажимать в них нечего. */
.sol-keep--still { cursor:default; }
.sol-keep--still:hover { box-shadow:none; transform:none; }
.sol-keep-text { display:block; margin-top:9px; font-size:14.5px; line-height:1.45; font-weight:600; }
.sol-keep-src { display:block; margin-top:7px; font-family:"JetBrains Mono",monospace; font-size:10px;
  font-weight:700; color:var(--muted); }
.sol .sol-cast-empty { display:none; font-size:13.5px; color:var(--muted); line-height:1.55; }
/* До разбора правая колонка — не дыра, а пустая рамка: место под результат
   объявлено, а результата ещё нет. Ровно так выглядит совещание, после
   которого никто не написал письмо, — о том и текст внутри. */
.sol-cast.armed:not(.done) .sol-cast-empty { display:flex; align-items:center; flex:1;
  min-height:150px; border:2px dashed var(--line-soft); border-radius:var(--r); padding:20px 22px; }
.sol .sol-panel-foot { padding:13px 18px; border-top:2px solid var(--ink); font-family:"JetBrains Mono",monospace;
  font-size:10.5px; font-weight:700; color:var(--muted); line-height:1.5; }

/* ── Цепочка адресации: встреча → хаб → доска ────────────────────────────── */
.sol-chain { list-style:none; margin:26px 0 0; padding:0; display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr)); gap:14px; }
.sol-chain li { border:2px solid var(--ink); border-radius:var(--r); background:var(--paper);
  padding:16px 18px 18px; position:relative; }
.sol-chain li:last-child { background:var(--y); }
.sol-chain b { display:block; font-size:15px; font-weight:800; }
.sol-chain span { display:block; margin-top:6px; font-size:13px; line-height:1.45; color:var(--muted); }
.sol-chain li:last-child span { color:var(--y-ink); opacity:.72; }

/* ── Стереодорожки: страница про перевод ─────────────────────────────────── */
/* Композиция страницы — две колонки, идущие в ногу. Оригинал слева бледный,
   перевод справа жёлтый: читают правую, и это видно до чтения подписей. */
.sol-duo { margin-top:28px; border:2px solid var(--ink); border-radius:var(--r-lg);
  background:var(--paper); overflow:hidden; }
.sol-duo-bar { display:flex; flex-wrap:wrap; align-items:center; gap:14px; padding:12px 18px;
  border-bottom:2px solid var(--ink); background:var(--raised); }
.sol-duo-play { border:2px solid var(--ink); border-radius:var(--r-sm); background:var(--y); color:var(--y-ink);
  font:inherit; font-size:11px; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  padding:8px 16px; cursor:pointer; box-shadow:2px 2px 0 0 var(--ink); }
.sol-duo-play:active { box-shadow:0 0 0 0 var(--ink); transform:translate(2px,2px); }
.sol-duo-play:focus-visible { outline:2px solid var(--ink); outline-offset:3px; }
.sol-duo-lag { margin-inline-start:auto; font-family:"JetBrains Mono",monospace; font-size:10.5px;
  font-weight:700; color:var(--muted); }
.sol-duo-heads { display:grid; grid-template-columns:1fr 1fr; border-bottom:1.5px solid var(--line-soft); }
.sol-duo-heads span { padding:9px 18px; font-family:"JetBrains Mono",monospace; font-size:10px;
  font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.sol-duo-heads span + span { border-inline-start:1.5px solid var(--line-soft); }
.sol-turns { list-style:none; margin:0; padding:0; }
.sol-turn { display:grid; grid-template-columns:1fr 1fr; border-top:1.5px solid var(--line-soft); }
.sol-turn:first-child { border-top:none; }
.sol-turn > div { padding:14px 18px; }
.sol-turn-dst { border-inline-start:1.5px solid var(--line-soft); background:var(--y-soft); }
.sol-turn-who { display:block; font-family:"JetBrains Mono",monospace; font-size:9px; font-weight:800;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin-bottom:5px; }
.sol-turn-text { font-size:14.5px; line-height:1.55; }
.sol-turn-src .sol-turn-text { color:var(--muted); }
/* Во время проигрывания перевод догоняет оригинал — отставание видно глазами,
   и это честнее, чем обещание «без задержки». */
.sol-duo.playing .sol-turn { opacity:.28; transition:opacity 200ms var(--ease); }
.sol-duo.playing .sol-turn.said { opacity:1; }
.sol-duo.playing .sol-turn .sol-turn-dst { opacity:0; transition:opacity 200ms var(--ease); }
.sol-duo.playing .sol-turn.done .sol-turn-dst { opacity:1; }
/* ── Вопросы: раскрывающиеся, а не семь абзацев подряд ───────────────────── */
/* Класс блока обязан быть РОВНО `faq`: по нему собирается разметка FAQPage
   (см. faq_questions в scripts/_landing_blog.py), и вложенных <div> внутри быть
   не должно — <details> подходит. Свой класс тут добавить нельзя, поэтому
   селектор начинается с `.sol`: у статей блока `.faq` своего оформления нет, и
   правило без префикса поехало бы во все двадцать пять статей сразу. */
.sol .faq { margin-top:26px; border-top:2px solid var(--ink); }
.sol .faq details { border-bottom:1.5px solid var(--line-soft); }
.sol .faq summary { list-style:none; cursor:pointer; padding:17px 40px 17px 0; position:relative; }
.sol .faq summary::-webkit-details-marker { display:none; }
.sol .faq summary:focus-visible { outline:2px solid var(--ink); outline-offset:-2px; }
.sol .faq summary:hover h3 { text-decoration:underline; text-decoration-color:var(--y);
  text-decoration-thickness:2px; text-underline-offset:4px; }
.sol .faq h3 { display:inline; font-size:16.5px; font-weight:700; letter-spacing:-0.01em; }
.sol .faq summary::after { content:""; position:absolute; inset-inline-end:6px; top:50%; width:12px; height:2px;
  background:var(--ink); transform:translateY(-50%); }
.sol .faq summary::before { content:""; position:absolute; inset-inline-end:11px; top:50%; width:2px; height:12px;
  background:var(--ink); transform:translateY(-50%); transition:transform 160ms var(--ease); }
.sol .faq details[open] summary::before { transform:translateY(-50%) scaleY(0); }
.sol .faq details p { padding:0 40px 18px 0; font-size:14.5px; max-width:70ch; }
.sol .faq details p:first-of-type { margin-top:-2px; }

/* ── Финал ───────────────────────────────────────────────────────────────── */
.sol-end { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:32px; align-items:center; }
.sol-end h2 { font-size:clamp(24px,3.4vw,40px); }
.sol-end p { margin-top:14px; max-width:52ch; }

/* ── Адаптив ─────────────────────────────────────────────────────────────── */
@media (max-width:900px) {
  /* Колонка данных сужается, но не настолько, чтобы «ДО → ПОСЛЕ» ломалось
     пополам: 76px не хватало ровно на один символ. */
  .sol { --sol-gutter:88px; }
  .sol-hero-grid { grid-template-columns:1fr; gap:30px; }
  .sol-beats { grid-template-columns:1fr 1fr; }
  .sol-chain { grid-template-columns:1fr 1fr; }
  .sol-cards { grid-template-columns:1fr; }
  .sol-end { grid-template-columns:1fr; gap:22px; }
}
@media (max-width:760px) {
  .sol-sec { padding:44px 0; }
  .sol-hero { padding:32px 0 40px; }
  /* Колонка данных уходит из сетки и встаёт над заголовком: 76px под отметку
     времени на телефоне съедали половину строки заголовка. */
  .sol-sec-head { grid-template-columns:1fr; gap:12px; }
  .sol .sol-kicker { border-top:none; padding-top:0; }
  .sol-ledger { grid-template-columns:1fr; }
  .sol-ledger-col + .sol-ledger-col { border-inline-start:none; border-top:2px solid var(--ink); }
  .sol-limits { grid-template-columns:1fr; }
  .sol-limits--rows .sol-limit { grid-template-columns:1fr; gap:0; }
  .sol-limits--rows .sol-limit b, .sol-limits--rows .sol-limit p { grid-column:1; }
  .sol-limits--rows .sol-limit b { margin-top:10px; }
  .sol-cast-cols { grid-template-columns:1fr; }
  .sol-cast-col + .sol-cast-col { border-inline-start:none; border-top:2px solid var(--ink); }
  .sol-cards--two { grid-template-columns:1fr; }
}
@media (max-width:560px) {
  /* Шкала времени встаёт вертикально: линия переезжает из горизонтали в
     вертикаль, кружки садятся на неё слева. */
  .sol-beats { grid-template-columns:1fr; }
  .sol-beat { padding:0 0 22px 36px; }
  .sol-beat:last-child { padding-bottom:0; }
  .sol-beat::before { top:0; }
  .sol-beat::after { top:20px; bottom:-2px; inset-inline-start:9px; inset-inline-end:auto;
    width:2px; height:auto; }
  .sol-chain { grid-template-columns:1fr; }
  /* Дорожки перевода складываются: оригинал сверху, перевод под ним — тот же
     порядок чтения, что и в оверлее приложения. */
  .sol-duo-heads { display:none; }
  .sol-turn { grid-template-columns:1fr; }
  .sol-turn-dst { border-inline-start:none; border-top:1.5px solid var(--line-soft); }
}
@media (max-width:420px) {
  /* В строке панели остаются кнопка, волна и счётчик: подпись «окно поверх
     экрана» на этой ширине переносится на две строки и ломает ряд. */
  .sol-cue-tag { display:none; }
}
@media (max-width:380px) {
  .sol-actions .btn { width:100%; }
}

@media (prefers-reduced-motion: reduce) {
  .sol-cue.on .sol-cue-wave i, .sol-cue-caret { animation:none; }
  .sol-cast.armed.done .sol-kept li { animation:none; }
  .sol-keep, .sol-said li,
  .sol-duo.playing .sol-turn, .sol-duo.playing .sol-turn .sol-turn-dst { transition:none; }
}

/* ── Оверлей в первом экране посадочной ───────────────────────────────────────
   Сама панель приходит готовым компонентом (`_overlay/`), здесь только её
   РАЗМЕЩЕНИЕ: на лендинге она вынесена за правый край окна, а в колонке
   посадочной такой вынос резал бы её о край сетки. Правила размещения и правила
   панели разделены намеренно — иначе один макет диктовал бы форму другому. */
.sol .sol-demo { min-width:0; display:flex; flex-direction:column; gap:10px; align-self:start; }
.sol .sol-demo .demo { width:100%; }
/* Свёрнутая пилюля держит правый край колонки, как в клиенте. */
.sol .sol-demo .demo.mini { margin-inline-start:auto; }
/* Надстройка компонентов под типы страниц SEO-графа.

   ЗАЧЕМ ОТДЕЛЬНЫМ ФАЙЛОМ. Базовый набор (`solutions/_page.css`) описывает три
   сценарные посадочные; графу нужны узлы, которых у тех не было: карта кластера
   на хабе, матрица сравнения, плитки-ссылки, блок «смотрите также». Держать их
   в базовом наборе значило бы возить матрицу сравнения на странице про
   собеседование.

   ИЗОЛЯЦИЯ ТА ЖЕ. Каждый селектор начинается с `.sol` или `.gr` — оба класса
   живут только на страницах графа и посадочных. Общие компоненты оболочки
   (`.btn`, `.crumbs`, `.tpl`, `.art-tbl`) используются как есть и не меняются.  */

/* ── Хлебные крошки над первым экраном ───────────────────────────────────── */
.gr-crumbs { padding-top:26px; padding-bottom:0; }
.gr-crumbs .crumbs { flex-wrap:wrap; row-gap:4px; }

/* ── Карта кластера: хаб показывает своих детей связями, а не списком ─────
   Это и есть запоминающийся элемент хабовой страницы: человек видит структуру
   раздела до того, как начал читать, а не после. */
.gr-map { margin-top:30px; border:2px solid var(--ink); border-radius:var(--r-lg);
  background:var(--paper); overflow:hidden; }
.gr-map-head { display:flex; flex-wrap:wrap; align-items:baseline; gap:12px;
  padding:14px 20px; background:var(--ink); color:var(--bg); }
/* color:inherit обязателен: базовое `.sol b` задаёт --ink той же специфичностью,
   и на тёмной плашке заголовок карты рисовался чёрным по чёрному. */
.gr-map-head b { font-family:"Unbounded","Unbounded Fallback",sans-serif; font-size:15px; font-weight:800;
  letter-spacing:-0.01em; color:inherit; }
.gr-map-head span { font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:700;
  letter-spacing:.1em; text-transform:uppercase; opacity:.62; }
.gr-map-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); }
.gr-node { display:block; padding:18px 20px 20px; text-decoration:none !important; color:inherit;
  border-top:2px solid var(--ink); border-inline-start:2px solid var(--ink);
  transition:background 120ms var(--ease); }
.gr-node:nth-child(3n+1) { border-inline-start:none; }
.gr-node:hover { background:var(--y-soft) !important; }
.gr-node-n { font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.gr-node b { display:block; margin-top:9px; font-size:15.5px; font-weight:800; letter-spacing:-0.01em; }
.gr-node span.gr-node-d { display:block; margin-top:7px; font-size:13.5px; line-height:1.5;
  color:var(--muted); }

/* Шкала тактов рассчитана на четыре шага; у страниц графа их бывает три или
   два, и пустая четверть справа читалась бы как оборванный ряд. */
.sol-beats--three { grid-template-columns:repeat(3,minmax(0,1fr)); }
.sol-beats--two { grid-template-columns:repeat(2,minmax(0,1fr)); }

/* ── Плитки-ссылки: короче карты, для второстепенных перечней ────────────── */
.gr-tiles { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:14px; margin-top:26px; }
.gr-tile { display:block; border:2px solid var(--ink); border-radius:var(--r); background:var(--paper);
  padding:16px 18px 18px; text-decoration:none !important; color:inherit;
  transition:transform 120ms var(--ease), box-shadow 120ms var(--ease); }
.gr-tile:hover { transform:translate(-2px,-2px); box-shadow:5px 5px 0 0 var(--ink); background:var(--paper) !important; }
.gr-tile b { display:block; font-size:15px; font-weight:800; letter-spacing:-0.01em; }
.gr-tile span { display:block; margin-top:6px; font-size:13.5px; line-height:1.5; color:var(--muted); }

/* ── Карта встречи: темы, под ними то, что из них осталось ──────────────
   Дерево, а не список: смысл разбора в том, что решение принадлежит теме, а
   задача — решению. Плоский список это отношение теряет. */
.gr-tree { margin-top:26px; border:2px solid var(--ink); border-radius:var(--r-lg);
  background:var(--paper); overflow:hidden; }
.gr-topic { padding:18px 20px 20px; }
.gr-topic + .gr-topic { border-top:2px solid var(--ink); }
.gr-topic-h { display:flex; flex-wrap:wrap; align-items:baseline; gap:10px; }
.gr-topic-h span { font-family:"JetBrains Mono",monospace; font-size:9.5px; font-weight:800;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }
.gr-topic-h b { font-size:16px; font-weight:800; letter-spacing:-0.01em; }
.gr-topic ul { list-style:none; margin:13px 0 0; padding:0; display:grid; gap:9px; }
.gr-leaf { display:flex; flex-wrap:wrap; align-items:baseline; gap:11px; border:2px solid var(--ink);
  border-radius:var(--r); background:var(--bg); padding:11px 14px; }
.gr-leaf p { margin:0 !important; font-size:14.5px; line-height:1.45; font-weight:600; color:var(--ink) !important; }
.gr-leaf-src { font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:700;
  color:var(--muted); margin-inline-start:auto; white-space:nowrap; }

/* ── Матрица сравнения ───────────────────────────────────────────────────
   Первый столбец — вопрос, который человек реально задаёт себе при выборе, а
   не название функции. Пустая клетка запрещена: там, где мы не проверяли,
   стоит «не проверяли», и это честнее прочерка. */
.gr-matrix { margin-top:26px; border:2px solid var(--ink); border-radius:var(--r);
  background:var(--paper); overflow-x:auto; }
/* min-width как ЗАПРОС, а не как требование: таблица стоит в узкой колонке
   героя (~515 px на 1440), и жёсткие 560 px обрезали третий столбец на всех
   тридцати страницах сравнений — по-английски ровно так же, как по-немецки.
   `min(560px, 100%)` оставляет комфортную ширину там, где место есть, и даёт
   переносить строки там, где его нет. */
.gr-matrix table { width:100%; min-width:min(560px, 100%); border-collapse:collapse; }
.gr-matrix th { background:var(--ink); color:var(--bg); padding:11px 14px; text-align:start;
  font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; }
.gr-matrix th:first-child { width:34%; }
.gr-matrix td { padding:13px 14px; border-top:1.5px solid var(--line-soft); vertical-align:top;
  font-size:14px; line-height:1.5; color:var(--muted); }
.gr-matrix td:first-child { font-weight:700; color:var(--ink); }
.gr-matrix tbody tr:hover td { background:var(--raised); }
.gr-mark { font-family:"JetBrains Mono",monospace; font-weight:800; font-size:12px; }
.gr-mark--yes { color:var(--grn); }
.gr-mark--no { color:var(--red); }
.gr-mark--part { color:var(--muted); }
[data-theme="dark"] .gr-mark--yes { color:#4FBF6E; }
[data-theme="dark"] .gr-mark--no { color:#F5766C; }

/* ── «Кто заходит в звонок»: механика вместо обещаний ────────────────────
   Слева то, как это устроено у ботов, справа — у нас. Форма одна, вывод разный:
   сравнение должно держаться на механике, а не на прилагательных. */
.gr-vs { display:grid; grid-template-columns:1fr 1fr; margin-top:26px;
  border:2px solid var(--ink); border-radius:var(--r); overflow:hidden; background:var(--paper); }
.gr-vs-col { padding:20px 22px 22px; }
.gr-vs-col + .gr-vs-col { border-inline-start:2px solid var(--ink); background:var(--y-soft); }
.gr-vs-cap { display:block; font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.gr-vs-col b { display:block; margin-top:9px; font-size:16px; font-weight:800; letter-spacing:-0.01em; }
.gr-vs ul { list-style:none; margin:12px 0 0; padding:0; }
.gr-vs li { position:relative; margin-top:9px; padding-inline-start:18px; font-size:14px;
  line-height:1.5; color:var(--muted); }
.gr-vs li::before { content:""; position:absolute; inset-inline-start:0; top:8px; width:7px; height:7px;
  border:2px solid var(--ink); border-radius:50%; }
.gr-vs-col + .gr-vs-col li::before { background:var(--y); }

/* ── Шаги настройки ──────────────────────────────────────────────────────── */
.gr-steps { list-style:none; counter-reset:gr; margin:26px 0 0; padding:0;
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
.gr-steps li { counter-increment:gr; border:2px solid var(--ink); border-radius:var(--r-lg);
  background:var(--paper); padding:18px 20px 20px; }
.gr-steps li::before { content:"0" counter(gr); display:inline-block;
  font-family:"JetBrains Mono",monospace; font-size:10.5px; font-weight:800; letter-spacing:.1em;
  background:var(--y); color:var(--y-ink); border:2px solid var(--ink); border-radius:999px;
  padding:2px 9px; }
.gr-steps b { display:block; margin-top:11px; font-size:15px; font-weight:800; letter-spacing:-0.01em; }
.gr-steps p { margin-top:7px !important; font-size:13.5px; }

/* ── Метки перечислений (языки, сервисы, клиенты) ────────────────────────── */
.gr-chips { display:flex; flex-wrap:wrap; gap:8px; margin-top:20px; padding:0; list-style:none; }
.gr-chips li { border:2px solid var(--ink); border-radius:999px; padding:6px 13px;
  font-size:12.5px; font-weight:700; background:var(--paper); }
.gr-chips li.on { background:var(--y); color:var(--y-ink); }

/* ── «Смотрите также»: соседи по графу ───────────────────────────────────── */
.gr-rel-h { font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }
.gr-rel { list-style:none; margin:14px 0 0; padding:0; display:flex; flex-wrap:wrap; gap:10px; }
.gr-rel a { display:inline-block; border:2px solid var(--ink); border-radius:999px;
  background:var(--paper); padding:9px 16px; font-size:13.5px; font-weight:600;
  text-decoration:none !important; color:var(--ink);
  transition:transform 110ms var(--ease), box-shadow 110ms var(--ease); }
.gr-rel a:hover { transform:translate(-2px,-2px); box-shadow:4px 4px 0 0 var(--ink);
  background:var(--y) !important; color:var(--y-ink); }

@media (max-width:900px) {
  .gr-map-grid, .gr-tiles, .gr-steps { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .gr-node:nth-child(3n+1) { border-inline-start:2px solid var(--ink); }
  .gr-node:nth-child(2n+1) { border-inline-start:none; }
}
@media (max-width:640px) {
  .gr-map-grid, .gr-tiles, .gr-steps { grid-template-columns:1fr; }
  .gr-node { border-inline-start:none !important; }
  .gr-vs { grid-template-columns:1fr; }
  .gr-vs-col + .gr-vs-col { border-inline-start:none; border-top:2px solid var(--ink); }
}
@media (prefers-reduced-motion: reduce) {
  .gr-tile, .gr-rel a, .gr-node { transition:none; }
}

/* Размещение оверлея в первом экране страницы графа — см. тот же блок в
   `solutions/_page.css`: набор компонентов у них общий, и расходиться этим
   двум правилам нельзя. */
.sol .sol-demo { min-width:0; display:flex; flex-direction:column; gap:10px; align-self:start; }
.sol .sol-demo .demo { width:100%; }
.sol .sol-demo .demo.mini { margin-inline-start:auto; }

/* Длинный разбор на страницах сравнений — бывшая статья блога, перенесённая
   на графовый адрес (CONFLICT-1, 19.09.2026). Ширина колонки — как у статьи,
   иначе строка растягивается на всю сетку и не читается. */
.sol-longread .gr-read { max-width:76ch; margin:0 auto; }
.sol-longread .sol-kicker { max-width:76ch; margin:0 auto 18px; }
/* Типографика длинного разбора: перенесено из оболочки статьи блога (.art) с
   именами графа — посадочная не должна носить классы статьи, это держит тест
   test_graph_page_is_a_landing_not_an_article. */
.gr-read { max-width:76ch; margin:0 auto; }
.gr-read h2 { font-family:"Unbounded","Unbounded Fallback",sans-serif; font-size:clamp(20px,2.4vw,26px); font-weight:800;
  letter-spacing:-0.02em; line-height:1.2; margin:44px 0 0; scroll-margin-top:88px; }
.gr-read h3 { font-size:17px; font-weight:800; margin:28px 0 0; letter-spacing:-0.01em; }
.gr-read p { margin:14px 0 0; font-size:15.5px; line-height:1.68; }
.gr-read b { font-weight:700; }
.gr-read ul, .gr-read ol { margin:16px 0 0; padding-inline-start:22px; }
.gr-read li { margin-top:11px; font-size:15.5px; line-height:1.62; }
.gr-read a { color:inherit; text-decoration:underline; text-decoration-color:var(--y);
  text-decoration-thickness:2px; text-underline-offset:3px; }
.gr-read a:hover { background:var(--y-soft); }
.gr-tbl { margin-top:24px; border:2px solid var(--ink); border-radius:var(--r);
  background:var(--paper); overflow-x:auto; }
.gr-tbl table { width:100%; min-width:520px; border-collapse:collapse; }
.gr-tbl th { background:var(--ink); color:var(--bg); padding:9px 13px; text-align:start;
  font-family:"JetBrains Mono",monospace; font-size:9.5px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; white-space:nowrap; }
.gr-tbl td { padding:12px 13px; border-top:1.5px solid var(--line-soft); vertical-align:top;
  font-size:14px; line-height:1.55; }
.gr-tbl td:first-child { font-weight:700; }
.gr-tbl code { font-family:"JetBrains Mono",monospace; font-size:12.5px; }
.gr-read .cmp-side.good .cmp-cap { color:var(--grn); }
.gr-read .cmp-side.bad .cmp-cap { color:var(--red); }

/* ── Инструмент «протокол из стенограммы» ─────────────────────────────
   Форма живёт на графовой странице; стили короткие и не зависят от
   оболочки статьи. Вывод рисуется классами длинного разбора (.gr-read, .gr-tbl). */
.gr-tool-form { margin-top:26px; }
.gr-tool-label { display:block; font-family:"JetBrains Mono",monospace; font-size:10px; font-weight:800;
  letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-bottom:8px; }
.gr-tool-input { width:100%; box-sizing:border-box; min-height:240px; resize:vertical; padding:16px 18px;
  border:2px solid var(--ink); border-radius:var(--r); background:var(--paper); color:var(--ink);
  font:inherit; font-size:15px; line-height:1.55; }
.gr-tool-input:focus { outline:none; box-shadow:4px 4px 0 0 var(--y); }
.gr-tool-bar { display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; margin-top:14px; }
.gr-tool-count { font-family:"JetBrains Mono",monospace; font-size:12px; color:var(--muted); }
.gr-gr-tool-count--over { color:var(--red); }
.gr-tool-status { margin-top:14px; font-size:14px; line-height:1.5; padding:12px 16px; border-radius:var(--r);
  background:var(--y-soft); border-inline-start:3px solid var(--y); }
.gr-gr-tool-status--error { background:var(--raised); border-inline-start-color:var(--red); }
.gr-tool-out { margin-top:26px; padding:22px 24px; border:2px solid var(--ink); border-radius:var(--r-lg); background:var(--paper); }
.gr-gr-tool-out-bar { display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-bottom:6px; }
.gr-tool-out .gr-read { max-width:none; min-height:48px; }
.gr-tool-out .gr-read h2 { font-size:19px; margin-top:26px; }
.gr-tool-out .gr-read h2:first-child { margin-top:0; }
.gr-tool-fine { margin-top:20px; font-size:13px; color:var(--muted); line-height:1.5; }
.gr-tool-form.is-busy .gr-tool-out .gr-read::after { content:""; display:inline-block; width:10px; height:18px; background:var(--y); margin-inline-start:4px; vertical-align:text-bottom; animation:tool-blink 1s steps(2) infinite; }
@keyframes tool-blink { to { opacity:0; } }
@media (max-width:640px) { .gr-tool-bar .btn { width:100%; justify-content:center; } }
  
