/* ============================================================
   ЛЕНДИНГ: фото в Hero, портрет основателя, аватарка, тизер материалов
   ------------------------------------------------------------
   Подключается только на главной, строго ПОСЛЕ site.css
   (templates/landing/index.html, блок extra_css).

   Файл содержит:
     1) новые блоки — .hero-media, «Об основателе», тизер материалов;
     2) точечные переопределения правил site.css (Hero, .avatar).
   Переопределения живут здесь намеренно: site.css принадлежит другому
   агенту, править его из этой задачи нельзя. Селекторы совпадают
   с исходными, поэтому выигрывают только за счёт порядка подключения —
   специфичность не накручена, и правила легко перенести обратно.

   Расчёты контраста, стопы скрима и геометрия — specs/design-hero.md.
   Новых цветов и шрифтов не введено: всё из :root в site.css.
   ============================================================ */

/* ============================================================
   HERO
   ============================================================ */
.hero{
  position: relative;
  isolation: isolate;
  overflow: clip;                       /* подрезает scale-анимацию фото */
  /* Фолбэк: если фото не пришло — ровно прежний кремовый вид.
     Шорткат `background` намеренно: он гасит градиент из site.css. */
  background: var(--s-cream);
  padding-block: var(--sp-8) 0;         /* 40px сверху, низ закрывает фото-полоса */

  /* Точка фокуса кадра. Объявляется на .hero, а не на .hero-media:
     иначе переопределения по брейкпоинтам не долетят до вложенных правил. */
  --hero-focus: 50% 42%;
}

/* ВАЖНО: --c-muted (#6B6B6B) в Hero запрещён — над скримом даёт 4.57:1,
   то есть порог 4.5 без запаса. Переведено на --c-muted-strong (#5F5F5F): 5.48:1
   над фото и 5.92:1 на чистом креме. Новых цветов не вводим. */
.hero-sub{ color: var(--c-muted-strong); }
.hero-note{ color: var(--c-muted-strong); }
.hero-note .icon{ stroke: var(--c-muted-strong); }

/* Усиленный фокус: в нескримленной зоне обводка 3px #1C1C1C теряется на фото.
   Белое кольцо добавляется к глобальному outline, новых цветов не вводит. */
.hero a:focus-visible,
.hero button:focus-visible{ box-shadow: 0 0 0 6px rgba(255,255,255,.85); }

/* ------------------------------------------------------------
   ФОТО: < 1024px — полоса во всю ширину под текстом
   ------------------------------------------------------------ */
.hero-media{
  position: relative;
  margin-top: var(--sp-7);              /* 32px */
  width: 100%;
  height: clamp(220px, 64vw, 380px);    /* 375 → 240, 414 → 265, 768 → 380 */
  overflow: hidden;
  pointer-events: none;

  /* LQIP из assets_src/derivatives.json (24px JPEG, ~700 байт).
     Лежит под <img>; снимать скриптом не нужно — фото непрозрачно,
     а кроп совпадает, потому что фокус общий (--hero-focus).
     blur() не применяем: апскейл 24px и так даёт мягкое пятно,
     а фильтр создал бы лишний композитный слой прямо под LCP-элементом. */
  background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABQODxIPDRQSEBIXFRQYHjIhHhwcHj0sLiQySUBMS0dARkVQWnNiUFVtVkVGZIhlbXd7gYKBTmCNl4x9lnN+gXz/2wBDARUXFx4aHjshITt8U0ZTfHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHz/wAARCAAQABgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDrGmX+8PwrIvr5nDIQNuat3c5juUjBwjDnArONrbuju7ncCerYrNu+iNErasPNENmzyAjHtRVdrueFiuzzIRxleeKKzuVZn//Z");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: var(--hero-focus);
}
.hero-media picture{ display: block; width: 100%; height: 100%; }
.hero-photo{
  display: block; width: 100%; height: 100%;
  object-fit: cover;
  object-position: var(--hero-focus);   /* всегда синхронно с LQIP-подложкой */
}

/* На мобильном скрим НЕ отвечает за контраст: текст лежит на чистом креме,
   фото физически ниже. Его задача — мягкий выход нижней кромки в белую #about. */
.hero-media::after{
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image: linear-gradient(0deg,
    rgba(255,255,255,.55)   0%,
    rgba(255,255,255,.18)   7%,
    rgba(255,255,255,0)    16%);
}

