/* ============================================================================
   Sonaro · компоненты
   Вид перенесён из NEW_DESIGN/nachisto.html (разделы «Система 01…07»
   и экраны 1–6). Имена классов остались нынешние: макет — источник правды
   по виду, а не по внутреннему устройству, и `app.js` обращается к разметке
   257 раз по идентификаторам и ставит 84 имени классов сам.

   Инлайновых style= в страницах расширения нет. Прежнее обоснование ссылалось
   на style-src 'self' в манифесте — такой строки там нет. Причина другая
   и от этого не слабее: разметку рисуют три места сразу (HTML, app.js,
   теневой корень плашки), и стиль, живущий атрибутом, из общего оформления
   выпадает молча.
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

/* Атрибут hidden обязан выигрывать: любое авторское display: flex/grid
   на том же элементе перебивает правило браузера, и «скрытый» блок
   продолжает рисоваться. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--text);
  font-size: 14px;
  line-height: 1.55;
  font-weight: 400;
  /* Табличные цифры на всё разом. Прежде их бесплатно давал моноширинный,
     теперь моноширинного нет: у Onest цифры десяти разных ширин (363…665
     единиц по файлу шрифта), с этой строкой — одной, 672. Без неё часы
     записи дёргаются на каждой секунде, а колонки чисел в таблицах едут. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* — заголовки —
   Unbounded набирается тонким: буквы у него широкие, и на полужирном
   заголовок превращается в плашку. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--face);
  font-weight: var(--face-weight);
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0 0 var(--a2);
}
h1 { font-size: 42px; line-height: 1.06 }
h2 { font-size: 30px; line-height: 1.14 }
h3 { font-size: 21px; line-height: 1.3 }
/* С четвёртого уровня заголовок перестаёт быть титулом и становится
   подписью внутри блока — там Unbounded мелким кеглем нечитаем. */
h4, h5, h6 { font-family: var(--text); font-weight: 600; letter-spacing: -0.01em }
h4 { font-size: 16.5px; line-height: 1.4 }
h5 { font-size: 14.5px; line-height: 1.45 }
h6 { font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; color: var(--ink-3) }

p { margin: 0 0 var(--a3) }
b, strong { font-weight: 600 }
a { color: var(--mark); text-underline-offset: 3px; text-decoration-thickness: 1px }
a:hover { color: var(--mark-deep) }
img { display: block; max-width: 100% }
figure { margin: 0 }
figcaption { font-size: 12px; margin-top: var(--a1); color: var(--ink-3) }

:focus { outline: none }
:focus-visible { outline: 2px solid var(--mark); outline-offset: 3px; border-radius: var(--r1) }
::selection { background: var(--mark-wash) }

.muted { color: var(--ink-2) }
/* Надпись-ярлык: не заголовок, а метка над блоком. */
.caps { font-size: 11px; letter-spacing: 0.09em; color: var(--ink-3); text-transform: uppercase; font-weight: 600 }
/* Мелкий приглушённый текст. Жил в `site.css`, но им набрана сноска
   в карточке пакета, а карточки теперь общие: без него кабинет рисовал
   сноску на два пикселя выше витрины — замер поймал разницу в высоте
   карточки. */
.tiny { font-size: 12.5px; line-height: 1.5; color: var(--ink-3) }
.sect { font-size: 11.5px; letter-spacing: 0.14em; color: var(--mark); text-transform: uppercase; font-weight: 600 }

/* — кнопки —
   Форма из макета: пилюля высотой 38, светлое полотно, тонкая тёплая рамка.
   Главная кнопка залита охрой. Размер цели нажатия — 38 при потребных 24. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  height: 38px; padding: 0 18px;
  font-family: var(--text); font-weight: 500;
  font-size: 14.5px; line-height: 1.2; color: var(--ink);
  background: var(--sheet); border: 1px solid var(--line-2); border-radius: var(--pill);
  transition: background .2s, border-color .2s, color .2s;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.btn svg { display: block }
.btn:hover:not(:disabled) { background: var(--inset) }
.btn:disabled { opacity: .45; cursor: not-allowed }
/* Мелкая кнопка — для панелей, где рядом с ней идёт содержимое, а не другие
   кнопки: плеер, шапка блока. */
