/* ══════════════════════════════════════════════════════════
   Восток 24 — макет 1
   Палитра и дисплейный шрифт взяты из печатных макетов меню.
   Кегли специально крупнее рынка: ядро аудитории 45–65 лет.
   ══════════════════════════════════════════════════════════ */

@font-face { font-family: 'Itikaf'; src: url('../assets/fonts/Itikaf.otf') format('opentype'); font-weight: 400; font-display: block; }
@font-face { font-family: 'Onest'; src: url('../assets/fonts/Onest-400.ttf') format('truetype'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Onest'; src: url('../assets/fonts/Onest-500.ttf') format('truetype'); font-weight: 500; font-display: swap; }
@font-face { font-family: 'Onest'; src: url('../assets/fonts/Onest-600.ttf') format('truetype'); font-weight: 600; font-display: swap; }
@font-face { font-family: 'Onest'; src: url('../assets/fonts/Onest-700.ttf') format('truetype'); font-weight: 700; font-display: swap; }

:root {
  --terracotta:      oklch(0.48 0.130 35);
  --terracotta-deep: oklch(0.37 0.105 34);
  --terracotta-hot:  oklch(0.53 0.175 40);
  --terracotta-lift: oklch(0.59 0.185 42);
  --cream:           oklch(0.94 0.026 82);
  --cream-deep:      oklch(0.89 0.036 80);
  --paperline:       oklch(0.84 0.040 78);
  --ink:             oklch(0.18 0.018 40);
  --ink-2:           oklch(0.26 0.020 40);
  --ceramic:         oklch(0.50 0.090 245);
  --ink-on-cream:    oklch(0.20 0.018 40);
  --cream-on-ink:    oklch(0.96 0.012 82);
  --muted-on-cream:  oklch(0.41 0.024 40);
  --muted-on-ink:    oklch(0.82 0.020 82);
  --ok:              oklch(0.70 0.17 145);

  --font-display: 'Itikaf', Georgia, serif;
  --font-text: 'Onest', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --step--1: clamp(0.95rem, 0.9rem + 0.2vw, 1.06rem);
  --step-0:  clamp(1.1rem, 1.05rem + 0.25vw, 1.22rem);
  --step-1:  clamp(1.4rem, 1.28rem + 0.6vw, 1.75rem);
  --step-2:  clamp(1.85rem, 1.6rem + 1.2vw, 2.6rem);
  --step-3:  clamp(2.4rem, 1.9rem + 2.4vw, 4rem);
  --step-4:  clamp(2.9rem, 2rem + 4.6vw, 5.6rem);

  --gutter: clamp(1.25rem, 4vw, 4rem);
  --section: clamp(3.5rem, 8vw, 7rem);
  --radius: 12px;
  --radius-pill: 999px;
  --tap: 56px;

  --z-rail: 60;
  --z-nav: 100;
  --z-callbar: 120;
  --z-promobar: 140;
  --z-sheet: 200;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-quart: cubic-bezier(0.25, 1, 0.5, 1);

  /* Каёмочка: восьмиконечная звезда «рубʼ-эль-хизб» (два квадрата под 45°),
     между звёздами — ромб на нитке. Плитка 44×22, стыкуется в непрерывную цепь.
     Рисунок работает маской, поэтому цвет задаётся через background у элемента
     и одна плитка обслуживает и светлый фон, и тёмный. */
  /* Кант: двойная линия по периметру и квадратные «ключи» в углах —
     восточная рамка, а не стоковая скруглённая коробка. Раздаётся через
     border-image: углы берутся из углов картинки, стороны растягиваются,
     поэтому одна плитка работает на любой ширине.
     Слайс 40 из 120 — угловая зона; ширина рамки задаётся на месте. */
  --frame-cream: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cg fill='none' stroke='%23F2E3C9' stroke-width='4'%3E%3Crect x='4' y='4' width='112' height='112'/%3E%3Crect x='14' y='14' width='92' height='92'/%3E%3Cpath d='M22 22h14v14H22z'/%3E%3Cpath d='M84 22h14v14H84z'/%3E%3Cpath d='M22 84h14v14H22z'/%3E%3Cpath d='M84 84h14v14H84z'/%3E%3Cpath d='M14 29h8M29 14v8M106 29h-8M91 14v8M14 91h8M29 106v-8M106 91h-8M91 106v-8'/%3E%3C/g%3E%3C/svg%3E");
  --frame-terracotta: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120'%3E%3Cg fill='none' stroke='%239B4A2F' stroke-width='4'%3E%3Crect x='4' y='4' width='112' height='112'/%3E%3Crect x='14' y='14' width='92' height='92'/%3E%3Cpath d='M22 22h14v14H22z'/%3E%3Cpath d='M84 22h14v14H84z'/%3E%3Cpath d='M22 84h14v14H22z'/%3E%3Cpath d='M84 84h14v14H84z'/%3E%3Cpath d='M14 29h8M29 14v8M106 29h-8M91 14v8M14 91h8M29 106v-8M106 91h-8M91 106v-8'/%3E%3C/g%3E%3C/svg%3E");

  /* Каёмка на швы секций. Мотив — кошкар-мюйиз (бараньи рога), вариант 04
     из КАЁМКИ.html. Чтобы поменять на другой, достаточно подменить эти две
     плитки: класс .ornband и все места применения останутся прежними. */
  --orn-cream: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='24' viewBox='0 0 40 24'%3E%3Cg fill='none' stroke='%23F2E3C9' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M2 20C2 10 8 5.6 13 8.6c3 1.8 2.2 6-0.8 6.4-2 0.3-2.8-1.6-1.6-2.6'/%3E%3Cpath d='M38 20C38 10 32 5.6 27 8.6c-3 1.8-2.2 6 0.8 6.4 2 0.3 2.8-1.6 1.6-2.6'/%3E%3C/g%3E%3Cpath d='M20 7.5L23.4 12.6L20 17.7L16.6 12.6Z' fill='%23F2E3C9'/%3E%3Cpath d='M0 21.8H40' stroke='%23F2E3C9' stroke-width='1.6'/%3E%3C/svg%3E");
  --orn-terra: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='24' viewBox='0 0 40 24'%3E%3Cg fill='none' stroke='%239B4A2F' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M2 20C2 10 8 5.6 13 8.6c3 1.8 2.2 6-0.8 6.4-2 0.3-2.8-1.6-1.6-2.6'/%3E%3Cpath d='M38 20C38 10 32 5.6 27 8.6c-3 1.8-2.2 6 0.8 6.4 2 0.3 2.8-1.6 1.6-2.6'/%3E%3C/g%3E%3Cpath d='M20 7.5L23.4 12.6L20 17.7L16.6 12.6Z' fill='%239B4A2F'/%3E%3Cpath d='M0 21.8H40' stroke='%239B4A2F' stroke-width='1.6'/%3E%3C/svg%3E");
  --orn-h: 22px;

  /* Стрелка «тяните вбок» у подсказки над лентой категорий */
  --swipe-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h15'/%3E%3Cpath d='m13 6 6 6-6 6'/%3E%3C/svg%3E");

  /* Замок свода у карточки отзыва: восьмиконечная звезда «рубʼ-эль-хизб» —
     два квадрата под 45°. Живёт фоном, поэтому не мешает раскладке текста. */
  --fan-crown: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26' viewBox='0 0 26 26'%3E%3Cg fill='none' stroke='%239B4A2F' stroke-width='1.6' opacity='0.55'%3E%3Crect x='6' y='6' width='14' height='14'/%3E%3Crect x='6' y='6' width='14' height='14' transform='rotate(45 13 13)'/%3E%3C/g%3E%3C/svg%3E");
}

/* Каёмка на шве: одна плитка, повтор по горизонтали. Лежит поверх содержимого
   секции, нажатия не перехватывает. Ставится в начало или в конец блока —
   границу между блоками держит она, а не голая линия. */
.ornband {
  position: absolute; left: 0; right: 0; z-index: 3; pointer-events: none;
  height: var(--orn-h);
  background-image: var(--orn-cream);
  background-repeat: repeat-x; background-position: center;
  background-size: auto var(--orn-h);
}
.ornband--flip { transform: scaleY(-1); }
.ornband--terra { background-image: var(--orn-terra); }
/* Места установки. Полоса лежит ВНУТРИ своего блока, вплотную к краю:
   кремовый узор по терракоте и по тёмному, а не вынесенный в соседнюю секцию. */
.promos > .ornband { top: 0; }
/* overflow — из-за веера: нижние карточки стопки повёрнуты и сдвинуты вправо,
   на узком экране они вылезали за край и тянули страницу вбок. */
.trust { position: relative; overflow: hidden; }
.trust > .ornband { top: 0; }
.trust > .ornband--flip { top: auto; bottom: 0; }
.foot > .ornband--foot { top: 0; opacity: 0.75; }

/* ── Швы между секциями ───────────────────────────────
   Границу держит каёмка (.ornband), поэтому срезанные углы у подвала сняты:
   клип обрубал орнамент по краям, а полоса должна идти от края до края.
   Герой и акции по-прежнему разводит мягкая тень сверху кадра
   (см. .promos::before).                                                   */
.seam { display: none; }
.foot { position: relative; }

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  font-family: var(--font-text);
  font-size: var(--step-0);
  line-height: 1.55;
  color: var(--ink-on-cream);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, video { display: block; max-width: 100%; }
h1, h2, h3 { text-wrap: balance; line-height: 1.03; }
p { text-wrap: pretty; }
a { color: inherit; }
button { font: inherit; }

/* Ширина под липкий телефон справа: на широком экране колонка не должна
   заезжать под кнопки. 1240 + два поля по 100 = 1440. */
.wrap { width: min(100% - var(--gutter) * 2, 1240px); margin-inline: auto; }

/* Якоря не должны прятаться под плавающей капсулой шапки (высота + верхний отступ) */
section[id], header[id] { scroll-margin-top: 104px; }
@media (max-width: 900px) { section[id], header[id] { scroll-margin-top: 88px; } }
.display { font-family: var(--font-display); font-weight: 400; letter-spacing: 0.005em; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ── Кнопки ─────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.65em;
  min-height: var(--tap); padding: 0 1.7rem;
  font: 600 var(--step-0)/1 var(--font-text);
  text-decoration: none; border-radius: var(--radius-pill);
  border: 2px solid transparent; cursor: pointer;
  transition: transform 0.4s var(--ease), background-color 0.3s var(--ease), border-color 0.3s var(--ease), box-shadow 0.4s var(--ease);
}
.btn svg { width: 1.25em; height: 1.25em; flex: none; }
.btn--hot { background: var(--terracotta-hot); color: #fff; box-shadow: 0 6px 20px oklch(0.53 0.175 40 / 0.28); }
.btn--hot:hover { background: var(--terracotta-lift); transform: translateY(-2px); box-shadow: 0 10px 26px oklch(0.53 0.175 40 / 0.36); }
.btn--ghost-light { border-color: rgba(255,255,255,0.78); color: #fff; }
.btn--ghost-light:hover { background: rgba(255,255,255,0.15); transform: translateY(-2px); }
.btn--ink { background: var(--ink); color: var(--cream-on-ink); }
.btn--ink:hover { background: var(--ink-2); transform: translateY(-2px); }
.btn--outline { border-color: var(--terracotta); color: var(--terracotta); }
.btn--outline:hover { background: var(--terracotta); color: var(--cream); transform: translateY(-2px); }

/* ══ 1. ШАПКА: плавающая капсула ═══════════════════════
   Механика снята с luccilambrusco.com:
   • на самом верху страницы капсула невидима — ни фона, ни рамки, ни блюра;
   • при любом отходе от нуля проступает полупрозрачный терракот + blur(10px)
     + кремовая рамка (переход 0.3s, задержка 0.1s);
   • скролл вниз убирает всю полосу за верхний край, скролл вверх возвращает.  */
.topbar {
  position: fixed; top: clamp(10px, 1.4vw, 20px); left: 0; right: 0;
  z-index: var(--z-nav);
  display: flex; justify-content: center;
  padding-inline: var(--gutter);
  pointer-events: none;
  transition: transform 0.5s var(--ease-quart);
}
.topbar > * { pointer-events: auto; }
.topbar.is-hidden { transform: translateY(calc(-100% - clamp(10px, 1.4vw, 20px) - 8px)); }

/* Капсула держится на канте: двойная линия с квадратными «ключами» в углах.
   Заливка остаётся полупрозрачной — сквозь неё виден кадр зала.
   Кант рисует псевдоэлемент через border-image, поэтому он не отъедает
   место у пунктов и не меняет высоту полосы.                              */
.topbar__capsule {
  position: relative;
  display: flex; align-items: center;
  gap: clamp(0.9rem, 2vw, 2rem);
  padding: 12px clamp(1.6rem, 2.8vw, 3.1rem);
  border: 0; border-radius: 0;
  background: transparent;
  transition:
    background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1) 0.1s,
    backdrop-filter 0.3s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
}
.topbar__capsule::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  border: 16px solid transparent;
  border-image-source: var(--frame-cream);
  border-image-slice: 40;
  border-image-repeat: stretch;
  filter: drop-shadow(0 1px 6px oklch(0.14 0.02 40 / 0.55));
  opacity: 0; transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1) 0.1s;
}
.topbar.is-stuck .topbar__capsule {
  background: oklch(0.48 0.130 35 / 0.42);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.topbar.is-stuck .topbar__capsule::after { opacity: 0.92; }

.topbar__side { display: flex; align-items: center; gap: clamp(0.9rem, 2vw, 2rem); }
.topbar__side a {
  display: inline-flex; align-items: center; min-height: 44px;
  padding-inline: 0.25rem;
  color: var(--cream-on-ink); text-decoration: none;
  font-size: var(--step--1); font-weight: 700;
  text-shadow: 0 1px 12px oklch(0.14 0.02 40 / 0.55);
  transition: opacity 0.3s var(--ease);
}
.topbar__side a:hover { opacity: 0.72; }

.topbar__call {
  display: inline-flex; align-items: center; gap: 0.5rem;
  min-height: 44px; padding: 0 1.25rem;
  border-radius: var(--radius-pill);
  background: var(--terracotta-hot); color: #fff;
  font-size: var(--step--1); font-weight: 700; text-decoration: none;
  transition: background-color 0.3s var(--ease), transform 0.35s var(--ease);
}
.topbar__call svg { width: 18px; height: 18px; flex: none; }
.topbar__call:hover { background: var(--terracotta-lift); transform: translateY(-1px); }

.topbar__burger { display: none; }
.topbar__mark { display: none; }

@media (max-width: 900px) {
  .topbar { padding-inline: clamp(0.6rem, 3vw, 1rem); }
  .topbar__capsule { width: 100%; justify-content: space-between; gap: 0.5rem; padding: 10px 14px 10px 10px; }
  .topbar__capsule::after { border-width: 13px; }
  .topbar__side { display: none; }
  .topbar__burger {
    display: grid; place-content: center; gap: 5px;
    width: 48px; height: 48px; padding: 0 12px;
    background: none; border: 0; cursor: pointer;
  }
  .topbar__burger span { display: block; width: 24px; height: 2px; border-radius: 2px; background: var(--cream); box-shadow: 0 1px 8px oklch(0.14 0.02 40 / 0.6); }
  .topbar__call span { display: none; }
  .topbar__call { padding: 0; width: 48px; justify-content: center; }
  .topbar__call svg { width: 20px; height: 20px; }

  /* Знак — по центру капсулы. Полёт знака через весь экран на телефоне
     выключен: два одинаковых знака на одном экране читались дублем,
     а середина капсулы при этом пустовала. */
  /* min-height — зона нажатия: сам знак 24 px, но ссылка ведёт наверх
     и по правилу тач-целей должна быть не ниже 44 px. */
  .topbar__mark { display: grid; align-content: center; flex: 1; min-width: 0; min-height: 44px; }
  .topbar__mark img {
    display: block; height: 24px; width: auto; margin-inline: auto;
    filter: drop-shadow(0 1px 8px oklch(0.14 0.02 40 / 0.7));
  }
  .flylogo, .hero__logo { display: none; }
}

/* ── Мобильное меню: шторка справа ─────────────────────
   Раньше это был экран, который просто проявлялся, и внутри было пусто.
   Теперь — многослойный выезд: три цветные подложки уходят вправо-влево
   со сдвигом задержек, панель едет следом, строки поднимаются по очереди.
   Состояние держит data-nav, а не атрибут hidden: hidden обрывает анимацию
   закрытия на первом же кадре.                                            */
.navsheet {
  position: fixed; inset: 0; z-index: var(--z-sheet);
  pointer-events: none; visibility: hidden;
  /* Закрытая панель отъехала вправо за экран и растягивала страницу
     по горизонтали: на телефоне появлялась прокрутка вбок на 12 px. */
  overflow: hidden;
  /* visibility не анимируется — без задержки шторка исчезала мгновенно и
     закрытие выглядело обрывом. Гасим её после того, как уход доиграл. */
  transition: visibility 0s linear 0.82s;
}
.navsheet[data-nav="open"] { pointer-events: auto; visibility: visible; transition-delay: 0s; }

.navsheet__dim {
  position: absolute; inset: 0; cursor: pointer;
  background: oklch(0.14 0.02 40 / 0.55);
  opacity: 0; transition: opacity 0.45s var(--ease) 0.35s;
}
.navsheet[data-nav="open"] .navsheet__dim { opacity: 1; transition-delay: 0s; }

.navsheet__panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(560px, 100vw);
  display: flex; flex-direction: column; overflow: hidden;
  /* translate3d, а не translateX: Safari на iPhone иначе не всегда уводит
     панель на GPU и въезд идёт рывками. */
  transform: translate3d(100%, 0, 0);
  transition: transform 0.7s cubic-bezier(0.65, 0.01, 0.05, 0.99) 0.1s;
  will-change: transform;
}
.navsheet[data-nav="open"] .navsheet__panel { transform: translate3d(0, 0, 0); transition-delay: 0s; }


.navsheet__bg { position: absolute; inset: 0; overflow: hidden; }
.navsheet__layer {
  position: absolute; inset: 0;
  transform: translate3d(101%, 0, 0);
  transition: transform 0.575s cubic-bezier(0.65, 0.01, 0.05, 0.99);
  will-change: transform;
}
.navsheet__layer--1    { background: var(--terracotta-hot);  transition-delay: 0.22s; }
.navsheet__layer--2    { background: var(--terracotta-deep); transition-delay: 0.11s; }
.navsheet__layer--base { background: var(--cream);           transition-delay: 0s;    }
.navsheet[data-nav="open"] .navsheet__layer--1    { transform: translate3d(0, 0, 0); transition-delay: 0s;    }
.navsheet[data-nav="open"] .navsheet__layer--2    { transform: translate3d(0, 0, 0); transition-delay: 0.11s; }
.navsheet[data-nav="open"] .navsheet__layer--base { transform: translate3d(0, 0, 0); transition-delay: 0.22s; }
/* Многослойный въезд остаётся и на телефоне — он и задуман как приём.
   Рывки на iPhone давали не слои, а два соседа: блокировка прокрутки у body
   (перестраивала вьюпорт вместе с адресной строкой ровно на первом кадре)
   и полупрозрачная шапка с размытием, которую Safari пересчитывал каждый
   кадр. Первое отложено в скрипте, вторая прячется на время открытия. */


.navsheet__in {
  position: relative; z-index: 2; flex: 1;
  display: flex; flex-direction: column;
  padding: clamp(5rem, 12vh, 7rem) clamp(1.25rem, 5vw, 2.4rem) clamp(1.5rem, 4vh, 2.2rem);
  color: var(--ink-on-cream); overflow-y: auto;
}
.navsheet__close {
  position: absolute; top: clamp(1rem, 3vh, 1.6rem); right: clamp(1.25rem, 5vw, 2.4rem);
  display: inline-flex; align-items: center; gap: 0.5rem;
  min-height: 44px; padding: 0 1rem;
  border: 1px solid oklch(0.48 0.130 35 / 0.3); border-radius: var(--radius-pill);
  background: transparent; color: var(--terracotta); cursor: pointer;
  font-family: var(--font-text); font-size: 0.86rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  transition: background-color 0.28s var(--ease), border-color 0.28s var(--ease);
}
.navsheet__close:hover { background: oklch(0.48 0.130 35 / 0.08); border-color: oklch(0.48 0.130 35 / 0.6); }

.navsheet__list { list-style: none; margin: 0 0 auto; padding: 0; }
/* overflow — чтобы строка выезжала из-за собственного края, как из шторки:
   тот же приём, что на kozflow.ai. Саму строку двигает GSAP. */
.navsheet__list li {
  position: relative; overflow: hidden;
  border-top: 1px solid oklch(0.48 0.130 35 / 0.16);
}
/* Запасной путь, если GSAP не загрузился: те же появления, но переходами */
body.no-gsap .navsheet__list li {
  opacity: 0; transform: translate3d(0, 14px, 0);
  transition: opacity 0.45s var(--ease), transform 0.5s var(--ease-quart);
}
.navsheet__list li:last-child { border-bottom: 1px solid oklch(0.48 0.130 35 / 0.16); }
body.no-gsap .navsheet[data-nav="open"] .navsheet__list li { opacity: 1; transform: translate3d(0, 0, 0); }
/* Пока шторка открыта, шапку убираем: её полупрозрачная заливка с блюром
   осталась бы под шторкой и заставляла Safari пересчитывать размытие
   на каждом кадре въезда. */
body.nav-open { overflow: hidden; }
body.nav-open .topbar { opacity: 0; pointer-events: none; transition: opacity 0.2s var(--ease); }
body.no-gsap .navsheet[data-nav="open"] .navsheet__list li:nth-child(1) { transition-delay: 0.30s; }
body.no-gsap .navsheet[data-nav="open"] .navsheet__list li:nth-child(2) { transition-delay: 0.36s; }
body.no-gsap .navsheet[data-nav="open"] .navsheet__list li:nth-child(3) { transition-delay: 0.42s; }
body.no-gsap .navsheet[data-nav="open"] .navsheet__list li:nth-child(4) { transition-delay: 0.48s; }
body.no-gsap .navsheet[data-nav="open"] .navsheet__list li:nth-child(5) { transition-delay: 0.54s; }
.navsheet__list a {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  min-height: var(--tap); padding: clamp(0.5rem, 1.6vh, 0.9rem) 0.2rem;
  font-family: var(--font-display); font-size: clamp(1.9rem, 8vw, 2.6rem);
  color: var(--ink-on-cream); text-decoration: none;
  transition: color 0.3s var(--ease);
}
.navsheet__list a i {
  font-style: normal; font-family: var(--font-text); font-size: 1.1rem;
  color: var(--terracotta); opacity: 0; transform: translateX(-8px);
  transition: opacity 0.3s var(--ease), transform 0.4s var(--ease-quart);
}
.navsheet__list a:hover, .navsheet__list a:active { color: var(--terracotta); }
.navsheet__list a:hover i, .navsheet__list a:active i { opacity: 1; transform: none; }

.navsheet__contacts {
  margin-top: clamp(1.6rem, 4vh, 2.4rem);
  display: grid; gap: 0.5rem;
}
/* Карточки контактов поднимает GSAP; переходы — только запасной путь */
body.no-gsap .navsheet__contacts {
  opacity: 0; transform: translateY(14px);
  transition: opacity 0.5s var(--ease) 0.6s, transform 0.55s var(--ease-quart) 0.6s;
}
body.no-gsap .navsheet[data-nav="open"] .navsheet__contacts { opacity: 1; transform: none; }
.navsheet__label {
  display: flex; align-items: center; gap: 0.75rem;
  font-size: 0.72rem; letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--muted-on-cream); padding-bottom: 0.3rem;
}
.navsheet__label::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, oklch(0.48 0.130 35 / 0.3), transparent);
}
.navcard {
  display: grid; grid-template-columns: 46px 1fr auto; align-items: center; gap: 0.85rem;
  padding: 0.75rem 0.9rem; border-radius: 14px; text-decoration: none;
  background: oklch(0.48 0.130 35 / 0.05);
  border: 1px solid oklch(0.48 0.130 35 / 0.14);
  color: var(--ink-on-cream);
  transition: transform 0.3s var(--ease-quart), background-color 0.28s var(--ease), border-color 0.28s var(--ease);
}
.navcard:hover, .navcard:active { transform: translateY(-2px); border-color: oklch(0.48 0.130 35 / 0.4); }
.navcard__ico {
  width: 46px; height: 46px; border-radius: 12px;
  display: grid; place-items: center; color: #fff;
}
.navcard__ico svg { width: 21px; height: 21px; }
.navcard--hot .navcard__ico { background: var(--terracotta-hot); }
.navcard--ink .navcard__ico { background: var(--ink); }
.navcard--vk  .navcard__ico { background: #07f; }
.navcard__body { min-width: 0; display: grid; gap: 2px; }
.navcard__body b { font-size: 1rem; font-weight: 600; }
.navcard__body small { font-size: 0.8rem; color: var(--muted-on-cream); }
.navcard__ar { font-style: normal; color: var(--terracotta); font-size: 1.05rem; }

/* ══ 3. ГЕРОЙ: один кадр, медленный наезд ══════════════
   Было: 20-секундная нарезка из семи фото, скрабившаяся скроллом — склейки
   рвали внимание. Стало: единственный кадр зала, который очень медленно
   наезжает и сносится параллаксом. Ноль монтажных стыков.                */
/* Ровно один экран. Раньше было 130svh — запас под полёт знака; знак теперь
   стоит на месте, а лишние 30svh давали заметный шов: кадр заканчивался,
   и дальше до самых акций тянулась плоская чернильная полоса. */
.hero { position: relative; height: 100svh; background: var(--ink); }
.hero__pin { position: sticky; top: 0; height: 100svh; overflow: hidden; display: grid; place-items: center; }
.hero__still {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 62%;
  /* Наезд по скроллу убран по требованию владельца: кадр «дышал» на каждое
     движение колеса и это читалось как сбой, а не как приём. Кадр статичен. */
  transform: scale(1.06);
  transform-origin: 50% 45%;
}
/* Пятно света за курсором убрано: на светлой левой части кадра оно читалось
   как засветка объектива. Остался ровный затемняющий слой — текст поверх
   держится на нём, а не на подсветке. Слева тень плотнее: там весь текст. */
.hero__veil {
  position: absolute; inset: 0; z-index: 1;
  /* Низ был почти непрозрачным (0.97) — кадр там гас в плоскую заливку, и
     граница читалась как посторонняя тёмная полоса. Хватает 0.72: текст и
     кнопки держатся, а зал внизу остаётся видно. */
  background: linear-gradient(180deg,
    oklch(0.14 0.02 40 / 0.58) 0%,
    oklch(0.14 0.02 40 / 0.16) 26%,
    oklch(0.14 0.02 40 / 0.42) 54%,
    oklch(0.14 0.02 40 / 0.64) 78%,
    oklch(0.14 0.02 40 / 0.72) 100%);
}
.hero__body { position: relative; z-index: 2; width: 100%; color: var(--cream-on-ink); }
/* Костяк уехал влево, справа — веер отзывов. Раньше всё стояло по центру
   и правая половина кадра простаивала. */
.hero__grid {
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
  gap: clamp(1.6rem, 4vw, 4.5rem); align-items: center;
}
.hero__lede { text-align: left; }
/* Знак стоит на месте. Раньше это была пустая распорка, а рисовал знак
   летящий слой .flylogo — по требованию владельца полёт снят, знак статичен. */
.hero__logo {
  width: clamp(13rem, 24vw, 21rem); height: auto; margin: 0 0 1.3rem;
  filter: drop-shadow(0 6px 34px oklch(0.14 0.02 40 / 0.85));
}
/* Летящий знак снят: владелец попросил статичный логотип. Слой оставлен в
   разметке, чтобы не переписывать её целиком, но не показывается. */
.flylogo {
  display: none;
  position: fixed; left: 0; right: 0; top: 0;
  z-index: 90; pointer-events: none;
  justify-items: center;
  will-change: transform;
}
.flylogo__stack {
  position: relative; display: block;
  width: clamp(13rem, 24vw, 21rem);
  /* origin по верхнему краю: тогда --fly-y — это ровно координата верха знака,
     и масштаб её не сбивает. Иначе знак не попадал в причал у акций. */
  transform-origin: 50% 0;
  transform: translate(var(--fly-x, 0px), var(--fly-y, 0px)) scale(var(--fly-scale, 1));
  opacity: var(--fly-opacity, 1);
  will-change: transform, opacity;
}
.flylogo__stack img { width: 100%; height: auto; }
.flylogo__cream { filter: drop-shadow(0 6px 34px oklch(0.14 0.02 40 / 0.85)); }
.flylogo__ink {
  position: absolute; inset: 0;
  opacity: var(--fly-ink, 0);
  filter: drop-shadow(0 4px 18px oklch(0.84 0.04 78 / 0.7));
}
/* На телефоне летящего знака нет: знак живёт в капсуле шапки (.topbar__mark),
   два одинаковых знака на одном экране читались дублем. Правило стоит здесь,
   а не рядом с шапкой: медиазапрос не добавляет веса, и объявления .flylogo
   ниже по файлу перебивали бы его. */
@media (max-width: 900px) {
  .flylogo, .hero__logo { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .flylogo__stack { transform: translateY(var(--fly-rest, 0px)); }
}
/* Текст героя больше никуда не пропадает: по скроллу двигается только знак */
/* Кегль ниже прежнего step-4: в заголовке теперь адресная фраза, она вдвое
   длиннее снятого слогана и в старом размере расходилась на шесть строк. */
.hero h1 {
  font-family: var(--font-display);
  font-size: clamp(2.1rem, 1.1rem + 2.6vw, 3.5rem);
  line-height: 1.08; margin-bottom: 1.3rem;
  /* Тень плотная и короткая. Была 30px размытия при 0.8 — на светлом кадре
     она собиралась в тёмное пятно позади строк и читалась как подложка,
     владелец просил её убрать. Контраст держит общая завеса .hero__veil,
     тени остаётся только отбить края букв от фона. */
  text-shadow: 0 1px 2px oklch(0.14 0.02 40 / 0.5);
}
.hero__sub {
  max-width: 34ch; margin-bottom: 2.2rem;
  font-size: var(--step-0); line-height: 1.5; text-wrap: pretty;
  color: var(--cream-on-ink);
  /* Кегль мелкий — тень чуть заметнее, чем у заголовка, но тоже без ореола */
  text-shadow: 0 1px 3px oklch(0.14 0.02 40 / 0.6);
}
.hero__sub b { display: block; margin-top: 0.35rem; font-weight: 700; color: #fff; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.9rem; justify-content: flex-start; }
@media (max-width: 560px) { .hero__actions .btn { width: 100%; } }

/* ── Веер отзывов ─────────────────────────────────────
   Восемь настоящих отзывов с Яндекс Карт лежат стопкой, как карты в руке.
   Передняя читается целиком, за ней видны корешки следующих. Раз в семь
   секунд верхняя уходит влево, остальные подаются вперёд. */
.fan[hidden] { display: none; }
.fan { display: grid; gap: 1rem; justify-items: center; }
/* Коробка стопки держит высоту самого длинного отзыва: карточки лежат
   абсолютом друг на друге, поэтому высоту им задаёт она, а не содержимое.
   Нижняя граница поднята с 272 до 350 — после отказа от обрезки многоточием
   длинный отзыв упирался в дно и срезался. */
.fan__deck { position: relative; width: min(100%, 31rem); height: clamp(350px, 44svh, 400px); }
/* Отзыв лежит не в прямоугольнике, а в нише-михрабе: купол сверху, узкие
   плечи, двойной кант по контуру и восьмиконечная звезда в замке свода.
   Прежний кант через border-image здесь не годился — border-image рисует
   строгий прямоугольник и не идёт по куполу. */
.fan__card {
  position: absolute; left: 0; right: 0; top: 0;
  display: grid; gap: 0.6rem; align-content: start; justify-items: center;
  padding: 3.4rem clamp(1.5rem, 2.4vw, 2rem) clamp(1.3rem, 2.2vw, 1.7rem);
  border: 0;
  border-radius: 48% 48% 10px 10px / 26% 26% 3% 3%;
  background: var(--cream); color: var(--ink-on-cream);
  background-image: var(--fan-crown);
  background-repeat: no-repeat;
  background-position: center 0.95rem;
  background-size: 26px 26px;
  box-shadow: 0 20px 46px oklch(0.10 0.02 40 / 0.55);
  transform-origin: 50% 130%;
  transform: rotate(var(--rot, 0deg)) translate(var(--tx, 0px), var(--ty, 0px)) scale(var(--sc, 1));
  opacity: var(--op, 1);
  transition: transform 0.62s var(--ease), opacity 0.5s var(--ease);
  will-change: transform, opacity;
}
/* Двойная линия повторяет контур ниши: inherit радиуса даёт ту же дугу */
.fan__card::after,
.fan__card::before {
  content: ''; position: absolute; pointer-events: none;
  border-radius: inherit; border: 1px solid var(--terracotta);
}
.fan__card::after  { inset: 7px;  opacity: 0.45; }
.fan__card::before { inset: 12px; opacity: 0.25; }
.fan__card.is-out { transform: translate(-42%, -4%) rotate(-15deg) scale(0.92); opacity: 0; }
/* У карточек в глубине стопки виден только край бумаги: обрывки чужого текста
   из-под передней читались как сбой вёрстки. */
.fan__card:not(.is-front) > * { opacity: 0; transition: opacity 0.45s var(--ease); }
/* Вторая карточка приглушена, но читаема: из-под передней выглядывает начало
   следующего отзыва и плавно выходит на первый план при смене. */
.fan__card.is-next > * { opacity: 0.5; }
/* Карточки в глубине повёрнуты вокруг точки под стопкой, поэтому их углы
   свисают на стрелки под веером и перехватывают нажатия. Кликается только
   верхняя. */
.fan__card:not(.is-front) { pointer-events: none; }
/* Под куполом углы срезаны — строка «звёзды слева, источник справа» упиралась
   в дугу. Стало столбиком по центру: ложится в самую широкую часть ниши. */
.fan__top { display: grid; justify-items: center; gap: 0.2rem; text-align: center; }
.fan__stars { color: var(--terracotta-hot); font-size: 1.05rem; letter-spacing: 0.14em; line-height: 1; }
.fan__src { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted-on-cream); }
/* Отзыв показываем целиком. Обрезка многоточием была компромиссом ради
   ровной высоты стопки, но обрубленная фраза на карточке читается как брак —
   владелец потребовал убрать. Высоту стопки теперь держит самый длинный
   отзыв (см. .fan__deck). */
.fan__text {
  font-size: var(--step--1); line-height: 1.5; color: var(--ink-on-cream);
  text-align: center; text-wrap: pretty;
}
.fan__who { display: flex; align-items: baseline; justify-content: center; gap: 0.6rem; flex-wrap: wrap; width: 100%; padding-top: 0.55rem; border-top: 1px solid var(--paperline); text-align: center; }
.fan__who b { font-weight: 600; }
.fan__who span { font-size: var(--step--1); color: var(--muted-on-cream); }
/* Стрелок нет: отзыв сменяется сам раз в семь секунд или по нажатию
   на саму карточку. */
.fan__foot { display: flex; align-items: center; justify-content: center; }
.fan__sum {
  display: inline-flex; align-items: center; gap: 0.45rem; min-height: 44px;
  font-size: var(--step--1); font-weight: 600; color: var(--cream-on-ink);
  text-decoration: none; text-shadow: 0 2px 14px oklch(0.14 0.02 40 / 0.9);
  border-bottom: 1px solid oklch(0.94 0.026 82 / 0.35);
}
.fan__sum:hover { border-bottom-color: var(--cream); }

/* Ниже 1024 герой снова в одну колонку: веер уходит под кнопки и ужимается
   до одной карточки — на телефоне стопка из четырёх съедала весь экран. */
@media (max-width: 1024px) {
  /* Ниже 1024 герой не закреплён: отзыв показываем целиком, и на узком экране
     самый длинный не влезал в закреплённые 100svh — низ карточки срезался.
     Экран остаётся не меньше 100svh, но растёт под содержимое.
     Запас в 125svh был нужен под полёт знака; полёт снят, и лишние 25svh
     оставались внизу тёмной полосой без кадра — теперь ровно один экран.
     overflow — на герое: раскреплённый .hero__pin перестал быть якорем для
     кадра, и наезжающая на 12% картинка вылезала вбок, растягивая страницу. */
  .hero { height: auto; min-height: 100svh; overflow: hidden; }
  .hero__pin { position: static; height: auto; min-height: 100svh; padding-block: clamp(1rem, 3vh, 2rem); }
  .hero__grid { grid-template-columns: 1fr; gap: 1.4rem; padding-top: clamp(38px, 6vh, 60px); }
  .hero__lede { text-align: center; }
  .hero__logo { margin-inline: auto; }
  /* Подача варианта 08 «ночная вывеска»: кадр живёт сверху и дышит, весь
     текст собран внизу плотной группой, заголовок набран капсом в две-три
     короткие строки. Бегущую строку сверху владелец просил не ставить. */
  .hero__pin { align-content: end; }
  .hero__grid { align-content: end; padding-top: 0; padding-bottom: 0.5rem; }
  .hero__lede { text-align: left; }
  .hero__actions { justify-content: stretch; }
  .hero h1 {
    text-transform: uppercase; font-size: clamp(2.3rem, 11vw, 3.1rem);
    line-height: 0.96; margin-bottom: 0.9rem;
  }
  .hero__sub { margin-inline: 0; margin-bottom: 1.3rem; font-size: var(--step--1); }
  .hero__sub b { margin-top: 0.3rem; }
  .hero .fan__foot { justify-content: flex-start; }
  .hero__still { object-position: 50% 40%; }
  /* Стопка остаётся веером и на телефоне — она переехала в блок отзывов,
     где под неё есть место. Разлёт скрипт считает отдельным набором. */
  .fan__deck { width: min(100%, 30rem); height: clamp(430px, 56svh, 480px); }
  /* Карточки одной высоты: раньше каждая тянулась под свой текст, и задняя
     с длинным отзывом торчала из-под передней голым листом далеко вниз.
     Отступ снизу — ровно под сдвиг стопки, чтобы её хвост остался в коробке. */
  /* Содержимое распирается по высоте: подпись автора садится на нижний край,
     и в просвете под передней карточкой видно, чей отзыв идёт следующим,
     а не пустое поле бумаги. */
  /* Содержимое собрано по центру карточки: при растяжке на всю высоту
     у коротких отзывов между текстом и подписью зияла дыра. */
  .fan__card { bottom: 92px; align-content: center; }
  /* В герое от веера остаётся одна строка с оценкой — сама стопка уехала
     в блок отзывов. Строку поднимаем к кнопкам, чтобы не висела в пустоте. */
  .hero .fan { gap: 0; }
  .hero .fan__foot { justify-content: center; }
  .fan__sum { font-size: 0.86rem; text-align: center; }
}
@media (max-width: 560px) {
  .hero { height: 125svh; }
  /* Верхний отступ не трогаем: под ним купол ниши и звезда в замке свода */
  .fan__card { padding: 3rem 1.1rem 1.1rem; gap: 0.55rem; }
}
/* Стрелка «листайте вниз» удалена по требованию владельца: страница и так
   очевидно прокручивается, а кружок наезжал на веер отзывов. */

/* ══ 4. БЕГУЩАЯ СТРОКА: ходовые блюда с ценами ════════
   Скорость задаётся скриптом от ширины ленты (~48 px/сек), а не жёстким
   временем: аудитория 45–65 должна успевать прочитать название и цену.   */
.ticker {
  background: var(--terracotta); color: #fff; overflow: hidden;
  padding: 0.95rem 0;
  border-block: 1px solid oklch(0.94 0.026 82 / 0.22);
}
.ticker__track { display: flex; width: max-content; animation: slide var(--dur, 60s) linear infinite; }
.ticker__item {
  display: inline-flex; align-items: baseline; gap: 0.65rem;
  padding-inline: 1.6rem;
  white-space: nowrap;
  font-family: var(--font-display); font-size: var(--step-1);
}
.ticker__item::after {
  content: '';
  width: 5px; height: 5px; border-radius: 50%;
  background: oklch(0.94 0.026 82 / 0.55);
  margin-left: 1.6rem; align-self: center;
}
.ticker__price {
  font-family: var(--font-text); font-weight: 700;
  font-size: var(--step--1);
  padding: 0.14em 0.6em; border-radius: var(--radius-pill);
  background: oklch(0.94 0.026 82 / 0.16);
}
@keyframes slide { to { transform: translateX(-50%); } }
.ticker:hover .ticker__track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .ticker__track { animation: none; } }

/* ══ 5. АКЦИИ: карусель под героем ═════════════════════
   Раньше это была узкая полоса поверх шапки. Стало — полноширинная
   витрина сразу под геройским экраном. Смена раз в 9 секунд и всегда
   с паузой по наведению: ядро аудитории 45–65, текст надо успеть прочесть. */
.promos { position: relative; background: var(--ink); overflow: hidden; }
/* Шов с героем: кадр героя упирался в кадр акции голой линией.
   Верх акции уходит в тень — стык растворяется, узор рисовать не нужно. */
.promos::before {
  content: ''; position: absolute; inset: 0 0 auto 0; z-index: 3; pointer-events: none;
  height: clamp(56px, 9vh, 120px);
  background: linear-gradient(180deg, var(--ink) 0%, oklch(0.16 0.02 40 / 0.72) 42%, transparent 100%);
}
.promos__viewport { position: relative; height: clamp(440px, 62svh, 660px); }
/* Причал знака «Восток 24»: пустая коробка, по ней скрипт считает,
   куда прилететь лого из героя. Ничего не рисует. */
.promos__mark {
  position: absolute; left: 50%; translate: -50% 0; z-index: 4;
  /* Ниже каёмки на шве: знак садился прямо на орнамент и наезжал на него */
  top: calc(var(--orn-h) + clamp(1rem, 2.6vh, 1.8rem));
  width: clamp(9rem, 15vw, 13.5rem); aspect-ratio: 1400 / 302;
  pointer-events: none;
}
.promos__mark img {
  width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 6px 28px oklch(0.14 0.02 40 / 0.8));
}
/* Кадры сменяются свайпом влево, а не проявлением: перекрёстное затухание
   двух движущихся зумов читалось как дёрганье. */
