/* ============================================================================
   GramSense · база для всех десяти макетов лендинга
   ----------------------------------------------------------------------------
   Здесь живёт ТОЛЬКО то, что обязано быть одинаковым во всех вариантах:
   бренд-палитра из брифа §13 (обе темы, ни один цвет не определён внутри одной
   темы), шкала скруглений, шрифты, сброс, доступность и общий контракт анимации
   (`prefers-reduced-motion` выключает движение, страница остаётся полноценной).

   Личность варианта — в его собственном style.css. База НЕ задаёт ни сетку,
   ни типографическую шкалу, ни компоненты: иначе десять «разных» макетов
   получились бы десятью скинами одного.
   ========================================================================== */

/* --- Палитра. Светлая тема — значение по умолчанию на голом :root, тёмная
       переопределяет ТЕ ЖЕ токены. Так ни один цвет не существует только
       в одной теме (чек-лист брифа §17). ------------------------------------ */
:root {
  color-scheme: light dark;

  /* фон и поверхности — тёплая бумага */
  --bg: #f3eee0;
  --s1: #faf7ed;
  --s2: #ede7d6;
  --s3: #e3dcc7;
  --line: #e2dac6;

  /* Текст. --tx и --tx-mut — точные значения брифа §13.
     --tx-dim ОТЛИЧАЕТСЯ ОТ БРИФА НАМЕРЕННО, и вот почему. Брифовый «тусклый»
     #A1977F на тёплой бумаге #F3EEE0 даёт 2.5 : 1, а на поверхности #E3DCC7 —
     2.3 : 1 при требуемых §15 четырёх с половиной. Это не оттенок текста, а
     оттенок ДЕКОРАЦИИ: линеек, засечек шкалы, выключенных значков. Арифметика
     не оставляет выбора: чтобы взять 4.5 : 1 на этой бумаге, тон обязан быть
     не светлее #6E6555 — то есть третьей ступени СВЕТЛОТЫ в светлой теме
     просто нет. Поэтому в светлой теме `--tx-dim` совпадает с `--tx-mut`, а
     третий уровень выражается кеглем и начертанием, а не яркостью.
     Исходные брифовые значения остались как `--tx-faint` — для того, чем они
     и являются: для линий и нечитаемой мелочи. */
  --tx: #2a2620;
  /* Приглушённый на один шаг темнее брифового #6E6555. Тот берёт 4.5 : 1 на
     фоне и первой поверхности, но на третьей (#E3DCC7 — плашки, пузыри
     переписки, строки показаний) падает до 4.19 : 1. Разница на глаз
     неразличима, а гейт §15 переходит с запасом на всех трёх поверхностях. */
  --tx-mut: #655c4c;
  --tx-dim: #6e6555;
  --tx-faint: #a1977f;

  /* акценты-заливки: одинаковы в обеих темах */
  --olive: #b6d24e;
  --olive-d: #8baa33;
  --coral: #ff8264;
  --teal: #56b0b0;
  --gold: #e8b84b;
  --on-bright: #15130e;

  /* цветной ТЕКСТ: в светлой теме затемнённые варианты, иначе нет контраста */
  --olive-tx: #5b6f1f;
  --coral-tx: #a24020;
  --teal-tx: #2d6b6b; /* #317272 на поверхности #ede7d6 давал 4,497 : 1 (audit-content 25.09) */
  --gold-tx: #856414;

  /* тени — мягкие и тёплые, применяются редко */
  --sh-1: 0 1px 2px rgba(42, 38, 32, 0.06), 0 2px 10px rgba(42, 38, 32, 0.05);
  --sh-2: 0 2px 6px rgba(42, 38, 32, 0.07), 0 18px 46px rgba(42, 38, 32, 0.1);
  --sh-glow: 0 0 0 rgba(0, 0, 0, 0);

  /* форма (бриф §13) */
  --r-card: 13px;
  --r-panel: 20px;
  --r-pill: 999px;

  /* шрифты */
  /* «… Fallback» — Arial с метриками фирменного шрифта (shared/fonts-fallback.css): пока шрифт
     грузится, строки уже той же ширины и высоты, и подмена не толкает раскладку. */
  --ff-h: "Nunito Sans", "Nunito Sans Fallback", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --ff-b: "Hanken Grotesk", "Hanken Grotesk Fallback", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --ff-s: "Fraunces", Georgia, "Times New Roman", serif;
  --ff-m: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;

  /* движение */
  --e-out: cubic-bezier(0.22, 1, 0.36, 1);
  --e-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --e-back: cubic-bezier(0.34, 1.56, 0.64, 1);
  --d-fast: 180ms;
  --d-mid: 420ms;
  --d-slow: 820ms;
}

