/* ============================================================================
   Общие секции лендинга (классы gs-*) — стиль по умолчанию для всех макетов.
   ----------------------------------------------------------------------------
   Всё в токенах base.css, поэтому макет меняет вид одним :root — свои
   --gs-wrap, --gs-radius, --gs-card, шрифты, отступы — и точечными селекторами.
   Здесь нет ничего «фирменного» для конкретного направления: только рабочая
   типографика, сетки и состояния, на которых любой макет читается целиком,
   даже если он не переопределил ни одной секции.
   ========================================================================== */

:root {
  --gs-wrap: 1200px;
  --gs-pad: clamp(56px, 8vw, 112px);
  --gs-card: var(--s1);
  --gs-card-line: var(--line);
  --gs-r: var(--r-panel);
  --tg: #3fb0ea;
  --tg-tx: #3fb0ea;
}
:root[data-theme="light"],
html:not([data-theme]) {
  --tg: #1f8fcf;
  --tg-tx: #0f6690;
}
@media (prefers-color-scheme: dark) {
  html:not([data-theme]) {
    --tg: #3fb0ea;
    --tg-tx: #3fb0ea;
  }
}
:root[data-theme="dark"] {
  --tg: #3fb0ea;
}

.gs-wrap {
  width: min(100% - 40px, var(--gs-wrap));
  margin-inline: auto;
}
@media (max-width: 560px) {
  .gs-wrap {
    width: min(100% - 26px, var(--gs-wrap));
  }
}
.gs-i {
  width: 24px;
  height: 24px;
  flex: none;
}
.t-coral {
  color: var(--coral-tx);
}
.t-olive {
  color: var(--olive-tx);
}
.t-teal {
  color: var(--teal-tx);
}
.t-tg {
  color: var(--tg);
}

/* ─────────────────────────────────────────────────────── кнопки, ссылки, чипы */
.gs-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 13px 22px;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-family: var(--ff-h);
  font-weight: 800;
  font-size: 16px;
  text-decoration: none;
  cursor: pointer;
  line-height: 1.2;
  transition:
    transform var(--d-fast) var(--e-out),
    background var(--d-fast),
    border-color var(--d-fast);
}
.gs-btn .gs-i {
  width: 18px;
  height: 18px;
}
.gs-btn-p {
  background: var(--olive);
  color: var(--on-bright);
}
.gs-btn-p:hover {
  background: var(--olive-d);
  transform: translateY(-1px);
}
.gs-btn-g {
  border-color: var(--line);
  background: color-mix(in srgb, var(--s1) 70%, transparent);
  color: var(--tx);
}
.gs-btn-g:hover {
  border-color: var(--olive);
  color: var(--olive-tx);
}
.gs-btn-lg {
  padding: 17px 30px;
  font-size: 18px;
}
.gs-link {
  background: none;
  border: 0;
  padding: 0;
  color: var(--teal-tx);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  font: inherit;
}
.gs-chip {
  padding: 8px 16px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: transparent;
  color: var(--tx-mut);
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--d-fast) var(--e-out);
}
.gs-chip:hover {
  color: var(--tx);
  border-color: var(--tx-dim);
}
.gs-chip[aria-pressed="true"] {
  background: var(--olive);
  border-color: var(--olive);
  color: var(--on-bright);
}