.promos__slide, .popup__slide {
  position: absolute; inset: 0;
  display: block; text-decoration: none; color: var(--cream-on-ink);
  pointer-events: none;
  /* overflow скрывает то, что кадр за время наезда вырастает на 12%:
     у уехавшего слайда картинка вылезала за его край и светлой полосой
     торчала с другой стороны экрана. */
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.85s var(--ease-quart);
  will-change: transform;
}
.promos__slide.is-on, .popup__slide.is-on { transform: none; pointer-events: auto; z-index: 2; }
.promos__slide.is-out-left, .popup__slide.is-out-left { transform: translateX(-100%); }
.promos__slide.is-out-right, .popup__slide.is-out-right { transform: translateX(100%); }
.promos__slide img, .promos__media {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.04);
}
/* Видео вертикальное (снято на телефон), кадр широкий — cover обрезает
   по бокам одинаково что на ПК, что на телефоне, лицо остаётся в кадре. */
.promos__media { object-position: 50% 30%; }
/* Медленный наезд идёт только у активного кадра — иначе браузер
   анимирует все четыре сразу и роняет частоту. Видео своим движением уже
   занято, наезд ему не нужен. */
.promos__slide.is-on img, .popup__slide.is-on img { animation: promoZoom 11s linear forwards; }
@keyframes promoZoom { to { transform: scale(1.12); } }
.promos__shade {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, oklch(0.14 0.02 40 / 0.86) 0%, oklch(0.14 0.02 40 / 0.55) 45%, oklch(0.14 0.02 40 / 0.15) 100%),
              linear-gradient(0deg, oklch(0.14 0.02 40 / 0.7) 0%, transparent 45%);
}
/* Содержимое слайда обязано жить внутри кадра, а не распирать его: сверху
   мешала каёмка (плашка вставала прямо под орнамент), снизу — точки и стык
   с бегущей строкой. Поля считаются от них, а не «на глаз». */