/* Системная тема уважается по умолчанию; явный выбор человека её перебивает. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #161410;
    --s1: #221f18;
    --s2: #2b2720;
    --s3: #332e25;
    --line: #3a352b;
    --tx: #c8c1b2;
    --tx-mut: #a79d8b;
    /* Брифовый #776E5E даёт 3.3 : 1 на поверхности #332E25. Подняли до
       минимума, который берёт 4.5 : 1 на самой светлой из тёмных поверхностей;
       исходный тон остался в --tx-faint для линий и декора. */
    --tx-dim: #a39982;
    --tx-faint: #776e5e;
    --olive-tx: #b6d24e;
    --coral-tx: #ff8264;
    --teal-tx: #56b0b0;
    --gold-tx: #e8b84b;
    --sh-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 10px rgba(0, 0, 0, 0.3);
    --sh-2: 0 2px 6px rgba(0, 0, 0, 0.45), 0 20px 50px rgba(0, 0, 0, 0.5);
  }
}

:root[data-theme="dark"] {
  --bg: #161410;
  --s1: #221f18;
  --s2: #2b2720;
  --s3: #332e25;
  --line: #3a352b;
  --tx: #c8c1b2;
  --tx-mut: #a79d8b;
  --tx-dim: #a39982;
  --tx-faint: #776e5e;
  --olive-tx: #b6d24e;
  --coral-tx: #ff8264;
  --teal-tx: #56b0b0;
  --gold-tx: #e8b84b;
  --sh-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 10px rgba(0, 0, 0, 0.3);
  --sh-2: 0 2px 6px rgba(0, 0, 0, 0.45), 0 20px 50px rgba(0, 0, 0, 0.5);
}

/* --- Сброс ---------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--tx);
  font-family: var(--ff-b);
  font-size: 17px;
  line-height: 1.55;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  /* Горизонтальной прокрутки страницы не должно возникать НИГДЕ (бриф §15). */
  overflow-x: clip;
}
h1,
h2,
h3,
h4,
h5 {
  font-family: var(--ff-h);
  font-weight: 800;
  margin: 0;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
p {
  margin: 0;
  text-wrap: pretty;
}
/* `height: auto` обязателен: у картинок стоят атрибуты width/height (они резервируют
   место и убирают сдвиг макета), но без этой строки атрибут height работает как
   презентационная подсказка и растягивает кадр 900×900 в колонку 430×900. */
img,
svg,
video {
  max-width: 100%;
  height: auto;
  display: block;
}
a {
  color: inherit;
}
button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}
/* `<select>` сообщает min-content по САМОМУ ДЛИННОМУ пункту («лёгкая, 1–3
   тренировки»), а элемент грида по умолчанию не сжимается ниже min-content —
   вместе это распирало страницу на планшете и давало горизонтальную прокрутку,
   запрещённую брифом §15. Гасим и у поля, и у его ячейки. */
input,
select,
textarea {
  min-width: 0;
  max-width: 100%;
}
.cf {
  min-width: 0;
}
ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}
table {
  border-collapse: collapse;
}

/* `hidden` обязан побеждать любой авторский display — иначе состояния хендоффа и
   скрытые блоки (место под отзывы) показываются все разом. */
[hidden] {
  display: none !important;
}

/* --- Доступность ---------------------------------------------------------- */
:focus-visible {
  outline: 3px solid var(--teal);
  outline-offset: 3px;
  border-radius: 4px;
}
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.skip {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 999;
  background: var(--olive);
  color: var(--on-bright);
  padding: 10px 18px;
  border-radius: var(--r-pill);
  font-weight: 700;
  transition: top var(--d-fast);
}
.skip:focus {
  top: 12px;
}

/* --- Общий контракт появления. Вариант решает, КАК именно (свои
       --rv-* переменные), база — только то, что без скрипта и без анимации
       содержимое видно полностью. ------------------------------------------ */
