/* ─── Баннеры ────────────────────────────────────────────────────────── */

/* На широком экране баннер держится той же ширины, что и плашка шапки: они
   стоят друг под другом, и разная ширина читается как перекос. На телефоне
   всё иначе — см. «Телефон: баннер во всю ширину» в конце файла. */
.banners {
  position: relative;
  /* Выше полосы шапки и её волны: карточка баннера заходит на волну. */
  z-index: 2;
  max-width: calc(var(--page-max) + var(--page-gutter) * 2);
  margin: 14px auto 0;
  padding: 0 var(--page-gutter);
}
.banners[hidden] {
  display: none;
}

.banners__track {
  /* Высота ленты — высота АКТИВНОГО баннера (--banners-h ставит скрипт), а не
     самого высокого: каждый баннер остаётся таким, каким его задали. */
  height: var(--banners-h, auto);
  align-items: start;
  transition: height var(--dur-base, 240ms) var(--ease-out);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  border-radius: var(--radius-lg);
}
.banners__track::-webkit-scrollbar {
  display: none;
}

/* Проявление: баннеры лежат друг на друге в одной клетке, видимым остаётся
   один. Листать пальцем здесь нечего — переключают точки и сам отсчёт. */
/* Мышью лента не листается сама: этим занимается скрипт, а пока идёт жест,
   прилипание отключается — иначе лента дёргается под пальцем. */
.banners__track[data-dragging="true"] {
  scroll-snap-type: none;
  cursor: grabbing;
  user-select: none;
}

.banners__track[data-effect="fade"] {
  /* Жест по горизонтали забирает скрипт, вертикальную прокрутку страницы
     оставляем браузеру. */
  touch-action: pan-y;
  display: grid;
  grid-auto-flow: row;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  overflow: hidden;
}
.banners__track[data-effect="fade"] > .banner {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--dur-slow, 420ms) var(--ease-out),
    visibility var(--dur-slow, 420ms);
}
.banners__track[data-effect="fade"] > .banner[data-active="true"] {
  opacity: 1;
  visibility: visible;
}

.banner {
  align-self: start;
  position: relative;
  scroll-snap-align: center;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--bg-deep);
  color: var(--on-accent);
  text-decoration: none;
  isolation: isolate;
}

/* ─── Оттенок подложки ───────────────────────────────────────────────── */
/* Работает у видов без снимка на всю ширину: там текст лежит на затемнении
   поверх фотографии, и подложке взяться неоткуда. */