/* Размер зовётся sm, а не tiny: `.tiny` в продукте уже значит «мелкий
   приглушённый текст» (site.css, панель оператора). На лендинге, где
   оба файла грузятся вместе, `.tiny` стоял ниже по порядку и перебивал
   цвет кнопки — все восемь мелких кнопок были набраны третьими
   чернилами вместо основных. Замер: rgb(114,102,92) вместо #241E18. */
.btn.sm { height: 30px; padding: 0 13px; font-size: 13px }
.btn-primary { background: var(--mark); border-color: var(--mark); color: #fff }
.btn-primary:hover:not(:disabled) { background: var(--mark-deep); border-color: var(--mark-deep) }
.btn-primary:active:not(:disabled) { background: #67310C; border-color: #67310C }
.btn-secondary:active:not(:disabled) { background: var(--inset-2) }
.btn-ghost { color: var(--ink-2); border-color: transparent; background: transparent }
.btn-ghost:hover:not(:disabled) { background: var(--inset); color: var(--ink) }
.btn-danger { border-color: var(--lost); color: var(--lost); background: transparent }
.btn-danger:hover:not(:disabled) { background: var(--lost); border-color: var(--lost); color: #fff }
.btn-icon { width: 38px; padding: 0; flex: none }
.btn-icon.sm { width: 30px }
.btn-block { width: 100% }

/* — знак —
   Обводка 1,7 на сетке 20, начертание Phosphor. Спрайт лежит в ui/glyphs.svg
   и подключается ссылкой: <svg class="gl"><use href="/ui/glyphs.svg#g-time"/></svg>.
   Эмодзи знаками не используются нигде: они разного размера, разного цвета
   и меняются с версией системы. */
.gl { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor;
      stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round }
.gl.wee { width: 13px; height: 13px }
.gl.big { width: 20px; height: 20px }
.gl.fill { fill: currentColor; stroke: none }

/* — имя продукта —
   Знак фирменный, `sonaro-mark.png`, один на все экраны: витрину, кабинет,
   попап, страницу разрешения. Рисовать его знаком из спрайта нельзя —
   это логотип, а не значок интерфейса.

   На экранах он показывается 17…30 px, на витрине 26. Оригинал — 1024×1024
   и 542 КБ, поэтому рядом лежит `sonaro-mark-64.png` на 5,8 КБ, и ссылаются
   везде на него. Оригинал остаётся нетронутым: он нужен для магазина
   расширений и печати. */
.brand {
  display: inline-flex; align-items: center; gap: 9px; flex: none;
  color: var(--ink); text-decoration: none;
}
.brand .bug { flex: none; display: block; object-fit: contain }

/* — поля — */
.field > label { display: block; font-size: 12.5px; margin-bottom: 5px; color: var(--ink-2) }
.input {
  width: 100%; min-height: 38px; padding: 8px 13px; font: inherit; font-size: 14.5px;
  color: var(--ink); caret-color: var(--mark);
  background: var(--sheet);
  border: 1px solid var(--line-2); border-radius: var(--r2);
  transition: border-color .2s;
}
.input::placeholder { color: var(--ink-3) }
.input:hover { border-color: var(--ink-3) }
.input:focus-visible { border-color: var(--mark); outline-offset: 0 }
.input:disabled { opacity: .55; cursor: not-allowed }

/* Селект рисуем сами: стрелка из макета, никаких системных элементов. */
.select-wrap { position: relative; display: block }
.select-wrap > svg { position: absolute; right: 11px; top: 50%; transform: translateY(-50%); pointer-events: none; color: var(--ink-2) }
select.input { cursor: pointer; appearance: none; padding-right: 32px }

.seg { display: inline-flex; overflow: hidden; border: 1px solid var(--line-2); border-radius: var(--pill); background: var(--sheet) }
.seg-opt { display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 15px; font-size: 13.5px; font-weight: 500; cursor: pointer; position: relative }
.seg-opt + .seg-opt { border-left: 1px solid var(--line) }
.seg-opt input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none }
.seg-opt:has(input:checked) { background: var(--mark); color: #fff }
.seg-opt:not(:has(input:checked)):hover { background: var(--inset) }
.seg-opt:has(input:focus-visible) { outline: 2px solid var(--mark); outline-offset: -2px }

.check { display: flex; align-items: center; gap: 9px; font-size: 13.5px; cursor: pointer }
.check input { position: absolute; opacity: 0; width: 0; height: 0 }
.check .box {
  width: 18px; height: 18px; flex: none; display: grid; place-items: center;
  border: 1px solid var(--line-2); background: var(--sheet); border-radius: 5px;
  transition: background .15s, border-color .15s;
}
.check .box svg { opacity: 0 }
.check input:checked + .box { border-color: var(--mark); background: var(--mark); color: #fff }
.check input:checked + .box svg { opacity: 1 }
.check input:focus-visible + .box { outline: 2px solid var(--mark); outline-offset: 2px }

/* — тумблер —
   Один на весь продукт. Прежде их было два: `.switch` с .knob внутри в попапе
   и `.sw` с классом `.on` в настройках кабинета — одна и та же вещь, набранная
   дважды и по-разному. Состояние держит aria-checked, а не класс: атрибут
   всё равно обязателен при role="switch", и второе место для той же правды —
   это место, где две правды разойдутся.
   Включённое положение зелёное, а не охряное: охра здесь означает действие,
   а тумблер ничего не запускает, он сообщает состояние. */
.sw {
  width: 40px; height: 24px; border-radius: var(--pill); flex: none; position: relative;
  background: var(--inset-2); border: 0; cursor: pointer; padding: 0;
  transition: background .2s;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.sw::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px;
  border-radius: 50%; background: var(--sheet);
  box-shadow: 0 1px 2px rgba(70,48,26,.28); transition: transform .2s;
}
.sw[aria-checked="true"] { background: var(--done) }
.sw[aria-checked="true"]::after { transform: translateX(16px) }
.sw:disabled { opacity: .5; cursor: not-allowed }

.sw-row { display: flex; align-items: center; gap: var(--a3); padding: 9px 0; cursor: pointer }
.sw-row + .sw-row { border-top: 1px solid var(--line) }
.sw-row .tx { flex: 1; min-width: 0 }
.sw-row .t1 { font-size: 13.5px; font-weight: 500; line-height: 1.35 }
.sw-row .t2 { font-size: 11.5px; color: var(--ink-3); margin-top: 1px }

/* — пилюля —
   Несущий элемент системы: ею помечены вид утверждения, состояние стадии,
   роль говорящего и основание. Форма важнее цвета — сплошная заливка
   означает сказанное, пунктирная рамка означает «только со слов». */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 11px; border-radius: var(--pill);
  font-size: 12.5px; font-weight: 500; line-height: 1.5; white-space: nowrap;
  background: var(--inset); color: var(--ink-2); border: 1px solid transparent;
}
.badge .dot { width: 5px; height: 5px; flex: none; border-radius: 50%; background: currentColor }
.badge.is-said  { background: var(--ink); color: var(--sheet) }
.badge.is-drawn { background: transparent; color: var(--ink-2); border-color: var(--line-2); border-style: dashed }
.badge.is-done  { background: var(--done-wash); color: var(--done) }
.badge.is-mark  { background: var(--mark-wash); color: var(--mark-deep); border-color: var(--mark-edge) }
.badge.is-run   { background: var(--inset); color: var(--ink) }
.badge.is-run .dot { background: var(--mark); animation: son-blink 1.2s ease-in-out infinite }
.badge.is-error { background: var(--lost-wash); color: var(--lost) }
.badge.is-wait  { background: transparent; border-color: var(--line-2); border-style: dashed; color: var(--ink-3) }

button.badge { cursor: pointer; font-family: var(--text); padding-right: 8px;
  transition: background .2s, border-color .2s;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent }
button.badge.is-said:hover  { background: #3C332B }
button.badge.is-drawn:hover { border-color: var(--ink-3); background: var(--inset) }
button.badge.is-error:hover { background: #F6DFDB }
.badge .chev { width: 12px; height: 12px; flex: none; stroke: currentColor; fill: none;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: .75; margin-left: 1px }

/* — прибор уровня: сегменты, верхние — перегруз — */
.meter { display: flex; gap: 2px; height: 12px }
.meter i { flex: 1; background: var(--inset-2); border-radius: 1px }
.meter i.on { background: var(--done) }
.meter i.clip { background: var(--lost) }

/* — сообщение об ошибке: что случилось и точный код стадии — */
.alert { border: 1px solid var(--lost); background: var(--lost-wash); padding: 12px 14px; border-radius: var(--r2) }
.alert .t { font-weight: 600; font-size: 15px; color: var(--lost); margin-bottom: 3px }
.alert .b { font-size: 13px; color: var(--ink-2) }
.alert .c { font-size: 11.5px; color: var(--ink-3); margin-top: 4px }

/* — таблица — */
.table { width: 100%; border-collapse: collapse; font-size: 14px }
.table th { text-align: left; font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 600; color: var(--ink-3);
  padding: var(--a2) var(--a3); border-bottom: 1px solid var(--line-2) }
.table td { padding: var(--a3); border-bottom: 1px solid var(--line) }
.table tbody tr:hover { background: var(--inset) }

/* — карточка — */
.card { background: var(--sheet); border: 1px solid var(--line); border-radius: var(--r3);
  padding: var(--a5); box-shadow: var(--up1) }

/* — модальное окно — */
.dialog-backdrop { position: fixed; inset: 0; display: grid; place-items: center; padding: var(--a4);
  background: rgba(36,30,24,.45); backdrop-filter: blur(2px) }
.dialog { width: min(430px, 100%); display: flex; flex-direction: column; gap: var(--a3);
  padding: var(--a5); background: var(--sheet); border: 1px solid var(--line);
  border-radius: var(--r3); box-shadow: var(--up3) }
.dialog-title { font-family: var(--face); font-weight: var(--face-weight); font-size: 21px; letter-spacing: -.02em }
.dialog-body { font-size: 14px; color: var(--ink-2) }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--a2); margin-top: var(--a2) }

/* ══════════════════════════ пакеты ══════════════════════════ */
/*
  Карточки пакетов. Показывает их и витрина, и кабинет — оформление
  одно на оба места: человек видит цену до входа и после, и она обязана
  выглядеть той же. Сборка карточки — `lib/plans.js`.
*/

/* Бесплатное стоит над пакетами, а не среди них.
 *
 * Пакеты сравнивают друг с другом: они отличаются только числом часов
 * и ценой, и выбор идёт по одной оси. У бесплатного этой оси нет вовсе —
 * ни часов, ни срока, — и в общем ряду оно предлагало сравнить 0 ₽ с 590 ₽
 * «за три часа», то есть читалось как самый маленький пакет. Оно не пакет,
 * а пол, на котором стоят остальные три.
 *
 * Четвёртая карточка вдобавок не помещалась: в сетке из трёх колонок она
 * переносилась на вторую строку и висела там одна. Разложить четыре по две
 * значило бы сказать «два и два», чего в тарифе нет; растянуть на четыре
 * колонки — сжать каждую до неудобной ширины. Три и полоса — единственная
 * раскладка, где строение экрана совпадает со строением тарифа.
 *
 * Заодно выделенный пакет вернулся в середину ряда: из четырёх карточек
 * он был третьим и висел вбок.
 *
 * Полоса на подложке --inset и без тени: то же семейство, что карточки
 * (радиус тот же), но на шаг назад по глубине. Ни одного цвета сверх
 * набора. */
.freeband{
  /* СТРОКА-ПОЛОСЫ: 254px — самая длинная из четырёх («Просмотр кадров без
     интернета»), замер measureText в браузере 30 августа. Две колонки списка
     требуют 254 + 254 + 24 зазора = 532 px; колонка действия закреплена на
     260, потому что по содержимому она забирала 371 и списку не хватало —
     строки ломались посреди слова. */
  display:grid;grid-template-columns:auto minmax(0,1fr) 260px;gap:var(--a6);align-items:center;
  margin-top:var(--a7);padding:var(--a5) var(--a6);
  background:var(--inset);border:1px solid var(--line);border-radius:var(--r4);
}
@media (max-width:920px){
  .freeband{grid-template-columns:1fr;gap:var(--a5);align-items:start}
}
.freeband .who{display:grid;gap:5px;min-width:0}
.freeband .nm{font-size:15px;font-weight:600}
.freeband .sum{display:flex;align-items:baseline;gap:7px}
/* 30 px против 38 у пакетов: ноль не выбирают среди цен, его сообщают. */
.freeband .sum b{font-family:var(--face);font-weight:300;letter-spacing:-.025em;
  font-size:30px;line-height:1}
.freeband .sum span{font-size:14px;color:var(--ink-3)}
.freeband .mins{font-size:13.5px;color:var(--ink-2);margin:0}
/* Две колонки, пока помещаются по замеру, иначе одна. Перелома по ширине
   экрана тут нет нарочно: полоса живёт внутри своей сетки, и её место
   зависит от соседей, а не от окна. */
.freeband ul{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(254px,1fr));gap:8px var(--a5)}
.freeband li{display:grid;grid-template-columns:18px 1fr;gap:9px;
  font-size:14.5px;line-height:1.5}
.freeband li .gl{color:var(--done);width:15px;height:15px;margin-top:3px}
/* Строка про отсутствие расшифровки помечена не только цветом: у неё свой
   значок. Цветом одним разницу передавать нельзя — её не увидит часть людей. */
.freeband li.no .gl{color:var(--ink-3)}
.freeband .act{display:grid;gap:9px;justify-items:stretch;min-width:0}
.freeband .act .btn{width:100%}
.freeband .act .tiny{margin:0}

/* `stretch`, а не `start`: карточки в ряду обязаны быть одной высоты.
   При `start` каждая держала свою, и нижние кнопки стояли на разных
   уровнях — у Pro сноска в одну строку против двух у соседей, и вся
   карточка выходила на 23 px короче. Кнопка прижата к низу своим
   `margin-top:auto`, поэтому выравниваются и высоты, и кнопки. */
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--a5);
  margin-top:var(--a5);align-items:stretch}
