/* ==================================================================
   «Видно дело» — слой стилей САЙТА.

   Читать вместе с dist/tokens.css. Разделение жёсткое и не косметическое:

   * tokens.css ГЕНЕРИРУЕТСЯ из sitegen.tokens.fixed_css() — это шкалы
     отступов, кегля, скруглений, теней, движения, состояний и зон
     нажатия нашего собственного генератора сайтов. Здесь этих
     переменных НЕ ОБЪЯВЛЯЮТ и НЕ ПЕРЕОПРЕДЕЛЯЮТ, здесь ими ПОЛЬЗУЮТСЯ.
     Расхождение роняет tests/site/test_tokens_borrowed.py, а попытка
     переобъявить — tests/site/test_site_tokens_usage.py.

   * этот файл — только то, чего в фиксированном слое нет и быть не
     может: палитра (фиксированный слой не знает ни одного цвета, он
     ссылается на --color-*), сетка страницы, первый экран, приём
     несовмещения красок, знак.

   Каждая ДОБАВЛЕННАЯ ступень шкалы помечена словом ДОБАВЛЕНО и
   объяснена. Добавлять — можно; переопределять — нет: тогда
   утверждение «наш сайт собран нашим же инструментом», напечатанное
   на самой странице, перестаёт быть правдой молча.
   ================================================================== */

:root {
  /* --- краски «Видно дело» -----------------------------------------
     Фиксированный слой намеренно не содержит ни одного литерального
     цвета — он ссылается на --color-*. Значения задаёт витрина. */
  --paper:      #E9EBE5; /* холодная бумага реестра, сознательно не крем */
  --paper-2:    #F5F6F2; /* поднятая поверхность: карточка, форма */
  --paper-3:    #DEE2D9; /* утопленная: пустая клетка поля, шкала */
  --ink:        #17201E; /* краска 1 — чёрная с сине-зелёным уклоном */
  --ink-2:      #59635E; /* приглушённый текст */
  --rule:       #C4CBBF; /* волосяная линейка */
  --red:        #CF3B1E; /* краска 2 — сурик: ЗАЛИВКИ, КРУПНЫЙ КЕГЛЬ, ЛИНИИ */
  --red-ink:    #A82D10; /* сурик для МЕЛКОГО ТЕКСТА — контраст 6:1 */
  --green:      #1F5B4E; /* краска 3 — то, что мы ДЕЛАЕМ */
  --green-pale: #D6E3DD;
  /* не наша краска: образец в песочнице. Она демонстрирует ВЫБОР
     КЛИЕНТА, поэтому живёт в палитре, но нигде на витрине не
     применяется. Белым по ней — 9,9:1. */
  --indigo:     #2B3D6B;

  /* мост к фиксированному слою: он объявляет body, ссылки и кольцо
     фокуса через эти три имени и не знает ни одного цвета сам */
  --color-bg:     var(--paper);
  --color-fg:     var(--ink);
  --color-accent: var(--green);

  /* --- гарнитуры ----------------------------------------------------
     Хвост каждой стопки — --font-sans генератора: если Google Fonts не
     доехал, страница садится ровно на тот системный стек, которым
     набраны страницы наших клиентов. */
  --display: "Unbounded", "Arial Black", var(--font-sans);
  --body:    "Golos Text", var(--font-sans);
  --mono:    "IBM Plex Mono", ui-monospace, Menlo, monospace;

  /* --- ДОБАВЛЕННЫЕ ступени -----------------------------------------
     Все четыре продолжают шкалы генератора вверх и вниз и названы в
     той же семье имён: расширение обязано читаться как продолжение
     шкалы, а не как вторая шкала рядом. (В концепте они назывались
     --s8 / --fs-symptom / --fs-mega; переименованы при переносе.) */

  /* ДОБАВЛЕНО. Ритм МЕЖДУ СЕКЦИЯМИ страницы. Верх шкалы генератора —
     --space-7 (54px) — это зазор между блоками ВНУТРИ страницы;
     у одностраничника нужна ступень выше, иначе секции слипаются. */
  --space-8: 80px;

  /* ДОБАВЛЕНО. Кегль поля маргиналий, кодов и мелких служебных
     пометок. Шкала генератора начинается с 14px — у неё нет регистра
     ниже основного мелкого текста, а у разворота описи он несущий. */
  --font-size-xs: 12px;

  /* ДОБАВЛЕНО. Заголовок-симптом каталога и примеров. Между
     --font-size-xl (28) и --font-size-display (40): 28 не отделяет
     симптом от заголовка секции, 40 забивает страницу. */
  --font-size-symptom: 34px;

  /* ДОБАВЛЕНО. Первый экран. Выше --font-size-display, которым
     генератор набирает сигнатурную цифру. */
  --font-size-mega: 72px;

  /* ДОБАВЛЕНО. Длительность и кривая ОДНОГО одноразового движения
     первого экрана (приход второй краски). У генератора есть только
     --duration-fast/base и --ease-standard/out — длительности реакции
     на действие; это движение не реакция, а показ. */
  --duration-slow: 900ms;
  --ease-slip: cubic-bezier(0.22, 1, 0.36, 1);

  /* --- сетка страницы ----------------------------------------------
     Разворот описи: широкие поля, тонкие линейки вместо коробок. */
  --shell: 1280px;
  --gutter: clamp(var(--space-5), 4vw, var(--space-8));
}

/* ------------------------------------------------------------------
   Основа. body/h1..h3/p/a/button приходят из фиксированного слоя —
   здесь только то, что он задать не мог.
   ------------------------------------------------------------------ */
