/* ═══════════════════════════════════════════════════════════════════════════
   СИНАСТРИЯ — вёрстка по макету Figma «Оракул» / секция Synastry.
   Спека и референсы: docs/design/synastry/README.md + screens/.

   Палитра и типографика здесь СВОИ, а не из base.html: макет пришёл из другой
   дизайн-системы (Manrope + фиолетово-персиковая гамма), и подмешивать её в
   общие --paper/--ink/--brand нельзя — на них живут нумерология, таро и имя.
   Поэтому все токены объявлены на .syn-scope и дальше только наследуются;
   корень страницы обязан нести этот класс, иначе поедет всё.

   Порядок файла:
     0  токены
     1  каркас и типографика
     2  кнопки
     3  чипы
     4  вкладки-пилюли
     5  аккордеон
     6  поля формы
     7  карточки, плашки, служебное
     8+ секции страниц (лендинг, результат) — ниже по файлу
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 0. Токены ─────────────────────────────────────────────────────────── */

.syn-scope {
  /* Поверхности */
  --syn-bg:            #ffffff;
  --syn-card:          #f6f3fc;   /* base/card-background */
  --syn-card-high:     #eee7f9;   /* base/hight-card-background */
  --syn-border:        #eee7f9;   /* base/border */

  /* Текст */
  --syn-headline:      #17161d;
  --syn-text:          #17161d;
  --syn-text-2:        #5d5874;   /* base/text-secondary */
  --syn-text-low:      #aba8bd;   /* base/text-low */

  /* Акценты */
  --syn-primary:       #7134c4;
  --syn-primary-soft:  #e3d7f4;   /* primary/active_primary_container */
  --syn-secondary:     #fda986;
  --syn-secondary-c:   #fdeee8;   /* secondary/secondary_container */
  --syn-secondary-a:   #fedbcd;   /* secondary/active_secondary_container */
  /* Персиковый как ЦВЕТ ТЕКСТА: #fda986 на светлой заливке даёт ~1.9:1 при
     пороге 4.5:1, поэтому для подписей заведён затемнённый оттенок той же
     гаммы. Заливки остаются прежними. */
  --syn-secondary-ink: #96431f;

  /* Заметки «Общего вывода». Зелёный намеренно другой, не --syn-good:
     мятный #76ff93 — семантика аспектов, и повторять её тут значит сказать
     «это тоже аспект». Здесь приглушённый травяной и пыльно-голубой, оба
     полупрозрачные — под текстом должна оставаться бумага, а не заливка. */
  --syn-note-good:      rgb(122 176 134 / 20%);
  --syn-note-good-edge: rgb(96 152 110 / 55%);
  --syn-note-good-ink:  #2f6b41;
  --syn-note-other:     rgb(118 158 205 / 18%);
  --syn-note-other-edge: rgb(92 133 184 / 55%);
  --syn-note-other-ink: #2c5580;
  /* Бумага и линовка: заметки лежат «на листе», а не на плитке интерфейса. */
  --syn-paper:      #fdfcfa;
  --syn-paper-rule: rgb(93 44 161 / 8%);

  /* Семантика аспектов */
  --syn-good:          #76ff93;
  --syn-good-ink:      #1f9d3c;   /* #76ff93 нечитаем как текст на белом */
  --syn-bad:           #e54336;

  /* Радиусы и шаги */
  --syn-r-xs: 4px;
  --syn-r-s:  8px;
  --syn-r:    16px;
  --syn-r-lg: 24px;
  --syn-r-pill: 1000px;

  /* Ширина контентной колонки — переопределяется страницей (§8, §9) */
  --syn-content: 876px;

  --syn-font: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  /* Заголовочный RR Opague TRIAL нам не передавали (и «TRIAL» в имени — риск
     по лицензии). До появления файла заголовки идут тем же Manrope в самом
     жирном начертании: переменная одна, подмена потом — в одну строку. */
  --syn-font-head: var(--syn-font);
}

/* Тёмная тема заведена ради data-theme="dark" из base.html. Своего /app/synastry
   webview нет, так что ветка почти мёртвая — но пусть страница не белеет
   насквозь, если тему включат глобально. */
html[data-theme="dark"] .syn-scope {
  --syn-bg:        #17161d;
  --syn-card:      #201e29;
  --syn-card-high: #2a2736;
  --syn-border:    #322e42;
  --syn-headline:  #f1f0f4;
  --syn-text:      #f1f0f4;
  --syn-text-2:    #b4afc6;
  --syn-text-low:  #7d7891;
  --syn-primary-soft: #3a2857;
  --syn-secondary-ink: #f3b18f;
  --syn-note-good:      rgb(122 176 134 / 22%);
  --syn-note-good-edge: rgb(140 200 155 / 55%);
  --syn-note-good-ink:  #8fd4a3;
  --syn-note-other:     rgb(118 158 205 / 22%);
  --syn-note-other-edge: rgb(140 180 225 / 55%);
  --syn-note-other-ink: #9dc2ec;
  --syn-paper:      #221f2c;
  --syn-paper-rule: rgb(246 243 252 / 7%);
}

/* ─── 1. Каркас и типографика ───────────────────────────────────────────── */

.syn-scope {
  font-family: var(--syn-font);
  font-weight: 400;
  color: var(--syn-text);
  background: var(--syn-bg);
  font-size: 16px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
}

/* Одна колонка: правые баннеры 308px в скоуп не входят, и сетка 1400 из
   макета схлопывается до контентной колонки. */
.syn-wrap {
  max-width: var(--syn-content);
  margin: 0 auto;
  padding: 0 24px;
}
@media (max-width: 640px) { .syn-wrap { padding: 0 16px; } }

/* section-space/s = 80 */
.syn-section { margin-top: 80px; }
.syn-section:first-child { margin-top: 0; }
@media (max-width: 640px) { .syn-section { margin-top: 48px; } }

.syn-h1,
.syn-h2 {
  font-family: var(--syn-font-head);
  font-weight: 800;
  font-size: clamp(30px, 4.4vw, 48px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--syn-headline);
  margin: 0;
  text-wrap: balance;
}
.syn-h3 {
  font-family: var(--syn-font-head);
  font-weight: 800;
  font-size: clamp(26px, 3.2vw, 36px);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--syn-headline);
  margin: 0;
}
.syn-h4 {
  font-family: var(--syn-font-head);
  font-weight: 800;
  font-size: clamp(20px, 2.2vw, 24px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--syn-headline);
  margin: 0;
}
.syn-h5 {
  font-family: var(--syn-font-head);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--syn-headline);
  margin: 0;
}

.syn-p {
  font-size: 16px;
  line-height: 1.4;
  color: var(--syn-text);
  margin: 0;
  text-wrap: pretty;
}
.syn-p + .syn-p { margin-top: 16px; }
.syn-p b, .syn-p strong { font-weight: 700; }
.syn-lead {
  font-size: 20px;
  line-height: 1.4;
  color: var(--syn-text);
  margin: 0;
  text-wrap: pretty;
}
@media (max-width: 640px) { .syn-lead { font-size: 17px; } }
.syn-small { font-size: 12px; line-height: 1.4; color: var(--syn-text-2); margin: 0; }
.syn-muted { color: var(--syn-text-2); }
.syn-accent { color: var(--syn-primary); }

/* Глифы планет и аспектов (☉ ♀ ☌ □ △). Manrope этих кодовых точек не
   содержит — без явного фолбэка браузер подставит что попало или нарисует
   «тофу». Порядок: системные символьные шрифты macOS / Windows / Linux. */
.syn-glyph {
  font-family: 'Apple Symbols', 'Segoe UI Symbol', 'Noto Sans Symbols 2',
               'DejaVu Sans', sans-serif;
  font-weight: 400;
}

/* ─── 2. Кнопки ─────────────────────────────────────────────────────────── */

.syn-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--syn-font);
  font-weight: 600;
  font-size: 16px;
  line-height: 1;
  padding: 16px 28px;
  border: none;
  border-radius: var(--syn-r-pill);
  cursor: pointer;
  text-decoration: none;
  transition: filter 0.15s ease, opacity 0.15s ease;
}
.syn-btn:hover { filter: brightness(1.07); }
.syn-btn:disabled,
.syn-btn[aria-disabled="true"] { opacity: 0.5; cursor: default; filter: none; }
/* Заодно (не задание m9, но рядом): своего фокус-стиля не было вовсе. */
.syn-btn:focus-visible {
  outline: 2px solid var(--syn-primary);
  outline-offset: 2px;
}
.syn-btn--primary { background: var(--syn-primary); color: #ffffff; }
.syn-btn--secondary { background: var(--syn-secondary); color: var(--syn-primary); }
/* Единственное место, где эта кнопка стоит — .synl-promo, фиолетовый
   градиент-баннер; фиолетовое кольцо там потерялось бы в фоне. */
.syn-btn--secondary:focus-visible { outline-color: #ffffff; }
.syn-btn--block { width: 100%; }
.syn-btn--lg { padding: 19px 32px; font-size: 17px; }

/* Стрелка «→» в кнопках макета — символ, а не иконка. */
.syn-btn__arrow { font-size: 1.05em; line-height: 1; }

/* ─── 3. Чипы ───────────────────────────────────────────────────────────── */

.syn-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: var(--syn-r-pill);
  font-size: 14px;
  line-height: 1.2;
  font-weight: 500;
  background: var(--syn-card);
  color: var(--syn-text);
  white-space: nowrap;
}
.syn-chip--peach { background: var(--syn-secondary-c); color: var(--syn-text); }
.syn-chip--outline { background: transparent; border: 1px solid var(--syn-border); }
.syn-chip--danger {
  background: #d62c1f; color: #ffffff; font-size: 13px; padding: 6px 14px;
}
.syn-chip__icon { display: inline-flex; width: 16px; height: 16px; }
.syn-chip__icon svg { width: 100%; height: 100%; display: block; }

/* ─── 4. Вкладки-пилюли ─────────────────────────────────────────────────── */

/* tab/background #f6f3fc, активная — персиковая пилюля с фиолетовым текстом.
   Высота 46, радиус 1000 (и у дорожки, и у пилюли). */
.syn-tabs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 4px;
  padding: 4px;
  background: var(--syn-card);
  border-radius: var(--syn-r-pill);
}
.syn-tab {
  appearance: none;
  border: none;
  background: transparent;
  font-family: var(--syn-font);
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  color: var(--syn-text-2);
  padding: 13px 12px;
  border-radius: var(--syn-r-pill);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background 0.15s ease, color 0.15s ease;
}
.syn-tab:hover { color: var(--syn-text); }
/* Своего фокус-стиля не было — без него Chrome рисует дефолтное синее кольцо,
   чужой цвет в этой палитре. `.syn-tab` общий класс для вкладок сфер и кнопок
   направления аспектов (`aria-pressed`) — правило действует на оба места.
   --syn-primary даёт ≥3:1 (порог WCAG для контуров, не текста) на всех трёх
   фонах, где встречается кольцо: белый, `.synf-card` (#f6f3fc) и активная
   персиковая пилюля (#fda986, самый слабый случай — 3.74:1). */