.promos__body {
  position: relative; z-index: 2;
  width: min(100% - var(--gutter) * 2, 1240px); margin-inline: auto;
  height: 100%; display: grid; align-content: center; gap: 0.8rem;
  max-width: min(100% - var(--gutter) * 2, 1240px);
  padding-top: calc(var(--orn-h) + 1.7rem);
  padding-bottom: 3.6rem;
  overflow: hidden;
}
/* Колонка шире прежних 34ch: у самого длинного заголовка («Первый в Твери
   пункт самовывоза в ресторане») при узкой колонке набиралось четыре
   дисплейные строки, и они одни съедали весь кадр. */
.promos__text { max-width: 40ch; display: grid; gap: 0.8rem; }
.promos__badge {
  justify-self: start;
  font-size: var(--step--1); font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  background: var(--terracotta-hot); color: #fff;
  padding: 0.4rem 0.85rem; border-radius: 5px;
}
/* Кегль срезан против общего --step-3: заголовок акции — не заголовок
   страницы, а подпись к кадру, и в высоту слайда он должен влезать
   вместе с плашкой, описанием и кнопками. */
.promos__title {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.05rem + 1.95vw, 2.7rem);
  line-height: 1.06;
  /* Строки делятся по смыслу и по длине, а не по остатку ширины: у самого
     длинного заголовка получалось «Первый в Твери / пункт / самовывоза в /
     ресторане» — рваная лесенка на четыре строки. С балансировкой выходит
     ровно то, что просил владелец: «Первый в Твери / пункт самовывоза /
     в ресторане». */
  text-wrap: balance;
}
/* Телефонные варианты плашки и описания в широком макете не показываются:
   на ПК подача прежняя — плашка, дисплейный заголовок, текст. */
@media (min-width: 701px) {
  .promos__badge--mob, .promos__lead--mob { display: none; }
}
/* Описание балансируется так же, как заголовок: иначе последняя строка
   повисала одним словом («кухня.»), а первая шла во всю ширину. */
.promos__lead { font-size: var(--step-0); color: oklch(0.9 0.015 82); text-wrap: balance; }
/* Кнопки каруселей прозрачные: плотная кремовая плашка забивала кадр,
   а он в акции главный. Единственное исключение — «Заказать доставку»
   (модификатор --fill): это платный сценарий, он должен выделяться. */