@media (min-width: 768px){
  .hero{ padding-block: var(--sp-10) 0; }   /* 64px сверху */
  .hero-media{ margin-top: var(--sp-8); }   /* 40px */
}

/* ------------------------------------------------------------
   ФОТО: >= 1024px — фон всей секции + боковой скрим
   ------------------------------------------------------------ */
@media (min-width: 1024px){
  .hero{
    display: grid; align-content: center;
    min-height: clamp(580px, 48vw, 720px);
    padding-block: var(--sp-11) var(--sp-12);   /* 80 / 96 */
    --hero-focus: 50% 38%;
  }
  .hero-grid{ position: relative; z-index: 1; }
  .hero-media{
    position: absolute; inset: 0; z-index: 0;
    margin-top: 0; height: auto;
  }

  /* Три слоя, первый в списке рисуется поверх остальных:
     1) верх — растворяет кромку под липкой белой .site-header;
     2) низ  — стык с секцией #about (она на --s-page #FFFFFF);
     3) бок  — ЕДИНСТВЕННЫЙ слой, отвечающий за контраст текста.

     ПРАВИЛО, КОТОРОЕ НЕЛЬЗЯ НАРУШАТЬ:
     плато alpha = 0.96 (стоп «56%») обязано перекрывать всю колонку копи
     плюс запас >= 24px (по расчёту запас 53…123px на 1024…1920).
     Тогда худший случай контраста не зависит от того, какое фото загружено:
     даже на абсолютно чёрном пикселе --c-ink держит 14.48:1,
     --c-muted-strong — 5.43:1. Именно поэтому .hero-copy{ max-width: 560px }
     в site.css трогать нельзя: на нём держится вся эта геометрия. */
  .hero-media::after{
    background-image:
      linear-gradient(180deg,
        rgba(255,255,255,.72)   0,
        rgba(255,255,255,0)  120px),
      linear-gradient(0deg,
        rgba(255,255,255,.55)   0%,
        rgba(255,255,255,0)    15%),
      linear-gradient(90deg,
        rgba(250,246,238,.97)   0%,
        rgba(250,246,238,.96)  56%,
        rgba(250,246,238,.90)  66%,
        rgba(250,246,238,.44)  78%,
        rgba(250,246,238,.12)  87%,
        rgba(250,246,238,0)    94%);
  }
}
@media (min-width: 1600px){
  /* На широких экранах cover масштабирует кадр по ширине и съедает высоту.
     Поднимаем фокус, чтобы рамка с цитатой не резалась сверху. */
  .hero{ --hero-focus: 50% 30%; }
}

/* ------------------------------------------------------------
   ВИДЕО-ФОН (SPEC-preview §11)
   ------------------------------------------------------------
   Слой лежит МЕЖДУ фотографией и скримом:
     .hero-photo  — статический поток (рисуется первым);
     .hero-video  — position: absolute (позиционированный элемент
                    рисуется поверх статических блоков);
     .hero-media::after — тоже позиционированный и идёт ниже по дереву,
                    поэтому скрим остаётся выше видео. Порядок держится
                    без z-index-гонки: ни одному слою число не назначено.

   До события `playing` слой полностью прозрачен — под ним видно фото.
   Это и есть фолбэк: ролик не загрузился, кодек не поддержан, JS выключен,
   экран уже, чем 1024 — первый экран выглядит ровно как раньше.

   Контраст проверен на 5 кадрах ролика (0,2 / 2 / 4 / 6 / 8,4 с) поверх
   боковой шторы: худший случай --c-ink 14,64:1 и --c-muted-strong 5,49:1
   на 1024…1920. Самый светлый пиксель ролика — RGB(245,239,226), у фото
   RGB(255,255,255), то есть видео ТЕМНЕЕ фото. Скрим усиливать не нужно.
   ------------------------------------------------------------ */
.hero-video{
  position: absolute; inset: 0;
  display: none;                          /* до 1024px тега в раскладке нет вовсе */
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: var(--hero-focus);     /* синхронно с фото и LQIP */
  opacity: 0;
  pointer-events: none;
}
@media (min-width: 1024px){
  .hero-video{ display: block; }
}
/* Класс ставит site.js по событию `playing`: до первого кадра подмены не видно */
.hero-video.is-playing{ opacity: 1; }
@media (prefers-reduced-motion: no-preference){
  .hero-video{ transition: opacity 600ms var(--ease-standard); }
}