.banner[data-tone="accent"] {
  --banner-bg: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
  --banner-fg: var(--on-accent);
  --banner-muted: rgba(255, 255, 255, 0.88);
}
.banner[data-tone="dark"] {
  --banner-bg: linear-gradient(135deg, #2b231b 0%, #171310 100%);
  --banner-fg: #f7f3ee;
  --banner-muted: rgba(247, 243, 238, 0.82);
}
.banner[data-tone="light"] {
  --banner-bg: var(--surface-raised);
  --banner-fg: var(--ink);
  --banner-muted: var(--ink-soft);
}

/* Ролик и GIF занимают место кадра и подчиняются тем же правилам: у видов
   со снимком высота баннера считается по ним. */
video.banner__media {
  object-fit: cover;
  background: var(--bg-deep);
}

.banner__media {
  display: block;
  width: 100%;
  /* Жест по баннеру не должен превращаться в перетаскивание картинки:
     браузер запускает своё drag-and-drop, и листание пальцем или мышью
     теряется на первом же движении. Событиями занимается сама лента. */
  -webkit-user-drag: none;
  user-select: none;
  pointer-events: none;
  /* height: auto обязателен — у <img> проставлены атрибуты width/height,
     и без него aspect-ratio не применяется. */
  height: auto;
  /* На телефоне баннер намеренно невысокий: блюда должны быть видны сразу.
     Вертикальный кадр включается, только если владелец загрузил отдельный
     снимок для телефона. */
  aspect-ratio: var(--b-ratio);
  max-height: var(--b-max);
  object-fit: cover;
  background: var(--bg-deep);
}

/* Высота баннера — три переменные: пропорция кадра и предел высоты.
   «Обычный» — прежний баннер; «узкий» почти полоса; «высокий» крупнее, но на
   телефоне не выше 60dvh: блюда под ним должны быть видны сразу. Правила про
   высоту стоят ПЕРЕД вертикальным кадром телефона, чтобы тот их не сбивал. */
.banner {
  --b-ratio: 16 / 9;
  --b-max: 42dvh;
  /* Снимок над текстом: весь баннер не выше 60dvh, текст занимает ~190px. */
  --b-split-max: min(34dvh, max(120px, calc(60dvh - 190px)));
  --b-text-min: 150px;
}
.banner[data-tall="true"] {
  --b-ratio: 4 / 3;
}
.banner[data-size="compact"] {
  --b-ratio: 16 / 6;
  --b-max: 28dvh;
  --b-split-max: 22dvh;
  --b-text-min: 0px;
}
.banner[data-size="tall"] {
  --b-ratio: 4 / 5;
  --b-max: 60dvh;
  --b-split-max: min(46dvh, max(120px, calc(60dvh - 190px)));
  --b-text-min: min(300px, 50dvh);
}
@container banners (min-width: 640px) {
  .banner,
  .banner[data-tall="true"] {
    --b-ratio: 2.5 / 1;
    /* Широкий экран: баннер остаётся полосой, а не занимает весь первый экран. */
    --b-max: 380px;
    --b-text-min: 170px;
  }
  .banner[data-size="compact"] {
    --b-ratio: 4.2 / 1;
    --b-max: 240px;
    --b-text-min: 0px;
  }
  .banner[data-size="tall"] {
    --b-ratio: 2 / 1;
    --b-max: min(560px, 60dvh);
    --b-text-min: min(340px, 60dvh);
  }
}

.banner__body {
  display: grid;
  gap: 8px;
  justify-items: start;
  padding: 18px 20px 20px;
}

/* Выравнивание текста. У полосы оно не нужно: там всё в одну строку. */
.banner[data-align="center"]:not([data-variant="strip"]) .banner__body {
  justify-items: center;
  text-align: center;
}
.banner[data-align="center"]:not([data-variant="strip"]) .banner__meta,
.banner[data-align="center"]:not([data-variant="strip"]) .banner__action {
  justify-content: center;
}
.banner[data-align="center"]:not([data-variant="strip"]) .banner__subtitle {
  margin-inline: auto;
}

/* ─── Снимок на всю ширину ───────────────────────────────────────────── */

/* Снимок и надпись лежат в одной клетке: надпись поверх кадра. Так снимок
   занимает всю высоту баннера — а она у всех в ленте общая, по самому
   высокому. Затемнение лежит на всём баннере, а не на блоке с текстом: тогда
   его направление следует за местом надписи (снизу, по центру, сверху). */
.banner[data-variant="cover"] {
  display: grid;
  /* Тёмная подложка под кадром. Надпись здесь белая и лежит на затемнении
     поверх снимка — а снимок может ещё качаться или не прийти вовсе. Без
     этой заливки в такую секунду белым по светлому фону не прочитать ничего. */
  background: #1a1510;
}
/* Ролик лежит в баннере сам, без обёртки <picture>, поэтому клетку сетки
   указываем обоим: иначе видео уезжает во вторую строку, а надпись остаётся
   над ним вместо того, чтобы лежать поверх. */
.banner[data-variant="cover"] > picture,
.banner[data-variant="cover"] > .banner__media {
  grid-area: 1 / 1;
  height: 100%;
}
.banner[data-variant="cover"] .banner__media {
  height: 100%;
  object-fit: cover;
}
.banner[data-variant="cover"]::after {
  content: "";
  grid-area: 1 / 1;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to top,
    rgba(20, 16, 12, 0.9) 0%,
    rgba(20, 16, 12, 0.72) 45%,
    rgba(20, 16, 12, 0.25) 80%,
    transparent 100%
  );
}
.banner[data-variant="cover"][data-pos="top"]::after {
  background: linear-gradient(
    to bottom,
    rgba(20, 16, 12, 0.9) 0%,
    rgba(20, 16, 12, 0.72) 45%,
    rgba(20, 16, 12, 0.25) 80%,
    transparent 100%
  );
}
.banner[data-variant="cover"][data-pos="center"]::after {
  background: radial-gradient(ellipse at center, rgba(20, 16, 12, 0.78) 0%, rgba(20, 16, 12, 0.62) 65%, rgba(20, 16, 12, 0.5) 100%);
}
.banner[data-variant="cover"] .banner__body {
  grid-area: 1 / 1;
  position: relative;
  z-index: 2;
  align-self: end;
  --banner-fg: #fff;
  --banner-muted: rgba(255, 255, 255, 0.92);
}
.banner[data-variant="cover"][data-pos="top"] .banner__body {
  align-self: start;
}
.banner[data-variant="cover"][data-pos="center"] .banner__body {
  align-self: center;
}
.banner[data-variant="cover"] .banner__title,
.banner[data-variant="cover"] .banner__subtitle {
  /* Снимок бывает светлым: тень держит надпись читаемой на любом кадре. */
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 1px 14px rgba(0, 0, 0, 0.45);
}