.syn-tab:focus-visible {
  outline: 2px solid var(--syn-primary);
  outline-offset: 2px;
}
.syn-tab--active,
.syn-tab[aria-selected="true"] {
  background: var(--syn-secondary);
  color: var(--syn-primary);
  font-weight: 600;
}
/* На мобилке пилюли переносятся в сетку 2×2 (мобильный лендинг 12208:117675). */
@media (max-width: 640px) {
  .syn-tabs {
    grid-auto-flow: row;
    grid-template-columns: 1fr 1fr;
    grid-auto-columns: auto;
    background: transparent;
    padding: 0;
    gap: 8px;
  }
  .syn-tab {
    background: var(--syn-card);
    padding: 14px 10px;
    font-size: 14px;
  }
  /* Дорожка на мобилке исчезает, и фон переезжает на сами пилюли — правило
     выше идёт позже .syn-tab--active при равной специфичности и перебило бы
     персиковую заливку активной вкладки. Возвращаем её здесь. */
  .syn-tab--active,
  .syn-tab[aria-selected="true"] { background: var(--syn-secondary); }
}

/* ─── Переключатель сфер на результате (.synt-) ─────────────────────────── */

/* Кнопки должны читаться кнопками (решение владельца 2026-08-11): белая
   карточка с бордером и тенью вместо пилюль на дорожке. Переопределяем
   поверх .syn-tabs/.syn-tab — базовые классы менять нельзя, ими же свёрстаны
   таб-меню направлений аспектов. */
.synt-section { margin-top: 48px; }
.synt-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 0;
  background: transparent;
}
.synt-tabs .syn-tab {
  flex: 1 1 auto;
  /* Токен, не #fff: --syn-text рядом инвертируется в тёмной теме, и с
     захардкоженным белым фоном текст на неактивной кнопке уходил
     белым-по-белому. */
  background: var(--syn-bg);
  border: 1px solid rgb(93 44 161 / 18%);
  box-shadow: 0 2px 10px rgb(46 26 71 / 7%);
  padding: 15px 18px;
  font-weight: 600;
  color: var(--syn-text);
  /* База .syn-tab — пилюля (радиус 1000px) с nowrap+ellipsis: без этих
     переопределений «карточка» остаётся пилюлей, а длинная подпись
     («Как понравиться партнеру») режется в «…» на средних ширинах. */
  border-radius: var(--syn-r);
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  transition: background 0.15s ease, color 0.15s ease,
              box-shadow 0.15s ease, transform 0.15s ease;
}
.synt-tabs .syn-tab:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgb(46 26 71 / 12%);
}
.synt-tabs .syn-tab--active,
.synt-tabs .syn-tab[aria-selected="true"] {
  background: var(--syn-primary);
  border-color: var(--syn-primary);
  color: #fff;
}
@media (max-width: 640px) {
  .synt-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .synt-tabs .syn-tab { padding: 14px 10px; }
  /* Подпись пятой кнопки (вкладка «Как понравиться») вдвое длиннее сфер —
     в сетке 2×2 она занимает всю строку целиком, иначе рвётся на три
     строки в половинной колонке. */
  .synt-tabs .synt-tab--wide { grid-column: 1 / -1; }
}

/* ── Подарочная кнопка среди кнопок сфер ── */

/* Сферы — белые карточки с лиловым бордером; подарок обязан читаться иначе,
   иначе он теряется пятым в ряду одинаковых. Персиковая гамма (--syn-secondary)
   в макете отвечает за акценты, здесь она и работает: тёплая заливка, тёплый
   бордер, тёплый текст. Градиент, а не плоская заливка, — чтобы кнопка не
   спорила по весу с активной фиолетовой. */
.synt-tabs .synt-tab--gift {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  background: linear-gradient(135deg, var(--syn-secondary-a), var(--syn-secondary-c) 70%);
  border-color: var(--syn-secondary);
  color: var(--syn-secondary-ink);
}
.synt-tabs .synt-tab--gift:hover {
  box-shadow: 0 4px 16px rgb(253 169 134 / 38%);
}

/* Активное состояние тоже персиковое, а не фиолетовое: раздел остаётся
   подарком и когда открыт, и путать его со сферой не нужно. */
.synt-tabs .synt-tab--gift.syn-tab--active,
.synt-tabs .synt-tab--gift[aria-selected="true"] {
  background: var(--syn-secondary);
  border-color: var(--syn-secondary);
  color: #40230f;
}

.synt-gift-mark { font-size: 17px; line-height: 1; }
.synt-gift-name { font-weight: 700; }

/* «в подарок» — подпись, а не второй заголовок: мельче, капсом, разрежена.
   Отличается кеглем и трекингом, но не прозрачностью: opacity: 0.75 гасила
   тот самый --syn-secondary-ink, который и заведён ради контраста, и на
   тёплом градиенте кнопки давала 3.3:1 при кегле 11px (порог AA — 4.5:1).
   Без неё #96431f на #fedbcd — 5.2:1, на #fdeee8 — 6.0:1. */