.promos__go {
  justify-self: start; margin-top: 0.5rem;
  display: inline-flex; align-items: center; gap: 0.55rem;
  min-height: var(--tap); padding: 0 1.7rem; border-radius: var(--radius-pill);
  background: transparent; color: var(--cream); font-weight: 700;
  border: 1px solid oklch(0.94 0.026 82 / 0.55);
  text-decoration: none;
  transition: background-color 0.3s var(--ease), transform 0.35s var(--ease), border-color 0.3s var(--ease);
}
.promos__slide:hover .promos__go, .popup__slide:hover .promos__go {
  background: oklch(0.94 0.026 82 / 0.14); border-color: oklch(0.94 0.026 82 / 0.8); transform: translateY(-2px);
}
.promos__go--fill { background: var(--cream); color: var(--ink); border-color: var(--cream); }
.promos__slide:hover .promos__go--fill, .popup__slide:hover .promos__go--fill { background: #fff; border-color: #fff; }
/* Слайд с двумя сценариями (доставка + самовывоз): группа двух кнопок вместо
   одной. Внешняя .promos__go тут просто flex-обёртка без своего фона —
   стили пилюли остаются только на вложенных <a>. */
/* min-width: 0 обязателен: без него две кнопки с nowrap задают минимальную
   ширину всей колонке грида, и текст слайда вылезал за край панели. */
/* border: 0 обязателен — обёртка носит класс .promos__go и иначе забирает
   его рамку, вокруг пары кнопок появлялся лишний контур. */
.promos__go--group { display: flex; flex-wrap: nowrap; gap: 0.6rem; min-width: 0; max-width: 100%; background: none !important; border: 0 !important; padding: 0 !important; min-height: 0 !important; }
/* Две кнопки стоят в ряд и вдвое компактнее одиночной: столбиком они
   занимали треть экрана телефона и выдавливали кадр. */
.promos__go--group .promos__go {
  margin-top: 0;
  min-height: 46px; padding: 0 0.95rem;
  font-size: var(--step--1); white-space: nowrap;
}
.promos__go--group .promos__go svg { width: 14px; height: 14px; }
/* .promos__go--ghost больше не нужен: прозрачность стала поведением
   по умолчанию, выделяется наоборот — .promos__go--fill. */
.promos__go--group .promos__go { border-width: 1px; }

/* Кругов по 52 px внизу больше нет — они забирали целую полосу кадра.
   Слой управления растянут на весь кадр и сам сквозной (pointer-events: none),
   ловят нажатия только точки и стрелки. Стрелки — голые шевроны по краям,
   без фона и окантовки: подсказка, что можно листать, а не кнопка-плашка. */
.promos__ui { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.promos__dots {
  position: absolute; left: 50%; translate: -50% 0; bottom: clamp(0.7rem, 2vh, 1.2rem);
  pointer-events: auto;
}
.promos__arrow, .popup__arrow {
  position: absolute; top: 50%; translate: 0 -50%;
  width: 46px; height: 72px; flex: none;
  display: grid; place-items: center;
  padding: 0; border: 0; background: none; box-shadow: none; backdrop-filter: none;
  color: oklch(0.94 0.026 82 / 0.4); cursor: pointer; pointer-events: auto;
  transition: color 0.3s var(--ease), transform 0.3s var(--ease);
}
.promos__arrow:hover, .popup__arrow:hover { color: oklch(0.94 0.026 82 / 0.95); }
/* Браузер рисовал вокруг шеврона свою рамку после нажатия — на кадре она
   читалась как посторонняя коробка. Стрелка и так отзывается цветом, а для
   клавиатуры остаётся собственная подсветка ниже. */
.promos__arrow:focus, .popup__arrow:focus { outline: none; }
.promos__arrow:focus-visible, .popup__arrow:focus-visible {
  outline: none; color: oklch(0.94 0.026 82 / 0.95);
  text-shadow: 0 0 12px oklch(0.94 0.026 82 / 0.6);
}
.promos__arrow svg, .popup__arrow svg { width: 30px; height: 30px; }
.promos__ui .promos__arrow:first-child, .popup__ui .popup__arrow:first-child { left: clamp(0.1rem, 1.2vw, 0.9rem); }
.promos__ui .promos__arrow:last-child, .popup__ui .popup__arrow:last-child { right: clamp(0.1rem, 1.2vw, 0.9rem); }
.promos__arrow:first-child:hover { transform: translateX(-3px); }
.promos__arrow:last-child:hover { transform: translateX(3px); }
.promos__dots, .popup__dots { display: flex; gap: 8px; align-items: center; justify-content: center; }
/* Лента и всплывашка тянутся пальцем и мышью — текст под курсором при
   протяжке выделяться не должен, снимок не должен «отрываться». */
.promos__viewport, .popup__track { touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.promos__slide img, .popup__slide img, .promos__media { -webkit-user-drag: none; user-drag: none; }
.promos__dot, .popup__dot {
  position: relative;
  width: 10px; height: 10px; padding: 0; border: 0; border-radius: 50%;
  background: oklch(0.94 0.026 82 / 0.42); cursor: pointer;
  transition: width 0.4s var(--ease), background-color 0.3s var(--ease);
}
/* Точка маленькая, но палец должен попадать: расширяем зону нажатия до 44px */
.promos__dot::after, .popup__dot::after { content: ''; position: absolute; inset: -17px -6px; }
.promos__dot.is-on, .popup__dot.is-on { background: var(--cream); width: 30px; border-radius: 5px; }

@media (max-width: 700px) {
  /* Запас поднят: у части слайдов заголовок в две строки (было гарантированно
     в одну), и без запаса бейдж наверху обрезался — контент прижат к низу
     (align-content: end), а слайд режет overflow:hidden. */
  .promos__viewport { height: clamp(460px, 80svh, 660px); }
  .promos__shade { background: linear-gradient(0deg, oklch(0.14 0.02 40 / 0.9) 8%, oklch(0.14 0.02 40 / 0.45) 62%, oklch(0.14 0.02 40 / 0.2) 100%); }
  /* стрелок под лентой больше нет — запас снизу срезан, текст стоит ниже.
     Справа оставлен коридор под плавающие кнопки: без него вторая кнопка
     слайда уходила прямо под них. */
  .promos__body { align-content: end; padding-block: 0 3.4rem; padding-right: 3.1rem; gap: 0.6rem; }
  .promos__go { width: 100%; justify-content: center; }
  /* группа из двух кнопок остаётся рядом и делит ширину пополам; текст
     переносится в две строки, стрелка на телефоне не нужна */
  .promos__text { max-width: 100%; }
  .promos__go--group .promos__go {
    width: auto; flex: 1 1 0; min-width: 0;
    padding: 0 0.5rem; justify-content: center; text-align: center;
    white-space: normal; line-height: 1.15; font-size: 0.86rem;
  }
  .promos__go--group .promos__go svg { display: none; }
  .promos__ui { justify-content: center; width: 100%; }
  /* Телефонная подача (правка владельца 13.08): дисплейного заголовка нет,
     всю нагрузку несут терракотовая плашка и описание. Плашка за счёт этого
     стала крупнее и плотнее, и села вплотную к тексту — заголовок между ними
     больше не стоит. Кадра при этом видно заметно больше. */
  .promos__title { display: none; }
  .promos__badge--pc { display: none; }
  .promos__lead--pc { display: none; }
  /* Левый шеврон падал прямо на первую букву описания — текст к левому краю
     прижат, места под него нет. Остаётся только правый: листать вперёд, а
     назад — пальцем. */
  .promos__ui .promos__arrow:first-child,
  .popup__ui .popup__arrow:first-child { display: none; }
  /* Плашка была мельче описания (0.84rem против ~1.11rem у --step-0) и в
     иерархии проваливалась. Теперь она крупнее описания и набрана плотнее по
     межбуквенному просвету — иначе самые длинные подписи («Музыкальная
     шоу-программа») переставали влезать в строку. Поля увеличены под кегль. */
  .promos__badge {
    font-size: 1.2rem; font-weight: 800; letter-spacing: 0;
    padding: 0.54rem 0.8rem; border-radius: 7px;
    max-width: max-content;
    margin-bottom: -0.15rem;   /* подтягивает плашку вниз, к описанию */
  }
  .promos__text { gap: 0.42rem; }
  /* Слайды с двумя кнопками и длинным описанием (доставка+самовывоз) не
     помещались в закреплённую высоту — бейдж наверху срезало. Ритм строк
     сжат у всех карточек разом: чуть плотнее и заголовок, и описание, и
     зазор перед кнопками. */
  .promos__text { gap: 0.5rem; }
  .promos__title { line-height: 0.98; }
  .promos__lead { line-height: 1.34; }
  .promos__go--group { gap: 0.5rem; }
}

/* ══ 5b. ВСПЛЫВАЮЩАЯ АКЦИЯ ════════════════════════════
   Показывается через 5 секунд и не чаще раза в сутки — закрыл,
   значит закрыл. Листается стрелками, точками и пальцем.        */
.popup[hidden] { display: none; }
.popup { position: fixed; inset: 0; z-index: var(--z-sheet); display: grid; place-items: center; padding: var(--gutter); }
.popup__backdrop { position: absolute; inset: 0; background: oklch(0.14 0.02 40 / 0.78); backdrop-filter: blur(4px); opacity: 0; transition: opacity 0.45s var(--ease); }
.popup.is-in .popup__backdrop { opacity: 1; }
.popup__panel {
  position: relative; z-index: 2;
  width: min(100%, 880px); max-height: min(90svh, 760px);
  border-radius: var(--radius); overflow: hidden; background: var(--ink);
  transform: scale(0.94) translateY(16px); opacity: 0;
  transition: transform 0.5s var(--ease), opacity 0.35s var(--ease);
}
.popup.is-in .popup__panel { transform: none; opacity: 1; }
.popup__track { position: relative; height: min(76svh, 620px); }
.popup__slide img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.popup__slide .promos__shade { background: linear-gradient(0deg, oklch(0.14 0.02 40 / 0.92) 12%, oklch(0.14 0.02 40 / 0.4) 62%, transparent 100%); }
/* Запас снизу был 6rem под стрелки — их нет, остаётся место под мелкий
   индикатор. Текст и кнопки за счёт этого стоят ниже, кадра видно больше. */
.popup__body { position: relative; z-index: 2; height: 100%; display: grid; align-content: end; gap: 0.85rem; padding: clamp(1.5rem, 4vw, 2.8rem); padding-bottom: 3.6rem; }
/* Слайд доставки — самый длинный: плашка, крупный заголовок, четыре строки
   описания и сразу две кнопки. На невысоком экране всё это съезжалось, и
   последняя строка текста подпирала кнопки. Заголовок здесь ограничен по
   кеглю и высоте, а перед кнопками стоит собственный отступ, который не
   схлопывается вместе с общим зазором. */
.popup__panel .promos__title {
  font-size: clamp(1.9rem, 3.4vw, 3.1rem);
  max-height: 4.2em; overflow: hidden;
  text-wrap: balance;
}
/* Колонка во всплывашке считается от панели, а не в «ch»: кегль заголовка
   здесь дисплейный и крупный, и мера в символах описания давала колонку
   вдвое уже нужной — заголовок рассыпался на четыре куцых строки. */
.popup__panel .promos__text { max-width: min(100%, 27rem); }
.popup__panel .promos__go--group,
.popup__panel .promos__go { margin-top: 0.5rem; }
.popup__panel .promos__lead { max-height: 7.5em; overflow: hidden; }
.popup__close {
  position: absolute; right: 12px; top: 12px; z-index: 5;
  width: 52px; height: 52px; border-radius: 50%; border: 0;
  background: oklch(0.14 0.02 40 / 0.6); color: #fff; font-size: 1.4rem; cursor: pointer;
  display: grid; place-items: center;
}
.popup__close:hover { background: oklch(0.14 0.02 40 / 0.9); }
/* Тот же приём, что в ленте акций: слой на весь кадр и сквозной, точки по
   центру снизу, шевроны по краям. */
.popup__ui { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.popup__dots {
  position: absolute; left: 50%; translate: -50% 0; bottom: clamp(0.9rem, 2.4vh, 1.3rem);
  pointer-events: auto;
}

/* ══ 6. ТРИ ДВЕРИ ═════════════════════════════════════ */
.doors { background: var(--cream-deep); padding: var(--section) 0; }
.doors__head { margin-bottom: clamp(1.4rem, 2.8vw, 2.2rem); }
.doors__title { font-family: var(--font-display); font-size: var(--step-3); color: var(--terracotta); line-height: 1.05; }
.doors__lede { margin-top: 0.7rem; max-width: 58ch; font-size: var(--step--1); color: var(--muted-on-cream); }
.doors__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: clamp(1rem, 2vw, 1.5rem); }
/* На широком экране четыре двери всегда стоят одним рядом: при колонке 1240 px
   четвёртая переносилась вниз и висела одиноким огрызком. Секция забирает
   больше ширины, чем остальной сайт, — карточкам нужен размер, они здесь
   главный экран выбора. */
@media (min-width: 1080px) {
  /* Именно width, а не max-width: у общего .wrap ширина задана свойством
     width, и max-width её не расширял — секция все эти месяцы оставалась
     в общих 1240 px, хотя правило писалось ради 1620. */
  .doors > .wrap { width: min(100% - var(--gutter) * 2, 1620px); }
  .doors__grid { grid-template-columns: repeat(4, 1fr); gap: clamp(1rem, 1.4vw, 1.4rem); }
  /* Колонка узкая, кадр должен быть высоким — иначе текст съедает весь снимок.
     13.08.2026 карточки заметно вытянуты (было 3/4.6): при прежней высоте
     текстовая группа занимала почти весь кадр и от снимка оставалась полоска
     сверху. Кегль не трогали — прибавка целиком ушла снимку. */
  .doors .door { aspect-ratio: 3 / 5; }
  .doors .door h3 { font-size: clamp(1.6rem, 1.1rem + 1vw, 2.3rem); line-height: 1.05; }
  .doors .door p { max-width: 100%; }
  /* Кегль кнопки в общем правиле растёт от ширины ОКНА, а здесь колонка одна
     четвёртая от него: «Позвонить администратору» в одну строку переставало
     влезать и уезжало за кадр вместе со стрелкой. В сетке дверей кнопка
     набирается мельче и с более тесными полями. */
  .doors .door__cta { font-size: 0.84rem; padding-inline: 0.75rem; gap: 0.4rem; }
}
/* Были белые карточки с картинкой сверху — на кремовом фоне они выглядели
   пришельцами из другого макета. Весь сайт держится на кадре с затемнением,
   поэтому и двери стали кадром во всю плитку, текст поверх. */
.door {
  position: relative; display: block; isolation: isolate;
  aspect-ratio: 4 / 5; border-radius: var(--radius); overflow: hidden;
  text-decoration: none; color: var(--cream-on-ink);
  box-shadow: 0 10px 28px oklch(0.18 0.02 40 / 0.16);
  transition: transform 0.45s var(--ease), box-shadow 0.45s var(--ease),
              opacity 0.45s var(--ease), filter 0.45s var(--ease);
}
.door:hover { transform: translateY(-5px); box-shadow: 0 20px 44px oklch(0.18 0.02 40 / 0.3); }
.door__img { position: absolute; inset: 0; }
.door__img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.9s var(--ease); }
.door:hover .door__img img { transform: scale(1.06); }
/* Текст ложится на кадр, где часто светлые кресла и белые скатерти,
   поэтому затемнение в средней зоне плотное, а не декоративное. */
.door__veil {
  position: absolute; inset: 0;
  background: linear-gradient(0deg, oklch(0.13 0.02 40 / 0.95) 6%, oklch(0.13 0.02 40 / 0.86) 34%, oklch(0.13 0.02 40 / 0.5) 62%, oklch(0.13 0.02 40 / 0.16) 100%);
}
/* Текстовая группа стоит в самом низу кадра и набрана по центру: раньше она
   жалась к левому краю, и в высокой карточке низ выглядел свёрстанным набок
   (правка владельца 13.08). */
.door__body {
  position: relative; z-index: 2; height: 100%;
  display: grid; align-content: end; justify-items: center; text-align: center;
  gap: 0.45rem; padding: clamp(1.3rem, 2.4vw, 1.9rem);
}
.door__kicker { font-size: 0.76rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: oklch(0.82 0.12 55); }
/* Плашку под банкетом пробовали и отменили: владелец вернул подачу как у
   остальных дверей — цветная строка без подложки, поменялся только текст
   («100 гостей» → «Банкетное предложение»). Класс оставлен пустым, чтобы не
   трогать разметку, если плашка вдруг понадобится снова. */
.door h3 { font-family: var(--font-display); font-size: var(--step-2); color: var(--cream-on-ink); margin-bottom: 0.15rem; }
.door p { font-size: var(--step--1); color: oklch(0.9 0.015 82); max-width: 34ch; }
/* Кнопки дверей — прозрачные с тонкой рамкой, как в каруселях: кремовая
   плашка закрашивала треть кадра. Заливка осталась только у доставки.
   nowrap: «Позвонить администратору» ломалось на две строки и кнопка
   раздувалась в пустой прямоугольник. */
.door__cta {
  justify-self: center; margin-top: 0.8rem;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 52px; padding: 0 1.25rem; border-radius: var(--radius-pill);
  background: transparent; color: var(--cream-on-ink); font-weight: 700;
  font-size: clamp(0.82rem, 0.68rem + 0.3vw, 0.98rem);
  white-space: nowrap;
  /* Ширины карточки кнопке хватало не всегда: «Позвонить администратору» в
     одну строку вылезало за кадр вместе со стрелкой. Ограничение по ширине
     плюс сжимаемые поля держат её внутри — вместо обрезанной стрелки
     сжимаются отступы. */
  max-width: 100%; padding-inline: clamp(0.7rem, 3vw, 1.25rem);
  border: 1px solid oklch(0.94 0.026 82 / 0.55);
  transition: background-color 0.3s var(--ease), transform 0.35s var(--ease), border-color 0.3s var(--ease);
}
/* Оранжевая заливка у доставки снята 13.08.2026: все четыре кнопки дверей
   одинаковые — прозрачные с тонкой светлой рамкой. */
.door:hover .door__cta { transform: translateY(-2px); background: oklch(0.94 0.026 82 / 0.16); border-color: oklch(0.94 0.026 82 / 0.85); }
/* Каре ягнёнка лежит в нижней трети кадра и пряталось за текстом:
   окно кадрирования сдвинуто вниз по снимку, мясо поднимается выше. */
.door__img--low { object-position: center 78%; }
/* Наведение у доставки тоже стало общим — своей оранжевой подсветки больше нет */
/* Наведение выделяет одну дверь и приглушает соседние: ряд читается как
   выбор, а не как четыре равных плитки. Только мышь — на тапе приглушать
   нечего, а blur на снимке 1800 px там дорого стоит. */
@media (hover: hover) and (pointer: fine) {
  .doors__grid:hover .door {
    transform: scale(0.97);
    opacity: 0.55;
    filter: blur(2px);
  }
  .doors__grid:hover .door:hover,
  .doors__grid .door:focus-visible {
    transform: scale(1.04);
    opacity: 1;
    filter: none;
    z-index: 3;
  }
  .doors__grid:hover .door:hover { box-shadow: 0 26px 54px oklch(0.18 0.02 40 / 0.34); }
}
/* Номер под кнопкой убран: кнопка и так набирает его, а строка серым
   висела хвостом и ломала низ карточки. */
.door__phone { display: none; }
@media (max-width: 560px) { .door { aspect-ratio: 5 / 6; } }

/* ══ 7. МЕНЮ ══════════════════════════════════════════ */
.menu { background: var(--cream); padding: var(--section) 0; }
.menu__head { margin-bottom: 2rem; }
.menu h2 { font-family: var(--font-display); font-size: var(--step-3); color: var(--terracotta); margin-bottom: 0.5rem; }
/* Кегль подсказки уравнен с .menuboard__hint («Листайте вбок») — владелец
   попросил тот же размер, был крупнее обычного текста. */
.menu__lead { color: var(--muted-on-cream); max-width: 62ch; font-size: var(--step--1); }

/* Полоса категорий прокручивается — правый край растворяется,
   чтобы это было видно без полосы прокрутки */
/* Полоса выходит за поля колонки и добирает отступ внутрь: раньше последние
   категории («К пиву», «Банкетное») упирались в край и не долистывались. */
.tabs { position: sticky; top: 12px; z-index: 40; display: flex; gap: 0.5rem; overflow-x: auto;
  padding: 0.9rem var(--gutter); margin: 0 calc(var(--gutter) * -1) 1.8rem;
  scroll-padding-inline: var(--gutter);
  background: var(--cream); border-bottom: 1px solid var(--paperline); scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 28px, #000 calc(100% - 48px), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 28px, #000 calc(100% - 48px), transparent 100%); }
.tabs::-webkit-scrollbar { display: none; }
.tab { flex: 0 0 auto; min-height: 48px; padding: 0 1.2rem; border: 1px solid var(--paperline); background: transparent; color: var(--ink-on-cream); border-radius: var(--radius-pill); font-size: var(--step--1); font-weight: 600; cursor: pointer; transition: background-color 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease); white-space: nowrap; }
.tab:hover { border-color: var(--terracotta); }
.tab[aria-selected='true'] { background: var(--terracotta); border-color: var(--terracotta); color: var(--cream); }

/* ── Доска меню: кухня и бар одинаковым устройством ──── */
.menuboard + .menuboard { margin-top: clamp(3rem, 6vw, 5.5rem); }
.menuboard__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem 2rem; flex-wrap: wrap; }
.menuboard__head h3 { font-family: var(--font-display); font-size: var(--step-2); color: var(--terracotta); }
/* Стрелка у подсказки: что ленту категорий можно тянуть вбок, по одному
   тексту не читалось. Слегка подталкивается вправо — намёк на жест. */
.menuboard__hint { display: inline-flex; align-items: center; gap: 0.5rem; font-size: var(--step--1); color: var(--muted-on-cream); }
.menuboard__hint::after {
  content: ''; width: 20px; height: 20px; flex: none;
  background: currentColor;
  -webkit-mask: var(--swipe-arrow) center / contain no-repeat;
  mask: var(--swipe-arrow) center / contain no-repeat;
  animation: hintNudge 1.9s ease-in-out infinite;
}
@keyframes hintNudge { 0%, 60%, 100% { transform: none; } 30% { transform: translateX(5px); } }
@media (prefers-reduced-motion: reduce) { .menuboard__hint::after { animation: none; } }

/* ── Карусель блюд ────────────────────────────────────
   Лента выходит за поля колонки: карточки уезжают за край экрана,
   а не упираются в невидимую стенку. Снап — чтобы палец на телефоне
   всегда останавливал ленту на целой карточке.                        */
.dishrail__wrap { position: relative; }
.dishrail {
  display: flex; gap: clamp(0.8rem, 1.6vw, 1.3rem);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-padding-left: var(--gutter);
  scrollbar-width: none;
  margin-inline: calc(var(--gutter) * -1);
  padding: 0.4rem var(--gutter) 1.1rem;
}
.dishrail::-webkit-scrollbar { display: none; }

.card {
  flex: 0 0 clamp(228px, 25vw, 312px);
  scroll-snap-align: start;
  display: grid; grid-template-rows: auto auto; gap: 0;
  padding: 0; border: 0; background: none; text-align: left;
  color: var(--ink-on-cream); cursor: pointer;
}
.card__media {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden;
  border-radius: var(--radius);
  box-shadow: 0 10px 26px oklch(0.18 0.02 40 / 0.14);
  transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease);
  /* Пока снимок едет, на месте карточки было глухое терракотовое пятно —
     на светлой полосе меню оно било в глаза сильнее самих блюд. Теперь
     спокойная песочная подложка с медленным бликом: видно, что снимок
     грузится, но взгляд она не перетягивает. */
  background: var(--sand, oklch(0.93 0.014 82));
}
.card__media::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(100deg,
    transparent 20%, oklch(1 0 0 / 0.55) 50%, transparent 80%);
  background-size: 220% 100%;
  animation: cardShimmer 1.6s linear infinite;
}
/* Блик гаснет, как только снимок на месте */
.card__media.is-ready::before { display: none; }
@keyframes cardShimmer {
  from { background-position: 140% 0; }
  to   { background-position: -40% 0; }
}
.card:hover .card__media { transform: translateY(-5px); box-shadow: 0 18px 38px oklch(0.18 0.02 40 / 0.22); }
.card__media img {
  position: relative; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  /* Снимок не возникает щелчком, а проявляется с лёгким наездом */
  opacity: 0; transform: scale(1.04);
  transition: opacity 0.55s var(--ease), transform 0.9s var(--ease);
}
.card__media.is-ready img { opacity: 1; transform: none; }
.card:hover .card__media.is-ready img { transform: scale(1.07); }
@media (prefers-reduced-motion: reduce) {
  .card__media::before { animation: none; }
  .card__media img { opacity: 1; transform: none; transition: none; }
}
/* Снимков всего восемь на сотню позиций. Заглушка — не пустая рамка,
   а «изразец»: имя блюда дисплейным шрифтом по терракоте с узором. */