/* ────────────────────────────────────────────────────────────────── шапка */
.gs-head {
  position: sticky;
  top: 0;
  z-index: 40;
  backdrop-filter: blur(14px) saturate(1.3);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  border-bottom: 1px solid transparent;
  transition:
    transform var(--d-mid) var(--e-out),
    border-color var(--d-mid);
}
.gs-head.scrolled {
  border-bottom-color: var(--line);
}
/* Прячется при прокрутке вниз, возвращается вверх (решение 12.09) */
.gs-head.scrolled:not(.up) {
  transform: translateY(-100%);
}
.gs-head-in {
  display: flex;
  align-items: center;
  gap: 20px;
  min-height: 64px;
}
.gs-brand {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.gs-nav {
  display: flex;
  gap: 20px;
  margin-inline: auto;
  font-size: 15px;
}
.gs-nav a {
  color: var(--tx-mut);
  text-decoration: none;
  padding: 6px 0;
  white-space: nowrap;
}
.gs-head-tools .gs-btn span {
  white-space: nowrap;
}
.gs-nav a:hover {
  color: var(--tx);
}
.gs-head-tools {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.gs-head-tools .gs-btn {
  padding: 9px 15px;
  font-size: 14.5px;
}
.gs-ico {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: none;
  color: var(--tx-mut);
  cursor: pointer;
}
.gs-ico .gs-i {
  width: 18px;
  height: 18px;
}
@media (max-width: 1080px) {
  .gs-nav {
    display: none;
  }
}
@media (max-width: 640px) {
  .gs-head-tg {
    display: none;
  }
  /* Не display:none: так у кнопки пропадало доступное имя, и диктор читал только иконку. */
  .gs-head-tools .gs-btn span {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .gs-head-tools .gs-btn {
    padding: 9px 12px;
  }
}

/* ──────────────────────────────────────────────────────────── первый экран */
.gs-hero {
  padding: clamp(32px, 6vw, 80px) 0 clamp(24px, 4vw, 48px);
}
.gs-hero-in {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
}
.gs-eyebrow {
  font-family: var(--ff-m);
  font-size: 12.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tx-dim);
  margin-bottom: 18px;
}
.gs-h1 {
  font-size: clamp(36px, 5.4vw, 76px);
  line-height: 1;
  letter-spacing: -0.035em;
  font-weight: 900;
}
.gs-h1 em {
  font-style: normal;
}
.gs-h1-b {
  display: block;
  margin-top: 0.35em;
  font-size: 0.5em;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--tx-mut);
}
.gs-lede {
  margin-top: 22px;
  max-width: 34ch;
  font-size: clamp(17px, 1.4vw, 20px);
  color: var(--tx-mut);
}
.gs-hero-links {
  margin-top: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  font-size: 15px;
  color: var(--tx-dim);
}
.gs-hero-links a {
  color: var(--teal-tx);
}
/* Ссылок три (28.09 добавился «Заработать звёзды Telegram»), и на узком экране строка переносится —
   разделитель «·» оставался первым символом новой строки. Там ссылки расходятся просто промежутком. */
@media (max-width: 560px) {
  .gs-hero-links { column-gap: 16px; row-gap: 8px; }
  .gs-hero-links > span[aria-hidden="true"] { display: none; }
}
.gs-hero-note {
  margin-top: 10px;
  font-size: 14.5px;
  color: var(--tx-dim);
  max-width: 44ch;
  transition: opacity var(--d-fast);
}

/* Персонажи на первом экране */
.gs-cast-intro {
  font-size: 15px;
  color: var(--tx-mut);
  margin-bottom: 14px;
  max-width: 40ch;
}
.gs-cast-list {
  display: grid;
  gap: 10px;
}
.gs-cast-item {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 14px;
  align-items: center;
  padding: 12px 14px;
  border-radius: var(--r-card);
  background: var(--gs-card);
  border: 1px solid var(--gs-card-line);
}
.gs-cast-item b {
  font-family: var(--ff-h);
  color: currentColor;
}
.gs-cast-item span {
  color: var(--tx-mut);
  font-size: 15px;
  grid-column: 2;
}
.gs-cast-img {
  grid-row: span 2;
  width: 56px;
  height: 84px;
  object-fit: cover;
  border-radius: 10px;
}
.gs-cast-dot {
  grid-row: span 2;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: currentColor;
}
@media (max-width: 860px) {
  .gs-hero-in {
    grid-template-columns: 1fr;
  }
}

/* Хендофф фото → Telegram */
.gs-handoff {
  margin-top: 26px;
}
.gs-hf-state {
  display: grid;
  gap: 12px;
  justify-items: start;
}
.gs-hf-drop {
  font-size: 14px;
  color: var(--tx-dim);
  padding: 14px 18px;
  border: 1px dashed color-mix(in srgb, var(--tx-dim) 60%, transparent);
  border-radius: var(--r-card);
  max-width: 44ch;
  transition: border-color var(--d-fast);
}
.gs-hf-drop.is-over {
  border-color: var(--olive);
  color: var(--tx);
}
.gs-hf-drop small {
  display: block;
  margin-top: 4px;
}
.gs-hf-preview {
  width: 120px;
  height: 120px;
  object-fit: cover;
  border-radius: var(--r-card);
  border: 1px solid var(--line);
}
.gs-hf-note {
  font-size: 14px;
  color: var(--tx-dim);
  max-width: 44ch;
}
.gs-hf-err {
  padding: 12px 16px;
  border-radius: var(--r-card);
  background: color-mix(in srgb, var(--coral) 14%, transparent);
  color: var(--coral-tx);
  font-size: 15px;
  max-width: 50ch;
}
@media (max-width: 560px) {
  .gs-hf-drop {
    display: none;
  }
}

/* Чипы цели */
.gs-goals {
  border-block: 1px solid var(--line);
  padding: 14px 0;
}
.gs-goals-in {
  display: flex;
  align-items: center;
  gap: 12px;
}
.gs-goals-l {
  flex: none;
  font-size: 14px;
  color: var(--tx-dim);
}
.gs-chips {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.gs-chips::-webkit-scrollbar {
  display: none;
}

/* ──────────────────────────────────────────────────────────────── секции */
.gs-sec {
  padding: var(--gs-pad) 0;
}
.gs-sec-alt {
  background: color-mix(in srgb, var(--s1) 55%, transparent);
  border-block: 1px solid var(--line);
}
.gs-sec-h {
  max-width: 820px;
  margin-bottom: clamp(24px, 4vw, 48px);
}
.gs-kick {
  font-family: var(--ff-m);
  font-size: 12.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--olive-tx);
  margin-bottom: 12px;
}
.gs-h2 {
  font-size: clamp(28px, 4vw, 54px);
  letter-spacing: -0.03em;
}
.gs-sub {
  margin-top: 14px;
  font-size: clamp(16px, 1.3vw, 19px);
  color: var(--tx-mut);
  max-width: 62ch;
}
.gs-p {
  color: var(--tx-mut);
  margin-bottom: 14px;
  max-width: 60ch;
}
.gs-p b {
  color: var(--tx);
}
.gs-line {
  margin-top: 22px;
  color: var(--tx-mut);
  max-width: 70ch;
}
.gs-line a {
  color: var(--teal-tx);
}
.gs-kicker-line {
  margin-top: 16px;
  padding-left: 16px;
  border-left: 3px solid var(--gold);
  color: var(--tx-mut);
  max-width: 70ch;
}
.gs-note {
  margin-top: 24px;
  font-size: 14.5px;
  color: var(--tx-dim);
}
.gs-after {
  margin-top: 14px;
  font-family: var(--ff-h);
  font-weight: 800;
  font-size: clamp(18px, 2.2vw, 26px);
  color: var(--teal-tx);
}
.gs-sub-note {
  margin-top: 20px;
  padding: 16px 20px;
  border-radius: var(--r-card);
  border: 1px solid color-mix(in srgb, var(--gold) 45%, var(--line));
  background: color-mix(in srgb, var(--gold) 9%, transparent);
  color: var(--tx-mut);
}
.gs-two {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
  gap: clamp(26px, 5vw, 64px);
  align-items: center;
}
@media (max-width: 860px) {
  .gs-two {
    grid-template-columns: 1fr;
  }
}

/* Сетки карточек */
/* Карточки переносятся рядами и растягиваются: при 7 карточках в четыре колонки последний ряд из
   трёх занимает всю ширину, а не обрывается дырой справа (владелец 19.09: «окна не выровнены»).
   Сетка auto-fit так не умеет — у неё колонки одной ширины на всех рядах. */
.gs-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}
.gs-grid > * {
  flex: 1 1 250px;
}
.gs-card,
.gs-icons li,
.gs-trust li,
.gs-calm li,
.gs-data li {
  padding: 22px;
  border-radius: var(--gs-r);
  background: var(--gs-card);
  border: 1px solid var(--gs-card-line);
  position: relative;
}
.gs-card .gs-i,
.gs-icons .gs-i {
  color: var(--olive-tx);
  margin-bottom: 14px;
  width: 26px;
  height: 26px;
}
.gs-card h3,
.gs-icons h3 {
  font-size: 18px;
  margin-bottom: 6px;
}
.gs-card p,
.gs-icons p {
  color: var(--tx-mut);
  font-size: 15.5px;
}
.gs-badge {
  position: absolute;
  top: 16px;
  right: 16px;
  font-family: var(--ff-h);
  font-weight: 800;
  font-size: 11.5px;
  padding: 4px 9px;
  border-radius: var(--r-pill);
  background: var(--coral);
  color: var(--on-bright);
}
.gs-trust li,
.gs-calm li {
  color: var(--tx-mut);
  font-size: 15.5px;
}
.gs-trust b,
.gs-calm b {
  color: var(--tx);
  font-family: var(--ff-h);
}
.gs-data li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  color: var(--tx-mut);
  font-size: 15.5px;
}
.gs-data .gs-i {
  color: var(--teal-tx);
}
.gs-disclaimer {
  margin-top: 20px;
  padding: 14px 18px;
  border-radius: var(--r-card);
  border: 1px dashed color-mix(in srgb, var(--tx-dim) 60%, transparent);
  color: var(--tx-mut);
  font-size: 14.5px;
}

/* Шаги */
.gs-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}
.gs-steps li {
  padding: 24px 22px;
  border-radius: var(--gs-r);
  background: var(--gs-card);
  border: 1px solid var(--gs-card-line);
}
/* Кегль 19px при весе 800 — порог «крупного текста»: акцентный цвет на подложке даёт 3,3 : 1,
   для мелкого это мало, для крупного достаточно. Менять цвет нельзя — он кодирует еду/движение/итог. */
.gs-step-n {
  display: grid;
  place-items: center;
  font-size: 19px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: color-mix(in srgb, currentColor 16%, transparent);
  color: currentColor;
  font-family: var(--ff-h);
  font-weight: 800;
  margin-bottom: 14px;
}
.gs-steps h3 {
  font-size: 22px;
  margin-bottom: 8px;
}
.gs-steps p {
  color: var(--tx-mut);
}
.gs-where .gs-step-n {
  color: var(--tg);
}
.gs-honest {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-top: 20px;
  padding: 16px 20px;
  border-radius: var(--gs-r);
  border: 1px solid color-mix(in srgb, var(--teal) 40%, var(--line));
  background: color-mix(in srgb, var(--teal) 9%, transparent);
  font-weight: 600;
}
.gs-honest .gs-i {
  color: var(--teal-tx);
}
.gs-exceptions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 20px;
}
.gs-exceptions li {
  padding: 7px 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  font-size: 14px;
  color: var(--tx-mut);
}

/* Чат и диалоги */
.gs-chat,
.gs-dlg {
  display: grid;
  gap: 8px;
  padding: 16px;
  border-radius: var(--gs-r);
  background: var(--bg);
  border: 1px solid var(--line);
}
.gs-msg {
  max-width: 88%;
  padding: 10px 13px;
  border-radius: 14px;
  font-size: 14.5px;
  line-height: 1.45;
}
.gs-msg.out {
  margin-left: auto;
  background: color-mix(in srgb, var(--olive) 20%, transparent);
  border-bottom-right-radius: 4px;
}
.gs-msg.in {
  background: var(--s2);
  border: 1px solid var(--line);
  border-bottom-left-radius: 4px;
}
.gs-msg.in b {
  display: block;
  font-family: var(--ff-h);
}
.gs-msg.in > span {
  display: block;
  color: var(--tx-mut);
}
.gs-dlg .gs-msg.in > span {
  color: var(--tx);
}
.gs-msg-btn {
  display: inline-block;
  margin-top: 8px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  font-size: 12.5px;
  color: var(--tx-mut);
}
.gs-msg-card {
  display: block;
  margin-top: 6px;
  font-style: normal;
  font-size: 12.5px;
  color: var(--teal-tx);
}
.gs-msg-card::before {
  content: "▢ ";
}
.gs-msg-album {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
  padding: 5px;
  max-width: 100%;
}
.gs-msg-album img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 7px;
}
.gs-example {
  color: var(--tx-dim);
  font-size: 12px;
  justify-self: end;
}
/* Реплика печатается при появлении (demos.js) */
.gs-dlg[data-dialogue] .gs-msg {
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity 320ms var(--e-out),
    transform 320ms var(--e-out);
}
.gs-dlg[data-dialogue] .gs-msg.shown,
html:not(.js) .gs-dlg .gs-msg {
  opacity: 1;
  transform: none;
}

