/* ==========================================================================
   03 · Компоненты
   Только то, что реально используется на странице: новый вариант добавляем,
   когда его требует конкретный блок, а не «на будущее».
   Каталог: spec/03-components.md
   ========================================================================== */

@layer components {
  /* ===== 03.1 · Logo — эмблема Канку + название в две строки ========== */

  .logo {
    display: grid; /* знак занимает обе строки, надписи стоят во второй колонке */
    grid-template-columns: auto auto;
    align-items: center;
    column-gap: var(--sp-2);
    row-gap: 2px;
    color: var(--c-red); /* перекрашивает эмблему через fill="currentColor" */
    text-decoration: none;
  }

  .logo__mark {
    grid-row: span 2;
    width: 46px; /* 38 × 1,2 ≈ +20 % */
    height: 46px;
  }

  .logo__name {
    font-family: var(--f-display);
    font-weight: 600;
    font-size: var(--fs-body);
    line-height: 1.2;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--c-on-dark); /* обе строки белые */
  }

  /* ===== 03.2 · Header — закреплённая шапка ============================ */

  .header {
    position: sticky; /* не прокручивается вместе с контентом */
    top: 0;
    z-index: var(--z-header);
    background: var(--c-bg-dark);
    --focus-ring: var(--c-on-dark); /* на чёрном фоне кольцо фокуса белое */
    transition: box-shadow var(--t-base) var(--ease);
  }

  .header.is-scrolled {
    box-shadow: var(--sh-header);
  }

  .header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    min-height: var(--header-h);
    padding-inline: calc(var(--pad-x) / 2); /* у шапки отступы вдвое меньше контейнерных */
  }

  /* ===== 03.3 · Button — красная кнопка действия ======================
     Белый текст на --c-red-cta = 5,66:1 ✓ (на чистом --c-red было бы 4,03:1) */

  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-inline: var(--sp-4);
    min-height: var(--tap);
    font-family: var(--f-display);
    font-weight: 600;
    font-size: var(--fs-sm);
    line-height: 1;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--c-white);
    background: var(--c-red-cta);
    border: 1px solid var(--c-red-cta);
    border-radius: var(--radius-sm);
    text-decoration: none;
    cursor: pointer;
    transition:
      background-color var(--t-base) var(--ease),
      border-color var(--t-base) var(--ease);
  }

  .btn:hover {
    background: var(--c-red-dark);
    border-color: var(--c-red-dark);
  }

  .btn:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
  }

  /* Компактная кнопка для шапки: ниже и уже обычной */
  .btn--sm {
    min-height: 36px;
    padding-inline: var(--sp-3);
  }

  /* Прозрачная кнопка: цвет берёт у фона (inherit), поэтому годится и на
     светлом, и на тёмном, а при наведении заливается красным — тот же приём,
     что у иконок карусели. Порядок важен: это правило идёт после .btn:hover,
     иначе фон кнопки на наведении перебивал бы прозрачность. */
  .btn--ghost {
    color: inherit;
    background: none;
    border-color: currentColor; /* цвет обводки — тот же, что у текста */
  }

  .btn--ghost:hover {
    color: var(--c-white);
    background: var(--c-red-cta);
    border-color: var(--c-red-cta);
  }

  /* ===== 03.4 · Hero — первый экран с видео-подложкой =================
     Текст стоит внизу, видео видно в верхней части. Затемнение — градиент
     (`.hero::after`): замер по ролику дал, что в средней зоне яркость доходит
     до 1,0 (белый), поэтому сверху засветка слабая, а под текстом сильная. */

  .hero {
    position: relative;
    display: grid;
    align-content: end;
    min-height: calc(100vh - var(--header-h)); /* для браузеров без svh */
    min-height: calc(100svh - var(--header-h));
    overflow: hidden;
    color: var(--c-on-dark); /* заголовок и текст наследуют белый */
  }