html {
  -moz-osx-font-smoothing: grayscale;
  scroll-behavior: smooth;
}

/* Гарнитура — единственное, что витрина забирает у --font-sans:
   генератор ставит системный стек, потому что страницы клиентов не
   вправе зависеть от внешнего хоста. Витрина может: она одна. */
body {
  font-family: var(--body);
}

h1, h2, h3 {
  margin: 0;
  letter-spacing: -0.02em;
}

p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

a {
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Подпись, которую слышно, но не видно: имя цвета у образца, отчёт
   песочницы о том, что изменилось. */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Ссылка на содержание — первая в порядке обхода, видна только фокусу. */
.skip {
  position: absolute;
  left: var(--space-4);
  top: var(--space-4);
  z-index: 20;
  padding: var(--space-3) var(--space-4);
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}
/* :focus, а не только :focus-visible — ссылку на содержание нельзя
   потерять ни в одном браузере: она первая в обходе. */
.skip:focus { transform: translateY(0); }

/* Кольцо фокуса на полях ввода. Фиксированный слой ставит его ссылкам,
   кнопкам и .btn — до input/select/textarea он не дотягивается, потому
   что генератор форм не делает. Значения взяты у него же, чтобы кольцо
   на странице было одно, а не два похожих. */
.inp:focus-visible,
.consent input:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}

/* Единственная единица ширины страницы. */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--space-7); }

@media (min-width: 64em) {
  .section { padding-block: var(--space-8); }
}

/* ------------------------------------------------------------------
   Служебная типографика описи.
   ------------------------------------------------------------------ */
.mono {
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

/* Поле маргиналий — левая колонка с кодами и счётом. Это данные,
   а не украшение: тот же слой, что печатается на полях описи. */
.marg {
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.08em;
  color: var(--ink-2);
  text-transform: uppercase;
}
.marg--plain { text-transform: none; letter-spacing: 0.03em; }

.eyebrow {
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red-ink);
}
.eyebrow--ink { color: var(--ink-2); }
.eyebrow--green { color: var(--green); }

.rule { height: 1px; background: var(--rule); border: 0; margin: 0; }

.lead {
  font-size: var(--font-size-lg);
  color: var(--ink-2);
  max-width: 64ch;
}

.note {
  font-size: var(--font-size-sm);
  color: var(--ink-2);
}

.tnum { font-variant-numeric: tabular-nums; }

/* Заголовок секции, посаженный НА линейку — как разделитель в реестре. */
.sechead {
  display: grid;
  gap: var(--space-2);
  border-top: 1.5px solid var(--ink);
  padding-top: var(--space-3);
}
.sechead h2 {
  font-size: clamp(24px, 1vw + 21px, var(--font-size-xl));
  order: 2;
}
/* На узком экране заголовок садится МЕЖДУ двумя пометками: номер
   раздела сверху, подпись снизу. Порядком, а не разметкой — DOM
   остаётся один и тот же на любой ширине. */
.sechead .marg { order: 1; }
.sechead > .marg:last-child { order: 3; }

@media (min-width: 64em) {
  .sechead {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--space-5);
  }
  .sechead h2,
  .sechead .marg,
  .sechead > .marg:last-child { order: 0; white-space: nowrap; }
  .sechead h2 { white-space: normal; }
}

/* ------------------------------------------------------------------
   ПРИЁМ: несовмещение красок (приводка). Красный слой сдвинут
   относительно чёрного — ровно то, чем мы торгуем: две записи об одном
   и том же не совпадают.
   ------------------------------------------------------------------ */
.op { position: relative; display: inline-block; }
.op::before {
  content: attr(data-echo);
  /* Красный слой — картинка, а не текст: экранный диктор не должен
     читать фразу дважды. Второе объявление задаёт пустую альтернативу;
     браузеры, которые его не понимают, оставляют первое. */
  content: attr(data-echo) / "";
  position: absolute;
  left: 0.055em;
  top: 0.035em;
  color: var(--red);
  mix-blend-mode: multiply;
  pointer-events: none;
  z-index: 0;
  white-space: pre;
}
.op > span { position: relative; z-index: 1; }
.op--mark::before { left: 0.1em; top: 0.055em; }
.op--step::before { left: 0.13em; top: 0.07em; }
/* Совмещённое состояние — то, что мы отдаём. */
.op--fit::before { left: 0; top: 0; opacity: 0; }

/* Живой приход: слой приезжает и НЕ ДОЕЗЖАЕТ — брак приводки
   происходит на глазах. Одно движение на весь сайт, один раз, при
   загрузке; transform и opacity, ничего раскладочного. */
@keyframes slip-in {
  from { transform: translate(-0.17em, -0.1em); opacity: 0; }
  60%  { opacity: 1; }
  to   { transform: translate(0, 0); opacity: 1; }
}
.op--live::before {
  animation: slip-in var(--duration-slow) var(--ease-slip) 260ms both;
}

/* Знак. «ВИДНО» стоит ровно — это видно. «ДЕЛО» разъехалось — видно
   НЕ ТО. Отдельной эмблемы нет и не нужно: знак — это слово. */
.wm {
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: 0.01em;
  line-height: 1;
  white-space: nowrap;
}

/* ------------------------------------------------------------------
   Шапка.
   ------------------------------------------------------------------ */
.masthead { padding-block: var(--space-5) var(--space-4); }

.masthead__in {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
}

.brand {
  color: inherit;
  text-decoration: none;
  display: block;
  min-width: 0;
}
.brand .wm { font-size: 22px; }
.brand .mono { margin-top: var(--space-2); display: block; }