/* Помощники */
.gs-helpers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
}
.gs-helper {
  /* Обложка идёт от края до края, поэтому внутренний отступ живёт на содержимом, а не на карточке. */
  padding: 0 0 22px;
  overflow: hidden;
  border-radius: var(--gs-r);
  background: var(--gs-card);
  border: 1px solid var(--gs-card-line);
  border-top: 3px solid currentColor;
  display: grid;
  gap: 14px;
  align-content: start;
}
.gs-helper > *:not(.gs-helper-cover) {
  margin-inline: 22px;
}
/* Обложка: та самая валяная фигурка. Кадр вертикальный (1000×1500), в широкой обложке от него
   нужна верхняя часть с лицом, отсюда object-position. Подложка под цвет персонажа, чтобы
   тёмное дерево кадра не спорило со светлой карточкой. */
.gs-helper-cover {
  aspect-ratio: 16 / 10;
  background: color-mix(in srgb, currentColor 14%, var(--gs-card));
}
.gs-helper-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 34%;
}
/* Шапка переписки: круглый аватар, имя, роль с точкой «на связи». */
.gs-helper-head {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-top: -2px;
}
.gs-helper-ava {
  width: 44px;
  height: 44px;
  flex: none;
  object-fit: cover;
  object-position: 50% 36%;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, currentColor 45%, transparent);
}
.gs-helper h3 {
  font-size: 22px;
  color: currentColor;
  line-height: 1.15;
}
.gs-helper-role {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--tx-dim);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.gs-helper-role i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--olive-d);
}
.gs-helper-about {
  color: var(--tx-mut);
  font-size: 14.5px;
}

/* Демо импорта плана */
.gs-demo {
  display: grid;
  grid-template-columns: minmax(180px, 0.7fr) 40px minmax(0, 1.3fr);
  align-items: center;
  gap: 14px;
  margin: 8px 0 28px;
}
/* Лист лежит на столе с лёгким наклоном и отбрасывает тень: это сразу читается как чужой документ,
   а не как ещё одна панель интерфейса. Наклон маленький — в узкой колонке он не должен давать
   горизонтальную прокрутку. */
.gs-doc {
  position: relative;
  padding: 30px 18px 18px;
  border-radius: 8px;
  background: var(--s1);
  border: 1px solid var(--line);
  box-shadow: var(--sh-2);
  display: grid;
  gap: 8px;
  rotate: -1.1deg;
}
/* Метка формата — плашка, а не бледная подпись: до 21.09 она была того же цвета, что и фон. */
.gs-doc-tag {
  position: absolute;
  top: 9px;
  right: 10px;
  padding: 2px 7px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--coral) 18%, transparent);
  color: var(--coral-tx);
  font-family: var(--ff-m);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
}
.gs-doc-line {
  position: relative;
  padding-right: 20px;
  font-family: var(--ff-m);
  font-size: 12px;
  /* Строка остаётся читаемой. Прежние 25 % непрозрачности превращали половину демонстрации
     в пустое место: перенос надо ПОКАЗАТЬ, а не стереть источник (владелец 21.09). */
  color: var(--tx-mut);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Галочка справа от строки — «эта строка уже в дневнике». Появляется по очереди, в том же ритме,
   в каком справа проявляются дни, поэтому глаз связывает лист и расписание. */
.gs-doc-line::after {
  content: "";
  position: absolute;
  right: 2px;
  top: 50%;
  width: 9px;
  height: 5px;
  border-left: 1.6px solid var(--olive-d);
  border-bottom: 1.6px solid var(--olive-d);
  transform: translateY(-70%) rotate(-45deg) scale(0.6);
  opacity: 0;
  transition:
    opacity 260ms var(--e-out),
    transform 260ms var(--e-back);
}
.gs-demo.run .gs-doc-line::after {
  opacity: 1;
  transform: translateY(-70%) rotate(-45deg) scale(1);
  transition-delay: calc(var(--i, 0) * 140ms);
}
/* Стрелка «лист → дневник». До 24.09 здесь стоял плюс, повёрнутый на 45°, то есть «×»: «PDF ×
   дневник» читалось как запрет или умножение. На телефоне колонки встают друг под друга — стрелка вниз. */
.gs-demo-arrow {
  color: var(--gold-tx);
  justify-self: center;
}
/* Справа налево лист стоит справа — стрелка смотрит влево. На телефоне она вниз при любом направлении. */
@media (min-width: 721px) { [dir="rtl"] .gs-demo-arrow { scale: -1 1; } }
.gs-days {
  display: grid;
  gap: 8px;
}
.gs-day {
  padding: 10px 12px;
  border-radius: var(--r-card);
  background: var(--s1);
  border: 1px solid var(--line);
}
.gs-day > b {
  display: block;
  font-family: var(--ff-h);
  font-size: 13px;
  color: var(--tx-dim);
  margin-bottom: 6px;
}
.gs-day-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  gap: 8px;
  align-items: center;
  padding: 6px 8px;
  border-radius: 8px;
  font-size: 13px;
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity 400ms var(--e-out),
    transform 400ms var(--e-out);
}
.gs-demo.run .gs-day-row,
html:not(.js) .gs-day-row {
  opacity: 1;
  transform: none;
}
.gs-day-row span {
  color: var(--tx-dim);
}
.gs-day-row em {
  font-style: normal;
}
.gs-day-row i {
  font-style: normal;
  color: var(--tx-mut);
  white-space: nowrap;
}
.gs-day-row button {
  padding: 4px 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--olive);
  background: transparent;
  color: var(--olive-tx);
  font-size: 12px;
  font-weight: 700;
  cursor: default;
}
.gs-day-row.done button {
  background: var(--olive);
  color: var(--on-bright);
}
.gs-set {
  grid-template-columns: 1fr auto;
}
.gs-set i {
  color: var(--olive-tx);
}
.gs-plan-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px 24px;
  color: var(--tx-mut);
  font-size: 15.5px;
}
.gs-plan-list b {
  color: var(--tx);
  font-family: var(--ff-h);
}
.gs-demo > *,
.gs-day-row > * {
  min-width: 0;
}
@media (max-width: 720px) {
  .gs-demo {
    grid-template-columns: 1fr;
  }
  .gs-demo-arrow {
    rotate: 90deg;
  }
  .gs-day-row {
    grid-template-columns: auto 1fr auto;
  }
  .gs-day-row button {
    grid-column: 1 / -1;
    justify-self: start;
  }
  .gs-doc-line {
    white-space: normal;
  }
}

/* Знакомство карточками */
.gs-onb {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: clamp(20px, 4vw, 48px);
  align-items: start;
}
.gs-onb-parts {
  display: grid;
  gap: 10px;
}
.gs-onb-part {
  padding: 14px 16px;
  border-radius: var(--r-card);
  background: var(--gs-card);
  border: 1px solid var(--gs-card-line);
  border-left: 3px solid currentColor;
  display: grid;
  gap: 4px;
}
.gs-onb-part b {
  font-family: var(--ff-h);
}
.gs-onb-part span {
  color: var(--tx-mut);
  font-size: 14.5px;
}
.gs-onb-part.is-active {
  background: color-mix(in srgb, currentColor 8%, var(--gs-card));
}
.gs-onb-part.is-done span::after {
  content: " ✓";
  color: var(--olive-tx);
}
.gs-onb-stage {
  min-height: 260px;
  padding: 24px;
  border-radius: var(--gs-r);
  background: var(--gs-card);
  border: 1px solid var(--gs-card-line);
  display: grid;
  gap: 16px;
  align-content: start;
}
.gs-onb-q {
  font-family: var(--ff-h);
  font-weight: 800;
  font-size: clamp(19px, 2vw, 24px);
}
.gs-onb-who {
  font-size: 13px;
  color: var(--tx-dim);
}
.gs-onb-opts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* Числовой шаг: сперва ОТВЕТ, потом чем его менять. Значение было мелкой подписью справа от
   шкалы, а сама шкала шла без границ — «неинформативно» (владелец 22.09). Теперь ответ крупный и
   он же поле ввода, под ним шкала во всю ширину с подписанными концами. */