[data-rv] {
  opacity: 0;
  transform: translate3d(var(--rv-x, 0), var(--rv-y, 22px), 0) scale(var(--rv-s, 1));
  transition:
    opacity var(--d-slow) var(--e-out),
    transform var(--d-slow) var(--e-out);
  transition-delay: var(--rv-d, 0ms);
  /* `will-change` здесь НЕ ставится намеренно: на странице до сотни таких
     элементов, и постоянный слой на каждом исчерпывает бюджет композитора —
     страница начинает отдавать пустой растр ниже первого экрана. Проверено
     в Chromium: 81 элемент с will-change = чёрный экран после прокрутки. */
}
[data-rv].in {
  opacity: 1;
  transform: none;
}
/* Без JS ничего не прячем: страница обязана быть полноценной. */
html:not(.js) [data-rv] {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  [data-rv] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    /* Задержки тоже в ноль: длительность без задержки оставляла плашки ролика и ленты дня
       проявляться через 0,7–3,1 с при выключенном движении — пауза вместо анимации. */
    animation-delay: 0s !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}

/* --- Мелочи, которые повторяются во всех вариантах ------------------------ */

/* Логотип: слово GramSense всегда набирается логотипом, а не текстом (§5). */
.gs-logo {
  display: block;
  height: 22px;
  width: auto;
}
.gs-logo-l {
  display: none;
}
:root[data-theme="light"] .gs-logo-d,
html:not([data-theme]) .gs-logo-d {
  display: none;
}
:root[data-theme="light"] .gs-logo-l,
html:not([data-theme]) .gs-logo-l {
  display: block;
}
@media (prefers-color-scheme: dark) {
  html:not([data-theme]) .gs-logo-d {
    display: block;
  }
  html:not([data-theme]) .gs-logo-l {
    display: none;
  }
}
:root[data-theme="dark"] .gs-logo-d {
  display: block;
}
:root[data-theme="dark"] .gs-logo-l {
  display: none;
}

/* Знак валюты GramS — та же четырёхлучевая звезда, что в продукте
   (webapp/src/react/icons/GramS.tsx). Имя пишется двумя цветами, «S» в степени. */
.gs-word {
  font-family: var(--ff-h);
  font-weight: 800;
  white-space: nowrap;
}
.gs-word i {
  font-style: normal;
  color: var(--olive-tx);
}
/* «S» поднята в степень (владелец, 2026-08-24): надстрочная буква превращает имя
   в короткий знак и не читается как английское множественное число «граммы».
   `line-height: 0` обязателен — иначе поднятая литера распирает строку заголовка. */
.gs-word sup {
  font-size: 0.5em;
  color: var(--coral-tx);
  top: -0.44em;
  line-height: 0;
  position: relative;
  font-weight: 800;
}

/* Полоса «горизонтальная прокрутка внутри своего контейнера» для широких таблиц. */
.scrollx {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

/* --- Размер цели: минимум WCAG 2.5.8 (AA) — 24×24 px ---------------------
   Три места промахивались мимо него во всех вариантах сразу, поэтому гарды
   стоят здесь, а не переписываются в каждом макете. */

/* Логотип в шапке: сама картинка около 20 px, ссылка вокруг неё была ровно
   такой же высоты. Клетка растянута, вид логотипа не меняется. */
.brand {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
}
/* Флажки и переключатели: браузерный размер около 13 px. Заодно фирменный
   цвет отметки вместо системного синего. */
input[type="checkbox"],
input[type="radio"] {
  width: 18px;
  height: 18px;
  accent-color: var(--olive);
  flex: none;
}
/* Подпись рядом с флажком — и есть цель: по ней и целятся. Держим её высоту
   выше минимума, иначе целью остаётся сам квадратик в 18 px. */
label:has(input[type="checkbox"]),
label:has(input[type="radio"]) {
  min-height: 26px;
}
/* Ссылки подвала и переключатели языка на телефоне: строка текста в 20 px
   не дотягивает до цели, хотя пальцем по ней и целятся. */
@media (max-width: 620px) {
  footer a,
  footer button {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
  }
}

/* Плейсхолдер числа, которое подставит заказчик. */
.ph {
  font-family: var(--ff-m);
  font-size: 0.86em;
  padding: 0.05em 0.35em;
  border-radius: 5px;
  background: color-mix(in srgb, var(--gold) 22%, transparent);
  color: var(--gold-tx);
  white-space: nowrap;
}