.synt-gift-note {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Подсказка под дорожкой, пока подарок закрыт. Она лежит соседом <nav>, а не
   внутри него (у tablist по ARIA могут быть только tab-потомки), поэтому
   ширину и перенос строки задавать нечем — обычный блок секции. */
.synt-gift-hint {
  margin: 12px 0 0;
  padding: 10px 14px;
  border: 1px dashed var(--syn-secondary);
  border-radius: var(--syn-r-s);
  background: var(--syn-secondary-c);
  color: var(--syn-secondary-ink);
}

@media (max-width: 640px) {
  .synt-tabs .synt-tab--gift { grid-column: 1 / -1; }
}

/* ─── Вкладка «Как понравиться партнеру» (.synk-) ───────────────────────── */

/* Не сфера: контент берётся из справочника по карте цели, поэтому ни шкал,
   ни процентов здесь нет — заголовок, тумблер направления и карточка текста.
   Отступы сверены с соседними .syn-card-секциями панели сферы: 16px под
   шапкой (класс .syna-dirs на тумблере даёт margin-top: 16px даром) и 24px
   внутри карточки — .synk-card ниже явно повторяет фундаментный .syn-card,
   а не переопределяет его. */
/* Тумблер направления — тот же компонент, что у аспектов (.syn-tabs/.syna-dirs),
   но подпись длиннее на «Как понравиться: », а база .syn-tab режет её в «…»
   (nowrap + ellipsis). Здесь разрешаем перенос — обрезанное «Как понравиться:
   Аня → …» не читается вовсе. Только в этом блоке: у аспектов подпись короткая
   и однострочная пилюля там осознанна. */
.synk-dirs .syn-tab {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.3;
}

/* Лента «подарочный раздел» над заголовком панели — та же персиковая
   семантика, что у кнопки: человек должен узнать блок, в который кликнул. */
.synk-ribbon {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 10px;
  padding: 5px 12px;
  border-radius: var(--syn-r-pill);
  background: var(--syn-secondary-a);
  color: var(--syn-secondary-ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* Вводка: объясняет, откуда советы, до того как человек начнёт их читать. */
.synk-lead { margin-top: 12px; max-width: 68ch; }

.synk-panel { margin-top: 24px; }
.synk-card { padding: 24px; }
.synk-intro { font-weight: 600; }
.synk-advice { margin: 16px 0 0; padding-left: 22px; display: grid; gap: 8px; }
.synk-sub { margin-top: 24px; }
@media (max-width: 640px) {
  .synk-card { padding: 20px; }
}

/* ─── 5. Аккордеон ──────────────────────────────────────────────────────── */

/* Один компонент на два места: FAQ на лендинге и «Диаграмма совместимости»
   на результате. Это <details>, а не Alpine: FAQ обязан раскрываться без JS
   (он же кормит FAQPage JSON-LD), а диаграмма ничего от интерактивности не
   выигрывает. */
.syn-acc { display: flex; flex-direction: column; gap: 12px; }

.syn-acc-item {
  background: var(--syn-bg);
  border: 1px solid var(--syn-border);
  border-radius: var(--syn-r);
  overflow: hidden;
}
/* Мягкий вариант — на белом фоне секции (лендинг): плитка сама лиловая. */
.syn-acc--soft .syn-acc-item { background: var(--syn-card); border-color: transparent; }

.syn-acc-item > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 24px 72px 24px 24px;
  position: relative;
  font-family: var(--syn-font-head);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--syn-headline);
}
.syn-acc-item > summary::-webkit-details-marker { display: none; }
.syn-acc-item > summary::marker { content: ""; }
/* Заодно: отрицательный offset — .syn-acc-item рядом обрезает overflow:hidden,
   наружное кольцо срезало бы себя же по скруглённому краю. */
.syn-acc-item > summary:focus-visible {
  outline: 2px solid var(--syn-primary);
  outline-offset: -3px;
}

/* Круглая кнопка 32px справа: «+» закрыт, «×» открыт. Один и тот же плюс,
   повёрнутый на 45° — так переход анимируется, а не дёргается подменой. */
.syn-acc-item > summary::after {
  content: "";
  position: absolute;
  right: 24px;
  top: 50%;
  width: 32px;
  height: 32px;
  margin-top: -16px;
  border-radius: 50%;
  background: var(--syn-primary-soft) no-repeat center / 14px 14px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M7 1v12M1 7h12' stroke='%237134c4' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  transition: transform 0.2s ease;
}
.syn-acc-item[open] > summary::after { transform: rotate(45deg); }
.syn-acc-item > summary:hover { color: var(--syn-primary); }

/* FAQ приходит из макроса faq_items(), который рисует голый <p> без обёртки —
   переопределить макрос нельзя, он общий на четыре лендинга. Поэтому тело
   аккордеона стилизуется и как .syn-acc-body, и как прямой <p> внутри item. */
.syn-acc-body { padding: 0 24px 24px; }
.syn-acc-item > p { padding: 0 24px 24px; }
.syn-acc-body > p,
.syn-acc-item > p {
  margin: 0;
  font-size: 16px;
  line-height: 1.5;
  color: var(--syn-text);
  text-wrap: pretty;
}
.syn-acc-body > p + p { margin-top: 12px; }
.syn-acc-body > p b, .syn-acc-body > p strong { font-weight: 700; }

/* Место под платный CTA. Кнопки и цену не рендерим (оплаты нет), но отступ
   под них заложен здесь: включение блока не должно требовать переверстки. */
.syn-acc-cta { margin-top: 20px; }

@media (max-width: 640px) {
  .syn-acc-item > summary { padding: 20px 60px 20px 16px; font-size: 17px; }
  .syn-acc-item > summary::after { right: 16px; }
  .syn-acc-body { padding: 0 16px 20px; }
}

/* ─── 6. Поля формы ─────────────────────────────────────────────────────── */

.syn-field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.syn-label { font-size: 16px; line-height: 1.2; color: var(--syn-text); }

/* input[type=date]/[type=time] несут собственную интринсик-высоту (нативные
   иконка/степпер), из-за чего три поля одного ряда .synf-grid (дата/время/
   город) на вид получались 55.19/56.8/53.19px при одинаковом .syn-input —
   фиксируем итоговую высоту явно (box-sizing уже border-box, так что паддинг
   в неё укладывается) вместо того чтобы полагаться на content-box. */
.syn-input {
  width: 100%;
  height: 56px;
  box-sizing: border-box;
  font-family: var(--syn-font);
  font-size: 16px;
  line-height: 1.2;
  color: var(--syn-text);
  background: var(--syn-bg);
  border: 1px solid var(--syn-border);
  border-radius: 12px;
  padding: 16px;
  transition: border-color 0.15s ease;
}
.syn-input::placeholder { color: var(--syn-text-low); }
.syn-input:focus { outline: none; border-color: var(--syn-primary); }
/* :focus-visible, а не :focus — кольцо только для клавиатуры, мышиный клик
   и так виден по смене цвета рамки строкой выше. Порядок правил важен:
   это правило идёт ПОСЛЕ .syn-input:focus, чтобы outline здесь победил
   outline:none оттуда при равной специфичности. */
.syn-input:focus-visible {
  outline: 2px solid var(--syn-primary);
  outline-offset: 2px;
}
.syn-input:disabled { opacity: 0.45; cursor: default; }
/* Родные иконки календаря/часов в Chrome серые и мелкие — макет рисует их
   лиловыми, но красить нативный shadow-DOM нечем. Оставляем как есть,
   только не даём им вылезать за скруглённый край. */
.syn-input::-webkit-calendar-picker-indicator { opacity: 0.55; cursor: pointer; }

/* Тап-таргет 326×18 — ниже нормы (≥40px по высоте). Раздуваем кликабельную
   зону вертикальным паддингом: визуальный квадрат чекбокса остаётся 18×18,
   растёт только площадь, по которой можно попасть пальцем.

   Отрицательные поля ровно на величину паддинга гасят его во внешнем потоке:
   без них строка «расчёт на полдень, без домов» ниже и поле времени выше
   разъезжались бы на 11px каждое (`.syn-field` — флекс-колонка с `gap: 8px`,
   и паддинг сложился бы с ним). Так тап-таргет 40px есть, а воздух вокруг
   ровно тот же, что был до правки. */
.syn-check {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 11px 0;
  margin: -11px 0;
  font-size: 13px;
  line-height: 1.35;
  color: var(--syn-text-2);
  cursor: pointer;
}
.syn-check input[type="checkbox"] {
  appearance: none;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1px solid var(--syn-border);
  border-radius: var(--syn-r-xs);
  background: var(--syn-bg) no-repeat center / 11px 11px;
  cursor: pointer;
}
/* appearance:none снимает и родной фокус-стиль тоже — без своего кольца
   квадратик получал дефолтное синее от Chrome (m9). */
.syn-check input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--syn-primary);
  outline-offset: 2px;
}
.syn-check input[type="checkbox"]:checked {
  background-color: var(--syn-primary);
  border-color: var(--syn-primary);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 6.4l2.6 2.6L10 3.4' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Радио пола — тот же кастомный вид, что у .syn-check-чекбоксов, но круглый
   и с точкой вместо галочки: appearance:none, своё focus-кольцо. */
.syn-check input[type="radio"] {
  appearance: none;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1px solid var(--syn-border);
  border-radius: 50%;
  background: var(--syn-bg);
  cursor: pointer;
}
.syn-check input[type="radio"]:focus-visible {
  outline: 2px solid var(--syn-primary);
  outline-offset: 2px;
}
/* Точка — заливка с inset-кольцом фона, без svg. */
.syn-check input[type="radio"]:checked {
  border-color: var(--syn-primary);
  background-color: var(--syn-primary);
  box-shadow: inset 0 0 0 3px var(--syn-bg);
}

/* Подсказка городов (partials/city_search.html) */
.syn-city-results { position: relative; }
.syn-city-list {
  position: absolute;
  z-index: 20;
  width: 100%;
  margin: 4px 0 0;
  padding: 0;
  max-height: 260px;
  overflow-y: auto;
  list-style: none;
  background: var(--syn-bg);
  border: 1px solid var(--syn-border);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgb(23 22 29 / 10%);
}
.syn-city-item {
  padding: 12px 16px;
  cursor: pointer;
  border-bottom: 1px solid var(--syn-border);
}
.syn-city-item:last-child { border-bottom: none; }
.syn-city-item:hover { background: var(--syn-card); }
/* Пункт, подсвеченный стрелками (он же aria-activedescendant поля). Свой
   класс, а не :hover: мышь и клавиатура могут указывать на разные пункты, и
   подсветок не должно быть две. Заливка заметнее ховерной — при закрытых
   глазах на мышь именно она заменяет фокусную рамку, которой у пункта нет:
   фокус всё это время остаётся в поле ввода. */
.syn-city-item.is-active {
  background: var(--syn-primary-soft);
  box-shadow: inset 3px 0 0 var(--syn-primary);
}
.syn-city-name { font-size: 16px; color: var(--syn-text); }
.syn-city-cc { display: block; font-size: 12px; color: var(--syn-text-low); }
.syn-city-empty { padding: 12px 16px; color: var(--syn-text-2); font-size: 14px; }

/* ─── 7. Карточки, плашки, служебное ────────────────────────────────────── */

.syn-card {
  background: var(--syn-bg);
  border: 1px solid var(--syn-border);
  border-radius: var(--syn-r);
  padding: 24px;
}
.syn-card--soft { background: var(--syn-card); border-color: transparent; }

/* Плашка-нотис: шапка «ⓘ Обратите внимание» на более плотной заливке. */
.syn-notice {
  border-radius: var(--syn-r);
  background: var(--syn-card);
  overflow: hidden;
}
.syn-notice__head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 24px;
  background: var(--syn-card-high);
  color: var(--syn-primary);
  font-size: 14px;
  font-weight: 500;
}
.syn-notice__body {
  padding: 20px 24px 24px;
  font-size: 18px;
  line-height: 1.4;
  color: var(--syn-text);
  margin: 0;
  text-wrap: pretty;
}
@media (max-width: 640px) {
  .syn-notice__head { padding: 12px 16px; }
  .syn-notice__body { padding: 16px 16px 20px; font-size: 16px; }
}

/* Сноски под блоками «Отношение аспектов»: первое предложение фиолетовым. */
.syn-footnote {
  font-size: 14px;
  line-height: 1.45;
  color: var(--syn-text);
  margin: 0;
  text-wrap: pretty;
}
.syn-footnote + .syn-footnote { margin-top: 12px; }
.syn-footnote b { color: var(--syn-primary); font-weight: 400; }

.syn-error {
  font-size: 14px;
  line-height: 1.4;
  color: var(--syn-bad);
  margin: 0;
}

/* Экран «Results / No connections»: сфера без единого аспекта. */
.syn-empty { display: flex; flex-direction: column; gap: 12px; margin-top: 24px; }

/* Флаги пары (удачное сочетание / много точек напряжения). */
.syn-pair-flag { margin-top: 24px; }

[x-cloak] { display: none !important; }

/* ─── Пустышка под пэйволом (lock == "paywall") ───────────────────────────
   Те же секции, что в полном отчёте, но из демо-пары и под блюром. `inert`
   в разметке снимает содержимое с клавиатуры и скринридера; здесь — только
   вид: размытие, запрет выделения и кликов, и мягкая кромка сверху, чтобы
   граница «открыто / закрыто» не была резкой на лиловом полотне.        */
.syn-locked {
  position: relative;
  filter: blur(7px);
  user-select: none;
  pointer-events: none;
}
/* Кромка — только у div-обёртки: у <li> ::before занят кружком с номером
   (.synm-item::before), и общий селектор стёр бы нумерацию хвоста. */
div.syn-locked::before {
  content: "";
  position: absolute;
  inset: -24px 0 auto 0;
  height: 120px;
  background: linear-gradient(to bottom, var(--syn-card), transparent);
  z-index: 1;
}
/* Отдельный размытый пункт в списке главных аспектов (хвост 3…N). */
li.syn-locked { filter: blur(6px); }

/* ─── 4. Лендинг /synastry ──────────────────────────────────────────────── */

/* Макет 12205:116138 (screens/20…25), мобильный 12208:117675
   (screens/09, 10). Разметка: templates/synastry.html.
   Вне скоупа и не верстается: дата статьи, «~9–12 минут», кнопка «Поделиться»,
   правый баннер «Карта дня» 308px, табы выбора сферы над формой, подписи и
   логотип Sotis. Карточка формы — отдельный блок (.synf-*, §4.5). */