/* ─── Снимок и текст рядом ───────────────────────────────────────────── */
/* На телефоне это столбик: снимок сверху, текст под ним. Ставить текст
   поверх узкого кадра значит закрыть собой само блюдо. */

.banner[data-variant="split"] {
  display: grid;
  background: var(--banner-bg);
  color: var(--banner-fg);
  --b-split-ratio: 16 / 9;
  --b-split-min: 0px;
}
.banner[data-variant="split"][data-size="compact"] {
  --b-split-ratio: 21 / 9;
}
.banner[data-variant="split"][data-size="tall"] {
  --b-split-ratio: 4 / 3;
}
.banner[data-variant="split"] .banner__media {
  aspect-ratio: var(--b-split-ratio);
  max-height: var(--b-split-max);
}
.banner[data-variant="split"] .banner__body {
  align-content: center;
}
@container banners (min-width: 640px) {
  .banner[data-variant="split"] {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    align-items: stretch;
    min-height: var(--b-split-min);
  }
  .banner[data-variant="split"][data-size="tall"] {
    --b-split-min: min(380px, 60dvh);
  }
  .banner[data-variant="split"] .banner__media,
  .banner[data-variant="split"][data-tall="true"] .banner__media {
    height: 100%;
    /* Без ограничения сверху: высота баннера в ленте общая, по самому
       высокому, и кадр должен доходить до низа, а не обрываться полоской. */
    max-height: none;
    aspect-ratio: auto;
  }
  .banner[data-variant="split"] .banner__body {
    padding: 26px 30px;
  }
}

/* ─── Только текст ───────────────────────────────────────────────────── */

.banner[data-variant="text"] {
  display: grid;
  align-content: center;
  min-height: var(--b-text-min);
  background: var(--banner-bg);
  color: var(--banner-fg);
}
.banner[data-variant="text"] .banner__body {
  padding: 24px 22px;
}
.banner[data-variant="text"][data-size="compact"] .banner__body {
  padding: 16px 20px;
}
.banner[data-variant="text"][data-size="tall"] .banner__title {
  font-size: clamp(1.5rem, 6cqi, 2.3rem);
}
@container banners (min-width: 640px) {
  .banner[data-variant="text"] .banner__body {
    padding: 30px 32px;
  }
  .banner[data-variant="text"][data-size="compact"] .banner__body {
    padding: 18px 28px;
  }
}

/* ─── Узкая полоса ───────────────────────────────────────────────────── */
/* Для короткого объявления: «сегодня до 18:00». Занимает одну строку, чтобы
   не отодвигать меню вниз. Высота от настройки «Размер» не зависит. */