.hero__media {
    position: absolute;
    inset: 0;
    margin-inline: auto; /* видео — колонка контента, а не во всю ширину экрана */
    max-width: var(--w-content);
    width: 100%;
    height: 100%;
    object-fit: cover; /* подложка на всю ширину и высоту блока */
  }

  .hero__inner {
    position: relative; /* выше подложки и засветки */
    z-index: var(--z-base);
    padding-block: var(--sp-12);
  }

  .hero__lead {
    margin-top: var(--sp-4);
  }

  /* ===== 03.5 · Points — три коротких пункта ========================== */

  .points {
    display: grid;
    gap: var(--sp-6);
    margin: var(--sp-8) 0 0;
    padding: 0;
    list-style: none;
  }

  .point {
    padding-inline-start: var(--sp-4);
    border-inline-start: 4px solid var(--c-red); /* единственный акцент, без карточек */
  }

  .point p {
    margin-top: var(--sp-1);
  }

  /* ===== 03.6 · Checklist — список «подходит / не подходит» ==========
     Одна разметка на оба случая: знак — псевдоэлемент, цвет знака — токен.
     Вариант --no гасит текст (--c-ink-2): честная часть блока не должна
     перетягивать внимание на себя, но читаться обязана. */

  .checklist {
    display: grid;
    gap: var(--sp-3);
    margin: var(--sp-6) 0 0;
    padding: 0;
    list-style: none;
  }

  .checklist__item {
    display: grid;
    grid-template-columns: 1.5rem 1fr; /* знак занимает свою колонку — текст выровнен */
    gap: var(--sp-2);
    align-items: start;
  }

  .checklist__item::before {
    content: '✓';
    color: var(--c-red);
    font-weight: 700;
    line-height: var(--lh-body);
    text-align: center;
  }

  .checklist--no .checklist__item {
    color: var(--c-ink-2);
  }

  .checklist--no .checklist__item::before {
    content: '−';
  }

  /* ===== 03.7 · Panel — плашка с выводом ==============================
     Тот же приём, что у .point: коробка + роль текста в одном классе.
     Заголовки внутри панели не ломаются: у h1–h4 свои правила в base.css,
     а наследование всегда проигрывает собственному правилу элемента. */

  .panel {
    margin-top: var(--sp-8);
    padding: var(--sp-5);
    background: var(--c-bg-soft);
    border-inline-start: 4px solid var(--c-red);
    border-radius: var(--radius-md);
    font-family: var(--f-display);
    font-weight: 600;
    font-size: var(--fs-h4);
    line-height: var(--lh-h3);
  }

  /* ===== 03.8 · Note — мелкая сноска ================================= */

  .note {
    margin-top: var(--sp-4);
    font-size: var(--fs-sm);
    line-height: var(--lh-sm);
    color: var(--c-muted);
  }

  /* ===== 03.9 · Carousel — карусель кадров 9:16 =======================
     Прокрутка нативная (scroll-snap): свайп, инерция и клавиатура — от браузера,
     без библиотек. Скрипт только подаёт её дальше по таймеру и останавливается. */

  .carousel {
    position: relative; /* для кнопок поверх кадров */
    margin: var(--sp-10) 0 0;
  }

  .carousel__track {
    display: flex;
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth; /* при prefers-reduced-motion снимается в base.css */
    scrollbar-width: none;
  }

  .carousel__track::-webkit-scrollbar {
    display: none;
  }

  .carousel__slide {
    position: relative; /* чтобы подпись внутри кадра встала по нему */
    flex: 0 0 100%;
    aspect-ratio: 9 / 16;
    scroll-snap-align: center;
  }

  /* Кадр: и картинка, и видео — одним классом */
  .carousel__media {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  .carousel__btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    display: grid;
    place-items: center;
    width: var(--tap);
    height: var(--tap);
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--c-bg-dark) 70%, transparent);
    color: var(--c-on-dark);
    --focus-ring: var(--c-on-dark);
    transition: background-color var(--t-base) var(--ease);
  }

  .carousel__btn:hover {
    background: var(--c-red-cta);
  }

  .carousel__btn svg {
    width: 20px;
    height: 20px;
  }

  .carousel__btn--prev {
    left: var(--sp-3);
  }

  .carousel__btn--next {
    right: var(--sp-3);
  }

  .carousel__btn--prev svg {
    transform: rotate(180deg); /* одна иконка на обе кнопки */
  }

  /* Затемнение снизу — под крупную надпись: то же решение, что в герое.
     Градиент живёт НА КАДРЕ, а не на фигуре: слайды позиционированы
     (position: relative) и поэтому рисуются поверх любого слоя фигуры —
     градиент на .carousel просто оказался бы под картинкой.
     Внутри кадра `::before` идёт после картинки, но до подписи: порядок
     отрисовки — статичный контент → позиционированный ::before → подпись. */
  .carousel__slide::before {
    content: '';
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 50%;
    background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--c-bg-dark) 85%, transparent));
  }

  /* Подпись поверх кадра: крупно, как в герое (`base.css` → `.display`) */
  .carousel__caption {
    position: absolute;
    inset-inline: 0;
    bottom: var(--sp-6);
    padding-inline: var(--sp-4);
    color: var(--c-on-dark);
  }

  /* На широких экранах кадр 9:16 во всю ширину был бы выше страницы:
     ограничиваем шириной контентной колонки (700 px) и центруем. */
  @media (min-width: 768px) {
    .carousel {
      max-width: var(--w-content);
      margin-inline: auto;
    }
  }

  /* ===== 03.10 · Sheet — шторка с формой заявки ======================
     Мобильный: выезжает снизу. Широкий экран: по центру (см. медиазапрос).
     Закрытое состояние — visibility (не display), чтобы работал переход;
     visibility: hidden заодно убирает форму из порядка табуляции. */

  /* visibility переключается без задержки при открытии и с задержкой на длительность
     затемнения при закрытии (visibility 0s linear <задержка>). Так поле можно
     сфокусировать сразу, а не после анимации: во время перехода visibility = hidden,
     и focus() на невидимом элементе молча не сработал бы. */
  .sheet {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: grid;
    align-items: end;
    visibility: hidden;
    opacity: 0;
    transition:
      opacity var(--t-base) var(--ease),
      visibility 0s linear var(--t-base);
  }

  /* .is-open ставит JS, :target — работает без JS (ссылка href="#signup") */
  .sheet.is-open,
  .sheet:target {
    visibility: visible;
    opacity: 1;
    transition:
      opacity var(--t-base) var(--ease),
      visibility 0s;
  }

  .sheet__backdrop {
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, var(--c-bg-dark) 65%, transparent);
  }

  .sheet__panel {
    position: relative; /* выше фона */
    width: 100%;
    max-height: 92svh;
    overflow-y: auto;
    padding: var(--sp-5) var(--sp-4) calc(var(--sp-6) + env(safe-area-inset-bottom, 0px));
    background: var(--c-bg);
    /* Выезжает снизу во всю ширину — верхние скругления не нужны (просили убрать).
       Вернутся сами на широком экране, где панель становится окном по центру. */
    box-shadow: var(--sh-3);
    transform: translateY(100%); /* выезжает снизу */
    transition: transform var(--t-slow) var(--ease);
  }

  .sheet.is-open .sheet__panel,
  .sheet:target .sheet__panel {
    transform: none;
  }

  /* Пока шторка открыта, страница под ней не прокручивается */
  .sheet-open {
    overflow: hidden;
  }

  .sheet__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sp-3);
  }

  .sheet__title {
    font-size: var(--fs-h3);
    line-height: var(--lh-h3);
    text-transform: none; /* это диалог, а не заголовок секции — не кричит */
  }

  .sheet__close {
    display: grid;
    place-items: center;
    flex: none;
    width: var(--tap);
    height: var(--tap);
    margin: calc(var(--sp-2) * -1) calc(var(--sp-2) * -1) 0 0; /* прижат к углу панели */
    border-radius: var(--radius-pill);
    color: var(--c-ink);
  }

  .sheet__lead {
    margin-top: var(--sp-2);
    font-size: var(--fs-sm);
    line-height: var(--lh-sm);
    color: var(--c-ink-2);
  }

  /* На широком экране та же шторка встаёт по центру и не тянется на всю ширину */
  @media (min-width: 768px) {
    .sheet {
      align-items: center;
      padding: var(--sp-6);
    }

    .sheet__panel {
      max-width: 520px;
      margin-inline: auto;
      padding: var(--sp-6) var(--sp-6) var(--sp-6);
      border-radius: var(--radius-lg);
      transform: translateY(12px); /* по центру «подъезжает», а не «выезжает» */
    }
  }

  /* ===== 03.11 · Form — поля формы заявки ============================ */

  .form {
    display: grid;
    gap: var(--sp-4);
    margin-top: var(--sp-5);
  }

  /* Авторское display перебивает системное [hidden] { display: none },
     поэтому скрытое состояние задаём явно. */
  .form[hidden] {
    display: none;
  }

  .form__field {
    display: grid;
    gap: var(--sp-1);
  }

  .form__label {
    font-size: var(--fs-sm);
    font-weight: 600;
  }

  .form__req {
    color: var(--c-red-dark); /* красный текст на белом = 7,36:1 */
  }

  .form__input {
    width: 100%;
    min-height: var(--tap); /* 44 px — зона нажатия с запасом */
    padding: var(--sp-3) var(--sp-4);
    background: var(--c-white);
    border: 1px solid var(--c-line-2);
    border-radius: var(--radius-sm);
    color: var(--c-ink);
    line-height: var(--lh-h3); /* одна высота у поля и у select, несмотря на разные шрифты */
  }

  .form__input::placeholder {
    color: var(--c-muted);
  }

  .form__input:focus {
    border-color: var(--c-ink);
  }

  /* Поле, которое пользователь уже заполнил и оно не сошлось с правилом */
  .form__input:user-invalid {
    border-color: var(--c-error);
  }

  .form__consent {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--sp-3);
    align-items: start;
    font-size: var(--fs-sm);
    line-height: var(--lh-sm);
    color: var(--c-ink-2);
  }

  .form__consent input {
    width: 20px;
    height: 20px;
    margin: 2px 0 0;
    accent-color: var(--c-red-cta); /* галочка в брендовом красном */
  }

  /* Кнопка на всю ширину панели — состояние по умолчанию для шторки */
  .btn--full {
    width: 100%;
  }

  /* Заявка ушла: форма скрыта, показываем это сообщение */
  .form-success {
    margin-top: var(--sp-5);
    padding: var(--sp-5);
    background: var(--c-bg-soft);
    border-inline-start: 4px solid var(--c-ok);
    border-radius: var(--radius-md);
  }
}