/* Нижний воздух страницы. Контентная колонка лендинга и так 876 — это уже
   дефолт --syn-content из §0 токенов (сетка макета 1400 = 956 внутри 876 плюс
   правая колонка 308 под баннеры; баннеры в скоуп не входят), переопределять
   нечего. Ревью-контракт разрешает трогать сам `.syn-*`-класс страницы только
   ради `--syn-content` (см. `.syn-result`) — раз он тут не нужен, класс идёт
   под своим префиксом, а не как переопределение фундамента. */
.synl-page { padding-bottom: 96px; }
@media (max-width: 640px) { .synl-page { padding-bottom: 64px; } }

/* Вертикальный ритм внутри секции: в макете почти всё разнесено на 24.
   Правило слабое по специфичности (0,1,0) — поэтому парные исключения ниже
   перечислены явно, включая .syn-p + .syn-p (у фундамента там 16, а в макете
   между абзацами лендинга те же 24). */
.synl-flow > * + * { margin-top: 24px; }
.synl-flow > .syn-p + .syn-p { margin-top: 24px; }
/* Надзаголовок и строка чипов-бейджей жмутся к своему заголовку. */
.synl-flow > .synl-eyebrow + *,
.synl-flow > .synl-chiprow + * { margin-top: 12px; }
/* Крупные блоки отбиваются сильнее, как в макете. */
.synl-flow > .synl-form { margin-top: 40px; }
.synl-flow > .synl-promo { margin-top: 40px; }
/* Экспертный блок: несколько H2/H3 в одной секции — новый подзаголовок
   после абзаца отбивается сильнее, чем обычный ритм 24, иначе сливается. */
.synl-about > .syn-p + .syn-h2,
.synl-about > .synl-list + .syn-h2 { margin-top: 48px; }
.synl-about > .syn-p + .syn-h4 { margin-top: 32px; }

.synl-eyebrow {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--syn-primary);
  margin: 0;
}

/* Строка чипов (тег статьи, рубрика, бейдж «Бесплатно»). */
.synl-chiprow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* Иконка внутри готовых примитивов (.syn-notice__head и т.п.): не даём флексу
   её сжать. Размеры проставлены атрибутами на самом <svg>. */
.synl-icon { flex: 0 0 auto; display: block; }

/* ── 4.1 Герой ──────────────────────────────────────────────────────────── */

/* Отступы внутри героя не совпадают с общим ритмом .synl-flow (в макете
   24 / 24 / 32 / 40 / 16), поэтому заданы поимённо. */
.synl-hero__h1 { margin-top: 24px; }
.synl-hero__meta { margin-top: 24px; }
.synl-hero__lead {
  margin-top: 32px;
  font-size: 17px;
  line-height: 1.5;
}
.synl-hero__sub { margin-top: 40px; }

@media (max-width: 640px) {
  .synl-hero__h1 { margin-top: 16px; }
  .synl-hero__meta { margin-top: 16px; }
  .synl-hero__lead { margin-top: 24px; font-size: 16px; }
  .synl-hero__sub { margin-top: 32px; }
}

/* Чипы четырёх сфер. Не кликабельные: табов сфер у нас нет, считаются сразу
   все четыре — поэтому это <ul>, а не кнопки.
   Раскладка: flex-wrap с плитками по содержимому. На 876 это ровно две штуки
   в ряду, как в макете (там ширины плиток в ряду разные — grid из двух равных
   колонок такого не даёт). На мобилке — колонка во всю ширину (screens/09). */
.synl-spheres {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}
.synl-sphere {
  /* Заливки сняты пипеткой со скриншота 20: это разовая палитра геро-блока,
     в переменных макета таких цветов нет. */
  --synl-sphere-bg: var(--syn-card);
  /* Плитки всегда светлые — тёмная тема их не перекрашивает, поэтому текст
     на них зафиксирован, а не унаследован из --syn-text. */
  --synl-sphere-ink: #17161d;   /* base/headline */

  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 13px 24px;
  border-radius: var(--syn-r-pill);
  background: var(--synl-sphere-bg);
  color: var(--synl-sphere-ink);
  font-size: 16px;
  line-height: 1.25;
}
.synl-sphere--emotional { --synl-sphere-bg: #ecd4ff; }
.synl-sphere--spiritual { --synl-sphere-bg: #cfebff; }
.synl-sphere--financial { --synl-sphere-bg: #ccffce; }
.synl-sphere--sexual    { --synl-sphere-bg: #ffdacc; }

.synl-sphere__icon { flex: 0 0 auto; display: block; }

@media (max-width: 640px) {
  .synl-spheres { flex-direction: column; margin-top: 12px; }
  .synl-sphere { justify-content: center; padding: 12px 20px; font-size: 15px; }
}

/* ── 4.3 «Вам поможет расчет совместимости, если» ───────────────────────── */

/* Tailwind (CDN, base.html) снимает маркеры со всех списков в preflight —
   list-style и отступ восстанавливаем явно, иначе нумерация пропадёт.
   margin-top при этом не трогаем: его задаёт ритм .synl-flow, а «margin: 0»
   здесь перебил бы его (та же специфичность, но правило ниже по файлу). */
.synl-list {
  margin-bottom: 0;
  padding: 0 0 0 26px;
  list-style: decimal outside;
  font-size: 16px;
  line-height: 1.4;
  color: var(--syn-text);
}
.synl-list > li { padding-left: 4px; }
.synl-list > li + li { margin-top: 8px; }

/* ── 4.4 Промо-баннер «Хотите полный разбор» ────────────────────────────── */

.synl-promo {
  /* В макете под фиолетовой заливкой лежит фото пары. Фото не тащим (ассета
     нет, лицензия неясна) — остаётся сама заливка. Тона сняты пипеткой со
     скриншота 25: верх #8454c6, низ уходит в #9476bd; середину держим на
     токене primary, чтобы баннер не расходился с кнопками. */
  --synl-promo-top: #8f60cf;
  --synl-promo-bot: #7d59bd;
  /* Текст на заливке: токена «on-primary» в макете нет, белый снят оттуда же. */
  --synl-promo-ink: #ffffff;
  --synl-promo-ink-2: rgb(255 255 255 / 90%);

  border-radius: var(--syn-r);
  padding: 64px 40px;
  text-align: center;
  background:
    radial-gradient(90% 70% at 50% 0%, rgb(255 255 255 / 14%), rgb(255 255 255 / 0%) 62%),
    linear-gradient(180deg, var(--synl-promo-top) 0%, var(--syn-primary) 52%, var(--synl-promo-bot) 100%);
}
.synl-promo .synl-promo__title {
  color: var(--synl-promo-ink);
  max-width: 620px;
  margin: 0 auto;
}
.synl-promo .synl-promo__text {
  color: var(--synl-promo-ink-2);
  max-width: 720px;
  margin: 24px auto 0;
}
.synl-promo__hl { color: var(--syn-secondary); }
.synl-promo__cta { margin-top: 32px; }

@media (max-width: 640px) {
  .synl-promo { padding: 40px 20px; }
  .synl-promo .synl-promo__text { margin-top: 16px; }
  .synl-promo__cta { margin-top: 24px; }
}

/* ─── 4.5 Карточка формы на лендинге ────────────────────────────────────── */

/* Макет 12306:116237 (screens/24-landing-sphere-tabs-and-form.png), мобильный
   вариант — screens/10-mobile-sphere-tabs-2x2.png.
   Берём только оформление: набор полей прежний (имя / дата / время / город на
   двоих), e-mail, «не знаю места рождения», оба чекбокса согласий и «фамилия
   партнёра» из макета не реализуются — см. README §3.5.
   Разметка: partials/synastry_form.html. */

.synf-card {
  background: var(--syn-card);
  border-radius: var(--syn-r-lg);
  padding: 32px;
}

.synf-title { margin: 0; }
.synf-sub { margin: 6px 0 0; }

/* Блок одного человека. Рамку и отступы fieldset обнуляем — визуально блок
   держится на фиолетовом legend'е, а не на рамке. min-width: 0 обязателен:
   у fieldset собственный min-inline-size: min-content, из-за которого сетка
   полей внутри отказывается сжиматься на узких экранах. */
.synf-block {
  border: 0;
  margin: 32px 0 0;
  padding: 0;
  min-width: 0;
}

.synf-legend {
  display: block;
  box-sizing: border-box;
  width: 100%;
  float: none;
  padding: 0;
  margin: 0 0 20px;
  font-family: var(--syn-font-head);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--syn-primary);
}

/* Имя — во всю ширину, под ним три колонки: дата | время | место. */
.synf-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px 24px;
}
.synf-wide { grid-column: 1 / -1; }

.synf-check-text { display: block; }

/* Радио пола: та же строка, что чекбокс времени, но горизонтально. */
.synf-gender { display: flex; gap: 20px; }

/* Хвост прежней подписи, вынесенный отдельной строкой. Отступ слева равен
   ширине чекбокса (18px) плюс gap .syn-check (8px) — текст выравнивается по
   подписи, а не по галочке. */
.synf-hint {
  margin: -4px 0 0;
  padding-left: 26px;
  font-size: 12px;
  line-height: 1.35;
  /* Не --syn-text-low: на лиловой карточке #aba8bd даёт около 2:1 к фону,
     для 12px это нечитаемо. Тот же цвет, что и у подписи чекбокса. */
  color: var(--syn-text-2);
}

/* Класс ошибки (.syn-form-error) задан контрактом разметки — тест сверяет
   class целиком (test_form_markup_alpine_and_htmx_attributes_survive_parsing),
   добавить свой .synf- рядом нельзя. Чтобы не переопределять фундаментальный
   .syn-* класс (см. review-чек-лист вёрстки), цепляемся не за class, а за
   пару alpine-атрибутов, которая для этого узла тоже фиксирована контрактом. */
.synf-card p[x-show="error"][x-text="error"] {
  margin: 20px 0 0;
  font-size: 14px;
  line-height: 1.4;
  color: var(--syn-bad);
}

.synf-submit { margin-top: 28px; }
/* Текст и стрелка — один span (второй, «Считаем…», переключается x-show'ом),
   поэтому inline-flex с тем же gap, что и у самой кнопки. */
.synf-submit-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

@media (max-width: 900px) {
  /* Две колонки: дата | время, а место рождения — во всю ширину. Иначе оно
     садится одно в левую колонку и рядом остаётся пустая ячейка. */
  .synf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .synf-city { grid-column: 1 / -1; }
}

@media (max-width: 640px) {
  /* 375 − поля 16 = 343 на контент; карточка ужимается по вертикали тоже. */
  .synf-card { padding: 20px 16px; border-radius: var(--syn-r); }
  .synf-block { margin-top: 24px; }
  .synf-legend { margin-bottom: 16px; font-size: 18px; }
  .synf-grid { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .synf-submit { margin-top: 24px; }
}

/* ─── 8. Результат: шапка отчёта, карточки людей, колёса ────────────────────
   Макет: 12306:116694 (шапка), 12345:12913 (карточки), 12884:12686 (колесо).
   Референсы: screens/01-person-cards.png, screens/02-wheel-section.png,
   screens/10-mobile-sphere-tabs-2x2.png.
   ─────────────────────────────────────────────────────────────────────────── */

/* Фрейм результата в макете 876 при контентной колонке 748 (поля по 64).
   .syn-wrap кладёт свои 24px паддинга внутрь этой ширины (box-sizing:
   border-box приходит из tailwind preflight в base.html).

   Ревью: здесь стояла ещё и `padding: 48px 0 80px` — ревью-контракт
   разрешает трогать `.syn-result` только ради `--syn-content`, так что пара
   строк снята. `<main>` в base.html и без того даёт `padding-top: 60px`
   (см. style-блок в base.html) — с чужим паддингом воздух наверху попросту
   удваивался бы. Верхний отступ первой секции — теперь на `.synh-head`
   (§8.1, свой префикс), нижний из макета сюда не переносим: последняя
   кнопка результата не в этом чанке. */
.syn-result {
  --syn-content: 748px;
}

/* Полотно страницы результата — лиловая карточка макета (rgb(246,243,252),
   base/card-background = --syn-card), а не белый --syn-bg фундамента.
   Специфичность равна `.syn-scope { background: var(--syn-bg); }` (§1) —
   побеждает по порядку следования (это правило ниже по файлу). Лендинг
   белым и остаётся: класс свой, `.syn-scope` не переопределён.

   Нижний воздух страницы (m5): было 0 — низ последней секции совпадал с
   scrollHeight. Заодно тёмная тема не белеет и не чернеет насквозь — токен
   --syn-card уже имеет тёмный вариант в §0. */
.synr-page {
  background: var(--syn-card);
  padding-bottom: 96px;
}
@media (max-width: 640px) { .synr-page { padding-bottom: 64px; } }

/* Поверхности результата, слитые с новым лиловым полотном (m3): .synx-ratio,
   .syng-line и .syn-empty все несут .syn-card--soft из разметки (лиловая
   заливка, прозрачный бордер) — на лиловом полотне превращались в невидимые
   плашки. По макету это белые карточки с бордером. Padding/radius уже даёт
   базовый .syn-card на этих же узлах — переопределяем только заливку и цвет
   бордера. Фундаментальный .syn-card--soft не трогаем (он же на лендинге,
   где полотно осталось белым и такое поведение по-прежнему уместно); все три
   класса здесь — либо с префиксом результата (synx-/syng-), либо проверены
   grep'ом как встречающиеся только в partials результата (.syn-empty). */
.synr-page .synx-ratio,
.synr-page .syng-line,
.synr-page .syn-empty.syn-card--soft {
  background: var(--syn-bg);
  border-color: var(--syn-border);
}

/* .synd-panel («Диаграмма совместимости») на референсе 04 вовсе не панель —
   белые строки аккордеона лежат прямо на лиловом полотне. Убираем собственную
   заливку/паддинг; отступы по бокам берёт .syn-wrap, вертикальные — .synd-lead
   и .synd-list уже расставлены отдельно (§ниже), так что паддинг снаружи не
   нужен нигде, кроме мобильного случая ниже. */
.synr-page .synd-panel {
  background: transparent;
  padding: 0;
  border-radius: 0;
}

/* ─── 8.1 Шапка отчёта ──────────────────────────────────────────────────── */

/* Верхний воздух страницы. `<main>` в base.html уже даёт `padding-top: 60px`
   на всех четырёх субпродуктах — здесь только разница сверх общего отступа,
   и она на своём классе (шапка — первая секция, `.syn-section:first-child`
   и так обнуляет её margin-top). */
.synh-head { padding-top: 48px; }
@media (max-width: 640px) { .synh-head { padding-top: 32px; } }

/* «Ваш отчет готов»: Headline/H4 24px, primary #7134c4. В макете написано
   без ё — так и оставлено. */
.synh-eyebrow {
  font-family: var(--syn-font-head);
  font-weight: 700;
  font-size: 24px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--syn-primary);
  margin: 0 0 12px;
}

/* Пилюль сфер здесь больше нет: переключатель уехал под «Отношение аспектов»
   (2026-08-11), вместе с ним ушёл и его отступ `.synh-tabs`. Кнопки живут в
   partials/synastry_sphere_tabs.html, стили — в секции «Переключатель сфер на
   результате (.synt-)». */

/* Итоговый процент пары под H1 (partials/synastry_report_head.html).
   В макете Figma его нет — блок заведён по комментариям астрологов.
   Цифра крупная и фиолетовая, подпись рядом на базовой линии: число здесь
   главное, «общая совместимость» его только называет. */
.synh-score {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin: 20px 0 0;
}
.synh-score__value {
  font-family: var(--syn-font-head);
  font-weight: 800;
  font-size: 56px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--syn-primary);
}
.synh-score__label {
  font-size: 18px;
  font-weight: 600;
  color: var(--syn-text-2);
}
/* Сноска про среднее — не мелким шрифтом ради галочки: ширина ограничена,
   чтобы она читалась как пояснение к цифре, а не как отдельный абзац. */
.synh-score__note { margin-top: 10px; max-width: 620px; }

@media (max-width: 640px) {
  .synh-score { margin-top: 16px; }
  .synh-score__value { font-size: 44px; }
  .synh-score__label { font-size: 16px; }
}

@media (max-width: 640px) {
  .synh-eyebrow { font-size: 20px; margin-bottom: 8px; }
}

/* ─── 8.2 Карточки людей ────────────────────────────────────────────────── */

/* Строка 748: две плитки 306×306 и «плюс» 47 между ними (306·2 + 44·2 + 47).
   Колонки долевые, плитку держит квадратной aspect-ratio — так строка
   сжимается вместе с контентной колонкой и ничего не режется. */
.synp-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 44px;
}