.card__plate {
  position: absolute; inset: 0; z-index: 1;
  display: grid; place-items: center; padding: 1.3rem;
  text-align: center; color: var(--cream);
  font-family: var(--font-display); font-size: var(--step-1); line-height: 1.15;
  background:
    radial-gradient(circle at 50% 8%, oklch(0.56 0.135 38) 0%, transparent 62%),
    repeating-linear-gradient(45deg, oklch(0.94 0.026 82 / 0.05) 0 9px, transparent 9px 18px),
    var(--terracotta-deep);
}
.card__hit {
  position: absolute; left: 10px; top: 10px; z-index: 2;
  background: var(--terracotta-hot); color: #fff;
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 0.3rem 0.6rem; border-radius: 5px;
  box-shadow: 0 2px 10px oklch(0.18 0.02 40 / 0.4);
}
.card__hit--calm { background: var(--ink); }
/* Порядок внимания: снимок → название → цена мелко */
/* Запас высоты держит подвал карточки, а не само название: тогда цена стоит
   вплотную под названием (у коротких названий она уезжала вниз на пустую
   вторую строку), а карточки в ряду всё равно одной высоты — названия во
   всех категориях начинаются на одном уровне. */
.card__foot {
  padding: 0.85rem 0.15rem 0; display: grid; gap: 0.2rem;
  align-content: start; min-height: calc(2em * 1.25 + 1.9em);
}
.card__name { font-size: var(--step-0); font-weight: 600; line-height: 1.25; }
.card__price { font-size: var(--step--1); font-weight: 600; color: var(--muted-on-cream); }

/* Стрелки у ленты блюд убраны по просьбе владельца: на мыши лента тянется
   рукой, как пальцем на телефоне. Курсор показывает, что её можно тащить;
   пока тащим — снап отключён, иначе лента дёргается на каждой карточке. */
@media (hover: hover) {
  .dishrail, .tabs { cursor: grab; }
  .dishrail.is-grabbing, .tabs.is-grabbing { cursor: grabbing; scroll-snap-type: none; }
  .dishrail.is-grabbing .card, .tabs.is-grabbing .tab { pointer-events: none; }
  .dishrail.is-grabbing .card:hover .card__media { transform: none; box-shadow: 0 10px 26px oklch(0.18 0.02 40 / 0.14); }
}

/* Карточка блюда: снимок уезжает влево, описание въезжает справа */
.sheet { position: fixed; inset: 0; z-index: var(--z-sheet); display: none; }
.sheet.is-open { display: block; }
/* Размытие подложки пересчитывается на каждом кадре листания — на ПК это
   съедало треть кадров, ровно как раньше на iPhone. Вместо блюра плотнее
   затемнение: на глаз то же самое, а лента едет без рывков. */
.sheet__backdrop { position: absolute; inset: 0; background: oklch(0.14 0.02 40 / 0.84); opacity: 0; transition: opacity 0.4s var(--ease); }
.sheet.is-in .sheet__backdrop { opacity: 1; }
/* Панель — окно просмотра ленты. Ширина карточки и просвет до соседа заданы
   переменными: на телефоне просвета нет, места и так мало. */
/* Карточка на ПК заметно крупнее: было 1060 px и потолок 720 px по высоте —
   на большом экране окно смотрелось марочкой посреди пустоты. Просвет до
   соседей заодно ужат, чтобы прибавка ушла в саму карточку. */
.sheet__panel {
  --sheet-w: min(100%, 1420px);
  --sheet-peek: clamp(14px, 2.2vw, 40px);
  --sheet-gap: clamp(12px, 1.4vw, 22px);
  position: absolute; inset: 0; display: grid; place-items: center;
  padding-block: var(--gutter);
  pointer-events: none; overflow: hidden;
}
/* Лента из трёх карточек. Сдвиг задаёт скрипт: он считает шаг по факту,
   а не по процентам, иначе просвет соседа ломает арифметику. */
.sheet__track {
  /* Ширина по окну, а содержимое центрируется: трёх карточек шире экрана,
     они переполняют его симметрично, и средняя стоит ровно посередине.
     Без этого лента прижималась к левому краю. */
  width: 100%; justify-content: center;
  display: flex; align-items: center; gap: var(--sheet-gap);
  pointer-events: auto;
  will-change: transform;
}
.sheet__track.is-eased { transition: transform 0.52s var(--ease-quart); }
/* Карточку тоже тянут мышью: на ПК её нечем было листать, кроме клавиш.
   Пока тянем — гасим выделение текста, иначе описание подсвечивается синим. */
@media (hover: hover) {
  .sheet__track { cursor: grab; }
  .sheet__track.is-grabbing { cursor: grabbing; user-select: none; }
  .sheet__track.is-grabbing .sheet__card { pointer-events: none; }
}
.sheet__card {
  flex: 0 0 calc(var(--sheet-w) - 2 * var(--sheet-peek) - 2 * var(--sheet-gap));
  background: var(--cream); border-radius: var(--radius); overflow: hidden;
  display: grid; grid-template-columns: 1fr 1fr; max-height: min(90svh, 880px);
  /* Соседи притушены и чуть уменьшены — глаз сразу читает, кто в фокусе */
  opacity: 0.45; transform: scale(0.94);
  transition: opacity 0.45s var(--ease), transform 0.52s var(--ease-quart);
  /* Слой заводим заранее: без этого браузер поднимает карточку в свой слой
     уже в первом кадре движения, и лента спотыкается на старте. */
  will-change: transform, opacity;
}
.sheet__card.is-cur { opacity: 1; transform: none; }
/* Появление окна: лента въезжает целиком */
.sheet__panel { opacity: 0; transform: translateY(16px) scale(0.98); transition: opacity 0.34s var(--ease), transform 0.46s var(--ease-quart); }
.sheet.is-in .sheet__panel { opacity: 1; transform: none; }
.sheet__close {
  position: absolute; z-index: 6; pointer-events: auto;
  right: clamp(0.8rem, 3vw, 2rem); top: clamp(0.8rem, 3vh, 2rem);
}
@media (max-width: 860px) {
  .sheet__panel { --sheet-peek: 0px; --sheet-gap: 14px; padding-inline: 14px; }
  .sheet__card { grid-template-columns: 1fr; grid-template-rows: auto 1fr; max-height: 92svh; border-radius: 20px; }
  /* Описание не прокручивается, а карточки выстроены по одной сетке:
     у названия и описания заданы минимальные высоты под самый длинный текст,
     поэтому линия над ценой, сама цена, граммовка и кнопка стоят на одном
     уровне у всех блюд — при листании ничего не прыгает. */
  /* Ничего не прокручивается и ничего не надо доскроливать: карточка фиксированной
     высоты, текст сразу под снимком плотной группой, а цена, граммовка и кнопка
     прижаты к низу. Поэтому у всех блюд линия, цифры и кнопка на одном уровне,
     а пустоты между строками нет. */
  .sheet__card { height: 88svh; }
  .sheet__media { height: 24svh; min-height: 150px; }
  .sheet__text {
    overflow: hidden; padding: 0.95rem 1.15rem 1.1rem;
    display: flex; flex-direction: column;
  }
  /* Описание забирает остаток высоты — нижняя группа всегда на одном месте */
  .sheet__desc { flex: 1 1 auto; }
  .sheet__cat { margin-bottom: 0.25rem; }
  .sheet__text h3 { font-size: var(--step-1); margin-bottom: 0.4rem; }
  .sheet__desc { line-height: 1.4; margin-bottom: 0; }
  .sheet__facts { padding-block: 0.7rem; margin-bottom: 0.85rem; gap: 0.3rem 1.6rem; }
  .sheet__facts b { font-size: var(--step-0); }
  /* Соседей на телефоне не видно, поэтому их не за чем анимировать: три
     одновременных перехода прозрачности и масштаба поверх едущей ленты
     съедали кадры. */
  .sheet__card { opacity: 1; transform: none; transition: none; }
  /* Размытие фона на iPhone пересчитывается на каждом кадре свайпа —
     заменено обычным затемнением. */
  .sheet__backdrop { backdrop-filter: none; -webkit-backdrop-filter: none; }
}
.sheet__media { position: relative; overflow: hidden; background: var(--ink); }
.sheet__media img { width: 100%; height: 100%; object-fit: cover; }
/* Для позиций без снимка — тот же изразец, что на карточке в карусели */
.sheet__plate { display: none; }
.sheet__media.is-plate .sheet__plate {
  display: grid; place-items: center; position: absolute; inset: 0; padding: 2rem;
  text-align: center; color: var(--cream);
  font-family: var(--font-display); font-size: var(--step-2); line-height: 1.15;
  background:
    radial-gradient(circle at 50% 8%, oklch(0.56 0.135 38) 0%, transparent 62%),
    repeating-linear-gradient(45deg, oklch(0.94 0.026 82 / 0.05) 0 9px, transparent 9px 18px),
    var(--terracotta-deep);
}
@media (max-width: 860px) { .sheet__media { height: 30svh; min-height: 200px; } }
/* Пока открыта карточка блюда, нижняя панель телефонов не мешает */
body.sheet-open .rail { transform: translateY(120%); }
.sheet__text { position: relative; padding: clamp(1.5rem, 3vw, 2.6rem); padding-bottom: 5.5rem; overflow-y: auto; }
.sheet__cat { font-size: var(--step--1); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--terracotta-hot); margin-bottom: 0.7rem; }
.sheet__text h3 { font-family: var(--font-display); font-size: var(--step-2); color: var(--terracotta); margin-bottom: 0.9rem; }
.sheet__desc { color: var(--ink-on-cream); margin-bottom: 1.6rem; max-width: 46ch; }
.sheet__facts { display: flex; flex-wrap: wrap; gap: 0.6rem 2rem; padding-block: 1.1rem; border-block: 1px solid var(--paperline); margin-bottom: 1.6rem; }
.sheet__facts b { font-family: var(--font-display); font-size: var(--step-1); color: var(--terracotta); display: block; }
.sheet__facts span { font-size: var(--step--1); color: var(--muted-on-cream); }
.sheet__actions { display: flex; flex-wrap: wrap; gap: 0.8rem; }
.sheet__close { width: 48px; height: 48px; border-radius: 50%; border: 0; background: oklch(0.14 0.02 40 / 0.6); color: #fff; font-size: 1.4rem; cursor: pointer; display: grid; place-items: center; }
.sheet__close:hover { background: oklch(0.14 0.02 40 / 0.85); }
/* Две круглые стрелки в углу убраны: на телефоне они попадали под большой
   палец и рисовались системными шевронами не в цвет. Листание — свайпом,
   на мыши — протяжкой. Подпись «Листайте вбок» тоже снята по просьбе
   владельца: жест очевиден, а строка отъедала место у описания. */

/* ══ 7b. ПЕЧАТНОЕ МЕНЮ: книжка прямо на странице ═══════
   Не отдельная секция, а довесок к разделу «Меню». Страницы — растр из тех же
   PDF, что лежат в assets/menu-pdf (печатные макеты растровые, текстового слоя
   в них нет). Пересобрать: node .research/pdf2pages.mjs                     */
.bookline {
  position: relative; margin-top: clamp(2rem, 4vw, 3rem);
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(1.2rem, 3vw, 2.5rem); align-items: center;
  padding: clamp(1.3rem, 2.4vw, 1.9rem) clamp(1.8rem, 3.4vw, 2.6rem);
  border: 0; border-radius: 0; background: var(--cream-deep);
}
/* Тот же кант, что у капсулы шапки, только терракотовый */
.bookline::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  border: 20px solid transparent;
  border-image-source: var(--frame-terracotta);
  border-image-slice: 40;
  border-image-repeat: stretch;
  opacity: 0.75;
}
.bookline h3 { font-family: var(--font-display); font-size: var(--step-2); color: var(--terracotta); margin-bottom: 0.4rem; }
.bookline p { font-size: var(--step--1); color: var(--muted-on-cream); max-width: 52ch; }
.bookline__lead { color: var(--terracotta-hot); font-weight: 600; }
.bookline__acts { display: grid; gap: 0.55rem; justify-items: stretch; }
.bookline__acts .btn { width: 100%; }
/* Раньше это были две подчёркнутые ссылки — читались как сноска мелким шрифтом
   под двумя крупными кнопками. Стали парой тихих плашек: та же иерархия
   (второстепенное действие), но одного роду-племени с кнопками над ними. */
.bookline__dls { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: stretch; }
.bookline__dls a {
  flex: 1 1 0; min-width: 0;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4rem; min-height: 44px; padding: 0 0.9rem;
  font-size: var(--step--1); font-weight: 500; color: var(--muted-on-cream);
  text-decoration: none; border-radius: 999px;
  border: 1px solid oklch(0.48 0.130 35 / 0.28);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease), background-color 0.25s var(--ease);
}
.bookline__dls a svg { width: 1rem; height: 1rem; flex: none; opacity: 0.8; }
.bookline__dls a i {
  font-style: normal; font-size: 0.72em; letter-spacing: 0.06em;
  padding: 0.12em 0.42em; border-radius: 999px;
  background: oklch(0.48 0.130 35 / 0.12); color: var(--terracotta);
}
.bookline__dls a:hover {
  color: var(--terracotta); border-color: oklch(0.48 0.130 35 / 0.55);
  background: oklch(0.48 0.130 35 / 0.06);
}
@media (max-width: 860px) { .bookline { grid-template-columns: 1fr; } }

/* ── Сама книжка ──────────────────────────────────────
   Разворот на две страницы, лист переворачивается через корешок.
   На узком экране — одна страница, переворот тот же.                */
.book[hidden] { display: none; }
.book { position: fixed; inset: 0; z-index: var(--z-sheet); display: grid; place-items: center; padding: clamp(0.6rem, 2vw, 1.6rem); }
.book__backdrop { position: absolute; inset: 0; background: oklch(0.10 0.02 40 / 0.96); backdrop-filter: blur(6px); opacity: 0; transition: opacity 0.4s var(--ease); }
.book.is-in .book__backdrop { opacity: 1; }
.book__panel {
  position: relative; z-index: 2;
  width: min(100%, 1320px); height: min(94svh, 980px);
  display: grid; grid-template-rows: auto 1fr; gap: 0.8rem;
  opacity: 0; transform: scale(0.96) translateY(14px);
  transition: opacity 0.35s var(--ease), transform 0.45s var(--ease);
}
.book.is-in .book__panel { opacity: 1; transform: none; }
.book__head {
  display: flex; align-items: center; gap: 0.7rem 1.2rem; flex-wrap: wrap;
  color: var(--cream-on-ink);
}
.book__head strong { font-family: var(--font-display); font-size: var(--step-1); }
.book__count { font-size: var(--step--1); color: var(--muted-on-ink); }
.book__dl {
  margin-left: auto; display: inline-flex; align-items: center; gap: 0.5rem;
  min-height: 44px; padding: 0 1.1rem; border-radius: var(--radius-pill);
  background: var(--terracotta-hot); color: #fff; font-size: var(--step--1); font-weight: 700; text-decoration: none;
  transition: background-color 0.3s var(--ease);
}
.book__dl:hover { background: var(--terracotta-lift); }
.book__close {
  width: 46px; height: 46px; flex: none; border-radius: 50%; border: 1px solid oklch(0.94 0.026 82 / 0.3);
  background: oklch(0.94 0.026 82 / 0.08); color: var(--cream); font-size: 1.3rem; cursor: pointer;
  display: grid; place-items: center;
}
.book__close:hover { background: oklch(0.94 0.026 82 / 0.2); }

/* Разворот прибит абсолютом сверху и снизу: только так его высота становится
   определённой и height:100% у страниц разрешается. В обычном потоке высота
   считалась от картинок — страницы вылезали за экран и обрастали белыми полями. */
.book__stage { position: relative; min-height: 0; perspective: 2400px; }
/* Размер разворота считает скрипт (fit): вписать лист A4 сразу по ширине и по
   высоте средствами одного CSS не выходит — либо страницы вылезают за экран,
   либо их режет по краям. */