.gs-onb-num {
  display: grid;
  gap: 6px;
  max-width: 340px;
}
.gs-onb-num input[type="range"] {
  width: 100%;
  accent-color: var(--olive);
}
.gs-onb-big {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--ff-h);
  font-weight: 800;
  line-height: 1;
}
.gs-onb-big input[type="number"] {
  /* Ширина по САМОМУ ДЛИННОМУ возможному значению шага, а не «на глаз»: у веса шаг дробный, и
     «68,5» в поле на четыре с половиной знака не помещалось (владелец 22.09). Число знаков
     считает разметка из границ и шага. */
  width: calc(var(--chars, 4) * 1ch + 0.6ch);
  padding: 2px 6px;
  border: 1px dashed var(--gs-card-line);
  border-radius: 10px;
  background: none;
  color: currentColor;
  font: inherit;
  font-size: clamp(34px, 3.6vw, 48px);
  text-align: right;
  -moz-appearance: textfield;
}
.gs-onb-big input[type="number"]::-webkit-outer-spin-button,
.gs-onb-big input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* Пунктир по краю — приглашение набрать: без него поле неотличимо от подписи и его не трогают. */
.gs-onb-big input[type="number"]:hover { border-color: currentColor; }
.gs-onb-big input[type="number"]:focus { outline: none; border-style: solid; border-color: currentColor; background: var(--gs-card); }
/* Единица была 0,42 от числа — рядом с 48 пикселями это выглядело опечаткой. Полтора десятка
   пикселей и тот же вес шрифта читаются как подпись, а не как случайный обрезок. */
.gs-onb-big i { font-style: normal; font-size: 17px; line-height: 1; color: var(--tx-dim); font-weight: 700; }
.gs-onb-bounds {
  display: flex;
  justify-content: space-between;
  font-family: var(--ff-m);
  font-size: 11px;
  color: var(--tx-faint);
}
.gs-onb-bounds i { font-style: normal; }
/* На телефоне шкала — ВО ВСЮ ширину карточки (владелец 23.09: на двух третях ширины ползунок
   грубее — на ту же сотню значений меньше точек под пальцем). Дорожка выше, чтобы попадать
   пальцем было легче. */
@media (max-width: 720px) {
  .gs-onb-num { max-width: none; }
  .gs-onb-num input[type="range"] { height: 32px; }
}
/* Реплика Gramfessor: он рассказывает, а не спрашивает (владелец 23.09). Обычный текст, не плашка:
   это его речь, продолжение заголовка, а не справка сбоку. */
.gs-onb-say {
  max-width: 62ch;
  font-size: 16.5px;
  line-height: 1.55;
  color: var(--tx-mut);
}
.gs-onb-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}
.gs-onb-progress {
  height: 4px;
  border-radius: 2px;
  background: var(--line);
  overflow: hidden;
}
.gs-onb-progress i {
  display: block;
  height: 100%;
  background: currentColor;
  width: var(--w, 0%);
  transition: width 300ms var(--e-out);
}
.gs-onb-result {
  display: grid;
  gap: 8px;
}
/* Раздел под цель из «Зачем ты здесь?» (onboarding.js applyWhy): ссылка в итоге знакомства и метка
   над заголовком самого раздела. */
.gs-onb-foryou { margin-top: 10px; font-size: 15px; color: var(--tx-mut); }
.gs-onb-foryou a { font-weight: 700; color: var(--coral-tx); }
.gs-foryou-badge {
  display: inline-block; margin: 0 0 12px; padding: 4px 12px; border-radius: 99px;
  font-size: 12.5px; font-weight: 700; letter-spacing: 0.02em;
  background: color-mix(in srgb, var(--coral) 18%, transparent); color: var(--coral-tx);
}
.gs-onb-result .big {
  font-family: var(--ff-h);
  font-weight: 900;
  font-size: clamp(34px, 4vw, 48px);
  line-height: 1;
}
.gs-onb-result .big small {
  font-size: 0.4em;
  color: var(--tx-mut);
  font-weight: 600;
}
.gs-onb-result p {
  color: var(--tx-mut);
  font-size: 15px;
}
@media (max-width: 860px) {
  .gs-onb {
    grid-template-columns: 1fr;
  }
}

/* Деньги */
.gs-money .gs-p {
  font-size: 17px;
  max-width: 68ch;
}
.gs-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.gs-facts li {
  padding: 7px 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  font-size: 14px;
  color: var(--tx-mut);
}

/* Сравнение */
.gs-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}
.gs-day-row button {
  max-width: 100%;
  white-space: normal;
}
.gs-tab {
  padding: 8px 16px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: transparent;
  color: var(--tx-mut);
  font-weight: 700;
  cursor: pointer;
}
.gs-tab[aria-pressed="true"] {
  background: var(--tx);
  color: var(--bg);
  border-color: var(--tx);
}
.gs-tbl {
  width: 100%;
  min-width: 560px;
  font-size: 15px;
}
.gs-tbl th,
.gs-tbl td {
  padding: 12px 14px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.gs-tbl thead th {
  font-family: var(--ff-h);
  font-size: 13px;
  color: var(--tx-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.gs-tbl tbody th {
  font-weight: 600;
}
.gs-tbl td {
  color: var(--tx-mut);
}
.gs-tbl .me {
  background: color-mix(in srgb, var(--olive) 9%, transparent);
  color: var(--tx);
}

/* Приложения, FAQ, финал, подвал */
.gs-apps {
  color: var(--tx-mut);
  font-size: 17px;
}
.gs-apps b {
  color: var(--tx);
  font-family: var(--ff-h);
}
.gs-faq {
  display: grid;
  gap: 8px;
  max-width: 860px;
}
.gs-faq details {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--gs-card);
}
.gs-faq summary {
  padding: 16px 20px;
  cursor: pointer;
  font-family: var(--ff-h);
  font-weight: 700;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.gs-faq summary::-webkit-details-marker {
  display: none;
}
.gs-faq summary::after {
  content: "+";
  color: var(--olive-tx);
  font-size: 22px;
  line-height: 1;
}
.gs-faq details[open] summary::after {
  content: "−";
}
.gs-faq p {
  padding: 0 20px 18px;
  color: var(--tx-mut);
  max-width: 72ch;
}
.gs-proof blockquote {
  margin: 0;
  padding: 20px;
  border-radius: var(--gs-r);
  border: 1px solid var(--line);
}
.gs-final {
  padding: clamp(64px, 10vw, 130px) 0;
  text-align: center;
  border-top: 1px solid var(--line);
}
.gs-final .gs-h2 {
  max-width: 18ch;
  margin-inline: auto;
}
.gs-final .gs-sub {
  margin-inline: auto;
}
.gs-final .gs-hf-state {
  justify-items: center;
  margin-top: 24px;
}
.gs-final .gs-hero-links {
  justify-content: center;
  margin-top: 16px;
}
.gs-foot {
  border-top: 1px solid var(--line);
  padding: 40px 0 24px;
  background: var(--s1);
}
.gs-foot-in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: 28px;
}
.gs-foot-dis {
  margin-top: 12px;
  font-size: 13.5px;
  color: var(--tx-dim);
  max-width: 36ch;
}
.gs-foot-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  font-size: 15px;
  align-content: start;
}
.gs-foot-nav a {
  color: var(--tx-mut);
  text-decoration: none;
}
.gs-foot-nav a:hover {
  color: var(--olive-tx);
}
.gs-foot-legal {
  margin-top: 26px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  text-align: center;
  font-size: 13px;
  color: var(--tx-dim);
}
@media (max-width: 720px) {
  .gs-foot-in {
    grid-template-columns: 1fr;
  }
}

/* ─────────────────────────────────────────────── таблицы: что можно вести · где что работает */
.gs-ftable-wrap, .gs-stable-wrap { border: 1px solid var(--gs-card-line); border-radius: var(--gs-r); background: var(--gs-card); overflow: hidden; }
.gs-ftable, .gs-stable { width: 100%; border-collapse: collapse; font-size: 15px; }
.gs-ftable th, .gs-ftable td, .gs-stable th, .gs-stable td { text-align: left; vertical-align: top; padding: 12px 16px; border-top: 1px solid var(--gs-card-line); }
.gs-ftable thead th, .gs-stable thead th { border-top: 0; font-family: var(--ff-m); font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--tx-dim); background: color-mix(in srgb, var(--tx) 4%, transparent); }
.gs-ftable tbody th[scope="row"] { font-family: var(--ff-h); font-weight: 700; width: 24%; }
.gs-ftable td { color: var(--tx-mut); }
.gs-ft-gh th { font-family: var(--ff-h); font-size: 13px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; padding-block: 10px; border-left: 4px solid currentColor; background: color-mix(in srgb, currentColor 9%, transparent); }
.gs-ft-coral .gs-ft-gh th { color: var(--coral-tx); }
.gs-ft-olive .gs-ft-gh th { color: var(--olive-tx); }
.gs-ft-teal .gs-ft-gh th { color: var(--teal-tx); }
.gs-ft-g:not(.gs-ft-coral):not(.gs-ft-olive):not(.gs-ft-teal) .gs-ft-gh th { color: var(--tx); }
.gs-stable th[scope="row"] { font-weight: 600; }
.gs-stable thead td { background: color-mix(in srgb, var(--tx) 4%, transparent); }
.gs-stable td { text-align: center; width: 17%; }
.gs-stable thead th { text-align: center; }
.gs-sf-yes { color: var(--olive-tx); font-weight: 800; font-size: 18px; }
/* Прочерк «нет» — это ответ в таблице, а не украшение: бледный цвет давал 1,5–2,7 : 1. */
.gs-sf-no { color: var(--tx-mut); }
.gs-sf-note { font-size: 13px; color: var(--tx-mut); }
.gs-sf-short { display: none; }
.gs-stable thead th:last-child { color: var(--coral-tx); }
.gs-sf-foot { margin-top: 16px; }
/* Телефон: строка таблицы — карточка, подпись колонки встаёт перед значением. */
@media (max-width: 720px) {
  .gs-ftable thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .gs-ftable, .gs-ftable tbody, .gs-ftable tr, .gs-ftable th, .gs-ftable td { display: block; width: auto; }
  .gs-ftable tbody th[scope="row"] { width: auto; padding-bottom: 4px; }
  .gs-ftable td { border-top: 0; padding-block: 2px 8px; font-size: 14px; }
  .gs-ftable td::before { content: attr(data-label); display: block; font-family: var(--ff-m); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--tx-dim); }
  .gs-sf-long { display: none; }
  .gs-sf-short { display: inline; }
  .gs-stable { font-size: 13px; }
  .gs-stable th, .gs-stable td { padding: 10px 6px; }
  .gs-stable thead th { font-size: 10px; letter-spacing: 0.02em; }
  .gs-sf-note { font-size: 11px; }
}