/* Кнопка паузы убрана по просьбе владельца — стилей у неё больше нет. */
@media (forced-colors: active), print{
  .hero-video{ display: none; }
}

/* ------------------------------------------------------------
   Моушн фото: только transform, без opacity
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: no-preference){
  /* Анимируем .hero-media целиком, а не <img>: LQIP-подложка и фото
     едут одним кадром, подмена заглушки не даёт рассинхрона.
     Прозрачность не трогаем: Chrome не засчитывает LCP элементу
     с нулевой прозрачностью, фейд отодвинул бы LCP на 560–900 мс.
     Правило не завёрнуто в html.js намеренно — без JS оно тоже отработает,
     и фото никогда не залипнет в увеличенном состоянии. */
  .hero-media{ animation: hero-media-settle 900ms var(--ease-out) both; }
  @keyframes hero-media-settle{
    from{ transform: scale(1.035); }
    to  { transform: none; }
  }
}

/* ------------------------------------------------------------
   Краевые режимы
   ------------------------------------------------------------ */
/* Windows High Contrast: CSS-градиенты вырезаются, а <img> остаётся —
   без этого правила текст лёг бы на голое фото. */
@media (forced-colors: active){
  .hero-media{ display: none; }
  .hero{ min-height: 0; background: Canvas; }
}

/* Повышенный контраст: плато до 1.0, старт растворения сдвинут вправо —
   фото остаётся, но только в правой трети. */
@media (prefers-contrast: more) and (min-width: 1024px){
  .hero-media::after{
    background-image:
      linear-gradient(180deg, rgba(255,255,255,.80) 0, rgba(255,255,255,0) 120px),
      linear-gradient(0deg,   rgba(255,255,255,.60) 0%, rgba(255,255,255,0) 15%),
      linear-gradient(90deg,
        rgba(250,246,238,1)    0%,
        rgba(250,246,238,1)   62%,
        rgba(250,246,238,.96) 72%,
        rgba(250,246,238,.60) 82%,
        rgba(250,246,238,.24) 90%,
        rgba(250,246,238,0)   96%);
  }
}

@media print{
  .hero-media{ display: none; }
  .hero{ min-height: 0; }
}

/* ============================================================
   ОБ ОСНОВАТЕЛЕ
   ============================================================ */
.founder{ display: grid; gap: var(--sp-7); }

.founder-media{
  width: min(72vw, 320px);
  margin-inline: auto;                    /* мобильный: портрет по центру над текстом */
  aspect-ratio: 4 / 5;
  border-radius: var(--r-xl);
  overflow: hidden;
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-md);
  /* LQIP портрета — тот же приём, что у Hero */
  background-image: url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABQODxIPDRQSEBIXFRQYHjIhHhwcHj0sLiQySUBMS0dARkVQWnNiUFVtVkVGZIhlbXd7gYKBTmCNl4x9lnN+gXz/2wBDARUXFx4aHjshITt8U0ZTfHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHz/wAARCAAeABgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDrRxWdeXrrKyIxQLxuAzk1ann8oAAZY9BWJOk0hl24V2J/Cs5TV7Fxj1NfTZ3uLbdLywOM+tFQ6QVjt1i5yO/rRVxkmtCWrMdO/wDpaDsFJqFdrTKPXGaqavLNbyNJGwI25ww6VXs76S7ijnHy4PIPtXNOLvd9zWL6GtbkC7Kr0DYoqLT2DKJh1PJzRV0dEyZ7n//Z");
  background-size: cover;
  background-position: 50% 30%;           /* синхронно с object-position */
}
.founder-media picture{ display: block; width: 100%; height: 100%; }
.founder-photo{
  display: block; width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 30%;               /* кроп по лицу и плечам */
}

.founder-lead{
  margin-top: 16px;
  font-size: var(--fs-lead);
  color: var(--c-ink);
  max-width: 56ch;
}
.founder-text{
  margin-top: 12px;
  color: var(--c-muted-strong);           /* 6.39:1 на белом */
  max-width: 56ch;
  white-space: pre-line;                  /* абзацы из админки не слипаются */
}
.founder-badge{
  margin-top: var(--sp-5);
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--s-cream);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 8px 14px;
  font-weight: 500; font-size: 14px;
  color: var(--c-muted-strong);
}
.founder-badge .icon{ width: 16px; height: 16px; stroke: var(--c-muted-strong); flex-shrink: 0; }