.banner[data-variant="strip"] {
  display: grid;
  align-content: center;
  background: var(--banner-bg);
  color: var(--banner-fg);
  border-radius: var(--radius-lg);
}
.banner[data-variant="strip"] .banner__body {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  padding: 12px 18px;
}
.banner[data-variant="strip"] .banner__title {
  font-size: clamp(1rem, 3.4cqi, 1.15rem);
}
.banner[data-variant="strip"] .banner__subtitle {
  flex: 1 1 14ch;
  font-size: 0.86rem;
}
.banner[data-variant="strip"] .banner__action {
  margin: 0 0 0 auto;
}
@container banners (min-width: 520px) {
  .banner[data-variant="strip"] .banner__body {
    padding: 12px 22px;
  }
}

/* ─── Общий текст баннера ────────────────────────────────────────────── */

.banner__title {
  font-size: clamp(1.15rem, 4.2cqi, 1.7rem);
  color: var(--banner-fg, #fff);
}
.banner__subtitle {
  font-size: 0.93rem;
  color: var(--banner-muted, rgba(255, 255, 255, 0.92));
  max-width: 46ch;
}

/* Строка над заголовком: плашка («−20%», «Новинка») и отсчёт. */
.banner__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}
.banner__eyebrow {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 2px 11px;
  border-radius: var(--radius-pill);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--banner-fg, #fff);
  background: rgba(127, 127, 127, 0.22);
  background: color-mix(in srgb, var(--banner-fg, #fff) 18%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--banner-fg, #fff) 28%, transparent);
}
.banner[data-variant="cover"] .banner__eyebrow {
  background: rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(6px);
}
/* Свой цвет владельца: на снимке он достаётся плашке, чтобы баннер читался
   «фирменным», хотя подложки у него нет. */
.banner[data-own="true"][data-variant="cover"] .banner__eyebrow {
  background: var(--banner-accent);
  color: var(--banner-on-accent);
  box-shadow: none;
  backdrop-filter: none;
}

.banner__countdown {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  font-size: 0.82rem;
  color: var(--banner-muted, rgba(255, 255, 255, 0.92));
}
.banner__countdown-value {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--banner-fg, #fff);
}

/* Цена блюда и кнопка — одной строкой, цена первой: ради неё и открывают. */
.banner__action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin-top: 4px;
}
.banner__price {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}
.banner__price-now {
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--banner-fg, #fff);
}
.banner__price-was {
  font-size: 0.9rem;
  color: var(--banner-muted, rgba(255, 255, 255, 0.92));
}
.banner[data-clickable="true"] {
  cursor: pointer;
}

.banner__cta {
  margin-top: 0;
  --btn-bg: var(--surface-raised);
  --btn-fg: var(--ink);
}
.banner__cta:hover {
  --btn-bg: #fff;
}
/* На светлой подложке белая кнопка растворяется — берём цвет акцента. */
.banner[data-tone="light"]:not([data-variant="cover"]) .banner__cta {
  --btn-bg: var(--accent-strong);
  --btn-fg: var(--on-accent);
}
/* Свой цвет: кнопка — цвет текста на цвете подложки, надпись — цвет подложки.
   Пара та же, что у баннера, поэтому читается так же, как он сам. */
.banner[data-own="true"]:not([data-variant="cover"]) .banner__cta,
.banner[data-own="true"]:not([data-variant="cover"]) .banner__cta:hover {
  --btn-bg: var(--banner-fg);
  --btn-fg: var(--banner-accent);
}
.banner[data-own="true"][data-variant="cover"] .banner__cta,
.banner[data-own="true"][data-variant="cover"] .banner__cta:hover {
  --btn-bg: var(--banner-accent);
  --btn-fg: var(--banner-on-accent);
}

/* ─── Движение внутри баннера ────────────────────────────────────────── */
/* Два украшения, оба выключаются одной настройкой владельца и оба исчезают
   при `prefers-reduced-motion`:

   «Наезд» — очень медленное приближение кадра. Он не должен читаться как
   движение: смысл в том, что картинка живая, а не в том, что она едет.

   «Выход надписи» — заголовок, строка и кнопка появляются по очереди, когда
   баннер стал активным. Поэтому признак активного ставится в обоих режимах
   смены, а не только при проявлении. */

[data-banner-motion="zoom"] .banner[data-variant="cover"] .banner__media,
[data-banner-motion="both"] .banner[data-variant="cover"] .banner__media,
[data-banner-motion="zoom"] .banner[data-variant="split"] .banner__media,
[data-banner-motion="both"] .banner[data-variant="split"] .banner__media {
  animation: banner-zoom 24s ease-in-out infinite alternate;
  transform-origin: center;
}

@keyframes banner-zoom {
  from {
    scale: 1;
  }
  to {
    scale: 1.07;
  }
}

[data-banner-motion="rise"] .banner[data-active="true"] .banner__title,
[data-banner-motion="both"] .banner[data-active="true"] .banner__title,
[data-banner-motion="rise"] .banner[data-active="true"] .banner__subtitle,
[data-banner-motion="both"] .banner[data-active="true"] .banner__subtitle,
[data-banner-motion="rise"] .banner[data-active="true"] .banner__action,
[data-banner-motion="both"] .banner[data-active="true"] .banner__action {
  animation: banner-rise 340ms var(--ease-out) both;
}
/* Небольшая задержка по строкам: надпись появляется первой, кнопка последней. */
[data-banner-motion="rise"] .banner[data-active="true"] .banner__subtitle,
[data-banner-motion="both"] .banner[data-active="true"] .banner__subtitle {
  animation-delay: 40ms;
}
[data-banner-motion="rise"] .banner[data-active="true"] .banner__action,
[data-banner-motion="both"] .banner[data-active="true"] .banner__action {
  animation-delay: 80ms;
}

@keyframes banner-rise {
  from {
    opacity: 0;
    translate: 0 14px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .banner__media,
  .banner__title,
  .banner__subtitle,
  .banner__action {
    animation: none !important;
  }
}

/* ─── Точки и отсчёт ─────────────────────────────────────────────────── */

.banners__dots {
  display: flex;
  justify-content: center;
  gap: 7px;
  margin-top: 10px;
}
.banners__dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  overflow: hidden;
  background: var(--line-bg-strong);
  cursor: pointer;
  transition:
    width var(--dur-base) var(--ease-out),
    background-color var(--dur-base) var(--ease-out);
}
.banners__dot[aria-current="true"] {
  width: 20px;
  border-radius: var(--radius-pill);
  background: var(--accent);
}

/* Полоска отсчёта. Живёт только при включённой смене: у выключенной точка
   остаётся обычной, и мигать ей незачем. */
.banners__dot-fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--accent-strong);
}
.banners__dots[data-autoplay="true"] .banners__dot[aria-current="true"] {
  background: var(--line-bg-strong);
}
.banners__dots[data-autoplay="true"] .banners__dot[aria-current="true"] .banners__dot-fill {
  animation: banner-tick var(--banner-interval, 6000ms) linear forwards;
}
.banners__dots[data-paused="true"] .banners__dot-fill {
  animation-play-state: paused;
}