.synp-card {
  position: relative;
  aspect-ratio: 1 / 1;
  min-width: 0;
  overflow: hidden;
  border-radius: var(--syn-r);
  /* Подложка на время загрузки иллюстрации — из токенов, а не серая. */
  background: var(--syn-card-high);

  /* Тёмно-фиолетовый вуали. В токенах такого нет: самый тёмный фиолетовый
     там --syn-primary #7134c4, а под белый текст нужен глубже — взят его
     затемнением до ~15% светлоты, совпадает с растровым
     assets/card_background_gradient.png макета (сам растр в вёрстку не идёт).
     Компонентами, а не hex — из них собираются полупрозрачные стопы. */
  --synp-veil: 34 13 74;   /* #220d4a */
  /* Плитка всегда тёмная, поэтому текст на ней белый в обеих темах:
     --syn-bg тут не годится, он инвертируется в data-theme="dark". */
  --synp-ink: 255 255 255;
}

.synp-art {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Градиент читаемости. Снизу — как в макете, под крупное название знака;
   сверху добавлена лёгкая вуаль: строка с именем в макете лежит на светлом
   участке иллюстрации, а у нас знак×пол меняются и светлым может оказаться
   что угодно. */
.synp-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to top,
      rgb(var(--synp-veil) / 88%) 0%,
      rgb(var(--synp-veil) / 52%) 24%,
      rgb(var(--synp-veil) / 0%) 54%),
    linear-gradient(to bottom,
      rgb(var(--synp-veil) / 78%) 0%,
      rgb(var(--synp-veil) / 58%) 30%,
      rgb(var(--synp-veil) / 32%) 45%,
      rgb(var(--synp-veil) / 0%) 60%);
}

.synp-meta {
  position: absolute;
  inset: 20px 14px auto;
  z-index: 2;
  color: rgb(var(--synp-ink));
  text-align: center;
}

.synp-line {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin: 0;
  font-size: 15px;
  line-height: 1.25;
}
.synp-line + .synp-line { margin-top: 8px; }
.synp-icon { flex: 0 0 auto; display: block; }
.synp-name { font-weight: 600; }
.synp-when { white-space: nowrap; }

/* Пометка есть только в варианте без времени, и это единственная строка,
   которая может лечь на светлый участок портрета: продлённая вуаль
   `.synp-card::after` держит медиану фона под ней ≥6:1, но иллюстрации у нас
   меняются по знаку и полу, и отдельные светлые пятна (блик, звёздочка,
   кожа) вуаль не гасит. Поэтому здесь белый в полную силу, а не 70%, плюс
   тень цветом самой вуали — она работает ровно там, где фон посветлел, и
   не видна там, где он и так тёмный. */
.synp-note {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.3;
  color: rgb(var(--synp-ink));
  text-shadow: 0 1px 3px rgb(var(--synp-veil) / 85%);
  text-wrap: pretty;
}

.synp-sign {
  position: absolute;
  inset: auto 14px 20px;
  z-index: 2;
  margin: 0;
  font-family: var(--syn-font-head);
  font-weight: 700;
  font-size: clamp(22px, 3.4vw, 28px);
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: rgb(var(--synp-ink));
  text-align: center;
}

/* Плюс между плитками — secondary #fda986 через currentColor. */
.synp-plus {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--syn-secondary);
}
.synp-plus svg { display: block; width: 40px; height: 40px; }

@media (max-width: 900px) { .synp-row { gap: 24px; } }

/* На мобильном плитки остаются в один ряд: столбцом они вдвоём съедали весь
   первый экран. Раскладка та же (1fr auto 1fr), сжимаются зазор, «плюс» и
   типографика — квадратная плитка на 360px выходит ~145px, и 15px строки
   в неё уже не помещаются. */