@media (min-width: 768px){
  .founder{
    grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    gap: var(--sp-9);
    /* Текст выравнивается по верхней кромке портрета, а не по центру
       (findings #67): при `center` на 1440 сверху и снизу от текста
       оставалось по ~103px пустоты, и правая колонка читалась как недовёрстанная. */
    align-items: start;
  }
  .founder-media{ width: 100%; margin-inline: 0; }
  /* Заголовок секции стоит вплотную к верхнему краю фото */
  .founder-copy > .section-head{ margin-top: -4px; }
}
@media (min-width: 1024px){
  .founder{ grid-template-columns: minmax(0, 400px) minmax(0, 1fr); gap: var(--sp-10); }
}

/* ============================================================
   АВАТАРКА В КОНТАКТАХ (переопределение site.css)
   ------------------------------------------------------------
   Вместо кружка с инициалами — фотография. Оба кольца (белый кант
   и тонкая жёлтая обводка) сделаны через box-shadow: размер бокса
   не меняется, сдвига макета нет. `border: 0` гасит кант из site.css.
   ============================================================ */
.avatar{
  position: relative;
  display: block;
  overflow: hidden;                       /* кроп фото по кругу */
  border: 0;
  box-shadow:
    0 0 0 4px #FFFFFF,
    0 0 0 6px var(--c-brand),
    var(--shadow-md);
}
.avatar picture{ display: block; width: 100%; height: 100%; }
.avatar img{ display: block; width: 100%; height: 100%; object-fit: cover; }

/* ============================================================
   ЦЕНЫ: необязательные дополнения
   ------------------------------------------------------------
   В эталоне их нет — правила срабатывают, только если администратор
   заполнил пункты тарифа или выделил карточку.
   ============================================================ */
.price-features{
  margin-top: 14px; display: grid; gap: 6px;
  font-size: var(--fs-small); color: var(--c-ink-2);
}
.price-features li{ position: relative; padding-left: 18px; }
.price-features li::before{
  content: ""; position: absolute; left: 0; top: .55em;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--c-brand);
}
.price-card--hl{ border: 2px solid var(--c-brand); padding: 23px; }

/* ============================================================
   ТИЗЕР МАТЕРИАЛОВ
   ------------------------------------------------------------
   Классы свои (.teaser-*): компоненты страницы материалов живут
   в materials.css, который на лендинге не подключается.
   ============================================================ */
.teaser-lead{
  margin: -8px auto 24px; text-align: center;
  font-size: var(--fs-lead); color: var(--c-muted-strong);
  max-width: var(--measure);
}

.teaser-grid{ display: grid; gap: 16px; list-style: none; }
@media (min-width: 640px){
  .teaser-grid{ grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px){
  .teaser-grid{ grid-template-columns: repeat(3, 1fr); gap: 20px; }
}

.teaser-card{
  height: 100%;
  /* `stretch`, а не `start`: тело карточки должно занять всю высоту, иначе
     мета-строку некуда прижимать и в ряду она гуляет по вертикали (SPEC-preview §10) */
  display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 16px; align-items: stretch;
  background: #FFFFFF; border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm); padding: 16px;
}
/* Обложка сохраняет соотношение 3:4 и не растягивается вслед за телом */
.teaser-card > .teaser-cover{ align-self: start; }
.teaser-body{ display: flex; flex-direction: column; min-width: 0; }
@media (min-width: 1024px){
  .teaser-card{ grid-template-columns: 96px minmax(0, 1fr); padding: 18px; }
}

.teaser-cover{
  display: block; width: 100%; aspect-ratio: 3 / 4;
  border-radius: var(--r-md); overflow: hidden;
  object-fit: cover;
}
/* Заглушка обложки: ноль запросов и ноль байт. Тон приходит из серии
   инлайновой переменной --teaser-acc; все шесть тонов пастельные,
   текст --c-ink даёт на них заведомо больше 4.5:1. */
.teaser-cover--ph{
  position: relative; display: grid; align-items: end;
  padding: 10px 10px 12px 16px;
  background: var(--teaser-acc, var(--s-cream));
}
.teaser-cover-spine{
  position: absolute; left: 0; top: 0; bottom: 0; width: 7px;
  background: rgba(28,28,28,.12);
}
.teaser-cover-title{
  font-family: var(--font-serif); font-weight: 600;
  font-size: 12px; line-height: 1.25; color: var(--c-ink);
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden;
}

.teaser-badge{
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--s-info); color: var(--c-ink);
  border-radius: var(--r-pill); padding: 4px 10px;
  font-weight: 700; font-size: 12px; line-height: 1.2;
}
.teaser-badge .icon{ width: 14px; height: 14px; stroke: var(--c-note); flex-shrink: 0; }