@media (min-width: 48em) {
  .brand .wm { font-size: 26px; }
}

/* Дескриптор укорачивается на телефоне, знак не уменьшается. */
.brand__long { display: none; }
@media (min-width: 30em) {
  .brand__long { display: inline; }
}

.burger {
  /* без JS кнопки нет вовсе: она ничего не сделает, а меню и так
     раскрыто. Скрипт снимает hidden сам. */
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  background: var(--paper-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
}
.burger:hover { border-color: var(--ink); opacity: 1; }
.burger i {
  display: block;
  width: 18px;
  height: 1.5px;
  background: var(--ink);
  position: relative;
}
.burger i::before,
.burger i::after {
  content: "";
  position: absolute;
  left: 0;
  width: 18px;
  height: 1.5px;
  background: var(--ink);
}
.burger i::before { top: -5px; }
.burger i::after  { top: 5px; }

.nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-5);
  width: 100%;
  padding-top: var(--space-3);
  border-top: 1px solid var(--rule);
}

.navlink {
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border-bottom: 1.5px solid transparent;
}
.navlink:hover { color: var(--red-ink); border-bottom-color: var(--red); opacity: 1; }

@media (min-width: 64em) {
  .nav {
    width: auto;
    padding-top: 0;
    border-top: 0;
    flex-wrap: nowrap;
  }
  /* на широком экране складывать нечего: кнопка уходит вместе с
     задачей, которую решала */
  .burger { display: none; }
}

/* Меню на узком экране складывается ТОЛЬКО когда есть чем его
   разложить. Без скрипта .js не появляется, меню остаётся на месте. */
@media (max-width: 63.99em) {
  .js .nav { display: none; }
  .js .nav.is-open { display: flex; }
}

/* ------------------------------------------------------------------
   Кнопки. Форма и состояния — из фиксированного слоя; здесь краски
   и то, что он задать не мог.
   ------------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 48px;
  padding: var(--space-2) var(--space-5);
  font-family: var(--body);
  font-size: var(--font-size-base);
  font-weight: var(--weight-medium);
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  cursor: pointer;
  text-decoration: none;
}
/* Заливка сурик, как на доске. Белым по ней — 4,89:1, порог 4.5 для
   подписи в 16px пройден с небольшим запасом; посчитано формулой в
   tests/site/test_site_a11y.py, а не оценено на глаз (глаз здесь
   ошибся первым и предложил заменить краску без нужды).
   opacity:1 гасит наведение из фиксированного слоя: оно осветляло бы
   заливку и съедало этот запас. */
.btn:hover {
  background: var(--red);
  border-color: var(--red);
  color: #FFFFFF;
  opacity: 1;
}
.btn:active { transform: translateY(1px) scale(1); }
.btn--ghost { background: transparent; color: var(--ink); }
.btn--ghost:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn--wide { width: 100%; }
.btn--sm { min-height: 44px; font-size: var(--font-size-sm); padding-inline: var(--space-4); }

.card {
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}
.card--ink   { border-color: var(--ink); }
.card--plain { background: transparent; }
.card--red   { border-color: var(--red-ink); background: transparent; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--rule);
  border-radius: 999px;
  color: var(--ink-2);
  background: var(--paper-2);
}
.chip--red { color: var(--red-ink); border-color: var(--red); background: transparent; }

/* Штамп «пример вымышленный» — обязателен на каждом примере.
   Примеры на витрине ВЫМЫШЛЕННЫЕ; штамп снимается только вместе
   с содержимым карточки, когда появится согласие живого владельца. */
.fake {
  display: inline-block;
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  font-weight: var(--weight-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--red-ink);
  border: 1.5px solid var(--red);
  padding: var(--space-1) var(--space-2);
  border-radius: 3px;
  transform: rotate(-2.5deg);
}

/* ------------------------------------------------------------------
   Знаки-симптомы. Один язык на все шесть случаев: ЧЁРНАЯ рамка — то,
   что есть у клиента, КРАСНАЯ аномалия — то, что не так.
   Классы, а не presentation-атрибуты: var() в атрибуте SVG — не
   гарантированное поведение.
   ------------------------------------------------------------------ */
.pict {
  display: block;
  width: 72px;
  height: 72px;
  flex: 0 0 auto;
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: square;
  stroke-linejoin: miter;
}
.pict .s { stroke: var(--ink); }
.pict .r { stroke: var(--red); }
.pict--xs { width: 44px; height: 44px; }

@media (min-width: 64em) {
  .pict { width: 104px; height: 104px; }
  .pict--xs { width: 44px; height: 44px; }
}

.kcode {
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px solid var(--rule);
  letter-spacing: 0.1em;
  text-align: center;
}

/* ==================================================================
   ПЕРВЫЙ ЭКРАН.
   ================================================================== */
/* Первый экран — ровно три части: подводка, пара аппаратов, всё
   остальное. Три, а не восемь, потому что на широком экране аппараты
   стоят СБОКУ и обязаны накрыть обе текстовые части сразу; плоский
   список из восьми детей потребовал бы «растянись до последней
   строки», а такого указания в сетке нет — `-1` считает только по
   ЯВНОЙ сетке и молча схлопывается в одну строку. Поймано в браузере:
   заголовок первого экрана уехал под аппараты. */
.hero { display: grid; gap: var(--space-5); }
.hero__intro > * + * { margin-top: var(--space-5); }

.hero__title {
  font-size: clamp(40px, 4.4vw + 22px, var(--font-size-mega));
  letter-spacing: -0.035em;
  line-height: 1.02;
}