@media (max-width: 640px) {
  .synp-row { gap: 8px; }
  .synp-plus svg { width: 20px; height: 20px; }
  .synp-meta { inset: 10px 6px auto; }
  .synp-line { font-size: 12px; gap: 2px 4px; }
  .synp-line + .synp-line { margin-top: 4px; }
  .synp-icon { width: 13px; height: 13px; }
  .synp-note { margin-top: 4px; font-size: 10px; }
  .synp-sign { inset: auto 6px 10px; font-size: 17px; }
}

/* ─── 8.3 Синастрическая карта отношений (би-колесо) ────────────────────── */

/* Абзац идёт во всю контентную колонку — как в макете. */
.synw-lead {
  margin-top: 12px;
  color: var(--syn-text-2);
}

.synw-box { margin: 0 auto; max-width: 720px; min-width: 0; }

/* Контейнер колеса. natal-wheel рисует внутрь .natal-wheel-root с width:100%
   и без собственной высоты — квадрат задаём мы, иначе до монтирования блок
   нулевой и страница дёргается. Имя своё (`synw-`, не голое `.syn-wheel`) —
   класс новый, JS/тесты держатся за атрибут `[data-syn-biwheel]`, а не за
   класс, так что переименование ничего не ломает. */
.synw-wheel {
  width: 100%;
  aspect-ratio: 1 / 1;
}

.synw-cap {
  margin: 12px 0 0;
  text-align: center;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--syn-text);
}

.synw-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 20px;
  margin: 12px 0 0;
  padding: 0;
}
.synw-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--syn-text-2);
}
.synw-legend-item::before {
  content: "";
  width: 18px;
  height: 2px;
  border-radius: 1px;
}
.synw-legend-item--soft::before { background: var(--nw-aspect-soft); }
.synw-legend-item--hard::before { background: var(--nw-aspect-hard); }
.synw-legend-item--conj::before { background: var(--nw-aspect-conjunction); }

@media (max-width: 640px) {
  .synw-lead { margin-top: 10px; }
}

/* Акцент внутри вендоренного колеса (подсветка выбранной точки). Библиотека
   ждёт компоненты RGB через пробел и сама собирает из них полупрозрачный
   вариант. Цвет — брендовый фиолетовый макета --syn-primary #7134c4.
   Селектор чужой (.natal-wheel-root из бандла), поэтому и переменные его. */
.natal-wheel-root {
  --nw-accent-rgb: 113 52 196;
  --nw-accent-20: rgb(var(--nw-accent-rgb) / 20%);
}

/* Контролы зума (+/-) в углу вендорного колеса заходят на зодиакальное
   кольцо на всех проверенных ширинах — угол квадратного `.synw-wheel`
   слишком мал под кнопку 40px рядом с окружностью. Вместо угла — резерв
   полосы ПОД колесом в `.synw-box` и свои координаты для `.natal-wheel-controls`
   (тот же приём, что и с `--nw-accent-rgb` выше: переопределяем классы
   вендора из своего файла, сам вендорный CSS не трогаем).
   `.natal-wheel-root` по размеру совпадает с `.synw-wheel` (ширина 100%,
   высота тянется по квадратному SVG), поэтому `top: 100%` кладёт контролы
   ровно на нижний край квадрата — в зарезервированный отступ, а не поверх
   кольца. Также увеличиваем кнопку до 40×40 (заодно закрывает тап-таргет
   из задания про размер тапа — тот же класс). */
.synw-wheel { margin-bottom: 56px; }

/* Вендорная таблица стилей подключена в разметке ПОСЛЕ synastry.css (см.
   synastry_result.html), поэтому при равной специфичности она перебивала бы
   голые `.natal-wheel-controls`/`.natal-wheel-control-btn` — предок `.synw-wheel`
   в селекторе поднимает специфичность и решает спор в нашу пользу без
   `!important`. */
.synw-wheel .natal-wheel-controls {
  flex-direction: row;
  top: 100%;
  bottom: auto;
  left: 50%;
  right: auto;
  transform: translate(-50%, 16px);
}
.synw-wheel .natal-wheel-control-btn {
  width: 40px;
  height: 40px;
}
/* У вендорной кнопки своего фокус-стиля нет, и Chrome рисует ей дефолтное
   синее кольцо — тот же чужой цвет в палитре, из-за которого m9 завели для
   вкладок. Кольцо здесь такое же, как у .syn-tab и .syn-input. */
.synw-wheel .natal-wheel-control-btn:focus-visible {
  outline: 2px solid var(--syn-primary);
  outline-offset: 2px;
}

/* На тач-устройствах вендор сам прячет контролы
   (`@media (pointer:coarse){.natal-wheel-controls{display:none}}`) — резерв
   под них не должен оставлять пустую дыру между колесом и подписью. */
@media (pointer: coarse) {
  .synw-wheel { margin-bottom: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   §4 «Отношение аспектов в ваших картах» — два виджета, с 2026-08-11 в разных
   партиалах и в разных местах страницы: A — двусторонние шкалы по всем сферам
   (partials/synastry_ratio.html, один блок над переключателем сфер), B — две
   карточки по направлениям влияния для текущей сферы
   (partials/synastry_directions.html, внутри панели вкладки).
   Референс: docs/design/synastry/screens/08-aspect-ratio-cards.png
   (виджет B; у виджета A скриншота нет — только текстовое описание в README).

   Обёртка использует готовые .syn-card / .syn-card--soft из фундамента —
   свои классы здесь только добавляют внутреннюю раскладку и отступы.
   ═══════════════════════════════════════════════════════════════════════════ */

.synx-ratio { margin-top: 24px; }
.synx-ratio__lead { margin-top: 12px; }
.synx-ratio__footnote { margin-top: 24px; }

/* ─── Виджет A: двусторонние шкалы ──────────────────────────────────────── */

.synx-scales { margin-top: 24px; }
.synx-scales__note { margin-top: 12px; }

.synx-scales__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
}
.synx-scales__name {
  font-family: var(--syn-font-head);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.2;
  color: var(--syn-headline);
}

/* Строка: значение | дорожка | название | дорожка | значение — пять узлов из
   разметки, без спейсерных колонок (зазор — через column-gap).

   Было: `minmax(28px, auto)` на колонке значения — авто-ширина под контент
   каждой строки по отдельности, поэтому одно и то же визуальное «100%
   доступной ширины» у дорожки получалось разным в каждой строке (значение
   «5» уже даёт другую ширину колонки, чем «-55»), и одна и та же величина
   рисовалась разными по факту отрезками в разных строках — при том что
   сравнивать длины дорожек между строками как раз и есть смысл виджета.

   Стало: колонке значения — фиксированная ширина по худшему случаю
   («-100» — 4 знака) в `ch` + табличные цифры (иначе у пропорционального
   начертания «1» и «0» разной ширины, и `ch` считает по «0»), дорожке —
   `minmax()`, чтобы у неё был явный минимум на узких экранах вместо
   бесконтрольного схлопывания. */
.synx-scale-row {
  display: grid;
  /* Средняя колонка тоже была `auto` — тот же баг, что и с колонкой значения,
     просто на названии сферы: у «Духовность» (88px) и «Секс» (36px) разная
     естественная ширина, значит и авто-колонка в их строках разной ширины,
     значит и дорожки по бокам (компенсирующие 1fr) снова расходятся между
     строками. Фиксируем и её — по самому длинному названию («Духовность»)
     с запасом. */
  grid-template-columns: 4.5ch minmax(140px, 1fr) 100px minmax(140px, 1fr) 4.5ch;
  column-gap: 12px;
  align-items: center;
  padding: 10px 12px;
  border-radius: var(--syn-r-s);
}
.synx-scale-row + .synx-scale-row { margin-top: 4px; }
.synx-scale-row--active { background: var(--syn-card); }

.synx-scale-value {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--syn-text);
  white-space: nowrap;
}
.synx-scale-value--left { text-align: right; }
.synx-scale-value--right { text-align: left; }

.synx-scale-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--syn-text-2);
  text-align: center;
  white-space: nowrap;
}
.synx-scale-row--active .synx-scale-name {
  font-weight: 700;
  color: var(--syn-headline);
}

.synx-scale-track {
  display: flex;
  height: 20px;
  border-radius: var(--syn-r-pill);
  background: var(--syn-border);
  overflow: hidden;
}
/* Левая дорожка растёт слева направо (бар прижат к левому краю). */
.synx-scale-track--left { justify-content: flex-start; }
/* Правая дорожка растёт справа налево (бар прижат к правому краю) —
   обе дорожки растут навстречу друг другу, к центру строки. */
.synx-scale-track--right { justify-content: flex-end; }

.synx-scale-bar {
  display: block;
  height: 100%;
  border-radius: var(--syn-r-pill);
  /* Ширина — буквально |total| в процентах (спека), без искусственного
     минимума: даже «1» рисуется почти незаметной полоской, как в моке. */
}

@media (max-width: 640px) {
  /* Перестройка сетки, не только чисел: на узких экранах дорожка при пяти
     колонках в ряд схлопывалась вплоть до 10px (см. §M3 отчёта QA).

     Две дорожки по 120px рядом в 320px просто не помещаются: под виджет
     остаётся 176px (320 − поля .syn-wrap − паддинги двух вложенных .syn-card
     − паддинг строки), а две дорожки с колонками значений просят 312.
     Поэтому на мобилке строка становится ТРЕМЯ: название сверху во всю
     ширину, под ним каждая сторона своей строкой во всю ширину. Дорожка
     получает 144px вместо десяти, и все восемь дорожек виджета одной длины.

     Привязка «кто где» при этом не теряется: левая дорожка по-прежнему
     прижата к левому краю со значением слева, правая — к правому со
     значением справа, ровно как имена в шапке виджета. Пять узлов разметки
     не трогаем, только раскладываем их по grid-area. */
  .synx-scale-row {
    grid-template-columns: 3.5ch minmax(120px, 1fr) 3.5ch;
    grid-template-areas:
      "name   name    name"
      "vl     trackl  trackl"
      "trackr trackr  vr";
    row-gap: 6px;
    column-gap: 8px;
    padding: 10px 8px;
  }
  .synx-scale-value--left { grid-area: vl; }
  .synx-scale-track--left { grid-area: trackl; }
  .synx-scale-name { grid-area: name; }
  .synx-scale-track--right { grid-area: trackr; }
  .synx-scale-value--right { grid-area: vr; }

  .synx-scale-value { font-size: 14px; }
  .synx-scale-name { font-size: 13px; white-space: normal; }
  .synx-scales__head { margin-bottom: 14px; }
  .synx-scales__name { font-size: 17px; }
}