@keyframes banner-tick {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

/* Просьба системы уменьшить движение сильнее любой настройки владельца:
   баннеры тогда не сменяются сами, и отсчитывать нечего. */
@media (prefers-reduced-motion: reduce) {
  .banners__dots[data-autoplay="true"] .banners__dot[aria-current="true"] {
    background: var(--accent);
  }
  .banners__dot-fill {
    animation: none !important;
  }
}

/* ─── Стрелки ────────────────────────────────────────────────────────── */
/* Только там, где есть мышь и место: на телефоне баннеры листают пальцем, и
   две кнопки поверх кадра лишь закрывали бы его. Показываются, когда курсор
   над баннером или кнопка получила фокус с клавиатуры. */

.banners__stage {
  container: banners / inline-size;
  position: relative;
}
.banners__arrow {
  display: none;
}
@media (hover: hover) and (min-width: 720px) {
  .banners__arrow {
    display: grid;
    place-items: center;
    position: absolute;
    top: 50%;
    z-index: 3;
    width: 42px;
    height: 42px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    translate: 0 -50%;
    background: rgba(255, 255, 255, 0.9);
    color: #241f1a;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.22);
    cursor: pointer;
    opacity: 0;
    transition:
      opacity var(--dur-base) var(--ease-out),
      scale var(--dur-fast) var(--ease-out);
  }
  .banners__arrow[data-dir="prev"] {
    left: 12px;
  }
  .banners__arrow[data-dir="next"] {
    right: 12px;
  }
  .banners__stage:hover .banners__arrow,
  .banners__stage:focus-within .banners__arrow {
    opacity: 1;
  }
  .banners__arrow:hover {
    scale: 1.08;
  }
  .banners__arrow svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
}
@media (prefers-reduced-motion: reduce) {
  .banners__arrow {
    transition: none;
  }
}


/* ─── Мелочи высоты ──────────────────────────────────────────────────── */

/* Узкий снимок: подзаголовок не помещается и забил бы весь кадр. */
.banner[data-variant="cover"][data-size="compact"] .banner__subtitle {
  display: none;
}
.banner[data-variant="cover"] .banner__subtitle {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.banner[data-variant="cover"][data-size="compact"] .banner__body {
  padding: 12px 16px;
}
.banner__media {
  /* Кадр всегда заполняет свою клетку. */
  object-fit: cover;
}

/* ─── Широкий экран: текст растёт вместе с баннером ──────────────────── */

@container banners (min-width: 1000px) {
  .banner__body > * {
    max-width: 560px;
  }
  .banner[data-variant="cover"] .banner__body,
  .banner[data-variant="text"] .banner__body {
    padding-inline: max(48px, calc((100cqi - 1200px) / 2));
    padding-block: 36px;
  }
  .banner__title {
    font-size: clamp(2rem, 3.2cqi, 2.75rem);
    line-height: 1.12;
  }
  .banner[data-variant="strip"] .banner__title {
    font-size: 1.3rem;
  }
  .banner__subtitle {
    font-size: 1.125rem;
    max-width: 560px;
  }
  .banner__cta {
    min-height: 48px;
    padding-inline: 26px;
    font-size: 1rem;
  }
  .banner__price-now {
    font-size: 1.8rem;
  }
  .banner__eyebrow {
    font-size: 0.82rem;
    min-height: 28px;
  }
  .banner[data-variant="cover"] .banner__subtitle {
    -webkit-line-clamp: 3;
  }
}

@media (prefers-reduced-motion: reduce) {
  .banners__track {
    transition: none;
  }
}

/* ─── Кнопка на снимке и узкий «снимок и текст» ──────────────────────── */

/* На снимке кнопка всегда светлая и контрастная, в любом шаблоне: цвет
   «поверхности» в тёмной теме — тёмно-серый, и кнопка тонула в затемнении. */
.banner[data-variant="cover"]:not([data-own="true"]) .banner__cta,
.banner[data-variant="cover"]:not([data-own="true"]) .banner__cta:hover {
  --btn-bg: #fff;
  --btn-fg: #241f1a;
}

/* Узкий вариант: кадр слева, текст справа даже на телефоне — столбик из
   снимка и текста не бывает ниже ~330px, и «узкий» ничем не отличался бы. */
.banner[data-variant="split"][data-size="compact"] {
  grid-template-columns: minmax(0, 38%) minmax(0, 1fr);
  align-items: stretch;
}
.banner[data-variant="split"][data-size="compact"] .banner__media {
  height: 100%;
  max-height: none;
  aspect-ratio: auto;
}
.banner[data-variant="split"][data-size="compact"] .banner__body {
  padding: 12px 14px;
  gap: 4px;
}
.banner[data-variant="split"][data-size="compact"] .banner__subtitle {
  display: none;
}
.banner[data-variant="split"][data-size="compact"] .banner__title {
  font-size: 1rem;
}
.banner[data-variant="split"][data-size="compact"] .banner__price-now {
  font-size: 1.1rem;
}
.banner[data-variant="split"][data-size="compact"] {
  min-height: 120px;
}

/* Шрифт баннера (`fonts.banner`): заголовок и подзаголовок. Размер заголовка
   задан по видам баннера выше, поэтому здесь только гарнитура и перенос. */
[data-font-banner] :is(.banner__title, .banner__subtitle, .banner__eyebrow, .banner__cta) {
  font-family: var(--font-banner);
  font-synthesis-weight: none;
}
[data-font-banner] .banner__title {
  overflow-wrap: anywhere;
  letter-spacing: 0;
}

/* Шрифт отдельного баннера (`banner.font`): `data-font-banner` стоит на самом
   узле, переменные берутся из «Карты шрифтов» в fonts.css. Поправка на ширину
   `--banner-fit` сжимает широкие гарнитуры (Unbounded, Rubik Mono) и чуть
   увеличивает узкие и рукописные: заголовок не вылезает из баннера. */
.banner[data-font-banner] .banner__title {
  zoom: var(--banner-fit, 1);
}
/* Рукописный или дисплейный шрифт — только заголовку. Всё мелкое остаётся
   на шрифте сайта. */
.banner[data-font-plain] :is(.banner__subtitle, .banner__eyebrow, .banner__cta, .banner__countdown, .banner__price) {
  font-family: var(--font-text);
}

/* ─── Баннер-картинка ────────────────────────────────────────────────── */
/* Ни слова — только снимок или ролик (`data-bare`, ставит createBanner).
   Надпись уже нарисована на картинке, поэтому кадр показывается целиком и в
   своей пропорции (`--bare-ratio`): без затемнения, без тёмной подложки и без
   пустого поля под текст. Высота ограничена — блюда должны остаться видны;
   картинка уже ленты встаёт по центру. */
.banner[data-bare="true"] {
  --bare-max-h: 62dvh;
  justify-self: center;
  width: 100%;
  max-width: calc(var(--bare-max-h) * var(--bare-ratio, 2.5));
  background: transparent;
}
.banner[data-bare="true"]::after {
  content: none;
}
.banner[data-bare="true"] .banner__media {
  height: auto;
  aspect-ratio: var(--bare-ratio, var(--b-ratio));
  max-height: var(--bare-max-h);
  background: transparent;
}
@container banners (min-width: 640px) {
  .banner[data-bare="true"] {
    --bare-max-h: min(460px, 70dvh);
  }
}

/* ─── Баннер-карточка ────────────────────────────────────────────────── */
/* Баннер стоит вставленной карточкой с полями страницы, скруглением и мягкой
   тенью под волной шапки; точки под ним — активная вытянутая пилюля цвета
   полосы шапки и маленькие серые кружки. Селектор через `.banners`
   намеренно: образец в админке собран из `.banners__stage` без этой обёртки
   и остаётся прежним.

   Слайды стоят с зазором 12px, и индекс листания считается по шагу
   (`bannerStride` в app.js), а не по ширине ленты. Лента — прокручиваемый
   контейнер и режет тень, поэтому снизу у неё запас (`padding-bottom`), а
   тень с отрицательным разносом не вылезает в стороны. */
.banners {
  --banner-r: 22px;
}
.banners .banners__track {
  box-sizing: content-box;
  padding-bottom: 12px;
  margin-bottom: -6px;
  border-radius: var(--banner-r);
}
.banners .banner {
  border-radius: var(--banner-r);
  box-shadow: 0 6px 12px -8px rgb(30 18 36 / 0.5);
}
.banners .banner[data-bare="true"] {
  max-width: none;
}
.banners__dots {
  margin-top: 4px;
  gap: 6px;
}
.banners__dot {
  width: 7px;
  height: 7px;
  background: color-mix(in srgb, var(--on-bg) 26%, transparent);
}
.banners__dot[aria-current="true"] {
  width: 22px;
  background: var(--hero-band-dot, var(--accent));
}
.banners__dots[data-autoplay="true"] .banners__dot[aria-current="true"] {
  background: color-mix(in srgb, var(--on-bg) 26%, transparent);
}
.banners__dot-fill {
  background: var(--hero-band-dot, var(--accent-strong));
}
@media (prefers-reduced-motion: reduce) {
  .banners__dots[data-autoplay="true"] .banners__dot[aria-current="true"] {
    background: var(--hero-band-dot, var(--accent));
  }
}