.book__spread {
  position: absolute; top: 50%; left: 50%; translate: -50% -50%;
  display: flex;
  transform-style: preserve-3d;
  filter: drop-shadow(0 24px 60px oklch(0.08 0.02 40 / 0.7));
}
.book__page { position: relative; height: 100%; flex: 1 1 0; min-width: 0; background: #fff; }
.book__page img { display: block; width: 100%; height: 100%; object-fit: cover; background: #fff; }
/* Тень у корешка: без неё разворот выглядит как две отдельные картинки */
.book__spread[data-spread='2']::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: 50%; width: 46px; translate: -50% 0;
  background: linear-gradient(90deg, transparent, oklch(0.14 0.02 40 / 0.28) 46%, oklch(0.14 0.02 40 / 0.28) 54%, transparent);
  pointer-events: none; z-index: 4;
}

.book__leaf {
  position: absolute; top: 0; bottom: 0; right: 0; width: 50%;
  transform-style: preserve-3d; transform-origin: left center;
  transition: transform 0.8s cubic-bezier(0.42, 0.02, 0.24, 1);
  z-index: 6;
}
.book__leaf--prev { left: 0; right: auto; transform-origin: right center; }
.book__leaf.is-turn { transform: rotateY(-179deg); }
.book__leaf--prev.is-turn { transform: rotateY(179deg); }
.book__leaf--single { width: 100%; }
.book__face { position: absolute; inset: 0; backface-visibility: hidden; background: #fff; overflow: hidden; }
.book__face img { display: block; width: 100%; height: 100%; object-fit: cover; }
.book__face--back { transform: rotateY(180deg); }

.book__nav {
  position: absolute; top: 50%; translate: 0 -50%; z-index: 8;
  width: 56px; height: 56px; border-radius: 50%;
  border: 1px solid oklch(0.94 0.026 82 / 0.35); background: oklch(0.14 0.02 40 / 0.6);
  color: var(--cream); display: grid; place-items: center; cursor: pointer;
  backdrop-filter: blur(6px);
  transition: background-color 0.3s var(--ease), opacity 0.3s var(--ease);
}
.book__nav:hover { background: oklch(0.14 0.02 40 / 0.9); }
.book__nav[disabled] { opacity: 0.25; pointer-events: none; }
.book__nav--prev { left: clamp(-6px, -1vw, 0px); }
.book__nav--next { right: clamp(-6px, -1vw, 0px); }
@media (max-width: 900px) {
  .book__panel { height: min(92svh, 900px); }
  .book__nav { width: 50px; height: 50px; }
}
/* На телефоне шапка книжки в одну строку не помещается: название и кнопки
   сверху, счётчик страниц — отдельной строкой под ними. */
@media (max-width: 600px) {
  .book__head { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 0.4rem 0.5rem; }
  .book__head strong { grid-area: 1 / 1; font-size: var(--step-0); }
  .book__dl { grid-area: 1 / 2; margin-left: 0; padding: 0 0.85rem; }
  .book__close { grid-area: 1 / 3; width: 42px; height: 42px; }
  .book__count { grid-area: 2 / 1 / 3 / -1; }
}

/* ══ 8. ОБЗОР ЗАВЕДЕНИЯ ════════════════════════════════
   Заменила «Скачать меню» и «Как у нас внутри».
   Два потока снимков идут навстречу друг другу: левый вверх, правый вниз.
   Ленты продублированы, сдвиг ровно на половину — стык не виден.        */
.about { position: relative; background: var(--ink); color: var(--cream-on-ink); padding: var(--section) 0; overflow: hidden; }
.about__glow {
  position: absolute; left: 18%; top: 50%; translate: -50% -50%;
  width: min(80vw, 900px); aspect-ratio: 1;
  background: radial-gradient(circle, oklch(0.55 0.14 40 / 0.42) 0%, oklch(0.45 0.10 38 / 0.16) 38%, transparent 68%);
  pointer-events: none;
}
.about__grid { position: relative; z-index: 2; display: grid; grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 5rem); align-items: stretch; }

/* Ленты идут от верха блока до низа — вровень с текстовой колонкой.
   Колонки прибиты абсолютом: иначе их собственная высота (восемь снимков
   подряд) задирает строку грида и секция растягивается на пол-экрана.
   Растворение по краям узкое: при 14% почти треть ленты уходила в пустоту
   и снимки казались обрубленными задолго до края. */
.about__streams {
  position: relative; align-self: stretch;
  --stream-gap: clamp(0.7rem, 1.4vw, 1.1rem);
  min-height: clamp(420px, 60svh, 640px);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 4%, #000 96%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 4%, #000 96%, transparent 100%);
}
.stream { position: absolute; top: 0; bottom: 0; width: calc(50% - var(--stream-gap) / 2); overflow: hidden; }
.stream--up { left: 0; }
.stream--down { right: 0; }
.stream__col { display: grid; gap: clamp(0.7rem, 1.4vw, 1.1rem); will-change: transform; }
.stream__col img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--radius); }
.stream--up .stream__col { animation: streamUp 54s linear infinite; }
.stream--down .stream__col { animation: streamDown 54s linear infinite; }
@keyframes streamUp { from { transform: translateY(0); } to { transform: translateY(-50%); } }
@keyframes streamDown { from { transform: translateY(-50%); } to { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .stream__col { animation: none; } }

.about__kicker { font-size: var(--step--1); font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: oklch(0.78 0.13 55); margin-bottom: 0.9rem; }
.about h2 { font-family: var(--font-display); font-size: var(--step-3); margin-bottom: 1.1rem; }
.about__lead { color: var(--muted-on-ink); max-width: 52ch; margin-bottom: 2rem; }

/* Каждый пункт раскрывается по нажатию — на <details>, без скрипта */
.facts { display: grid; gap: 0.55rem; margin-bottom: 2rem; }
.fact { border: 1px solid oklch(0.94 0.026 82 / 0.16); border-radius: var(--radius); background: oklch(0.94 0.026 82 / 0.04); overflow: hidden; transition: border-color 0.3s var(--ease), background-color 0.3s var(--ease); }
.fact[open], .fact:hover { border-color: oklch(0.94 0.026 82 / 0.38); background: oklch(0.94 0.026 82 / 0.08); }
.fact summary {
  display: flex; align-items: center; gap: 1rem;
  min-height: var(--tap); padding: 0.7rem 1.1rem;
  cursor: pointer; list-style: none; font-weight: 600;
}
.fact summary::-webkit-details-marker { display: none; }
.fact summary::after {
  content: '+'; margin-left: auto; font-size: 1.5rem; line-height: 1;
  color: oklch(0.78 0.13 55); transition: transform 0.35s var(--ease);
}
.fact[open] summary::after { transform: rotate(45deg); }
.fact__num {
  flex: none; min-width: 3.2rem; text-align: center;
  font-family: var(--font-display); font-size: var(--step-1); color: oklch(0.82 0.12 55);
}
.fact__name { font-size: var(--step-0); }
.fact p { padding: 0 1.1rem 1.1rem 5.3rem; color: var(--muted-on-ink); font-size: var(--step--1); }
.about__actions { display: flex; flex-wrap: wrap; gap: 0.8rem; }
.about .btn--outline { border-color: oklch(0.94 0.026 82 / 0.5); color: var(--cream-on-ink); }
.about .btn--outline:hover { background: var(--cream); color: var(--ink); border-color: var(--cream); }

@media (max-width: 900px) {
  .about__grid { grid-template-columns: 1fr; gap: 2rem; }
  .about__streams { min-height: 0; height: clamp(300px, 46svh, 420px); order: -1; }
  .about__glow { left: 50%; top: 28%; }
  .fact p { padding-left: 1.1rem; }
  .about__actions .btn { flex: 1 1 100%; }
}

/* ══ 10. ОТЗЫВЫ ═══════════════════════════════════════ */
.trust { background: var(--terracotta); color: #fff; padding: var(--section) 0; }
/* Стопка отзывов приезжает сюда с узкого экрана (см. app.js, reviewFan).
   На широком экране блок пустой и места не занимает. */
.trust__fan:empty { display: none; }
.trust__fan { margin-bottom: clamp(2.2rem, 6vw, 3.2rem); }
.trust__fan .fan__deck { width: min(100%, 30rem); margin-inline: auto; }
.trust__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: clamp(1.5rem, 3vw, 3rem); text-align: center; }
/* Именно .trust__grid, а не .trust: в блок переезжает карточка отзыва,
   и общие правила на b/span перекрашивали имя автора в дисплейный шрифт
   тройного кегля. */
.trust__grid b { font-family: var(--font-display); font-size: var(--step-3); display: block; line-height: 1; margin-bottom: 0.5rem; }
.trust__grid span { font-size: var(--step--1); opacity: 0.92; }
.trust__link { display: inline-flex; align-items: center; gap: 0.5rem; margin-top: 2.2rem; color: #fff; font-weight: 600; text-decoration: underline; text-underline-offset: 4px; min-height: 44px; }

/* ══ 11. КАК НАС НАЙТИ ════════════════════════════════ */
.find { background: var(--cream-deep); padding: var(--section) 0; }
/* Карта — главный элемент блока, поэтому колонка под неё шире и выше */
.find__grid { display: grid; grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr); gap: clamp(1.5rem, 3vw, 3rem); align-items: start; }
@media (max-width: 900px) { .find__grid { grid-template-columns: 1fr; } }
.find h2 { font-family: var(--font-display); font-size: var(--step-2); color: var(--terracotta); margin-bottom: 1.4rem; }
/* Строки равной высоты: у «круглосуточно» подпись в две строки, и без этого
   ниши-арки стояли на разном расстоянии друг от друга — колонка выглядела кривой. */
.find__rows { display: grid; grid-auto-rows: 1fr; gap: 1.1rem; margin-bottom: 1.8rem; }
.find__row { display: grid; grid-template-columns: auto 1fr; gap: 1rem; align-items: start; }
/* Иконка в нише-арке: форма взята с восточного портала, а не из типового
   набора линейных пиктограмм */
.find__row .arch {
  flex: none; width: 46px; height: 52px;
  display: grid; place-items: center;
  color: var(--cream);
  background: var(--terracotta);
  border-radius: 50% 50% 14% 14% / 62% 62% 14% 14%;
  box-shadow: inset 0 0 0 1px oklch(0.94 0.026 82 / 0.35);
}
.find__row .arch svg { width: 1.35rem; height: 1.35rem; }
.find__row b { display: block; font-weight: 600; }
.find__row span { font-size: var(--step--1); color: var(--muted-on-cream); }

/* Белые пилюли выглядели чужеродно на кремовом. Теперь — тёмные плашки
   с арочной насечкой слева, одной семьи с остальным блоком. */
.find__routes { display: grid; gap: 0.6rem; }
.route {
  display: flex; align-items: center; gap: 0.85rem;
  min-height: var(--tap); padding: 0.6rem 1.3rem;
  border-radius: var(--radius);
  border: 1px solid transparent; background: var(--ink); color: var(--cream-on-ink);
  text-decoration: none; font-weight: 600;
  transition: background-color 0.3s var(--ease), transform 0.35s var(--ease);
}
.route::before {
  content: ''; flex: none; width: 12px; height: 16px;
  background: var(--terracotta-hot);
  border-radius: 50% 50% 12% 12% / 62% 62% 12% 12%;
}
.route:hover { background: var(--terracotta); transform: translateX(4px); }
/* Подпись «откроется в приложении» была на каждой кнопке — не влезала и ломала строку.
   Теперь она одна на весь блок. */
.find__note { margin-top: 0.4rem; font-size: var(--step--1); color: var(--muted-on-cream); max-width: 44ch; }
.find__map { position: relative; border-radius: 0; overflow: hidden; min-height: clamp(460px, 62svh, 640px); background: var(--paperline); box-shadow: 0 14px 40px oklch(0.18 0.02 40 / 0.16); }
.find__map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* Карта была единственным прямоугольником без опознания — тот же кант,
   что у капсулы шапки и плашки печатного меню. Рисует псевдоэлемент,
   поэтому карта под ним остаётся кликабельной. */
.find__map::after {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  border: 18px solid transparent;
  border-image-source: var(--frame-terracotta);
  border-image-slice: 40;
  border-image-repeat: stretch;
  filter: drop-shadow(0 1px 4px oklch(1 0 0 / 0.9));
}

/* ── Подтверждение возраста для алкогольных категорий ── */
.gate { position: fixed; inset: 0; z-index: var(--z-sheet); display: grid; place-items: center; padding: var(--gutter); }
.gate__backdrop { position: absolute; inset: 0; background: oklch(0.14 0.02 40 / 0.78); backdrop-filter: blur(4px); opacity: 0; transition: opacity 0.35s var(--ease); }
.gate.is-in .gate__backdrop { opacity: 1; }
.gate__box {
  position: relative; z-index: 2; width: min(100%, 460px);
  display: grid; gap: 1rem; padding: clamp(1.5rem, 4vw, 2.2rem);
  border-radius: var(--radius); background: var(--cream);
  transform: scale(0.94) translateY(12px); opacity: 0;
  transition: transform 0.4s var(--ease), opacity 0.3s var(--ease);
}
.gate.is-in .gate__box { transform: none; opacity: 1; }
.gate__box h3 { font-family: var(--font-display); font-size: var(--step-2); color: var(--terracotta); }
.gate__box p { font-size: var(--step--1); color: var(--muted-on-cream); }
.gate__row { display: flex; flex-wrap: wrap; gap: 0.7rem; }
.gate__row .btn { flex: 1 1 auto; }

/* ── Документы и согласие на cookie ──────────────────── */
.foot__docs { display: flex; flex-wrap: wrap; gap: 0.6rem 2rem; padding-top: 1.6rem; margin-top: 2rem; border-top: 1px solid oklch(0.94 0.026 82 / 0.14); }
.foot__docs a { display: inline-flex; align-items: center; min-height: 44px; font-size: var(--step--1); color: var(--cream-on-ink); text-decoration: underline; text-underline-offset: 3px; }
.foot__docs a:hover { color: oklch(0.82 0.12 55); }

.cookies[hidden] { display: none; }
.cookies {
  position: fixed; left: clamp(0.8rem, 2vw, 1.6rem); bottom: clamp(0.8rem, 2vw, 1.6rem);
  z-index: var(--z-callbar);
  width: min(calc(100vw - 2rem), 460px);
  display: grid; gap: 0.9rem;
  padding: 1.2rem 1.3rem;
  border-radius: var(--radius);
  background: oklch(0.18 0.018 40 / 0.96); color: var(--cream-on-ink);
  border: 1px solid oklch(0.94 0.026 82 / 0.18);
  box-shadow: 0 14px 40px oklch(0.14 0.02 40 / 0.45);
  backdrop-filter: blur(8px);
  opacity: 0; transform: translateY(14px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.cookies.is-in { opacity: 1; transform: none; }
.cookies p { font-size: var(--step--1); color: var(--muted-on-ink); }
.cookies a { color: var(--cream-on-ink); text-decoration: underline; text-underline-offset: 3px; }
.cookies .btn { justify-self: start; min-height: 48px; }
/* На телефоне нижняя панель телефонов уже занимает низ экрана */
@media (max-width: 860px) { .cookies { bottom: 86px; left: 0.6rem; right: 0.6rem; width: auto; } }

/* ══ 12. ПОДВАЛ ═══════════════════════════════════════ */
.foot { background: var(--ink); color: var(--cream-on-ink); padding: var(--section) 0 2rem; }
/* Первая колонка — знак и слоган, ей нужно больше воздуха, чем спискам:
   на auto-fit все четыре получались одинаковой ширины и марка терялась. */
.foot__grid { display: grid; grid-template-columns: 1.35fr repeat(3, 1fr); gap: 2.6rem; margin-bottom: 2.6rem; }
@media (max-width: 900px) { .foot__grid { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); } }
.foot__brand { width: 236px; height: auto; margin-bottom: 1.3rem; display: block; }
/* Соцсети значком, а не строкой в списке разделов: раньше ВКонтакте терялся
   пятым пунктом среди якорей на секции этой же страницы. */
.foot__soc { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.2rem; }
.foot__soc a {
  display: inline-flex; align-items: center; gap: 0.55rem;
  min-height: 44px; padding: 0 1rem 0 0.6rem;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255, 255, 255, 0.16);
  color: var(--cream-on-ink); text-decoration: none;
  font-size: var(--step--1); font-weight: 600;
  transition: background-color 0.28s var(--ease), border-color 0.28s var(--ease);
}
.foot__soc a svg { width: 30px; height: 30px; padding: 6px; border-radius: 50%; background: #07f; color: #fff; flex: none; }
.foot__soc a:hover { background: rgba(255, 255, 255, 0.07); border-color: rgba(255, 255, 255, 0.34); }
/* Заголовки колонок были мелким серым капслоком — на фоне дисплейного
   шрифта всего сайта подвал читался как чужая служебная плашка.
   Стало: тот же Itikaf терракотой, с короткой чертой-засечкой слева. */
.foot h3 {
  font-family: var(--font-display); font-weight: 400;
  font-size: var(--step-1); letter-spacing: 0; text-transform: none;
  color: oklch(0.82 0.12 55); margin-bottom: 0.8rem;
}
.foot ul { list-style: none; padding: 0; display: grid; gap: 0.2rem; }
/* Тач-цели в подвале тоже ≥44px: ядро аудитории 45–65 лет */
.foot a { text-decoration: none; display: inline-flex; align-items: center; min-height: 44px; }
.foot a:hover { text-decoration: underline; }
.foot__phone { font-family: var(--font-display); font-size: var(--step-1); }
.foot__note { color: var(--muted-on-ink); font-size: var(--step--1); }
.foot__lede { color: var(--muted-on-ink); font-size: var(--step--1); max-width: 32ch; line-height: 1.5; }
.foot__links a { color: var(--cream-on-ink); }
.foot__links a:hover { color: oklch(0.82 0.12 55); text-decoration: none; }
.menu__lead a { display: inline-flex; align-items: center; min-height: 44px; }

/* ── низ подвала ──────────────────────────────────────────────────
   Документы слева, адрес справа — одной полосой, разделённой линией.
   Раньше три текстовых строки шли подряд и низ выглядел как обрывок. */
.foot__bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0.4rem 2.5rem;
  padding-top: 1.5rem; margin-top: 0.5rem;
  border-top: 1px solid oklch(0.94 0.026 82 / 0.14);
}
.foot__docs { display: flex; flex-wrap: wrap; gap: 0 1.6rem; padding-top: 0; margin-top: 0; border-top: 0; }
.foot__docs a { font-size: var(--step--1); color: var(--muted-on-ink); text-decoration: none; }
.foot__docs a:hover { color: var(--cream-on-ink); text-decoration: underline; text-underline-offset: 3px; }
.foot__where { font-style: normal; text-align: right; display: grid; gap: 1px; }
.foot__where b { font-family: var(--font-display); font-weight: 400; font-size: var(--step-1); color: var(--cream-on-ink); }
/* Блок стоит у правого края подвала, а город под адресом набран по центру
   строки с адресом — иначе одно короткое слово висело у правого края. */
.foot__where span { font-size: var(--step--1); color: var(--muted-on-ink); text-align: center; }
@media (max-width: 700px) { .foot__where { text-align: left; } }

/* Реквизиты — самая мелкая строка сайта, разделители точками.
   Это сноска, а не абзац: раньше она шла тем же кеглем, что ссылки. */
.foot__legal {
  padding-top: 1.1rem; margin-top: 1.1rem;
  border-top: 1px solid oklch(0.94 0.026 82 / 0.09);
  font-size: 0.78rem; line-height: 1.6; color: oklch(0.7 0.012 82 / 0.72);
  display: flex; flex-wrap: wrap; gap: 0.2rem 0.9rem;
}
.foot__legal span + span::before { content: '·'; margin-right: 0.9rem; opacity: 0.6; }

/* ══ 13. ЛИПКИЙ ТЕЛЕФОН СПРАВА ════════════════════════
   Появляется после героя, не перекрывает контент.
   На узком экране превращается в нижнюю панель.              */
/* Правый НИЖНИЙ угол — как у маркетплейсов. Раньше висело по центру справа.
   display:flex, а не grid: в гриде обе кнопки тянулись до ширины общего трека,
   и раскрытие одной визуально раскрывало вторую. */
.rail {
  position: fixed; right: clamp(0.8rem, 2vw, 1.6rem); bottom: clamp(1rem, 3vh, 2rem);
  z-index: var(--z-rail);
  display: flex; flex-direction: column; align-items: flex-end; gap: 0.6rem;
  transform: translateX(140%); opacity: 0;
  transition: transform 0.55s var(--ease), opacity 0.4s var(--ease);
}
.rail.is-on { transform: none; opacity: 1; }
/* Кружки стали меньше и полупрозрачными: тремя плотными кругами по 60 px они
   закрашивали правый край кадра и ролика. Сквозь них теперь видно картинку,
   но контур и тень держат кнопку заметной. При наведении/раскрытии цвет
   набирает полную плотность. */
.rail__btn {
  display: grid; grid-template-columns: auto 0fr; align-items: center;
  min-height: 48px; padding: 0 0.6rem; border-radius: var(--radius-pill);
  background: oklch(0.53 0.175 40 / 0.6); color: #fff; text-decoration: none;
  border: 1px solid oklch(0.94 0.026 82 / 0.34);
  box-shadow: 0 6px 18px oklch(0.18 0.02 40 / 0.28);
  transition: grid-template-columns 0.45s var(--ease), background-color 0.3s var(--ease), transform 0.35s var(--ease);
  overflow: hidden;
}
.rail__btn--alt { background: oklch(0.24 0.02 40 / 0.6); }
.rail__btn--ask { background: oklch(0.58 0.14 40 / 0.6); }
.rail__btn:hover { grid-template-columns: auto 1fr; transform: translateX(-3px); background: var(--terracotta-hot); }
.rail__btn--alt:hover { background: var(--ink); }
.rail__btn--ask:hover { background: var(--terracotta); }
.rail__btn svg { width: 21px; height: 21px; }
.rail__dot { display: grid; place-items: center; }
.rail__short { display: none; }
.rail__label { overflow: hidden; white-space: nowrap; display: grid; gap: 1px; padding-left: 0; transition: padding-left 0.45s var(--ease); }
.rail__btn:hover .rail__label { padding-left: 0.8rem; }
.rail__label small { font-size: 0.78rem; opacity: 0.85; }
.rail__label b { font-size: 1rem; font-weight: 700; }

/* На телефоне кнопки лежат свёрнутыми кружками — так же, как на десктопе до
   наведения. Полосу во всю ширину убрали: она съедала низ экрана. Тап
   разворачивает кнопку в «язычок» с номером (вариант 6 из
   .research/rail-variants.html), второй тап уходит на звонок. Разворот делает
   скрипт: на сенсорном экране наведения нет, а сразу звонить по первому
   касанию нельзя — человек не увидит, куда звонит. */
@media (max-width: 860px) {
  .rail {
    right: clamp(0.6rem, 3vw, 1rem); left: auto; top: auto; bottom: clamp(1rem, 4vh, 2rem);
    flex-direction: column; align-items: flex-end; gap: 0.5rem;
    padding: 0; background: none; border: 0; backdrop-filter: none;
    transform: translateX(140%);
  }
  .rail.is-on { transform: none; }
  .rail__btn {
    grid-template-columns: auto 0fr; gap: 0;
    min-height: 44px; padding: 0 0.5rem;
    border-radius: var(--radius-pill);
    transition: grid-template-columns 0.42s var(--ease), border-radius 0.42s var(--ease), padding 0.42s var(--ease), background-color 0.3s var(--ease);
  }
  /* раскрытая кнопка — уже осознанное действие, здесь плотность полная */
  .rail__btn.is-open {
    grid-template-columns: auto 1fr;
    padding: 0 1.05rem 0 0.5rem;
    border-radius: var(--radius-pill) 8px 8px var(--radius-pill);
    background: var(--terracotta-hot);
  }
  .rail__btn--alt.is-open { background: var(--ink); }
  .rail__btn--ask.is-open { background: var(--terracotta); }
  .rail__btn svg { width: 19px; height: 19px; }
  .rail__dot {
    width: 28px; height: 28px; border-radius: 50%;
    background: transparent; transition: background-color 0.42s var(--ease);
  }
  .rail__btn.is-open .rail__dot { background: rgba(255, 255, 255, 0.18); }
  .rail__short { display: none; }
  .rail__label { display: grid; padding-left: 0; }
  .rail__btn.is-open .rail__label { padding-left: 0.7rem; }
  .rail__btn:hover { transform: none; grid-template-columns: auto 0fr; }
  .rail__btn.is-open:hover { grid-template-columns: auto 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  .hero { height: 100svh; }
  .hero__pin { position: relative; }
}

/* ── Карточка блюда на телефоне: ничего не прокручивается ──────────────
   Базовое правило .sheet__text задаёт overflow-y: auto и стоит ниже
   мобильного блока, поэтому перебивало его. Здесь, в конце файла,
   последнее слово за нами: содержимое ужато так, чтобы всё влезало
   в один экран без прокрутки. */
@media (max-width: 860px) {
  .sheet__card { height: 88svh; grid-template-rows: auto minmax(0, 1fr); }
  /* Высота снимка в svh, а не в процентах: процент от грид-строки браузер
     не резолвит, и карточка складывалась — снимок схлопывался, а под ним
     зияла пустота. */
  .sheet__media { height: 24svh; min-height: 150px; }
  .sheet__text {
    overflow: hidden; min-height: 0;
    padding: 0.85rem 1.1rem 1rem;
    display: flex; flex-direction: column;
  }
  .sheet__cat { font-size: 0.78rem; margin-bottom: 0.2rem; }
  .sheet__text h3 { font-size: var(--step-1); line-height: 1.05; margin-bottom: 0.35rem; }
  /* Кегль здесь не задаём: его подбирает скрипт под высоту карточки
     (fitCard в app.js). overflow — страховка: если даже на минимальном
     кегле текст не влезет, он обрежется снизу, а не наедет на линию
     над ценой, как это было у длинных описаний. */
  .sheet__desc { line-height: 1.38; margin-bottom: 0; flex: 1 1 auto; min-height: 0; overflow: hidden; }
  /* Полоса «цена / порция» ужата по высоте: место нужно описанию и блоку
     КБЖУ под ней. Подписи мелкие и сидят вплотную к цифрам. */
  .sheet__facts { padding-block: 0.3rem; margin-bottom: 0.3rem; gap: 0 1.3rem; }
  .sheet__facts b { font-size: var(--step-0); line-height: 1.08; }
  .sheet__facts span { font-size: 0.68rem; line-height: 1.15; }
  .sheet__actions { flex: none; }
  .sheet__actions .btn { min-height: 46px; }
  /* Освободившееся место отдаём снимку: в карточке блюда смотрят на еду. */
  .sheet__media { height: 30svh; min-height: 190px; }
}

/* Полосу интерфейса ВК сверху ролика срезали в самом файле (ffmpeg, верхние
   20% кадра), поэтому в вёрстке ничего двигать не нужно. Заодно ролик стал
   легче: 9,5 МБ → 2 МБ. */
.hero__still { object-position: 50% 50%; }

/* Safari на iPhone рисует поверх ролика собственную круглую кнопку play,
   когда автозапуск ему запрещён — чаще всего это режим энергосбережения.
   Кнопка выглядит как элемент интерфейса сайта и сбивает с толку: нажимать
   её незачем, ролик здесь фон, а не проигрыватель. Прячем её; если завести
   ролик так и не выйдет, на первом экране просто останется постер —
   тот же кадр, только неподвижный. Правило общее на оба ролика: ПК-версия
   с 12.08.2026 тоже видео, не снимок. */
.hero__still::-webkit-media-controls,
.hero__still::-webkit-media-controls-start-playback-button,
.hero__still::-webkit-media-controls-panel,
.hero__still::-webkit-media-controls-overlay-play-button {
  display: none !important;
  -webkit-appearance: none;
  appearance: none;
  opacity: 0;
}

/* ── Герой на телефоне: доводка по замечаниям владельца ───────────────
   Кнопки убраны — телефон уже висит в шапке и в плавающих язычках, две
   крупные кнопки только съедали экран. Заголовок мельче и ровно в четыре
   строки. «Работаем круглосуточно» поднято над адресом и набрано крупнее:
   это главный довод, а не сноска. Часы — маленьким кружком рядом. */
@media (max-width: 900px) {
  .hero { min-height: 108svh; }
  .hero__pin { min-height: 92svh; }
  .hero__actions { display: none; }
  /* Кегль подобран под ручные переносы: самая длинная строка «набережная
     реки Тьмаки, 7» должна влезать целиком, иначе последняя строка рвётся
     посередине адреса. Блок стоит внизу экрана (align-content: end у
     .hero__body) — чем мельче кегль, тем ниже к нижнему краю садится верх
     заголовка и тем больше ролика видно над текстом, это и был запрос
     «надпись пусть будет ниже». */
  .hero h1 { font-size: clamp(1.28rem, 6.4vw, 1.6rem); line-height: 1.08; margin-bottom: 0.7rem; }
  .hero__sub { display: grid; gap: 0.45rem; margin-bottom: 1.1rem; }
  .hero__sub span { font-size: var(--step--1); color: var(--cream-on-ink); }
}

/* Затемнение ролика ослаблено по просьбе владельца: кадр было почти не
   разобрать. Плотность оставлена только там, где лежит текст — нижняя
   треть; верх и середина открыты, ролик читается как ролик.
   Совсем убрать нельзя: ролик светлеет в середине, и кремовые буквы на
   белой скатерти пропадали. */
@media (max-width: 900px) {
  .hero { min-height: 100svh; }
  .hero__pin { min-height: 88svh; padding-block: clamp(0.6rem, 2vh, 1.2rem); }
  .hero__veil {
    background: linear-gradient(180deg,
      oklch(0.14 0.02 40 / 0.26) 0%,
      oklch(0.14 0.02 40 / 0.03) 30%,
      oklch(0.14 0.02 40 / 0.14) 54%,
      oklch(0.14 0.02 40 / 0.5) 76%,
      oklch(0.14 0.02 40 / 0.74) 100%);
  }
}

/* ── Карточка блюда: крупнее текст, меньше пустоты ────────────────────
   Снимок выше, кегли подняты — пустое поле между описанием и ценой
   съедается содержанием, а не распоркой. */
@media (max-width: 860px) {
  .sheet__media { height: 30svh; min-height: 180px; }
  /* Тип блюда владелец просил не трогать — кегль прежний.
     Название крупнее: описание к нему подстраивается скриптом (fitCard),
     потолок описания — 58% от названия, поэтому иерархия видна сразу. */
  .sheet__cat { font-size: 0.84rem; letter-spacing: 0.07em; }
  .sheet__text h3 { font-size: clamp(1.72rem, 7.6vw, 2.2rem); line-height: 1.02; }
  .sheet__desc { line-height: 1.45; }
  .sheet__facts b { font-size: var(--step-1); }
  .sheet__facts span { font-size: 0.88rem; }
}

/* Рейтинг в герое — по левому краю, вслед за заголовком и адресом */
@media (max-width: 1024px) {
  .hero .fan { justify-items: start; }
  .hero .fan__foot { justify-content: flex-start; }
  .hero .fan__sum { text-align: left; }
}

/* ── Режим работы в правом верхнем углу (телефон) ──────────────────────
   Строка ушла из нижней группы под кнопку звонка: справа вверху пустовал
   угол, а внизу «Работаем круглосуточно» разбивало ритм между заголовком
   и адресом. Набрано тем же дисплейным шрифтом и тем же цветом, что
   «казаны», под ним «24/7» — в цвет круглой кнопки звонка в шапке.
   Часы-иконку владелец убрал: цифры говорят то же самое короче.
   Позиционируется от .hero (у него position: relative), поэтому уголок
   не зависит от того, закреплён ли .hero__pin. */
.hero__nbr, .hero__247 { display: none; }
@media (max-width: 900px) {
  /* Точка отсчёта для уголка — весь экран героя, а не текстовая группа.
     Ближайшим позиционированным предком у .hero__open был .hero__body,
     и строка вставала в 68 px от начала текста, наезжая на заголовок.
     Растягиваем body на всю закреплённую часть, содержимое в нём
     по-прежнему прижато к низу. */
  .hero__pin { position: relative; }
  /* Нижний отступ повторяем у самого body: inset: 0 считается от padding-box
     закреплённой части, поэтому её собственный padding-bottom съедался и
     строка оценки прилипала к краю экрана. */
  .hero__body {
    position: absolute; inset: 0; display: grid; align-content: end;
    padding-bottom: clamp(1.2rem, 3.4vh, 2rem);
  }
  /* Селектор через .hero__sub обязателен: правило .hero__sub b (класс + тип)
     специфичнее одиночного .hero__open и держало здесь display: block.
     В блочном контейнере gap не работает вовсе — сколько его ни увеличивай,
     «24/7» стояло вплотную к строке выше. */
  .hero__sub .hero__open {
    position: absolute; right: 16px; top: 78px; z-index: 3;
    display: grid; justify-items: end; gap: 0.5rem;
    margin: 0; text-align: right;
    font-family: var(--font-display); font-weight: 400;
    font-size: 1.42rem; line-height: 1.04;
    color: var(--cream-on-ink);
    /* Ни подложки, ни ореола. Пробовали пятно градиентом и размытую плашку —
       на светлом кадре обе читались тёмным прямоугольником (а размытие ещё и
       роняло воспроизведение в Safari на iPhone). Широкая мягкая тень тоже
       не подошла: вокруг букв висело тёмное облако. Осталась только узкая
       кромка — она держит контур и на кадре не читается пятном. */
    text-shadow:
      0 1px 2px oklch(0.14 0.02 40 / 0.9),
      0 1px 4px oklch(0.14 0.02 40 / 0.65);
  }
  .hero__nbr { display: inline; }
  .hero__247 {
    display: block; font-style: normal;
    font-family: var(--font-display); font-size: 1.9rem; line-height: 1;
    color: var(--terracotta-hot);
    text-shadow:
      0 1px 2px oklch(0.14 0.02 40 / 0.9),
      0 1px 4px oklch(0.14 0.02 40 / 0.65);
  }
}

/* ── Карточка блюда на телефоне: лишнее место отдаём снимку ────────────
   Прежде текстовая часть занимала всю оставшуюся высоту и распирала
   описание распоркой. У кухни это работало, а в баре описания короткие
   («Газированный напиток») — под текстом зияло до 260 px пустоты, и никакой
   кегль её не закрывал.
   Теперь наоборот: текст занимает столько, сколько ему нужно, а остаток
   забирает снимок (у позиций без фото — изразец с названием). Высота самой
   карточки прежняя, поэтому кнопка у всех блюд стоит на одном уровне.
   Потолок текстовой части — 58svh: выше него описание не растёт, а кегль
   подбирает скрипт (fitCard), чтобы всё влезало без обрезки. */
@media (max-width: 860px) {
  .sheet__card { grid-template-rows: minmax(30svh, 1fr) auto; }
  .sheet__media { height: auto; min-height: 0; }
  .sheet__text {
    display: block; max-height: 58svh; overflow: hidden;
    padding: 0.9rem 1.1rem 1.05rem;
  }
  /* Распорки больше нет: описание — обычный блок по содержимому */
  .sheet__desc { flex: none; margin-bottom: 0; }
  .sheet__facts { margin-top: 0.75rem; }
}

/* ── Герой на широком экране ───────────────────────────────────────────
   С 12.08.2026 здесь тоже ролик (проход по залу), не снимок — но заголовок
   и порядок строк подписи остались от «прежнего вида», который владелец
   вернул после варианта 08. Блок стоит в конце файла, потому что перебивает
   более ранние правила (в том числе общее .hero__still { object-position:
   50% 50% }). */
.hero__wideonly { display: none; }
@media (min-width: 1025px) {
  /* Второй ролик из DOM не убираем: src ему не проставлен, файл не качается */
  .hero__still--narrow { display: none; }
  .hero h1 br { display: none; }
  /* Довесок «, без выходных.» живёт только здесь: на телефоне строки
     разнесены и запятая мешает. */
  .hero__wideonly { display: inline; font-style: normal; }
  /* Подпись и кнопки подтянуты к заголовку: адрес переехал внутрь h1,
     оставшийся текст короче прежнего, и без этой правки под заголовком
     оставался лишний зазор — владелец просил «работаем круглосуточно» и
     кнопки сдвинуть чуть выше. */
  .hero h1 { margin-bottom: 0.85rem; }
  .hero__sub { margin-bottom: 1.5rem; }
}

/* ── Герой на телефоне: посадка блока и ровный ритм строк ──────────────
   Три замечания владельца одним блоком.
   1. Чёрная пустота под героем. Её давала строка .hero { height: 125svh }
      для узких экранов: за первым экраном оставалось ещё четверть экрана
      фона --ink, и акции начинались далеко за сгибом. Теперь герой ровно
      в один экран, каёмка-шов с акциями приходит сразу за ним.
   2. Текстовая группа стоит в левом низу первого экрана: закреплённая
      часть героя выросла до полного экрана, содержимое прижато к низу
      (align-content: end стоит выше). Ничего не «прыгает» — размеры
      заданы в CSS, а появление строк идёт трансформом, а не потоком.
   3. Строка с оценкой была на отшибе: до неё складывались нижний отступ
      подписи и зазор одноколоночного грида — 40 px против 7 px между
      остальными фразами. Теперь ритм задаётся вручную и одинаков; у
      строки оценки учтена её тач-высота 44 px (внутри бокса ~12 px
      воздуха сверху, поэтому боксовый зазор отрицательный).
   Порог 900, а не 1024: выше него в герое ещё стоят две кнопки, и в один
   экран группа уже не укладывается — на планшете строка оценки уезжала
   за сгиб. Владелец правит именно телефон, планшет остаётся как был. */
@media (max-width: 900px) {
  .hero { height: auto; min-height: 100svh; }
  .hero__pin { min-height: 100svh; padding-block: 0 clamp(1.2rem, 3.4vh, 2rem); }
  /* Ритм между фразами держим margin'ами, а не зазором грида */
  .hero__grid { gap: 0; }
  .hero h1 { margin-bottom: 0.55rem; }
  .hero__sub { margin-bottom: 0; }
  .hero .fan__foot { margin-top: -4px; }
}
@media (max-width: 560px) {
  /* Перебивает прежние 125svh: высота героя ровно в экран */
  .hero { height: auto; min-height: 100svh; }
}

/* ── Карточка блюда на ПК: крупное окно и крупный набор ────────────────
   Владелец просил, чтобы открытая карточка была заметно больше, а шрифт
   в ней — пропорционально крупнее. Блок стоит в самом конце файла
   намеренно: базовые правила .sheet__text h3 и .sheet__facts b объявлены
   ниже по файлу, чем блок карточки, и при одинаковой специфичности
   перебивали бы эти значения.
   Высота задана минимумом, иначе у коротких описаний окно вытягивалось
   узкой полосой. Кегль описания считает fitCard — его потолок 58% от
   названия, поэтому иерархия держится сама. */
@media (min-width: 861px) {
  .sheet__card { min-height: min(74svh, 700px); }
  .sheet__text { display: grid; align-content: center; }
  .sheet__text h3 { font-size: clamp(2.4rem, 1.6rem + 1.9vw, 3.4rem); line-height: 1.02; margin-bottom: 1.1rem; }
  .sheet__cat { font-size: var(--step-1); margin-bottom: 0.85rem; }
  .sheet__desc { max-width: 42ch; }
  .sheet__facts { padding-block: 1.4rem; margin-bottom: 1.8rem; gap: 0.6rem 2.6rem; }
  .sheet__facts b { font-size: clamp(2rem, 1.4rem + 1.3vw, 2.8rem); }
  .sheet__facts span { font-size: var(--step-0); }
  .sheet__actions .btn { min-height: 62px; font-size: var(--step-0); padding-inline: 2rem; }
}

/* ══════════════════════════════════════════════════════════════════
   ВИДЫ ЗАВЕДЕНИЯ — полосы на широком экране, веер на телефоне.
   Секция идёт во всю ширину: кадры разворачиваются от края до края,
   поле у заголовка и у ленты одинаковое.
   ══════════════════════════════════════════════════════════════════ */
.halls {
  --edge: clamp(1.25rem, 3vw, 3.4rem);
  /* сверху секция и так отбита нижним полем «О заведении» — полный отступ
     давал 112 px пустоты, поэтому верх подрезан */
  padding: clamp(1.2rem, 2.4vw, 2.4rem) 0 var(--section);
  background: var(--cream);
}
.halls__head { padding: 0 var(--edge) clamp(1rem, 2.4vw, 1.8rem); }
/* Цвета надкидки и заголовка поменяны местами: терракота ушла на сам
   заголовок, а надпись над ним набрана тем же приглушённым тоном, что и
   вводный абзац «Как поесть у нас» (.doors__lede). */
.halls__kicker {
  display: block;
  font-size: 0.78rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--muted-on-cream); font-weight: 600;
  margin-bottom: 0.15rem;
}
.halls__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 1.3rem + 3vw, 3.8rem);
  line-height: 1.04;
  color: var(--terracotta);
}
.halls__pc { display: block; padding: 0 var(--edge); }
.halls__mob { display: none; }
@media (max-width: 900px) {
  .halls__pc { display: none; }
  .halls__mob { display: block; }
  .halls__head { text-align: center; }
}