/* ─── Виджет B: карточки по направлениям ────────────────────────────────── */

/* Лид виджета переехал сюда из шапки `.synx-ratio` вместе с самим виджетом
   (2026-08-11): у `.syn-lead` margin: 0, а над ним в панели сферы стоит
   `.syn-h3` — тоже с margin: 0. Без этого отступа лид слипается с заголовком
   сферы. 24px — тот же зазор, что раньше давал `.synx-ratio` под заголовком. */
.synx-dir-lead { margin-top: 24px; }

.synx-directions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-top: 32px;
}
@media (max-width: 640px) {
  .synx-directions { grid-template-columns: 1fr; gap: 16px; margin-top: 24px; }
}

.synx-dir-card {
  /* Тёмно-фиолетовый градиент со светлым кругом справа — цвета сняты
     пипеткой с screens/08-aspect-ratio-cards.png (не токенизированы:
     это заливка карточки-варианта, а не семантический цвет). */
  --synx-dir-deep: #2d1354;
  --synx-dir-glow: #8a4f97;
  background:
    radial-gradient(120% 140% at 82% 40%, var(--synx-dir-glow) 0%, transparent 55%),
    linear-gradient(160deg, var(--synx-dir-deep) 0%, #1c0c38 100%);
  border-radius: var(--syn-r);
  padding: 24px;
  text-align: center;
  overflow: hidden;
}

.synx-dir-title {
  margin: 0 0 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--syn-font-head);
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
}
.synx-dir-title__from { color: var(--syn-secondary); }
.synx-dir-title__arrow,
.synx-dir-title__to { color: #ffffff; }

.synx-dir-dots {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}
.synx-dir-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #ffffff;
  flex: 0 0 auto;
}
.synx-dir-dot--good { background: var(--syn-good); }
.synx-dir-dot--bad { background: var(--syn-bad); }
.synx-dir-dot--mirror { background: #ffffff; }

/* nowrap — на 320 «Напряжённые аспекты: 0» и т.п. ровно упирались в ширину
   карточки (текст и доступная ширина после паддинга совпадали с точностью
   до долей пикселя) и одна из трёх строк переносилась, растягивая только
   одну из парных карточек. Имя партнёра сюда не попадает (оно в
   .synx-dir-title, который переносится по-прежнему) — здесь только
   фиксированные подписи + счётчик, так что nowrap безопасен. */
.synx-dir-stat {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: #ffffff;
  white-space: nowrap;
}
@media (max-width: 640px) {
  /* Небольшой запас на случай двузначного счётчика (10+ аспектов в одном
     направлении) — на 320 после паддинга карточки самой узкой ширины. */
  .synx-dir-card { padding: 24px 16px; }
  .synx-dir-stat { font-size: 15px; }
}

/* ─── 60. Аспекты синастрии ─────────────────────────────────────────────
   §5 макета (12884:12695) — partials/synastry_aspects.html.
   Референсы: screens/03-aspect-cards-list.png, 06-aspect-card-same-conjunction.png,
   07-tab-menu-directions.png.

   Таб-меню направлений — фундаментные .syn-tabs / .syn-tab / .syn-tab--active
   (в макете это тот же компонент, что и вкладки сфер: высота 46, радиус 1000,
   активная — персиковая пилюля). Здесь у него только отступ.               */

.syna-section {
  /* Блок идёт вторым внутри панели сферы, после «Отношения аспектов». */
  margin-top: 48px;

  /* Шумовая текстура шапки карточки. В макете это картинка
     (assets/aspect_header_noise.png, 3.2 МБ, одна на все три типа) — вместо
     неё inline-SVG feTurbulence в data-URI: тайл 180×180, обесцвеченный
     (feColorMatrix saturate 0), собственная альфа 0.15. Кладётся отдельным
     слоем фона и смешивается с градиентом через background-blend-mode:
     overlay — не псевдоэлементом поверх, иначе плёнка легла бы и на текст. */
  --syna-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='syna-n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23syna-n)' opacity='0.15'/%3E%3C/svg%3E");

  /* Подстраховка, если тип карточки почему-то не проставлен: нейтральная
     лиловая заливка вместо «фон не нарисовался вовсе» (var() без значения
     обнуляет всё свойство background-image целиком). */
  --syna-fill: linear-gradient(90deg, var(--syn-card-high), var(--syn-card));
}
@media (max-width: 640px) { .syna-section { margin-top: 32px; } }

/* Шаги 16 сняты с макета: заголовок → лид → табы → список. */
.syna-intro { margin-top: 16px; }
.syna-dirs  { margin-top: 16px; }
.syna-list  { margin-top: 16px; }

/* ── Карточка аспекта ── */

.syna-card {
  /* Шапка-градиент уходит в край карточки, поэтому скругление и обрезка
     живут на самой карточке, а не на шапке. */
  border-radius: var(--syn-r);
  overflow: hidden;
}
.syna-card + .syna-card { margin-top: 16px; }

.syna-card__head {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 80px;
  margin: 0;
  padding: 12px 24px;
  font-family: var(--syn-font);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  color: #ffffff;
  background-color: transparent;
  background-image: var(--syna-noise), var(--syna-fill);
  background-repeat: repeat, no-repeat;
  background-size: 180px 180px, cover;
  background-blend-mode: overlay, normal;
}
/* Одна инлайновая строка внутри флекс-шапки: без обёртки браузер разрезал бы
   текст на анонимные флекс-элементы и съел пробелы вокруг глифов. */
.syna-card__line { text-wrap: balance; }

/* Заливки шапок — меш-градиенты дизайн-системы, в токенах их нет. Значения
   сняты пипеткой со screens/03 (гармоничный, напряжённый) и screens/06
   (одинаковый) и разложены в линейные по замерам поперёк шапки. */
/* Название сценария в шапке карточки. Шапка — flex по центру, поэтому имя и
   формула встают в колонку, а не в строку. */
.syna-card__head { flex-direction: column; gap: 4px; }

.syna-card__name {
  font-family: var(--syn-font-head);
  font-weight: 800;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* Формула под именем: тот же белый, но мельче и приглушённее — читается как
   подпись, а не как второй заголовок. Прозрачность, а не серый цвет: под ней
   градиент, и любой фиксированный серый на нём поплывёт. */
.syna-card__line--sub {
  font-size: 13px;
  font-weight: 600;
  opacity: 0.82;
}

@media (max-width: 640px) {
  .syna-card__name { font-size: 18px; }
  .syna-card__line--sub { font-size: 12px; }
}

.syna-card--harmonious .syna-card__head {
  /* Средний стоп #69af83 давал 2.61:1 под белым текстом (порог 4.5:1) —
     затемнили все стопы до 70% (замер pix2.py показал провал по всей верхней
     половине градиента, не только в центре), 88%/100% уже проходили и не
     тронуты. */
  --syna-fill: linear-gradient(90deg,
    #31766d 0%, #397665 30%, #3f7754 50%, #397665 70%, #247c6f 88%, #227b6c 100%);
}
.syna-card--tense .syna-card__head {
  /* Не находка QA (там мерили только гармоничную шапку), но тот же дефект:
     светлые стопы #bc336c и #d2496e давали под белым текстом 4.2:1 в верхнем
     процентиле заливки при пороге 4.5. Затемнены ровно настолько, чтобы
     пройти — крайние стопы и так проходили и не тронуты. */
  --syna-fill: linear-gradient(90deg,
    #ad2c62 0%, #a41d52 30%, #bb3d60 50%, #9e184c 70%, #920e40 100%);
}
/* Светло-сиреневая заливка — единственная, на которой белый текст не читается:
   по макету он тёмный. Ось градиента диагональная (тёмный угол — верхний
   правый), поэтому 225deg. */
.syna-card--mirrored .syna-card__head {
  --syna-fill: linear-gradient(225deg, #c7bbd4 0%, #dccfea 45%, #eae1f3 100%);
  color: var(--syn-headline);
}

.syna-card__body {
  padding: 24px;
  background: var(--syn-bg);
  border: 1px solid var(--syn-border);
  border-top: none;
  border-radius: 0 0 var(--syn-r) var(--syn-r);
}

/* Метка типа аспекта — по центру, цветом типа. */
.syna-kind {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
}
.syna-card--harmonious .syna-kind { color: var(--syn-good-ink); }
.syna-card--tense .syna-kind { color: var(--syn-bad); }
.syna-card--mirrored .syna-kind { color: var(--syn-primary); }

/* Пояснение только у одинакового аспекта: две строки по центру. Ширина
   подобрана по макету — она и задаёт перенос после «что говорит». */
.syna-note {
  max-width: 420px;
  margin: 4px auto 0;
  font-size: 16px;
  line-height: 1.4;
  color: var(--syn-text-2);
  text-align: center;
  text-wrap: balance;
}

/* Текст интерпретации: по левому краю, колонка 700 — как в макете. */
.syna-text {
  max-width: 700px;
  margin: 12px 0 0;
  font-size: 16px;
  line-height: 1.4;
  color: var(--syn-text);
  text-wrap: pretty;
}

/* Сноска про вынесенные наверх аспекты — под списком карточек, тем же
   отступом, что и между карточками: она относится ко всему списку, а не к
   последней из них. */
.syna-hoisted { margin: 16px 0 0; }

@media (max-width: 640px) {
  /* Шапка перестаёт быть однострочной: высота растёт, кегль мельче. */
  .syna-card__head { padding: 14px 16px; font-size: 15px; }
  .syna-card__body { padding: 16px; }
}

/* ─── «Общий вывод» (partials/synastry_general.html, префикс .syng-) ────────
   Наш блок, в макете его нет (README «Принятые решения», п.7). Один H4,
   лид-абзац и список карточек-плиток в одну колонку — .syn-card--soft уже
   даёт лиловую заливку/скругление/паддинг, здесь только межэлементные
   отступы. */

.syng-intro { margin-top: 16px; }

/* Фолбэк-плитка (когда заметок нет вовсе) осталась прежней. */
.syng-line {
  font-size: 16px;
  line-height: 1.4;
  margin-top: 24px;
}

/* ── Заметки на полях ── */

/* Две колонки: зелёная — что даётся легко, голубая — всё остальное. На узком
   экране складываются в одну, порядок сохраняется. */
.syng-notes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 24px;
}
@media (max-width: 720px) {
  .syng-notes { grid-template-columns: 1fr; gap: 16px; }
}

/* Лист бумаги в линейку: горизонтальные линии — repeating-linear-gradient,
   поверх них полупрозрачная заливка колонки. Именно поэтому заливка задана
   через rgb(... / %), а не плотным цветом: линовка должна просвечивать, иначе
   «бумага» превращается в обычную плитку. */
.syng-col {
  position: relative;
  padding: 20px 22px 22px;
  border-radius: var(--syn-r);
  background-color: var(--syn-paper);
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0 27px,
    var(--syn-paper-rule) 27px 28px
  );
  box-shadow: 0 2px 10px rgb(46 26 71 / 8%);
}

/* Цветная кромка слева — как поля тетради, отчёркнутые карандашом. */
.syng-col::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  border-radius: var(--syn-r) 0 0 var(--syn-r);
}
.syng-col--good::before  { background: var(--syn-note-good-edge); }
.syng-col--other::before { background: var(--syn-note-other-edge); }

/* Полупрозрачная заливка поверх линовки — отдельным слоем, чтобы не гасить
   линии и не трогать читаемость текста. */
.syng-col::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--syn-r);
  pointer-events: none;
}
.syng-col--good::after  { background: var(--syn-note-good); }
.syng-col--other::after { background: var(--syn-note-other); }
.syng-col > * { position: relative; z-index: 1; }