.hero__lead {
  font-size: var(--font-size-lg);
  color: var(--ink-2);
  line-height: 1.45;
  max-width: 38ch;
}

.hero__cta { display: grid; gap: var(--space-3); }

/* Ссылка-переход внутри блока — не строчная ссылка в предложении, а
   самостоятельный орган управления, поэтому и зона нажатия у неё как
   у органа: 44px по высоте (2.5.5). */
.golink {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: var(--weight-bold);
}

.hero__aside {
  border-top: 1.5px solid var(--ink);
  padding-top: var(--space-4);
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
  max-width: 46ch;
}

@media (min-width: 30em) {
  .hero__cta { grid-auto-flow: column; justify-content: start; gap: var(--space-4); }
}

@media (min-width: 64em) {
  .hero {
    grid-template-columns: minmax(0, 1fr) minmax(0, 560px);
    gap: var(--space-6) var(--space-7);
    align-items: start;
  }
  .hero__intro   { grid-column: 1; grid-row: 1; }
  .hero__after   { grid-column: 1; grid-row: 2; }
  .hero__devices { grid-column: 2; grid-row: 1 / 3; }
}

/* --- пара аппаратов ------------------------------------------------
   Приём: телефон как ПРЕДМЕТ, а не ещё одна таблица. Каркас честный:
   без нарисованной строки состояния и без нарисованной клавиатуры. */
.hero__devices { margin: 0; }

.devlabels,
.devpair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
@media (min-width: 64em) {
  .devlabels,
  .devpair { gap: 28px; }
}

/* планка состояния над экраном: цвет несёт смысл раньше подписи */
.devlab { border-top: 2px solid var(--red); padding-top: var(--space-2); }
.devlab--fix { border-top-color: var(--green); }
.devpair { margin-top: var(--space-3); }

.dev {
  position: relative;
  border: 5px solid var(--ink);
  /* Концентрика: внешнее скругление = внутреннее + рамка. На доске
     стояло 24px, которого в шкале генератора нет; --radius-xl (28px) —
     ближайшая ступень, концентрика сохраняется. */
  border-radius: var(--radius-xl);
  background: #FFFFFF;
  overflow: hidden;
  box-shadow: var(--shadow-md);
  /* размеры внутренностей аппарата — доли ЕГО ширины, не окна */
  container-type: inline-size;
}
@media (min-width: 64em) {
  .dev { border-width: 7px; }
}