@media (max-width:920px){.plans{grid-template-columns:1fr}}
.plan{
  background:var(--sheet);border:1px solid var(--line);border-radius:var(--r4);
  padding:var(--a6) var(--a5) var(--a5);display:flex;flex-direction:column;gap:var(--a4);
  box-shadow:var(--up1);
}
/* Средний пакет выделен рамкой и тенью, без надписи. Ленточка «Популярный»
   стояла здесь стилем, а не словом в разметке, — и снять её поиском по
   странице было нельзя. Продукт только вышел: популярным ничего быть
   не может, и эта аудитория такое замечает первой. */
.plan.pick{border-color:var(--mark-edge);box-shadow:var(--up2);position:relative}
.plan .nm{font-size:15px;font-weight:600}
.plan .sum{display:flex;align-items:baseline;gap:7px}
.plan .sum b{font-family:var(--face);font-weight:300;letter-spacing:-.025em;
  font-size:38px;line-height:1}
.plan .sum span{font-size:14px;color:var(--ink-3)}
/* Объём пакета. Встречи набраны как цена — тем же начертанием и почти тем
   же кеглем: это второе число, которое сравнивают между карточками. */
.plan .vol{display:flex;flex-direction:column;gap:2px}
.plan .vol b{font-family:var(--face);font-weight:400;letter-spacing:-.02em;
  font-size:23px;line-height:1.1}
.plan .vol span{font-size:13.5px;color:var(--ink-3)}
.plan .mins{font-size:14.5px;color:var(--ink-2);margin:0}
.plan ul{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.plan li{display:grid;grid-template-columns:18px 1fr;gap:9px;font-size:14.5px;line-height:1.55}
.plan li .gl{color:var(--done);width:15px;height:15px;margin-top:4px}
.plan .btn{margin-top:auto;width:100%}
/* 490 px — 71 знак при замеренной средней букве 6,9 px на 13,5-м кегле.
   На 620 px сноска шла на 89 знаков: мелкий кегль растягивается незаметнее
   крупного, и потолок ему нужнее. */
.price-note{margin-top:var(--a5);font-size:13.5px;color:var(--ink-2);max-width:490px}