/* Заголовок колонки — рукописным Caveat: он и даёт ощущение, что человек
   надписал колонки сам. Сами заметки остаются Manrope: рукописный шрифт на
   длинных строках читается заметно хуже, а это содержательный текст. */
.syng-col__title {
  font-family: 'Caveat', 'Segoe Script', cursive;
  font-size: 26px;
  line-height: 1.1;
  margin: 0 0 14px;
  transform: rotate(-1.2deg);
  transform-origin: left center;
}
.syng-col--good .syng-col__title  { color: var(--syn-note-good-ink); }
.syng-col--other .syng-col__title { color: var(--syn-note-other-ink); }

.syng-note-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Маркер — не буллет, а «галочка/стрелка от руки»: отчёркнутая мысль. */
.syng-note {
  position: relative;
  padding-left: 26px;
  font-size: 15.5px;
  line-height: 1.75;   /* под шаг линовки: 28px при 15.5px кегле */
  color: var(--syn-text);
}
.syng-note::before {
  position: absolute;
  left: 0;
  font-family: 'Caveat', 'Segoe Script', cursive;
  font-size: 22px;
  line-height: 1.2;
}
.syng-col--good .syng-note::before {
  content: "✓";
  color: var(--syn-note-good-ink);
}
.syng-col--other .syng-note::before {
  content: "→";
  color: var(--syn-note-other-ink);
}

.syng-col__empty {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--syn-text-2);
  font-style: italic;
}

@media (max-width: 640px) {
  .syng-col { padding: 18px 18px 20px; }
  .syng-col__title { font-size: 23px; }
}

/* ─── «Диаграмма совместимости в паре» (partials/synastry_diagram.html,
       префикс .synd-) ─────────────────────────────────────────────────────
   Секция целиком сидит на лиловой подложке (base/card-background — тот же
   --syn-card, что и у .syn-card--soft); аккордеон внутри остаётся белым —
   это уже даёт .syn-acc-item сам по себе, поэтому .syn-acc--soft здесь не
   добавляется (иначе строки слились бы с фоном панели). */

.synd-panel {
  background: var(--syn-card);
  border-radius: var(--syn-r);
  padding: 32px;
}
@media (max-width: 640px) {
  .synd-panel { padding: 20px 16px; }
}

.synd-lead { margin-top: 16px; }

.synd-list { margin-top: 32px; }
@media (max-width: 640px) {
  .synd-list { margin-top: 24px; }
}

/* Шапка строки аккордеона: процент фиолетовым и потяжелее, название сферы —
   стандартным весом summary (700, цвет headline — задаёт фундамент, здесь
   переопределять нечего). flex/min-width — чтобы длинное название сферы
   переносилось само, а не толкало круглую +/× кнопку за край на мобилке. */
.synd-percent {
  flex: 0 0 auto;
  color: var(--syn-primary);
  font-weight: 800;
}
.synd-name {
  flex: 1 1 auto;
  min-width: 0;
}

/* ─── «Аспекты, которые определяют ваши отношения»
       (partials/synastry_top_aspects.html, префикс .synm-) ─────────────────
   Наш блок, в макете его нет. Полотно результата залито --syn-card, поэтому
   строки списка белые с бордером — тот же приём, что у .synx-ratio и
   .syng-line (см. CLAUDE.md, раздел «Синастрия»): лиловая плитка на лиловом
   полотне не читалась бы как отдельная карточка.                          */

.synm-lead { margin-top: 16px; }

/* Нумерация — счётчиком, а не маркерами <ol>: цифра рисуется кружком в углу
   карточки, родной маркер такого не умеет. list-style снят, номер идёт через
   counter() в ::before. Счётчик назван по префиксу блока (`synm`): `synt` в
   этом файле принадлежит переключателю сфер, и одноимённый счётчик читался
   бы как его. */
.synm-list {
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
  counter-reset: synm;
  display: grid;
  gap: 16px;
}

.synm-item {
  position: relative;
  counter-increment: synm;
  background: var(--syn-bg);
  border: 1px solid var(--syn-border);
  border-left: 4px solid var(--syn-border);
  border-radius: var(--syn-r);
  padding: 20px 20px 20px 64px;
}

/* Цветная кромка слева — тот же язык, что у карточек аспектов: гармоничный,
   напряжённый, одинаковый. Зелёный берётся в варианте --syn-good-ink:
   #76ff93 на белом не виден. */
.synm-item--harmonious { border-left-color: var(--syn-good-ink); }
.synm-item--tense      { border-left-color: var(--syn-bad); }
.synm-item--mirrored   { border-left-color: var(--syn-secondary); }

.synm-item::before {
  content: counter(synm);
  position: absolute;
  left: 20px;
  top: 20px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--syn-font-head);
  font-weight: 800;
  font-size: 14px;
  color: #fff;
  background: var(--syn-primary);
}

.synm-name {
  font-family: var(--syn-font-head);
  font-weight: 800;
  font-size: 19px;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--syn-headline);
  margin: 0;
  text-wrap: balance;
}

.synm-title {
  font-family: var(--syn-font-head);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.3;
  color: var(--syn-headline);
  margin: 0;
}

/* Когда имя есть, формула становится подписью под ним. */
.synm-title--sub {
  font-weight: 600;
  font-size: 13.5px;
  color: var(--syn-text-2);
  margin-top: 4px;
}

.synm-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  margin: 8px 0 0;
  font-size: 14px;
  line-height: 1.4;
  color: var(--syn-text-2);
}

.synm-kind { font-weight: 700; }
.synm-kind--harmonious { color: var(--syn-good-ink); }
.synm-kind--tense      { color: var(--syn-bad); }
.synm-kind--mirrored   { color: var(--syn-primary); }

.synm-sphere {
  padding: 2px 10px;
  border-radius: var(--syn-r-pill);
  background: var(--syn-card-high);
  color: var(--syn-text-2);
}

/* Направление — ровно тот вопрос «кто на кого влияет», ради которого
   колонки в скоринге и разделены. Стрелка не должна отрываться от имён при
   переносе, поэтому строка не ломается внутри. */
.synm-dir { white-space: nowrap; }
.synm-dir__arrow { color: var(--syn-primary); font-weight: 700; }

.synm-text { margin: 12px 0 0; }

@media (max-width: 640px) {
  .synm-item { padding: 16px 16px 16px 16px; }
  /* На узком экране кружок с номером уезжает из-под текста в строку над
     заголовком: 64px отступа слева съедали бы треть ширины карточки. */
  .synm-item::before { position: static; margin-bottom: 8px; }
  .synm-name { font-size: 17px; }
  .synm-title { font-size: 16px; }
  .synm-title--sub { font-size: 12.5px; }
  .synm-list { gap: 12px; }
}

/* ─── Дисклеймер в конце страницы результата ─────────────────────────────
   Сноска на всю ширину колонки, но с меньшим верхним отступом, чем у обычной
   секции: она относится ко всему, что выше, и не должна выглядеть отдельным
   разделом.                                                               */
.syn-disclaimer { margin-top: 48px; }
.syn-disclaimer .syn-footnote { max-width: 68ch; }
@media (max-width: 640px) { .syn-disclaimer { margin-top: 32px; } }

/* ─── Замок регистрации (synastry_reg_lock.html, lock == "reg") ───────────
   Единственный блок под шапкой у анонима: карточка на полотне результата,
   центрированная, с обычной primary-кнопкой синастрии. `.num-lock-cta` —
   общее имя кнопки лока для reg_popup.js, визуал берёт .syn-btn.          */
.synk-lock {
  margin-top: 48px;
  padding: 40px 24px;
  background: var(--syn-bg);
  border: 1px dashed var(--syn-primary-soft);
  border-radius: var(--syn-r-lg);
  text-align: center;
}
.synk-lock__title { margin: 0 0 12px; text-wrap: balance; }
/* --syn-text-low (#aba8bd on #ffffff) is ~2.4:1 — under WCAG AA 4.5:1 for body
   text explaining what's behind the lock. --syn-text at .72 opacity keeps the
   same visual weight while staying readable (brief's named fallback). */
.synk-lock__text { max-width: 56ch; margin: 0 auto 24px; color: var(--syn-text); opacity: .72; }
@media (max-width: 640px) {
  .synk-lock { margin-top: 32px; padding: 28px 16px; }
}