/* Строка «скажи — запишет» под карточками помощников (ADR 0121). */
.gs-helper-log { margin-top: 18px; padding: 14px 18px; border-radius: var(--gs-r); border: 1px dashed color-mix(in srgb, var(--coral) 55%, transparent); background: color-mix(in srgb, var(--coral) 8%, transparent); max-width: 72ch; }

/* ─────────────────────────────────────────────── S9b · сравнение: факты, таблица с наборами, честная полоса */
.gs-cmp-facts { list-style: none; padding: 0; margin: 0 0 28px; display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.gs-cmp-facts li { padding: 20px 20px 16px; border: 1px solid var(--gs-card-line); border-radius: var(--gs-r); background: var(--gs-card); }
.gs-cmp-facts b { display: block; font-family: var(--ff-h); font-size: clamp(22px, 2.4vw, 30px); line-height: 1.05; letter-spacing: -0.02em; color: var(--coral-tx); margin-bottom: 8px; }
.gs-cmp-facts li:nth-child(2) b { color: var(--olive-tx); }
.gs-cmp-facts li:nth-child(3) b { color: var(--teal-tx); }
.gs-cmp-facts p { margin: 0 0 8px; color: var(--tx-mut); font-size: 15px; }
.gs-cmp-sets { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.gs-cmp-sets .gs-tab { display: grid; text-align: left; gap: 2px; }
.gs-cmp-sets .gs-tab span { font-size: 11.5px; font-weight: 500; opacity: 0.75; }
.gs-cmp-scroll { overflow-x: auto; border: 1px solid var(--gs-card-line); border-radius: var(--gs-r); background: var(--gs-card); overscroll-behavior-x: contain; }
.gs-cmp-t { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
.gs-cmp-t th, .gs-cmp-t td { text-align: left; vertical-align: top; padding: 12px 14px; border-top: 1px solid var(--gs-card-line); }
.gs-cmp-t thead th { border-top: 0; font-family: var(--ff-m); font-size: 12px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--tx-dim); background: color-mix(in srgb, var(--tx) 4%, transparent); }
.gs-cmp-t[data-active="pop"] [data-set]:not([data-set="pop"]),
.gs-cmp-t[data-active="ai"] [data-set]:not([data-set="ai"]),
.gs-cmp-t[data-active="chat"] [data-set]:not([data-set="chat"]) { display: none; }
.gs-cmp-t .gs-cmp-f { width: 20%; min-width: 150px; font-weight: 600; font-family: var(--ff-h); }
.gs-cmp-t td { width: 16%; min-width: 140px; }
.gs-cmp-t .gs-cmp-me { background: color-mix(in srgb, var(--coral) 9%, transparent); box-shadow: inset 3px 0 0 var(--coral); }
.gs-cmp-t thead .gs-cmp-me { color: var(--coral-tx); }
.gs-cmp-t small { display: block; margin-top: 4px; font-size: 12.5px; line-height: 1.35; color: var(--tx-mut); }
.gs-cmp-gh th { font-family: var(--ff-h); font-size: 12.5px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; padding-block: 9px; border-left: 4px solid currentColor; background: color-mix(in srgb, currentColor 8%, transparent); color: var(--tx); }
.gs-cmp-g.gs-ft-coral .gs-cmp-gh th { color: var(--coral-tx); }
.gs-cmp-g.gs-ft-olive .gs-cmp-gh th { color: var(--olive-tx); }
.gs-cmp-g.gs-ft-teal .gs-cmp-gh th { color: var(--teal-tx); }
.gs-v { display: inline-block; font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 99px; line-height: 1.5; }
/* «Да» у GramSense — залитый оливковый, цвет «да», а не коралловый: коралл близок к «нет» у соседей,
   и столбец читался тревожно (владелец 27.09). Коралл остаётся подсветкой самого столбца. */
.gs-v-me { background: var(--olive); color: var(--on-bright, #1b1410); }
.gs-v-yes { background: color-mix(in srgb, var(--olive) 22%, transparent); color: var(--olive-tx); }
.gs-v-paid { background: color-mix(in srgb, #e5a50a 22%, transparent); color: color-mix(in srgb, #8a5a00 85%, var(--tx)); }
.gs-v-part { background: color-mix(in srgb, #e5a50a 14%, transparent); color: var(--tx-mut); }
.gs-v-no { background: color-mix(in srgb, var(--coral) 16%, transparent); color: var(--coral-tx); }
.gs-v-nf { color: var(--tx-dim); padding-inline: 0; }
.gs-cmp-src { display: inline-flex; gap: 4px; margin-left: 6px; font-family: var(--ff-m); font-size: 10.5px; vertical-align: 1px; }
.gs-cmp-src a { color: var(--tx-dim); text-decoration: none; border-bottom: 1px dotted currentColor; }
.gs-cmp-src a:hover { color: var(--coral-tx); }
.gs-cmp-more { margin-top: 20px; font-weight: 600; }
/* Тёмная тема: «за подписку» на тёмном — светлее. */
:root[data-theme="dark"] .gs-v-paid { color: #e5b95a; }
@media (prefers-color-scheme: dark) { html:not([data-theme]) .gs-v-paid { color: #e5b95a; } }
/* Телефон: колонки «что важно» и GramSense закреплены, конкуренты листаются вбок. */
@media (max-width: 760px) {
  .gs-cmp-t { font-size: 13px; }
  .gs-cmp-t th, .gs-cmp-t td { padding: 10px; }
  .gs-cmp-t .gs-cmp-f { position: sticky; left: 0; z-index: 2; min-width: 112px; max-width: 120px; background: var(--gs-card); font-size: 13px; }
  .gs-cmp-t .gs-cmp-me { position: sticky; left: 112px; z-index: 1; min-width: 130px; background: color-mix(in srgb, var(--coral) 12%, var(--gs-card)); }
  .gs-cmp-t td { min-width: 150px; }
  .gs-cmp-gh th { position: sticky; left: 0; }
}

/* ── Знакомство: стартовое состояние панели ───────────────────────────────────────────────────
   Кнопка «Давай» стояла одна посреди пустой панели (владелец 21.09). Теперь на старте видно, кто
   спрашивает, что обещает и каким будет первый вопрос: варианты ответа нарисованы неактивными,
   поэтому панель заполнена, а нажатие обещает ровно то, что показано. */
.gs-onb-open { display: grid; gap: 12px; }
.gs-onb-open-h { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; align-items: center; }
.gs-onb-open-h img,
.gs-onb-open-h video {
  grid-row: 1 / 3;
  width: 54px;
  height: 54px;
  object-fit: cover;
  object-position: 50% 56%;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, currentColor 45%, transparent);
}
.gs-onb-open-h b { font-family: var(--ff-h); font-size: 17px; color: currentColor; align-self: end; }
.gs-onb-open-h span { color: var(--tx-mut); font-size: 14px; align-self: start; }
.gs-onb-open-k {
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--gs-card-line);
  font-family: var(--ff-m);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tx-dim);
}
/* Вариант ответа до нажатия: та же пилюля, что в живом шаге, но приглушённая и без курсора. */
.gs-onb-ghost {
  padding: 8px 14px;
  border-radius: var(--r-pill);
  border: 1px dashed var(--gs-card-line);
  background: color-mix(in srgb, currentColor 5%, transparent);
  color: var(--tx-dim);
  font-size: 14px;
}
.gs-onb-open-go { margin-top: 4px; }

/* НАВИГАЦИЯ ШАГА — ПОЛОСА ПОД ЧЕРТОЙ (владелец 23.09: «кнопка Далее не отличима от кнопки
   выбора… может сделать в блоке Назад, Далее»). «Дальше» стояла под ответами той же салатовой
   пилюлей, что и выбранный ответ. Теперь навигация отделена чертой и стоит своей строкой: «Назад»
   слева — тихая, обведённая; «Дальше →» справа — заливка цветом текста, которой нет ни у одного
   ответа, поэтому в любой теме и у любой части она читается действием, а не вариантом.
   «Назад» переехала сюда из строки «кто спрашивает · шаг N из M» (там она жила с 21.09): две
   кнопки навигации в разных углах карточки искались бы по отдельности. Строка сохраняет прежнюю
   высоту, иначе портрет на телефоне встал бы выше, чем на стартовом экране. */
.gs-onb-head { display: flex; align-items: center; gap: 10px; min-height: 28px; }
.gs-onb-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 6px;
  padding-top: 16px;
  border-top: 1px solid color-mix(in srgb, currentColor 16%, var(--gs-card-line));
}
.gs-onb-back {
  flex: none;
  padding: 10px 16px;
  border-radius: var(--r-pill);
  border: 1px solid var(--gs-card-line);
  background: none;
  color: var(--tx-mut);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: color var(--d-fast), border-color var(--d-fast);
}
.gs-onb-back:hover { color: var(--tx); border-color: var(--tx-dim); }
.gs-onb-back::before { content: "←"; margin-right: 6px; }
.gs-onb-next {
  margin-left: auto;
  background: var(--tx);
  /* Текст — цветом САМОЙ карточки, а не страницы: несколько макетов (v01, v07, v09) переопределяют
     --tx внутри «бумажных» секций, и --bg там совпал бы с заливкой по тону. */
  color: var(--gs-card, var(--bg));
  border-color: var(--tx);
}
.gs-onb-next::after { content: "→"; margin-left: 8px; transition: transform var(--d-fast) var(--e-out); }
.gs-onb-next:hover { transform: translateY(-1px); }
.gs-onb-next:hover::after { transform: translateX(3px); }
.gs-onb-next[hidden] { display: none; }

/* Вторая дверь первого экрана — знакомство (владелец 22.09). Рядом с главной кнопкой и ниже её по
   весу: обведённая, без заливки. На узком экране встаёт своей строкой. */
/* Всегда своей строкой под главной кнопкой, а не «рядом, если влезет»: две широкие подписи то
   вставали в ряд, то переносились, и первый экран прыгал по ширине окна. */
.gs-hf-onb { margin: 10px 0 0; }

/* РАВНЫЙ ВЕС (макеты с opts.onbStrong, владелец 27.09). Две залитые кнопки одной ширины и высоты,
   одна под другой: рядом две длинные подписи в колонку первого экрана не влезали. Знакомство —
   коралловое, цветом Grammon, который его открывает; на кнопке лица трёх помощников. */
.gs-hf-pair { display: grid; gap: 10px; width: min(100%, 460px); }
.gs-hf-pair .gs-btn { width: 100%; min-height: 62px; justify-content: center; margin: 0; white-space: nowrap; }
.gs-btn-onb { background: var(--coral); color: var(--on-bright); }
.gs-btn-onb:hover { background: color-mix(in srgb, var(--coral) 88%, #000); transform: translateY(-1px); }
.gs-onb-faces { display: inline-flex; flex: none; }
.gs-onb-faces img { width: 30px; height: 30px; border-radius: 50%; background: var(--gs-card, var(--bg)); box-shadow: 0 0 0 2px var(--coral); object-fit: cover; }
.gs-onb-faces img + img { margin-left: -9px; }
.gs-hf-onb-note { margin: 2px 0 0; font-size: 14px; color: var(--tx-mut); max-width: 46ch; }
/* Рядом с парой кнопок пунктирная зона перетаскивания лишняя (владелец 27.09): бросить снимок можно
   на весь блок (handoff.js слушает drop на нём целиком), а зона появляется, только пока файл тащат. */
.gs-handoff:has(.gs-hf-pair) .gs-hf-drop:not(.is-over) { display: none; }
/* Плашка знакомства внизу экрана телефона. Только на узком экране: на широком обе кнопки и так в
   первом экране, а раздел знакомства — сразу под ним. */
.gs-onb-dock {
  position: fixed; left: 16px; right: 16px; bottom: calc(14px + env(safe-area-inset-bottom)); z-index: 40;
  display: flex; align-items: center; justify-content: center; gap: 10px; padding: 13px 18px;
  border-radius: 999px; background: var(--coral); color: var(--on-bright); text-decoration: none;
  font-family: var(--ff-h); font-weight: 800; font-size: 16px; white-space: nowrap;
  box-shadow: 0 12px 30px rgb(0 0 0 / 0.28);
  transition: transform var(--d-fast) var(--e-out), opacity var(--d-fast);
}
.gs-onb-dock[hidden] { display: flex; opacity: 0; transform: translateY(140%); pointer-events: none; }
.gs-onb-dock .gs-onb-faces img { width: 26px; height: 26px; }
@media (min-width: 721px) { .gs-onb-dock { display: none !important; } }
@media (prefers-reduced-motion: reduce) { .gs-onb-dock { transition: none; } }


/* ════════════════════════════════════════════════════ ЗНАКОМСТВО КРУПНО (все макеты, 22.09) ══
   Сначала это была проба на одном макете: шаг перестаёт быть строчкой в панели и становится
   сценой — слева портрет того, кто спрашивает, справа его вопрос во всю ширину, вокруг тон его
   цвета, а карточки частей стоят вровень со сценой и несут плоские стикеры, как полоса мира.
   Владелец 22.09 принял вид и попросил его на все пятнадцать, поэтому блок переехал из
   v01/style.css сюда целиком. Макет по-прежнему может его переопределить — но теперь исключением,
   а не правилом.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */
/* ── Знакомство крупно (проба, владелец 21.09) ───────────────────────────────────────────────
   Шаг перестаёт быть строчкой в панели и становится сценой: слева портрет того, кто спрашивает,
   справа его вопрос во всю ширину, вокруг — тон его цвета. Разметка общая для всех макетов,
   включается только здесь — остальные четырнадцать показывают знакомство по-прежнему.

   Портрет вынут из потока сетки и позиционирован. В сетке он тянул за собой высоту строк: вопрос
   вставал у его верхнего края, а варианты уезжали к нижнему, через двести пустых пикселей. Теперь
   он занимает левое поле, а содержимое просто течёт одной колонкой справа. */
.gs-onb-stage {
  position: relative;
  overflow: hidden;
  --face: clamp(130px, 14vw, 190px);
  padding: 26px 30px 30px;
  background:
    radial-gradient(120% 90% at 0% 0%, color-mix(in srgb, currentColor 13%, transparent), transparent 62%),
    var(--gs-card);
  border-color: color-mix(in srgb, currentColor 26%, var(--gs-card-line));
}
/* Поле под портрет держат ОБА состояния — и шаг, и стартовый экран. Портрет появлялся только после
   нажатия «Давай», и раздел выглядел до и после по-разному: владелец 22.09 видел на странице одно, а
   на показанном снимке другое. Стартовый экран — это тот же шаг, просто ещё не начатый. */
.gs-onb-stage:has(.gs-onb-face),
.gs-onb-stage:has(.gs-onb-open) { min-height: 400px; padding: 0 30px 30px calc(30px + var(--face) + 28px); }
.gs-onb-stage:has(.gs-onb-open) { padding-top: 26px; }
.gs-onb-stage:has(.gs-onb-face) .gs-onb-progress { margin: 0 -30px 14px calc(-30px - var(--face) - 28px); border-radius: 0; }
/* Круглый аватар стартового экрана становится тем же портретом, что у шага, и на том же месте.
   РОВНО НА ТОМ ЖЕ: 48 = 74 у шага минус 26 собственного отступа стартового экрана (абсолютные
   отступы считаются от внутреннего края карточки, а он у двух состояний разный). Пока чисел было
   два, портрет на первом же ответе прыгал вниз на 22 точки — ровно на высоту появляющейся строки
   «Назад · кто спрашивает · шаг N» (владелец 23.09). */
.gs-onb-open-h img,
.gs-onb-open-h video {
  position: absolute;
  left: 30px;
  top: 48px;
  bottom: 30px;
  width: var(--face);
  height: auto;
  object-fit: cover;
  object-position: 50% 42%;
  border-radius: 16px;
  border: 0;
  box-shadow: var(--sh-2);
}
.gs-onb-open-h video { aspect-ratio: 2 / 3; }
@media (prefers-reduced-motion: reduce) {
  .gs-onb-open-h video { display: none; }
}
.gs-onb-open-h { grid-template-columns: 1fr; gap: 2px; }
.gs-onb-open-h b { font-size: 20px; }
.gs-onb-open .gs-onb-q { font-size: clamp(23px, 2.4vw, 32px); line-height: 1.14; letter-spacing: -0.02em; color: var(--tx); }
.gs-onb-stage .gs-onb-face {
  display: block;
  position: absolute;
  left: 30px;
  top: 74px;
  bottom: 30px;
  width: var(--face);
  object-fit: cover;
  object-position: 50% 42%;
  border-radius: 16px;
  box-shadow: var(--sh-2);
}
.gs-onb-stage .gs-onb-q {
  font-size: clamp(23px, 2.4vw, 32px);
  line-height: 1.14;
  letter-spacing: -0.02em;
  color: var(--tx);
}
.gs-onb-opts { gap: 10px; }
.gs-onb-opts .gs-chip { padding: 12px 22px; font-size: 16.5px; }
.gs-onb-opts-many { gap: 7px; }
.gs-onb-opts-many .gs-chip { padding: 8px 14px; font-size: 14.5px; }
@media (max-width: 720px) {
  .gs-onb-opts-many { gap: 6px; }
  .gs-onb-opts-many .gs-chip { padding: 7px 11px; font-size: 13.5px; }
}
/* ВЫБРАННЫЙ ОТВЕТ. Заливка берётся из тона части явным токеном, а НЕ из `currentColor`: в одном
   правиле с `color` тот резолвится уже в новое значение, поэтому фон и текст становились одной
   краской — вернувшись назад, человек видел вместо своего ответа чёрную пилюлю без букв
   (владелец 23.09). Тон задаётся ниже, на самой сцене. */
.gs-onb-opts .gs-chip[aria-pressed="true"] {
  background: var(--onb-fill);
  border-color: var(--onb-fill);
  color: var(--on-bright);
}
.gs-onb-stage,
.gs-onb-open { --onb-fill: var(--olive); }
.gs-onb-stage.t-coral, .gs-onb-open.t-coral { --onb-fill: var(--coral); }
.gs-onb-stage.t-olive, .gs-onb-open.t-olive { --onb-fill: var(--olive); }
.gs-onb-stage.t-teal, .gs-onb-open.t-teal { --onb-fill: var(--teal); }
.gs-onb-result .big { font-size: clamp(34px, 4vw, 52px); }
/* ── Смена карточек знакомства ─────────────────────────────────────────────────────────────────
   Уход — 0,15 с: текст гаснет и чуть уходит в сторону, портрет только растворяется. Появление —
   0,32 с с мягким торможением: вопрос первым, ответы следом. «Назад» (is-back) — зеркально.
   Полоса прогресса не участвует: она одна на всю часть. Логика — onboarding.js, transition(). */
.gs-onb-stage > :not(.gs-onb-progress):not(.gs-onb-pic),
.gs-onb-pic > * { transition: opacity 0.15s ease-in, transform 0.15s ease-in; }
.gs-onb-stage.is-leaving > :not(.gs-onb-progress):not(.gs-onb-pic) { opacity: 0; transform: translateX(-16px); }
.gs-onb-stage.is-leaving.is-back > :not(.gs-onb-progress):not(.gs-onb-pic) { transform: translateX(16px); }
.gs-onb-stage.is-leaving .gs-onb-pic > * { opacity: 0; }
.gs-onb-stage.is-entering > :not(.gs-onb-progress):not(.gs-onb-pic) { animation: gs-onb-in 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.gs-onb-stage.is-entering.is-back > :not(.gs-onb-progress):not(.gs-onb-pic) { animation-name: gs-onb-in-back; }
.gs-onb-stage.is-entering .gs-onb-pic > *:not(.gs-onb-fx) { animation: gs-onb-fade 0.32s ease-out both; }
.gs-onb-stage.is-entering > .gs-onb-q { animation-delay: 0.04s; }
.gs-onb-stage.is-entering > .gs-onb-q ~ * { animation-delay: 0.09s; }
@keyframes gs-onb-in { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }
@keyframes gs-onb-in-back { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: none; } }
@keyframes gs-onb-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .gs-onb-stage > *, .gs-onb-pic > * { transition: none; animation: none; }
}
/* Рамка портрета: ролик, заглушка и звёздочки. На широком экране её «нет» (display: contents) —
   портрет по-прежнему стоит в левой колонке, отсчитываясь от самой карточки. На узком она
   становится блоком над вопросом, и всё внутри выстраивается по ней. */
.gs-onb-pic { display: contents; }
@media (max-width: 720px) {
  .gs-onb-stage { padding: 20px 18px 22px; }
  /* ПОРТРЕТ НАД ВОПРОСОМ, НЕ МЕНЬШЕ ПОЛОВИНЫ ЭКРАНА (владелец 23.09: «на мобильных анимации очень
     маленькие»). Прежде портрет шириной 84 точки стоял колонкой слева от вопроса — сценки с
     улиткой, книгой и мишенью на нём было не разглядеть. Теперь две трети ширины экрана, не больше
     300 точек, и полные пропорции 2:3: сценки живут и над головой (колпак), и у края стола
     (улитка, рыбка), поэтому кадр не обрезается. */
  .gs-onb-stage:has(.gs-onb-face),
  .gs-onb-stage:has(.gs-onb-open) { min-height: 0; padding: 0 18px 22px; }
  .gs-onb-stage:has(.gs-onb-open) { padding-top: 20px; }
  .gs-onb-stage:has(.gs-onb-face) .gs-onb-progress { margin: 0 -18px 12px; }
  .gs-onb-pic {
    display: block;
    position: relative;
    width: min(66vw, 300px);
    aspect-ratio: 2 / 3;
    /* 32 сверху — чтобы портрет шага стоял на той же высоте, что на стартовом экране, где над ним
       имя и подпись (замер 23.09: без отступа 81 против 109 на старте). */
    margin: 32px auto 16px;
  }
  .gs-onb-stage .gs-onb-pic .gs-onb-face { inset: 0; width: 100%; height: 100%; }
  .gs-onb-pic .gs-onb-fx { inset: 0; width: auto; }
  /* Стартовый экран: тот же размер и место, над именем и вопросом. */
  .gs-onb-open-h img,
  .gs-onb-open-h video {
    position: relative;
    inset: auto;
    grid-row: auto;
    display: block;
    width: min(66vw, 300px);
    height: auto;
    aspect-ratio: 2 / 3;
    margin: 0 auto 12px;
  }
  /* Имя и подпись стартового экрана — НАД портретом, на месте строки «Назад · кто · шаг N» у шагов.
     Иначе портрет стоял бы на старте у самого верха карточки, а на шагах ниже на эту строку, и на
     первом ответе прыгал бы вниз — ровно то, что владелец уже ловил на широком экране. */
  .gs-onb-open-h b,
  .gs-onb-open-h span { order: -1; }
  .gs-onb-open-h span { margin-bottom: 10px; }
  .gs-onb-stage .gs-onb-q { font-size: 21px; }
}

/* ПАНЕЛЬ «НАЗАД / ДАЛЬШЕ» ВСЕГДА НА ОДНОЙ ВЫСОТЕ (владелец 24.09: «скачут в зависимости от
   количества информации»). Замер по всем шагам: панель стояла от 224 до 520 точек от верха карточки
   на широком экране и от 650 до 981 на телефоне. Карточка шага теперь — колонка высотой с САМЫЙ
   ВЫСОКИЙ шаг при текущей ширине (`--onb-h` меряет onboarding.js, fitHeight), а панель прижата к её
   низу. Числа ниже — запас на время до замера и без скрипта: 496 на широком экране, а на телефоне —
   от портрета, который тянется за шириной экрана (min(66vw, 300px) при 2:3). Стоит ПОСЛЕ мобильного
   блока выше, иначе его `min-height: 0` перебивал бы эту высоту. */
.gs-onb-stage:has(.gs-onb-nav) { display: flex; flex-direction: column; gap: 16px; min-height: var(--onb-h, 496px); }
.gs-onb-stage:has(.gs-onb-nav) > .gs-onb-nav { margin-top: auto; }
/* Кнопки панели одной высоты и в одну строку: «Давай — Grammlin →» на телефоне переносился, панель
   итога становилась выше, и её верх уезжал на 19 точек от остальных шагов. */
.gs-onb-nav .gs-onb-back,
.gs-onb-nav .gs-onb-next { min-height: 46px; white-space: nowrap; box-sizing: border-box; }
@media (max-width: 720px) {
  /* 566 = самый высокий шаг («чего ты не ешь», вопрос в две строки широким шрифтом v07) по замеру
     всех пятнадцати макетов 24.09. */
  .gs-onb-stage:has(.gs-onb-nav) { min-height: var(--onb-h, calc(min(66vw, 300px) * 1.5 + 566px)); }
}

/* ── Карточки частей: стикер слева и высота вровень со сценой ─────────────────────────────────
   Левая колонка была ниже сцены, и раздел висел на разной высоте (владелец 22.09). Три карточки
   растягиваются на высоту сцены, а освободившееся место занимает плоский стикер персонажа — тот
   же приём, что в полосе мира, когда у персонажа есть сообщение. */
.gs-onb { align-items: stretch; }
.gs-onb-parts { grid-template-rows: repeat(3, 1fr); height: 100%; }
.gs-onb-part {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: 14px;
  align-content: center;
  padding: 14px 18px;
}
.gs-onb-part-fig {
  display: block;
  grid-row: 1 / 3;
  align-self: center;
  width: clamp(44px, 5.2vw, 68px);
  height: auto;
  /* Стикер стоит на подложке своего цвета — как фигурка в полосе мира, а не как картинка в тексте. */
  border-radius: 50%;
  background: color-mix(in srgb, currentColor 14%, transparent);
}
.gs-onb-part b { align-self: end; }
.gs-onb-part span { align-self: start; }


/* ── Звёздочки на удар о весы ─────────────────────────────────────────────────────────────────
   Цифры отсюда убраны (владелец 22.09): вылетающее число спорило с самим полем ответа, которое
   стоит рядом и крупнее. Звёздочки остались — они ничего не утверждают о человеке, в отличие от
   числа, и потому свободны от правила про настоящие значения.

   Запуск одноразовый, по классу burst: прыжок теперь отклик на изменение веса, а не карусель. */
.gs-onb-fx {
  position: absolute;
  left: 30px;
  top: 26px;
  width: var(--face);
  bottom: 30px;
  pointer-events: none;
}
.gs-fx-star {
  position: absolute;
  left: 50%;
  bottom: 18%;
  opacity: 0;
  background: var(--gold);
  clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
}
.gs-onb-fx.burst .gs-fx-star { animation: gs-fx-star 1.1s ease-out 1; }
/* Момент вылета — `--fx-at` со слоя звёздочек: у каждого ролика свой удар. Весы — 0,86 с (касание
   чаши), рост — приземление в колпаке. Раньше задержки были числами на каждой звёздочке, и второй
   ролик вылетал бы на чужом такте. */
.gs-fx-star.s0 { --dx: -54px; --dy: -46px; width: 12px; height: 12px; animation-delay: var(--fx-at, 0.86s); }
.gs-fx-star.s1 { --dx: 48px; --dy: -58px; width: 9px; height: 9px; animation-delay: calc(var(--fx-at, 0.86s) + 0.04s); }
.gs-fx-star.s2 { --dx: -30px; --dy: -74px; width: 8px; height: 8px; animation-delay: calc(var(--fx-at, 0.86s) + 0.08s); }
.gs-fx-star.s3 { --dx: 66px; --dy: -30px; width: 10px; height: 10px; animation-delay: calc(var(--fx-at, 0.86s) + 0.02s); }
.gs-fx-star.s4 { --dx: 8px; --dy: -86px; width: 7px; height: 7px; animation-delay: calc(var(--fx-at, 0.86s) + 0.12s); }
@keyframes gs-fx-star {
  0% { opacity: 0; transform: translate(-50%, 0) scale(0.4) rotate(0deg); }
  25% { opacity: 1; transform: translate(calc(-50% + var(--dx) * 0.5), calc(var(--dy) * 0.5)) scale(1) rotate(45deg); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), var(--dy)) scale(0.7) rotate(120deg); }
}
/* Заглушка для тех, кто просил систему не двигать интерфейс. Селектор ОБЯЗАН быть не слабее общего
   правила портрета `.gs-onb-stage .gs-onb-face { display: block }`: прежде он был слабее, заглушка
   лежала поверх ролика у всех, и ролик шёл невидимым под ней — владелец видел только звёздочки
   (23.09). Время ролика при этом честно шло, поэтому замеры по `currentTime` дефекта не видели;
   поймал его только вопрос «какой элемент наверху в центре портрета». */
.gs-onb-stage .gs-onb-face-still { display: none; }
@media (prefers-reduced-motion: reduce) {
  /* `video[data-hello]` — ролик приветствия стартового экрана: класса gs-onb-face у него нет, и без
     этого селектора при уменьшенном движении показывались оба портрета, один под другим (27.09). */
  .gs-onb-stage video.gs-onb-face,
  .gs-onb-stage video[data-hello] { display: none; }
  .gs-onb-stage .gs-onb-face-still { display: block; }
}