.dev__chrome {
  display: flex;
  align-items: center;
  gap: 0.9em;
  height: 3.4em;
  padding: 0 1.2em;
  background: var(--paper-3);
  border-bottom: 1px solid var(--rule);
}
.dev__dot {
  width: 0.9em;
  height: 0.9em;
  border-radius: 50%;
  background: var(--rule);
  flex: 0 0 auto;
}
.dev__url {
  font-family: var(--mono);
  font-size: 1.35em;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Единственная точка, где задан кегль внутренностей аппарата. Всё
   ниже — em от него, поэтому макет аппарата масштабируется целиком и
   на любой ширине остаётся тем же рисунком. max() держит нижнюю
   границу на узком экране; px-запас — для браузеров без cq-единиц. */
.dev__chrome,
.dev__view {
  font-size: 6px;
  font-size: max(4.2px, 2.4cqw);
}

.dev__view {
  position: relative;
  overflow: hidden;
  background: #fff;
  aspect-ratio: 100 / 173;
}

/* «как есть»: страница шире окна и всё время уезжает вбок.
   Ширина задана долей окна, поэтому сдвиг ТОЧНО доводит до правого
   края при любом размере: содержимое 150% окна → за кадром ровно
   треть его собственной ширины. */
.wide {
  width: 150%;
  padding: 1.5em 1.7em;
  color: #333;
}
.dev--bad .wide { animation: drift 9s var(--ease-slip) infinite; }
@keyframes drift {
  0%, 10%  { transform: translateX(0); }
  50%, 60% { transform: translateX(-33.34%); }
  100%     { transform: translateX(0); }
}

.hscroll {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 5px;
  background: var(--paper-3);
}
.hscroll i {
  display: block;
  height: 5px;
  width: 66%;
  border-radius: 3px;
  background: var(--ink-2);
}
.dev--bad .hscroll i { animation: thumb 9s var(--ease-slip) infinite; }
@keyframes thumb {
  0%, 10%  { transform: translateX(0); }
  50%, 60% { transform: translateX(51%); }
  100%     { transform: translateX(0); }
}

/* мелочь внутри «как есть» — картинка нечитаемости, не текст к прочтению */
.bad-nav { display: flex; gap: 1.1em; align-items: center;
           border-bottom: 1px solid #DCDCDC; padding-bottom: 0.9em; }
.bad-logo { font-family: var(--display); font-weight: 800; font-size: 1.4em; white-space: nowrap; }
.bad-menu { display: flex; gap: 1.3em; font-size: 1em; color: #6B6B6B; white-space: nowrap; }
.bad-h { font-size: 2.1em; font-weight: 700; margin-top: 1.4em; white-space: nowrap; color: #111; }
.bad-p { font-size: 1em; color: #5B5B5B; line-height: 1.7; margin-top: 1em; }
.bad-tbl { display: grid; grid-template-columns: 3fr 2fr 2fr; margin-top: 1.4em;
           font-size: 1em; color: #333; }
.bad-tbl > span { border-bottom: 1px solid #EEE; padding: 0.5em 0; white-space: nowrap; }
.bad-tbl > .th { border-bottom-color: #DCDCDC; }
.bad-imgs { display: flex; gap: 0.8em; margin-top: 1.4em; }
.bad-imgs > i { display: block; flex: 1 1 0; height: 9em; background: var(--rule); border-radius: 2px; }
.bad-foot { font-size: 1em; color: #5B5B5B; margin-top: 1.4em; white-space: nowrap; }

/* «что отдаём»: одна колонка, зона нажатия 44+, ничего лишнего */
.good {
  height: 100%;
  padding: 2.2em;
  display: flex;
  flex-direction: column;
  gap: 1.7em;
}
.good__name { font-family: var(--display); font-weight: 800; font-size: 2.5em; line-height: 1.1; }
.good__sub  { font-size: 1.85em; color: var(--ink-2); line-height: 1.4; }
.good__now  {
  align-self: flex-start;
  font-family: var(--mono);
  font-size: 1.6em;
  color: var(--green);
  background: var(--green-pale);
  border-radius: 999px;
  padding: 0.35em 0.8em;
}
.good__cta {
  min-height: 7.2em;
  border-radius: var(--radius-sm);
  background: var(--ink);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--weight-medium);
  font-size: 1.6em;
}
.good__row {
  display: flex;
  justify-content: space-between;
  gap: 1.5em;
  font-size: 1.5em;
  color: var(--ink-2);
  border-top: 1px solid var(--rule);
  padding-top: 1em;
}
.good__row b { color: var(--ink); font-weight: var(--weight-medium); }
.good__map { margin-top: auto; font-size: 1.5em; color: var(--green); font-weight: var(--weight-medium); }

/* Замер «как есть → после нас». Настоящая таблица, а не сетка из
   рамок: это высказывание первого экрана, и оно обязано быть
   доступно диктору строкой со заголовком строки и столбца — сами
   аппараты выше отданы диктору как рисунок. */
.meastable {
  margin-top: var(--space-5);
  border-top: 1.5px solid var(--ink);
  padding-top: var(--space-3);
}
.meastable table { width: 100%; border-collapse: collapse; font-size: var(--font-size-sm); }
.meastable caption { text-align: left; padding-bottom: var(--space-3); }
.meastable th,
.meastable td { text-align: left; padding: var(--space-2) 0; vertical-align: baseline; }
.meastable tbody th { font-weight: var(--weight-regular); padding-right: var(--space-3); }
.meastable tbody tr + tr th,
.meastable tbody tr + tr td { border-top: 1px solid var(--rule); }
.meastable td {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  padding-left: var(--space-3);
}
/* nowrap только там, где колонке хватает места: на узком экране
   «уезжает вбок» обязано перенестись, а не наехать на соседа */
/* Два соседних значения — «как есть» и «после нас» — стоят в одну
   строку и оба набраны моноширинным. Без внятного зазора глаз читает
   их как одну фразу («уезжает вбок по экрану»), а это ровно обратное
   тому, что таблица говорит. Зазор поэтому крупный, не декоративный. */
@media (min-width: 30em) {
  .meastable td { white-space: nowrap; width: 7.5em; padding-left: var(--space-5); }
}
.meastable .was { color: var(--red-ink); }
.meastable .now { color: var(--green); }

.devcap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-4);
  flex-wrap: wrap;
}

/* ==================================================================
   КАТАЛОГ СИМПТОМОВ. Герой карточки — симптом СЛОВАМИ КЛИЕНТА;
   внутренний код (а–д) остаётся мелкой технической пометкой под
   знаком: он нужен для сверки с письмом и отчётом, а не витрине.
   Нумерации здесь нет намеренно — это пять взаимоисключающих
   случаев, а не последовательность.
   ================================================================== */
.krow {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  grid-template-areas:
    "icon title"
    "body body"
    "fix  fix";
  gap: var(--space-4);
  padding: var(--space-6) 0;
  border-top: 1px solid var(--rule);
  align-items: start;
}
.krow__icon  { grid-area: icon; }
.krow__title { grid-area: title; font-size: clamp(22px, 1.6vw + 16px, var(--font-size-symptom));
               letter-spacing: -0.025em; line-height: 1.12; }
.krow__body  { grid-area: body; color: var(--ink-2); max-width: 54ch; }
.krow__fix   { grid-area: fix; border-left: 2px solid var(--green); padding-left: var(--space-4); }
.krow__fix h4 { margin: var(--space-2) 0 0; font-size: var(--font-size-lg); font-weight: var(--weight-bold); }
.krow__fix p  { margin-top: var(--space-2); color: var(--ink-2); font-size: var(--font-size-sm); }

@media (min-width: 64em) {
  .krow {
    grid-template-columns: 132px minmax(0, 1fr) 380px;
    grid-template-areas:
      "icon title fix"
      "icon body  fix";
    gap: var(--space-4) var(--space-6);
  }
}

.krow--find { border-top: 1.5px solid var(--ink); }

/* ==================================================================
   КАК ЭТО РАБОТАЕТ. Шесть шагов — НАСТОЯЩАЯ последовательность,
   поэтому нумерация здесь законна. Рельс несёт границу: пунктир —
   мы только смотрим, сплошная зелёная — начинается работа. Границу
   видно раньше, чем читаешь подпись.
   На доске фазы стояли двумя подписями над одной лентой из шести
   колонок. В текучей вёрстке лента ломается, а граница обязана
   пережить перенос — поэтому фаза стала своей группой: на узком
   экране группы идут одна под другой, и рельс у каждой свой.
   ================================================================== */
.phases { display: grid; gap: var(--space-6); margin-top: var(--space-6); }
.track  { display: grid; gap: 0; margin-top: var(--space-4); }

.trk {
  position: relative;
  padding: var(--space-5) var(--space-4) var(--space-5) 0;
  border-top: 2px dashed var(--red);
}
.trk--do { border-top: 2px solid var(--green); }
/* створ: место, где мы перестаём только смотреть */
.trk--gate::before {
  content: "";
  position: absolute;
  top: -11px;
  left: 0;
  width: 2px;
  height: 22px;
  background: var(--ink);
}
/* Селектор именно .trk .stepno, а не .stepno: иначе его перебивает
   .trk p ниже — та же весовая категория плюс тип элемента. */
.trk .stepno {
  font-family: var(--display);
  font-weight: 800;
  font-size: var(--font-size-display);
  line-height: 0.9;
  color: var(--ink);
}
.trk h3 { font-size: var(--font-size-lg); margin-top: var(--space-3); }
.trk p  { margin-top: var(--space-2); color: var(--ink-2); font-size: var(--font-size-sm); }

@media (min-width: 48em) {
  .track { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 64em) {
  .phases { grid-template-columns: 1fr 1fr; gap: var(--space-6); }
}

.twoup { display: grid; gap: var(--space-5); margin-top: var(--space-7);
         border-top: 1.5px solid var(--ink); padding-top: var(--space-4); }
@media (min-width: 64em) { .twoup { grid-template-columns: 1fr 1fr; gap: var(--space-6); } }

.mono--para { text-transform: none; letter-spacing: 0.02em; line-height: 1.6; }

/* ==================================================================
   ПРИМЕРЫ РАБОТ. Все — вымышленные, со штампом на каждом.
   Разметка карточки не зависит от содержимого: чтобы поменять пример
   на настоящий, меняют текст и превью внутри .ex, структуру — нет.
   ================================================================== */
.ex {
  display: grid;
  gap: var(--space-5);
  padding: var(--space-6) 0;
  border-top: 1px solid var(--rule);
  align-items: start;
}
.ex__sym  { font-size: clamp(22px, 1.6vw + 16px, var(--font-size-symptom));
            letter-spacing: -0.025em; line-height: 1.12; }
.ex__who  { margin-top: var(--space-3); font-weight: var(--weight-bold); font-size: var(--font-size-lg); }
.ex__kind { margin-top: var(--space-4); font-weight: var(--weight-bold); color: var(--green);
            font-size: var(--font-size-lg); }
.ex__body { margin-top: var(--space-3); color: var(--ink-2); max-width: 58ch; }

@media (min-width: 64em) {
  .ex { grid-template-columns: 300px minmax(0, 1fr); gap: var(--space-6); }
}

.mini {
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  overflow: hidden;
  max-width: 320px;
}
.mini-band { background: var(--ink); color: var(--paper); padding: var(--space-3) var(--space-4); }
.mini-band strong { font-family: var(--display); font-weight: var(--weight-bold); font-size: var(--font-size-lg); }
.mini-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  font-family: var(--mono);
  font-size: var(--font-size-xs);
}
.mini-row + .mini-row { border-top: 1px solid var(--rule); }
.mini-row--dim { background: var(--paper-3); }
.mini-cta {
  margin: var(--space-3) var(--space-4);
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius-sm);
  text-align: center;
  padding: var(--space-3);
  font-weight: var(--weight-medium);
  font-size: var(--font-size-sm);
}

/* пара «до / после» — тот же приём, что на первом экране, в масштабе
   превью: слева страница шире аппарата, справа — одна колонка */
.ba { display: flex; gap: var(--space-4); align-items: flex-start; }
.ba > div { min-width: 0; flex: 1 1 0; max-width: 150px; }
.phone {
  border: 1.5px solid var(--ink);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: #fff;
  aspect-ratio: 100 / 179;
  container-type: inline-size;
}
.phone--bad { border-color: var(--red); }
/* Кегль задан ВНУТРИ контейнера, а не на нём: элемент не может
   опрашивать сам себя — cqw на .phone считался бы от окна и превращал
   превью в плакат. Ошибка была поймана в браузере, не на глаз. */
.phone__in {
  padding: 1.2em;
  font-size: 7px;
  font-size: max(5px, 5.6cqw);
}
.phone__in--wide { width: 165%; }
.phone__t  { font-weight: 700; font-size: 1.5em; }
.phone__d  { font-family: var(--display); font-weight: 800; font-size: 1.5em; line-height: 1.2; }
.phone__m  { font-family: var(--mono); font-size: 1em; color: #666; margin-top: 0.4em; }
.phone__p  { margin-top: 0.8em; font-size: 1em; line-height: 1.35; color: #222; }
.phone__tbl { margin-top: 1em; width: 100%; border-collapse: collapse; font-size: 1em; }
.phone__tbl td { border: 1px solid #999; padding: 0.35em; white-space: nowrap; }
.phone__cta { background: var(--ink); color: #fff; border-radius: 0.8em; text-align: center;
              padding: 1em; font-size: 1.3em; font-weight: 600; margin-top: 1.1em; }
.phone__card { border: 1px solid #ddd; border-radius: 0.8em; padding: 0.8em; margin-top: 0.9em; font-size: 1.2em; }
.phone__card b { display: block; }
.phone__card span { color: #666; }

.report-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3);
  font-family: var(--mono);
  font-size: var(--font-size-xs);
}
.report-line .bad  { color: var(--red-ink); }
.report-line .fine { color: var(--green); }

/* ==================================================================
   ПЕСОЧНИЦА.
   ================================================================== */
.split { display: grid; gap: var(--space-6); margin-top: var(--space-5); align-items: start; }
@media (min-width: 64em) { .split { grid-template-columns: 1fr 1fr; gap: var(--space-7); } }

.ticks { display: grid; gap: var(--space-3); margin-top: var(--space-5); }
.ticks li { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: var(--space-3); align-items: start; }
.ticks b { color: var(--green); }

.linkbox {
  margin-top: var(--space-6);
  border: 1px dashed var(--rule);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  background: var(--paper-2);
}
.linkbox__url {
  font-family: var(--mono);
  font-size: var(--font-size-sm);
  margin-top: var(--space-3);
  word-break: break-all;
}
.linkbox__url .dim { color: var(--ink-2); }
.linkbox__url .hid { color: var(--red-ink); }

.sb__head { display: flex; justify-content: space-between; align-items: baseline;
            gap: var(--space-4); flex-wrap: wrap; }
.sb__grid { display: grid; gap: var(--space-5); margin-top: var(--space-4); align-items: start; }
@media (min-width: 30em) { .sb__grid { grid-template-columns: minmax(0, 1fr) 190px; } }
@media (min-width: 64em) { .sb__grid { grid-template-columns: minmax(0, 1fr); } }
@media (min-width: 76em) { .sb__grid { grid-template-columns: minmax(0, 1fr) 190px; } }

.sbprev { border: 1px solid var(--rule); border-radius: var(--radius-md); overflow: hidden; background: #fff; }
.sbprev__band { padding: var(--space-4); color: #fff; background: var(--red); }
.sbprev__band b { display: block; font-weight: var(--weight-bold); font-size: var(--font-size-lg); line-height: 1.2; }
.sbprev__band span { font-size: var(--font-size-sm); }
.sbprev__body { padding: var(--space-4); display: grid; gap: var(--space-3); }
.pblock {
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
}
.pblock b { font-size: var(--font-size-sm); font-weight: var(--weight-medium); color: var(--ink); }
.pblock span { font-size: var(--font-size-xs); color: var(--ink-2); }
/* первый блок обведён выбранной краской: скрипт кладёт её в color,
   рамка берёт currentColor, а текст внутри перекрашен обратно */
.pblock--first { border-color: currentColor; }

.ctl { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4);
       padding: var(--space-3) 0; }
.ctl + .ctl { border-top: 1px solid var(--rule); }
.ctl > .mono { width: 4.5em; flex: 0 0 auto; }
.ctl [data-sb-version] { white-space: nowrap; }
.ctl--top { align-items: flex-start; }

.sw {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
}
.sw[aria-pressed="true"] { border-color: var(--ink); box-shadow: 0 0 0 2px var(--paper-2) inset; }
/* Кружок 32px < 44px, поэтому зона нажатия расширяется .hit-area из
   фиксированного слоя. Арифметика оттуда же: зазор >= 44 - 32 = 12px,
   поставлено --space-4 (16px). */
.swatches { display: flex; flex-wrap: wrap; gap: var(--space-4); }

.tbtn {
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  color: var(--ink-2);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  min-height: 44px;
  cursor: pointer;
}
.tbtn[aria-pressed="true"] { border-color: var(--ink); color: var(--ink); background: #fff; }

.mv {
  border: 1px solid var(--rule);
  background: var(--paper-2);
  border-radius: var(--radius-sm);
  width: 44px;
  height: 44px;
  flex: 0 0 auto;
  cursor: pointer;
  font-size: var(--font-size-base);
  line-height: 1;
  color: var(--ink);
}
.mv[disabled] { opacity: 0.4; cursor: default; }
.orderlist { display: grid; gap: var(--space-2); }
.orderlist li { display: flex; align-items: center; gap: var(--space-3); }

/* Панель правки живёт только со скриптом: кнопка, которая ничего не
   делает, хуже отсутствующей. Без JS остаётся превью и объяснение. */
.js-only { display: none; }
.js .js-only { display: block; }
.js .nojs-only { display: none; }

/* ==================================================================
   ЦИФРЫ. Измерений по популяции на витрине НЕТ — решение владельца:
   доказываем методом, а не числами. Числа по городу и нише уходят
   в письмо вместе с методом.
   ================================================================== */
.dorow { border-top: 1px solid var(--rule); padding-top: var(--space-3); }
.dorow h4 { margin: 0; font-size: var(--font-size-base); font-weight: var(--weight-bold); }
.dorow--not h4 { color: var(--red-ink); }
.dorow p { margin-top: var(--space-2); font-size: var(--font-size-sm); color: var(--ink-2); }

/* Замощение: одна клетка — один квадрат обхода. Тёмные пройдены,
   светлые в очереди. Долей и процентов здесь нет намеренно. */
.tiles {
  display: grid;
  grid-template-columns: repeat(60, minmax(0, 1fr));
  gap: 2px;
  margin-top: var(--space-4);
  max-width: 900px;
}
.tiles i { display: block; aspect-ratio: 1 / 1; border-radius: 1px; background: var(--paper-3); }
.tiles i.on { background: var(--ink); }

/* ==================================================================
   ЗАКАЗ И КОНТАКТЫ.
   ================================================================== */
.doors { display: grid; gap: var(--space-5); margin-top: var(--space-6); align-items: start; }
@media (min-width: 64em) {
  .doors { grid-template-columns: 1fr 1fr 0.8fr; gap: var(--space-6); }
}

/* Подпись — настоящий <label>, плейсхолдер только подсказывает
   формат. Подсказка живёт отдельным абзацем и связана через
   aria-describedby: она нужна и до ввода, и в момент ошибки. */
.field { display: block; }
.field > label {
  display: block;
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.inp {
  display: block;
  width: 100%;
  margin-top: var(--space-2);
  min-height: 48px;
  padding: var(--space-3) var(--space-4);
  font-family: var(--body);
  font-size: var(--font-size-base);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
}
.inp:focus { border-color: var(--ink); }
textarea.inp { min-height: 92px; resize: vertical; }
.fields { display: grid; gap: var(--space-5); margin-top: var(--space-5); }

.hint {
  margin-top: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--ink-2);
}

/* Ошибка — текстом рядом с полем и без единой строки скрипта:
   :user-invalid срабатывает только ПОСЛЕ того, как человек тронул
   поле, поэтому пустая форма не встречает его красным. Текст ошибки
   лежит внутри той же подсказки, на которую уже указывает
   aria-describedby, — диктору не нужно искать второй адрес. */
.err { display: none; }
.inp:user-invalid { border-color: var(--red-ink); }
.inp:user-invalid ~ .hint { color: var(--red-ink); }
.inp:user-invalid ~ .hint .err { display: inline; font-weight: var(--weight-medium); }
.consent input:user-invalid ~ .hint .err { display: inline; color: var(--red-ink);
                                           font-weight: var(--weight-medium); }

/* Согласие на обработку. Не проставлено заранее — это требование,
   а не оформление: галочка, поставленная за человека, согласием
   не является. */
.consent {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  gap: var(--space-2) var(--space-3);
  align-items: start;
}
.consent input {
  width: 24px;
  height: 24px;
  margin: 0;
  accent-color: var(--green);
}
.consent > label { font-size: var(--font-size-sm); }
.consent .hint { grid-column: 2; margin-top: 0; }

/* Ловушка от ботов. Скрыта стилем, а не type="hidden": заполнившая её
   машина себя и называет. Капчи здесь нет намеренно — она добавила бы
   иностранного обработчика в тракт персональных данных. */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.cases { margin: var(--space-5) 0 0; padding: 0; border: 0; }
.cases__list { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.cases legend {
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding: 0;
  margin-bottom: var(--space-3);
}
.cases input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.cases label {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid var(--rule);
  background: #fff;
  color: var(--ink-2);
  border-radius: 999px;
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
}
.cases input:checked + label { border-color: var(--ink); color: var(--ink); }
.cases input:focus-visible + label { outline: 3px solid var(--color-accent); outline-offset: 2px; }
.tcode {
  font-family: var(--mono);
  font-size: var(--font-size-xs);
  letter-spacing: 0.1em;
  color: var(--ink-2);
  border-left: 1px solid var(--rule);
  margin-left: var(--space-2);
  padding-left: var(--space-2);
  text-transform: none;
}

.direct { margin: var(--space-3) 0 0; }
.direct dt { margin-top: var(--space-3); }
.direct dd { margin: 0; font-size: var(--font-size-lg); color: var(--ink-2); word-break: break-word; }

/* ==================================================================
   ПОДВАЛ.
   ================================================================== */
.foot { border-top: 1px solid var(--rule); padding-block: var(--space-5) var(--space-7); }
.foot__in { display: flex; justify-content: space-between; gap: var(--space-5); flex-wrap: wrap; align-items: baseline; }
.foot .wm { font-size: var(--font-size-lg); }

/* ------------------------------------------------------------------
   Движение гасится по требованию системы. Фиксированный слой снимает
   переходы; кадровые анимации — здесь, их он не знает.
   ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; }
}


/* --- Правовые страницы ---------------------------------------------------
   Собираются из site/legal/*.md (site/legal_pages.py). Своей сетки у них
   нет намеренно: ширину даёт .shell, как и всей витрине. Здесь только то,
   без чего сплошной юридический текст не читается — мера строки, воздух
   между разделами и видимые границы таблиц. */
.legal { padding-block: var(--space-7); max-width: 72ch; }
.legal h1 { font-size: var(--font-size-2xl); margin-bottom: var(--space-5); }
.legal h2 { font-size: var(--font-size-xl); margin-top: var(--space-6); }
.legal h3 { font-size: var(--font-size-lg); margin-top: var(--space-5); }
.legal p, .legal li { margin-top: var(--space-3); color: var(--ink-2); }
.legal ul, .legal ol { margin-top: var(--space-3); padding-left: var(--space-5); }
.legal blockquote {
  margin-top: var(--space-4);
  padding-left: var(--space-4);
  border-left: 3px solid var(--color-accent);
  color: var(--ink-1);
}
.legal table { margin-top: var(--space-4); border-collapse: collapse; width: 100%; }
.legal th, .legal td {
  border: 1px solid var(--rule);
  padding: var(--space-2) var(--space-3);
  text-align: left;
  vertical-align: top;
}
.legal hr { margin-block: var(--space-6); border: 0; border-top: 1px solid var(--rule); }
.legal__foot {
  padding-block: var(--space-5);
  border-top: 1px solid var(--rule);
  color: var(--ink-2);
}


/* Таблица цен. Ширина колонки имени фиксирована долей, чтобы числа
   выстроились в столбец: цена, поставленная вразнобой, читается дольше,
   чем ищется. */
.prices { width: 100%; border-collapse: collapse; margin-top: var(--space-5); }
.prices th, .prices td {
  border-top: 1px solid var(--rule);
  padding: var(--space-4) var(--space-3);
  text-align: left;
  vertical-align: top;
}
.prices th { width: 34%; font-weight: 600; }
.prices td { color: var(--ink-2); }
.prices b { color: var(--ink-0); }
@media (max-width: 47.99em) {
  .prices th, .prices td { display: block; width: auto; }
  .prices td { border-top: 0; padding-top: 0; }
}