/* ── полосы ─────────────────────────────────────────────────────── */
.strips {
  display: flex;
  gap: 8px;
  height: clamp(400px, 68vh, 780px);
}
.strips__item {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  border-radius: 14px;
  overflow: hidden;
  cursor: pointer;
  background: #241a15;
  transition: flex-grow 0.72s var(--ease);
}
.strips__item.is-open { flex-grow: 4.6; }
/* внутри полосы два кадра: показанный и приёмник, ждущий над верхней кромкой */
.strips__stack { position: absolute; inset: 0; }
.strips__shot {
  position: absolute; inset: 0;
  transform: translateY(0);
  transition: transform 0.9s var(--ease);
  will-change: transform;
}
.strips__shot.is-up { transform: translateY(-100%); }
.strips__shot img { width: 100%; height: 100%; object-fit: cover; }
/* приглушение свёрнутой полосы — слоем, а не фильтром: filter на снимке
   1800 px пересчитывался при каждой смене кадра и давал тяжёлый кадр */
.strips__shot::after {
  content: '';
  position: absolute; inset: 0;
  background: rgba(24, 16, 12, 0.34);
  transition: opacity 0.6s ease;
  pointer-events: none;
}
.strips__item.is-open .strips__shot::after { opacity: 0; }
.strips__item::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(20, 14, 11, 0.9) 0%, rgba(20, 14, 11, 0) 46%);
  opacity: 0.85;
  transition: opacity 0.5s ease;
  pointer-events: none;
}
.strips__item.is-open::after { opacity: 1; }
.strips__cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 1.6rem 1.8rem;
  display: flex; flex-direction: column; gap: 5px;
  opacity: 0; transform: translateY(10px);
  transition: opacity 0.45s ease 0.14s, transform 0.5s var(--ease) 0.14s;
}
.strips__item.is-open .strips__cap { opacity: 1; transform: none; }
.strips__cap b {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.5rem, 1.1rem + 1.5vw, 2.5rem);
  color: var(--cream);
  white-space: nowrap;
}
.strips__cap span {
  font-size: clamp(0.95rem, 0.9rem + 0.3vw, 1.14rem);
  color: rgba(245, 236, 220, 0.78);
  white-space: nowrap;
}
.strips__spine {
  position: absolute; z-index: 2;
  left: 50%; bottom: 1.5rem;
  transform: translateX(-50%) rotate(180deg);
  writing-mode: vertical-rl;
  font-size: clamp(0.95rem, 0.85rem + 0.35vw, 1.25rem);
  letter-spacing: 0.13em; text-transform: uppercase;
  color: rgba(245, 236, 220, 0.9);
  white-space: nowrap;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  transition: opacity 0.3s ease;
}
.strips__item.is-open .strips__spine { opacity: 0; }
.strips__zoom {
  position: absolute; right: 14px; bottom: 14px; z-index: 3;
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(20, 14, 11, 0.45);
  backdrop-filter: blur(6px);
  color: var(--cream);
  opacity: 0; transform: scale(0.8);
  transition: opacity 0.4s ease, transform 0.4s var(--ease);
  pointer-events: none;
}
.strips__item.is-open .strips__zoom { opacity: 1; transform: none; }