/* Заголовок ограничен двумя строками — иначе карточки в ряду «прыгают»
   по высоте и мета-строка расходится (SPEC-preview §10) */
.teaser-title{
  margin-top: 8px; font-size: 17px; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.teaser-title:first-child{ margin-top: 0; }
.teaser-stretch{ text-decoration: none; }
/* Ссылка на карточке одна: её псевдоэлемент растянут на всю площадь,
   поэтому кликается вся карточка, а таб-стоп остаётся один. */
.teaser-stretch::after{
  content: ""; position: absolute; inset: 0; border-radius: inherit;
}
.teaser-stretch:focus-visible{ outline: none; }
.teaser-stretch:focus-visible::after{
  outline: 3px solid var(--focus-color); outline-offset: 2px;
}

/* Мета-строка прижата к низу карточки: во всём ряду она встаёт на одну линию.
   `padding-top` держит воздух от чипа/заголовка не меньше 20px (--sp-5) даже
   в самой короткой карточке — это и есть «слипшиеся чипы» из просьбы клиента. */
.teaser-meta{
  margin-top: auto; padding-top: var(--sp-5);
  display: flex; align-items: center; gap: 6px;
  font-size: 14px; color: var(--c-muted-strong);
}
.teaser-meta .icon{ width: 16px; height: 16px; stroke: var(--c-muted-strong); flex-shrink: 0; }

/* Блок скачивания (SPEC-preview §3). Ряд одинаковой высоты и с файлом,
   и без него — иначе мета-строки соседних карточек разъедутся. */
.teaser-dl-row{ margin-top: var(--sp-3); min-height: 36px; display: flex; align-items: center; }
/* z-index поднимает ссылку над растянутым `::after` заголовка карточки:
   без него клик попадал бы на детальную страницу, а не на файл. */
.teaser-dl{
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 36px; padding: 0 12px; border-radius: var(--r-pill);
  border: 1.5px solid var(--c-brand); background: #FFFFFF;
  font-weight: 600; font-size: 14px; color: var(--c-ink); text-decoration: none;
  transition: background-color 180ms var(--ease-standard);
}
.teaser-dl .icon{
  width: 16px; height: 16px; flex-shrink: 0;
  fill: none; stroke: var(--c-ink); stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
@media (hover: hover) and (pointer: fine){
  .teaser-dl:hover{ background: var(--s-cream); }
}
.teaser-soon{
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--c-muted-strong);
}
.teaser-soon .icon{ width: 16px; height: 16px; stroke: var(--c-muted-strong); flex-shrink: 0; }

.teaser-action{ margin-top: 24px; display: flex; justify-content: center; }

/* Кнопка-контур. Граница --c-muted (5.33:1 на белом): --line-strong дал бы
   1.42:1 и провалил WCAG 1.4.11. Правила совпадают с описанием компонента
   в specs/design-materials.md §2.1 — когда появится materials.css с тем же
   селектором, дубль отсюда можно убрать. */
.btn--ghost{
  background: #FFFFFF; color: var(--c-ink);
  border: 1.5px solid var(--c-muted);
  box-shadow: none;
}
.btn--ghost::before{ background: var(--s-cream); }
.btn--ghost::after{ box-shadow: var(--shadow-md); }
.btn--ghost .icon{ stroke: var(--c-ink); }
@media (hover: hover) and (pointer: fine){
  .btn--ghost:hover{ border-color: var(--c-ink); }
}

/* ============================================================
   СИММЕТРИЯ КАРТОЧЕК ЛЕНДИНГА (SPEC-preview §10)
   ------------------------------------------------------------
   Высоту карточек в ряду выравнивает сам grid (`align-items: stretch`
   по умолчанию) — с этим на лендинге всё в порядке и раньше.
   Ломалось другое: содержимое прижато к верху, поэтому последние строки
   карточек — цена/сноска у тарифов, подпись автора у отзывов, мета-строка
   у тизера — стояли на разной высоте, и ряд читался как «кривой».

   Приём один на все блоки: карточка становится flex-колонкой, а её
   замыкающий элемент получает `margin-top: auto`. Тогда нижние строки
   ложатся на одну горизонталь при любой длине текста.

   Правила живут здесь, а не в site.css: тот файл принадлежит другому
   агенту, а hero.css подключается на лендинге строго после него.
   Селекторы совпадают с исходными — специфичность не накручена.
   ============================================================ */

/* Тарифы: сноска под ценой прижата к низу, её верхняя линейка
   образует общую горизонталь у всех трёх карточек ряда */
.price-card{ display: flex; flex-direction: column; }
.price-card .price-note{ margin-top: auto; }

/* Отзывы: подпись автора — на одной линии во всех карточках.
   `padding-top` уже есть в site.css, воздух над подписью не меньше 14px. */
.review{ display: flex; flex-direction: column; }
.review figcaption{ margin-top: auto; }

/* Сетка отзывов рассчитана на три плитки, третьей была карточка Яндекс Карт.
   Без заполненного `maps_url` она больше не выводится (findings #64), и в ряду
   оставалась дыра справа. Если отзывов ровно два — раскладываем их на две
   колонки во всю ширину. `:has` не поддержан — остаётся прежний вид, не хуже. */
@media (min-width: 1024px){
  .reviews-grid:has(> :nth-child(2):last-child){ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Плашки под ценами и карточки «О школе»: содержимое сверху, но сами
   карточки обязаны быть равной высоты — фиксируем явно, чтобы правило
   не зависело от значения align-items по умолчанию */
.pricing-extras{ align-items: stretch; }
.extra-card{ height: 100%; }
.about-item{ display: flex; flex-direction: column; }

/* Шаги на десктопе: карточки уже растянуты сеткой, но текст внутри
   центрируется по контенту — прижимаем описание к общей верхней сетке,
   чтобы заголовки шагов стояли на одной базовой линии */
@media (min-width: 1024px){
  .step{ height: 100%; justify-content: flex-start; }
  .step-body{ flex: 1; }
}

/* ============================================================
   НЕАКТИВНЫЕ ССЫЛКИ (findings #17, #31, #63, #65)
   ------------------------------------------------------------
   Правило одно на весь лендинг: то, что не кликается, не должно
   выглядеть кликабельным. Приглушённая пилюля + видимая подпись
   «скоро» вместо одного лишь sr-only-пояснения.
   ============================================================ */
/* `.pill--muted` описан в forms.css (страница «Спасибо»); там же серая
   заливка. Здесь добавляем то, чего в нём нет: гашение hover-подъёма
   и обесцвечивание фирменного знака MAX — у него собственные заливки,
   и `fill` из forms.css до фигур внутри символа не долетает. */
.pill--muted{ box-shadow: none; }
.pill--muted svg{ filter: grayscale(1); opacity: .75; }
@media (hover: hover) and (pointer: fine){
  .pill--muted:hover{ transform: none; }
}
.pill--muted:active{ transform: none; }
.pill-soon{
  font-weight: 500; font-size: 12px; letter-spacing: var(--ls-caps);
  text-transform: uppercase; color: var(--c-muted-strong);
}

/* ============================================================
   ФОРМА ЗАЯВКИ В КОНТАКТАХ
   ------------------------------------------------------------
   Сама форма стилизуется агентом заявок; здесь только отбивка
   от карточки контактов и заголовок над ней.
   ============================================================ */
/* Заголовок над формой (findings #9, CTA-COPY §1 строка 8). Отбивка та же,
   что была у формы без заголовка, — высота секции не меняется.
   Оформление берётся у общего `.section-head`, своих правил не заводим. */
.contacts-inner + .form-head{ margin-top: var(--sp-8); }
@media (min-width: 768px){
  .contacts-inner + .form-head{ margin-top: var(--sp-9); }
}
.contacts-inner + .form-wrap{ margin-top: var(--sp-8); }
@media (min-width: 768px){
  .contacts-inner + .form-wrap{ margin-top: var(--sp-9); }
}