/* ── веер на телефоне ───────────────────────────────────────────── */
.cover__frame {
  --card: min(74vw, 320px);
  position: relative;
  overflow: hidden;
  padding: 1.6rem 0;
  cursor: grab;
  perspective: calc(var(--card) * 3);
  touch-action: pan-y;
  outline: none;
}
.cover__track {
  position: relative;
  height: calc(var(--card) * 1.24);
  transform-style: preserve-3d;
  user-select: none;
}
.cover__card {
  position: absolute; left: 50%; top: 0;
  width: var(--card);
  height: calc(var(--card) * 1.24);
  border-radius: 14px;
  overflow: hidden;
  background: #241a15;
  will-change: transform;
  cursor: pointer;
}
.cover__card img { width: 100%; height: 100%; object-fit: cover; }
.cover__corner {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: 2.4rem 1rem 0.95rem;
  background: linear-gradient(to top, rgba(20, 14, 11, 0.86), rgba(20, 14, 11, 0));
  color: var(--cream);
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}
.cover__card.is-mid .cover__corner { opacity: 1; }
.cover__corner b {
  display: block;
  font-family: var(--font-display); font-weight: 400;
  font-size: 1.35rem; line-height: 1.15;
}
.cover__corner span { display: block; margin-top: 0.15rem; font-size: 0.9rem; color: rgba(245, 236, 220, 0.78); }

/* ── просмотр во весь экран ─────────────────────────────────────── */
.lb {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(12, 9, 7, 0.985);
  backdrop-filter: blur(10px);
  display: flex; flex-direction: column;
  justify-content: center; align-items: center;
  opacity: 0;
  transition: opacity 0.35s ease;
  touch-action: pan-y;
}
.lb[hidden] { display: none; }
.lb.is-on { opacity: 1; }
.lb__stage {
  position: relative;
  width: 100%;
  display: grid; place-items: center;
  padding: 0 clamp(0.6rem, 2vw, 1.6rem);
  min-height: 0;
}
.lb__stage img {
  grid-area: 1 / 1;
  max-width: 100%;
  width: auto; height: auto;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.9);
  opacity: 0;
  transform: translateX(var(--from, 0)) scale(0.99);
  transition: opacity 0.5s var(--ease-quart), transform 0.66s var(--ease);
  will-change: opacity, transform;
}
.lb__stage img.is-on { opacity: 1; transform: none; z-index: 2; }
.lb__stage img.is-out { opacity: 0; transform: translateX(var(--to, 0)) scale(0.99); z-index: 1; }
.lb__bar {
  display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap;
  width: var(--shot-w, auto);
  max-width: 100%;
  margin-inline: auto;
  padding: 1rem 0 clamp(1.2rem, 3vw, 2rem);
  color: var(--cream);
  text-align: left;
}
.lb__bar b { font-family: var(--font-display); font-weight: 400; font-size: clamp(1.3rem, 1.1rem + 1vw, 2rem); }
.lb__bar span { color: rgba(245, 236, 220, 0.72); font-size: clamp(0.94rem, 0.9rem + 0.2vw, 1.1rem); }
.lb__bar i { font-style: normal; color: rgba(245, 236, 220, 0.5); font-variant-numeric: tabular-nums; letter-spacing: 0.1em; font-size: 0.86rem; }
.lb__nav, .lb__close {
  position: absolute; z-index: 4;
  border-radius: 50%;
  border: 1px solid rgba(245, 236, 220, 0.36);
  background: rgba(20, 14, 11, 0.5);
  color: var(--cream);
  cursor: pointer;
  display: grid; place-items: center;
  backdrop-filter: blur(6px);
  transition: background 0.25s ease, border-color 0.25s ease, transform 0.25s ease;
}
.lb__nav { top: 50%; width: 58px; height: 58px; font-size: 20px; transform: translateY(-50%); }
.lb__nav:hover { background: var(--terracotta); border-color: var(--terracotta); transform: translateY(-50%) scale(1.06); }
.lb__nav--prev { left: clamp(0.6rem, 2.4vw, 2.4rem); }
.lb__nav--next { right: clamp(0.6rem, 2.4vw, 2.4rem); }
.lb__close { position: fixed; top: clamp(0.8rem, 2.4vw, 2rem); right: clamp(0.8rem, 2.4vw, 2rem); width: 48px; height: 48px; font-size: 22px; line-height: 1; }
.lb__close:hover { background: var(--terracotta); border-color: var(--terracotta); }
@media (max-width: 720px) {
  .lb__stage { padding: 0 0.35rem; }
  .lb__nav { width: 44px; height: 44px; }
  .lb__nav--prev { left: 0.35rem; }
  .lb__nav--next { right: 0.35rem; }
  .lb__bar { gap: 0.3rem; flex-direction: column; align-items: center; padding-top: 1rem; text-align: center; }
}
@media (prefers-reduced-motion: reduce) {
  .strips__shot, .strips__item, .cover__card { transition: none; }
}


/* ══════════════════════════════════════════════════════════════════
   Пищевая ценность в карточке блюда. Заполняется в редакторе /admin;
   если поля пустые — блока нет вовсе, прочерков не рисуем.
   Две строки: заголовок «на 100 г» и сами цифры кеглем описания.
   ══════════════════════════════════════════════════════════════════ */
.sheet__nutri {
  display: grid;
  gap: 0.35rem;
  /* линия уже есть под ценой и порцией — вторая рядом читалась как ошибка */
  margin: -0.5rem 0 1.5rem;
}
.sheet__nutri[hidden] { display: none; }

.sheet__nutri-cap {
  /* вдвое крупнее прежней подписи и жирный: строка должна читаться сразу,
     а не теряться между ценой и кнопкой */
  font-family: var(--font-text);
  font-weight: 700;
  font-size: clamp(1.2rem, 1rem + 0.7vw, 1.55rem);
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--terracotta);
}

/* сами цифры — тем же начертанием и кеглем, что описание блюда */
.sheet__nutri-vals {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.5rem;
  color: var(--ink-on-cream);
  line-height: 1.45;
}
.sheet__nutri-vals span[hidden] { display: none; }
.sheet__nutri-vals span { font-variant-numeric: tabular-nums; white-space: nowrap; }


@media (max-width: 860px) {
  /* Блок КБЖУ появился позже, чем подбиралась мобильная раскладка карточки,
     и своими двумя строками выталкивал кнопку заказа за нижний край.
     Подпись «на 100 г» встала в одну строку с цифрами, кегль срезан —
     блок стал вдвое ниже, кнопка вернулась внутрь карточки.
     Правило стоит здесь, в конце файла: базовый .sheet__nutri объявлен выше
     и при равной силе перебивал бы медиазапрос порядком. */
  .sheet__nutri {
    display: flex; flex-wrap: wrap; align-items: baseline;
    gap: 0.1rem 0.7rem; margin: 0 0 0.5rem;
  }
  .sheet__nutri-cap { font-size: 0.86rem; }
  /* кегль цифр подставляет скрипт инлайном (fitCard → syncNutri),
     поэтому здесь !important — иначе строка снова разъедется на две */
  .sheet__nutri-vals { gap: 0.1rem 0.8rem; line-height: 1.3; font-size: 0.82rem !important; }

  /* Ритм карточки на телефоне (правка владельца 14.08): описание набиралось
     почти вровень с названием и шло разреженными строками, занимая полкарточки;
     подписи «цена» и «порция» стояли отдельными строчками под своими числами
     и читались как чужие; а строка КБЖУ упиралась в кнопку заказа. */
  .sheet__text h3 {
    font-size: clamp(1.42rem, 1.06rem + 1.7vw, 1.82rem);
    line-height: 1.08; margin-bottom: 0.45rem;
  }
  .sheet__desc { line-height: 1.32; }

  /* Подпись рядом со своим числом, на одной базовой линии */
  .sheet__facts {
    gap: 0.3rem 1.2rem; padding-block: 0.6rem; margin-bottom: 0.55rem;
  }
  .sheet__facts > div { display: flex; align-items: baseline; gap: 0.32rem; }
  .sheet__facts b { display: inline; font-size: 1.2rem; line-height: 1.1; }
  .sheet__facts span { order: -1; font-size: 0.8rem; }

  /* Воздух между КБЖУ и кнопкой заказа */
  .sheet__nutri { margin: 0 0 0.85rem; }
  .sheet__actions { margin-top: 0.1rem; }
}

/* Короткий экран (Safari с обеими панелями, старые iPhone): карточка держит
   88svh, а содержимое не резиновое — ужимаем ещё на шаг, чтобы кнопка заказа
   гарантированно осталась внутри кремового поля. */
@media (max-width: 860px) and (max-height: 680px) {
  /* Название держим крупным даже здесь: место под него отыграно у описания,
     которое теперь набирается мельче (см. долю 0.56 в fitCard). Раньше на
     коротком экране заголовок падал до кегля описания и карточка читалась
     сплошным текстом. */
  .sheet__text h3 { font-size: 1.28rem; line-height: 1.06; margin-bottom: 0.32rem; }
  .sheet__facts { padding-block: 0.32rem; margin-bottom: 0.4rem; }
  .sheet__facts b { font-size: 1.05rem; }
  .sheet__nutri { margin-bottom: 0.7rem; }
  .sheet__nutri-cap { font-size: 0.78rem; }
  .sheet__nutri-vals { font-size: 0.76rem !important; }
  .sheet__actions .btn { min-height: 44px; }
}

/* Подбор кегля описания читает scrollHeight — браузер каждый раз пересчитывает
   всю страницу. Границы делают пересчёт локальным: при листании карточек на
   ПК это снимало заметные пропуски кадров. */
.sheet__text { contain: layout style; }
.sheet__card { contain: layout paint; }

/* Пока открыта карточка блюда, шапка и полоса категорий не нужны: раньше их
   прятало размытие подложки, а без него они читались сквозь затемнение и
   спорили с карточкой. */
body.sheet-open .topbar,
body.sheet-open .flylogo,
body.sheet-open .rail {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease);
}

/* ══ 14. ВЫХОД ПЕРВОГО ЭКРАНА ══════════════════════════
   Раньше текст героя выезжал по таймеру, а ролик появлялся когда успевал —
   на телефоне это читалось как подвисание: сначала пустой кадр, потом рывком
   надпись, потом отдельно капсула шапки. Теперь всё ждёт первого кадра
   ролика и выходит одним движением (см. heroIntro в app.js).

   Класс js-intro ставит инлайновый скрипт в <head>, до отрисовки, и снимает
   либо анимация, либо страховочный таймер на 3,2 с. */
.js-intro .topbar__capsule,
.js-intro .hero__logo,
.js-intro .hero__lede h1,
.js-intro .hero__sub,
.js-intro .hero__actions,
.js-intro .hero .fan { opacity: 0; }
/* Кадр НЕ прячем. Раньше прятали — и первое, что видел гость, был чёрный
   экран с одним логотипом: текст скрыт классом, а кадр ещё не проявлен.
   Теперь постер виден с первой отрисовки, а поверх него выходит текст.
   Знак заведения и веер отзывов раньше не входили в этот список вовсе —
   логотип стоял на месте с первого кадра, а карточки отзывов выскакивали
   без захода, как только JS успевал их дорисовать. Теперь оба ждут общего
   выхода героя, как и весь остальной первый экран. */

/* Заголовок выходит построчно из-под маски — приём «занавес», один и тот же
   на любой ширине экрана. На узком — настоящие строки по <br> из разметки,
   на широком — тот же приём на единственной строке (<br> там просто
   скрыты стилями). Нижнее поле у маски обязательно: без него маска срезает
   хвосты «р», «у» и запятые. Компенсируется отрицательным margin, чтобы
   строки не разъехались. */
.hero__line { display: block; overflow: hidden; padding-bottom: 0.12em; margin-bottom: -0.12em; }
.hero__line-in { display: block; will-change: transform; }

@media (prefers-reduced-motion: reduce) {
  .js-intro .topbar__capsule,
  .js-intro .hero__logo,
  .js-intro .hero__lede h1,
  .js-intro .hero__sub,
  .js-intro .hero__actions,
  .js-intro .hero .fan { opacity: 1; }
}
