/* booking-widget. Скоуп .hb-root (CSS Nesting): селекторы внутри — как в
   landing.css, каскад наружу не течёт. @font-face — на топ-уровне (в nesting
   не работает). Размерная единица --u — от КОНТЕЙНЕРА (cqw), не от viewport.
   Файл собирается копированием в public-static/booking-widget.css и позже
   подключается И на лендинге — НИКАКИХ топ-уровневых правил для html/body/
   глобальных тегов (резеты, нужные разметке, скоуплены внутрь .hb-root).
   Донор: public-static/landing.css — блоки скопированы КАК ЕСТЬ; правки
   зеркалить в обе копии до задачи переключения лендинга на модуль. */

/* 1) @font-face Inter — копия обоих блоков landing.css (топ-уровень).
   Inter — самохостинг (variable woff2, same-origin) → грузится быстро и без
   зависимости от Google Fonts; цифры и весь текст сразу в Inter. */
@font-face{
  font-family:'Inter';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('/static/fonts/inter-cyrillic.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('/static/fonts/inter-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

.hb-root {
  /* 2) переменные — содержимое :root из landing.css. Исключение: --u из
     донора (calc(100vw/320)) не переносим — единица виджета идёт от
     контейнера (п.3), а не от viewport (D-P1/D-P6); @media-cap 480px донора
     воспроизведён капом min(…, 1.5px) в @supports ниже. */
  --base-width: 320;

  --bg:#ededf2; --card:#fff; --card-2:#f0f3f9;
  --ink:#062b47; --ink-2:#24362e; --muted:#355873; --muted-2:#3c4f5d;
  --accent:#B1FFAD; --warn:#fe204d; --highlight:#fff705; --tg:#229ed9;
  --shadow-card: 0 1px 3px rgb(0 0 0 / 0.04), 0 0 0 1px rgb(0 0 0 / 0.02);
  --shadow-cta: 0 4px 14px rgb(177 255 173 / 0.45);
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* 3) единица от контейнера + фолбэк */
  --u: 1.2px;                      /* px-фолбэк (iOS < 16) */
  font-family: var(--font-sans);
  color: var(--ink);
  /* типографический контекст body из landing.css (font-weight/сглаживание) —
     без него незаданные веса падают в 400 вместо 500 */
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
  box-sizing: border-box;
  /* Явная ширина: mount-узел лендинга — flex-item, а inline-size containment
     на .hb-sizebox обнуляет intrinsic-вклад контента → без width:100% вся
     цепочка схлопывается в 0 (см. фикс BW-14). */
  width: 100%;

  /* Контейнер размеров отделён от корня (.hb-sizebox создаёт index.js):
     container-type на .hb-root включал бы layout containment и делал бы корень
     containing block'ом для fixed-модалки (css-contain §layout). Модалка живёт
     сиблингом sizebox → fixed от вьюпорта; cqw-юниты (--u из @supports ниже)
     внутри sizebox резолвятся от его ширины, в модалке — svw-фолбэк ≈
     поведение монолитного 100vw/320.
     ИНВАРИАНТ: container-type только здесь; любой другой предок .modal с
     container-type вернёт баг containing block для fixed. */
  & .hb-sizebox { container-type: inline-size; width: 100%; }

  /* Скоуплённые резеты — в монолите глобальные (landing.css: *, a, button);
     разметка модуля перенесена дословно и опирается на них. Тег-селекторы —
     через «&» (строгий nesting Safari 16.5 не парсит голый ident). */
  *,*::before,*::after{box-sizing:border-box}
  & a{color:inherit;text-decoration:none}
  & button{font-family:inherit;color:inherit;border:0;background:transparent;cursor:pointer}

  /* 4) донорские блоки landing.css — селекторы БЕЗ изменений */

  /* ═══ BOOKING CARD (inner; внешний .booking-каркас в разметке модуля нет) ═══ */
  .booking-inner{
    background:var(--card-2);
    border-radius: calc(24 * var(--u));
    width: 100%;                    /* было calc(301*u) фикс-колонка — расширено под ширину nav-ряда */
    min-height: calc(133 * var(--u));
    margin: 0 auto;
    /* верх −8px: было calc(12*u) сверху, стало 5·u; низ оставлен 12·u; гор. 8.5·u */
    padding: calc(5 * var(--u)) calc(8.5 * var(--u)) calc(12 * var(--u));
    display:flex;flex-direction:column;align-items:center;
    gap: calc(10 * var(--u));
  }
  .booking-header{display:flex;align-items:center;justify-content:space-between;gap: calc(6 * var(--u))}
  .booking-title{
    /* Inter Bold 11 — сдвинут на 5 влево */
    color:var(--ink);
    font-size: calc(11 * var(--u));font-weight:700;line-height:1;
    margin: 0 0 0 calc(-5 * var(--u));
  }
  /* display:inline-flex перебивает встроенный display:none у [hidden] —
     без этой строки скрытая пилюля осталась бы видимой. */
  .pill[hidden]{ display:none; }
  .pill{
    /* Inter Bold 10 */
    display:inline-flex;align-items:center;justify-content:center;
    height: calc(24 * var(--u));
    padding: 0 calc(10 * var(--u));
    border-radius: calc(12 * var(--u));
    font-size: calc(10 * var(--u));font-weight:700;white-space:nowrap;
  }
  .pill--pending{background:var(--warn);color:#fff}
  .pill--ok{background:var(--accent);color:var(--ink-2)}
  .cta{
    /* 131×34 rx 24 */
    align-self:center;
    display:flex;align-items:center;justify-content:center;
    gap: calc(6 * var(--u));
    width: calc(131 * var(--u));
    height: calc(34 * var(--u));
    padding: 0 calc(12 * var(--u));
    border-radius: calc(24 * var(--u));
    background:var(--accent);color:var(--ink-2);
    font-size: calc(11 * var(--u));font-weight:700;
    transition: background .15s ease, color .15s ease;
  }
  .cta:active:not(:disabled){transform:scale(.98)}
  .cta svg, .cta__icon{width: calc(16 * var(--u));height: calc(18 * var(--u));object-fit:contain}
  .cta:disabled{
    background:var(--card-2);color:var(--muted);
    cursor:not-allowed;
  }
  .cta:disabled svg{stroke:var(--muted)}

  /* ═══ MODULE #2 — Онлайн-бронирование ═══════════════════════════════
     Тот же outer 320×147, но inner растягивается под picker'ы и slots */
  .booking-inner--book{
    position:relative;
    /* Inner может быть выше 133, если контента больше */
    min-height: calc(133 * var(--u));
    height:auto;
    gap: calc(8 * var(--u));
  }
  /* Виджет (single-layout): пикеры и форма — в ОДНОЙ карточке, как модалка
     «Бронирование стола». CTA карточки скрыт, слоты появляются по выбору, поэтому
     резерв высоты 133·u не нужен (он давал пустой провал под пикерами). Поля —
     как у .modal__card, чтобы контент не лип к краям шейпа. */
  .booking-inner--book:has(.hb-inline-form){
    min-height:0;
    padding: calc(12 * var(--u)) calc(14 * var(--u)) calc(20 * var(--u));
  }
  /* Логотип ресторана над заголовком «Забронировать». Только страница виджета:
     на лендинге логотип живёт в собственной шапке, и второй был бы дублем.

     100px даёт САМ слот, а не padding карточки. Так пустых 100px не остаётся,
     когда логотип не задан, — а когда задан, отступ над заголовком ровно тот,
     что согласовали.

     Фиксированные px, а не сетка (N·u): у картинки своя натуральная высота, ей
     нужен предсказуемый габарит, а не доля ширины контейнера — при 100·u на
     узком телефоне слот схлопнулся бы до ~78px.

     object-fit: contain: логотип любой пропорции впишется целиком, не обрежется
     и не растянется. */
  .hb-logo{
    height:100px;
    display:grid;place-items:center;
    /* Своего нижнего отступа нет: слот — flex-ребёнок .booking-inner--book, и
       его gap (8·u) уже отбивает логотип от блока брони. Собственный
       margin-bottom складывался с ним и опускал блок на лишние 4.69px. */
  }
  /* Сама иконка — 60px по высоте внутри 100px слота: остаются поля сверху и
     снизу, логотип не упирается в край карточки и в заголовок. */
  .hb-logo img{
    max-width:100%;max-height:60px;
    width:auto;height:auto;
    object-fit:contain;display:block;
  }
  /* Слот сам отбивает верх карточки — иначе к 100px добавились бы ещё 12·u. */
  .booking-inner--book:has(.hb-logo){ padding-top:0; }
  /* Шейпы вокруг динамической части (дата/гости/время + сетка слотов): ДВА
     вложенных, геометрия дословно с пары .booking / .booking-inner— белый
     снаружи, серый внутри. Контактная форма лежит за ними и остаётся на фоне
     карточки, поэтому выделен ровно блок бронирования слотов.

     width:100% + border-box обязательны: родитель — flex с align-items:center,
     без них обёртка сожмётся по контенту, а .picker-row (width:100%) вылезет.

     Ширина: серый должен быть 292·u (337.63px на контейнере 370) — ровно та
     ширина, которую белый занимал раньше. Значит белый расширяется на свои
     горизонтальные паддинги, +9.5·u с каждой стороны, и выходит за поля
     карточки. Запас есть: у .booking-inner--book padding 14·u, белый съедает
     9.5·u, до края остаётся 4.5·u. Форма ниже не двигается — она width:100%
     от карточки, её эти 19·u не касаются.

     ═══ ОФОРМЛЕНИЕ — ТОЛЬКО ВИДЖЕТ, И ЭТО НЕ ПРИДИРКА ═══
     bookingBlockHtml — ОДНА разметка на виджет и на лендинг, а этот css
     подключён на обеих страницах. Первая версия правил была без скоупа, и
     шейпы уехали на лендинг: там блок брони уже лежит в своей белой .booking,
     и внутри неё появилась ВТОРАЯ белая карточка, а в ней третья серая
     (поймано владельцем на живом лендинге, DEBT D41).

     Признак виджета — inline-форма: она существует только в layout `single`,
     на лендинге контакты живут в модалке. Поэтому всё ВИДИМОЕ (фон, радиус,
     паддинги, расширение по ширине, min-height) висит на
     `.booking-inner--book:has(.hb-inline-form)`, а раскладка (flex/gap) —
     общая: обёртки стоят между .booking-inner--book и его детьми на ОБЕИХ
     страницах, и без flex-контекста .booking-header растянулся бы во всю
     ширину, а его space-between развёл бы заголовок и пилл по углам. */
  /* РАСКЛАДКА — обе страницы. width:100% обязателен и на лендинге: родитель —
     flex с align-items:center, без него обёртка сожмётся по контенту и утащит
     за собой .picker-row и .slots, которые тянутся на 100% уже от неё. */
  .hb-dynamic{ width:100%; box-sizing:border-box; }
  /* ВИД — только виджет. Ширина здесь ДРУГАЯ: белый расширен на свои
     горизонтальные паддинги (+19·u), чтобы серый внутри вышел ровно на 292·u. */
  .booking-inner--book:has(.hb-inline-form) .hb-dynamic{
    background: var(--card);
    border-radius: calc(24 * var(--u));
    /* Вертикальный паддинг И ЕСТЬ зазор между белым и серым: сверху и снизу
       других отступов между ними нет. 5·u = 5.9px на опорной 375 (было 7·u =
       8.2px). Горизонтальные 9.5·u не трогаем — от них считается ширина серого
       (292·u), и их правка сдвинула бы согласованный размер. */
    padding: calc(5 * var(--u)) calc(9.5 * var(--u));
    width: calc(100% + 19 * var(--u));
  }
  /* Внутренний серый — копия .booking-inner + gap 8·u из .booking-inner--book.
     min-height:133·u донора НЕ переносим: в inline-layout CTA скрыт и слоты
     появляются по выбору, резерв высоты дал бы пустой провал под пикерами.

     flex + align-items:center + gap — ТОТ ЖЕ контекст, что был у
     .booking-inner--book до появления обёрток: в блочном потоке .booking-header
     растянулся бы во всю ширину, а его space-between развёл бы заголовок и пилл
     по углам. Пикеры и слоты сами width:100%, центрирование их не сужает. */
  /* РАСКЛАДКА — обе страницы. Обёртки стоят между .booking-inner--book и его
     детьми и на лендинге тоже, поэтому flex-контекст нужен всегда: без него
     .booking-header растянется во всю ширину и space-between разведёт заголовок
     и пилл по углам. Ни фона, ни паддингов здесь нет — на лендинге обёртки
     обязаны быть невидимыми. */
  .hb-dynamic__inner{
    width:100%; box-sizing:border-box;
    display:flex;flex-direction:column;align-items:center;
    gap: calc(8 * var(--u));
    /* Сетка слотов до выбора гостей пуста: высоты у неё нет, но как flex-ребёнок
       она всё равно забирает свой gap (8·u) — блок раздувался на 9.25px мимо
       согласованных 112. hidden ставится не всегда (пустой рендер оставляет
       узел видимым), поэтому гасим именно по :empty. */
    & > .slots:empty{ display:none; }
  }
  /* ВИД — только виджет (см. разбор выше). */
  .booking-inner--book:has(.hb-inline-form) .hb-dynamic__inner{
    background: var(--card-2);
    border-radius: calc(24 * var(--u));
    padding: calc(8 * var(--u)) calc(8.5 * var(--u)) calc(12 * var(--u));
    /* 100·u = 117.2px на опорной ширине 375 (та же, в которой сняты все замеры
       в DESIGN.md) — согласованная высота пустого состояния. Единица от
       контейнера, поэтому в px значение «плывёт»: при 390 это 121.9px. Именно
       min-, а не height: со слотами блок обязан расти. */
    min-height: calc(100 * var(--u));
  }
  /* ─── Пикер «Ресторан» (сеть) — над серым шейпом ────────────────────
     Существует ТОЛЬКО при cfg.network (single-layout): лендинг и одиночные
     виджеты его не рендерят, поэтому скоуп-страховка здесь про аккуратность,
     а не про необходимость. Кнопка — тем же языком, что Дата/Гости/Время. */
  .booking-inner--book:has(.hb-inline-form) .picker--rest{
    display:block;
    margin-bottom: calc(5 * var(--u)); /* тот же зазор, что паддинг белого шейпа */
  }
  /* Кнопка без лейбла: одна строка по центру, высота 34·u (≈40px при 375).
     Шеврон — absolute справа, чтобы он не участвовал в центрировании текста
     (иначе надпись сместилась бы влево на его ширину). */
  .booking-inner--book:has(.hb-inline-form) .picker--rest .picker__btn{
    width:100%;
    height: calc(34 * var(--u));
    padding: 0 calc(10 * var(--u));
    position:relative;
  }
  /* Тот же знак «раскрыть», что у выбора страны в телефоне — один язык. */
  .picker--rest .picker__caret{
    position:absolute;right: calc(12 * var(--u));top:50%;
    width: calc(9 * var(--u));height: calc(9 * var(--u));margin-top: calc(-4.5 * var(--u));
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%233c4f5d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 2l4 4 4-4'/></svg>");
    background-size:contain;background-repeat:no-repeat;background-position:center;
    transition: transform .18s cubic-bezier(.22,.61,.36,1);
  }
  /* Выбранный ресторан — тёмная кнопка, стрелка на ней должна быть светлой. */
  .picker--rest .picker__btn.is-filled .picker__caret{
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 2l4 4 4-4'/></svg>");
  }
  .picker--rest[data-open="true"] .picker__caret{ transform: rotate(180deg); }
  /* До выбора — серая кнопка тем же тоном, что внутренний шейп (--card-2):
     белая сливалась с белым шейпом вокруг. Синей (is-filled, как у Даты)
     становится ТОЛЬКО после выбора ресторана. */
  /* Состояние фона берём из того же класса, что у «Даты» — is-filled, его
     ставит JS. Одно правило на «не выбран» вместо пары [data-chosen], которая
     дублировала бы уже существующее .picker__btn.is-filled и спорила с ним за
     каскад. data-chosen остаётся, но только как гейт для JS (restChosen). */
  .picker--rest .picker__btn:not(.is-filled){ background: var(--card-2); }
  .picker--rest .picker__btn:not(.is-filled) .picker__value{ color: var(--muted); font-weight:600; }
  /* Значение в обычных пикерах опущено на 3·u — это компенсация лейбла над
     ним. Здесь лейбла нет, и сдвиг утаскивал текст ниже центра кнопки:
     снимаем, чтобы надпись стояла ровно по центру шейпа в обоих состояниях. */
  .picker--rest .picker__value{ top:0; }
  /* Логотип и первый шейп: слот 100px давал слишком много воздуха, вся карточка
     уезжала вниз. 84px — тот же логотип (иконка ≤60px), меньше пустоты сверху;
     всё, что ниже, подтягивается вместе с ним.
     Отрицательный margin гасит gap карточки (8·u) ТОЛЬКО под логотипом: без
     этого зона сверху была несимметричной — 12px над картинкой и 21.4 под ней
     (12 внутри слота + gap). Теперь слот и есть вся зона до шейпа, и картинка
     стоит в ней по центру. */
  .booking-inner--book:has(.hb-inline-form) .hb-logo{
    height:84px;
    margin-bottom: calc(-8 * var(--u));
  }
  /* Файл целиком вложен в .hb-root — селекторы здесь БЕЗ префикса .hb-root,
     иначе скомпилируется .hb-root .hb-root и правило умрёт молча. */
  .picker--rest .picker__dropdown{
    display:flex; flex-direction:column; gap: calc(2 * var(--u));
    padding: calc(4 * var(--u));
  }
  .net-option{
    display:block; width:100%; text-align:left;
    border:0; background:transparent; cursor:pointer;
    font:inherit; font-size: calc(11 * var(--u)); font-weight:600; color:var(--ink);
    padding: calc(6 * var(--u)) calc(8 * var(--u));
    border-radius: calc(12 * var(--u));
  }
  .net-option.is-current{ background: var(--card-2); }
  .net-option:not(.is-current):hover,
  .net-option:not(.is-current):active{ background: var(--card-2); }

  /* Ряд «Дата · Гости · Время» опущен на 4·u (≈5px при 375) — воздуха под
     шапкой блока не хватало. Только в виджете: на лендинге тот же ряд живёт
     в модалке со своим ритмом. */
  .booking-inner--book:has(.hb-inline-form) .picker-row{ margin-top: calc(4 * var(--u)); }
  /* После отправки (.is-sent ставит contact-form) блок становится сводкой брони:
     ряд уезжает ещё на ~10px ниже — 12.5·u вместо 4·u, 14.65px против 4.69. */
  .booking-inner--book.is-sent:has(.hb-inline-form) .picker-row{ margin-top: calc(12.5 * var(--u)); }

  /* flex-ребёнок при align-items:center сжался бы по контенту — тянем на ширину. */
  .booking-inner--book > .hb-inline-form{ width:100%; }
  /* Поля формы нарисованы под БЕЛУЮ модалку: фон --card-2 читается на белом
     .modal__card. Внутри карточки виджета фон ровно такой же (--card-2), и поля
     слились с ним в сплошное пятно. Здесь язык обратный — белые шейпы на светло-
     сером (так же выглядят пикеры и чипы рядом), поэтому поля делаем белыми. */
  .hb-inline-form .modal__input,
  .hb-inline-form .country-code__btn,
  .hb-inline-form .modal__consent-box{ background: var(--card); }
  /* Текст полей печатался в 16px (пол против зума iOS при фокусе) и выбивался из
     сетки: лейблы 11·u, «+7» 11·u, чипы 10·u, кнопка 12·u. В inline-layout
     возвращаем сеточный размер — поля читаются заодно с остальной формой. */
  .hb-inline-form .modal__input{ font-size: calc(11 * var(--u)); }
  /* …но НА ТАЧЕ возвращаем пол 16px. iOS Safari при фокусе в поле с текстом
     меньше 16px увеличивает всю страницу — и НЕ возвращает масштаб обратно после
     закрытия клавиатуры. Снаружи это выглядит так, будто форма после ввода стала
     шире: на самом деле зазумлена вся страница.
     Порог 16px — единственный рычаг: другой способ подавить автозум — запретить
     масштабирование (maximum-scale=1 / user-scalable=no), но пинч-зум мы у гостя
     не отбираем.
     max(), а не плоские 16px: на широком контейнере 11·u уже больше 16px, и там
     размер должен и дальше расти по сетке — пол только поднимает нижнюю границу.
     Правило только для тача, поэтому на десктопе и во встраивании на десктопном
     сайте вид остаётся прежним, сеточным. */
  @media (pointer: coarse) {
    .hb-inline-form .modal__input{ font-size: max(16px, calc(11 * var(--u))); }
  }

  /* Picker-row: Дата | Время | Гости — 3 колонки */
  .picker-row{
    display:grid;grid-template-columns:1fr 1fr 1fr;
    gap: calc(5 * var(--u));
    width:100%;
  }
  /* picker — wrapper для кнопки + dropdown */
  .picker{position:relative}
  .picker__btn{
    appearance:none;border:0;cursor:pointer;
    width:100%;background:var(--card);
    /* 16·u — как у плашки выбора в колесе (.date-wheel__band / .time2__band) */
    border-radius: calc(16 * var(--u));
    padding: calc(6 * var(--u)) calc(10 * var(--u));
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap: calc(2 * var(--u));
    height: calc(43 * var(--u));   /* = высота nav-кнопки (была 38·u, picker был на ~11% ниже) */
    transition: background .15s ease;
    font-family:inherit;
  }
  .picker__btn:hover{background:#f7f8fa}
  .picker[data-open="true"] .picker__btn{background:#f0f3f9}
  /* пикер с выбранным значением — тёмно-синий (как иконка/выбранный слот) */
  .picker__btn.is-filled{background:var(--ink)}
  .picker__btn.is-filled:hover{background:#0a3a5e}
  .picker[data-open="true"] .picker__btn.is-filled{background:#0a3a5e}
  .picker__btn.is-filled .picker__label{color:rgba(255,255,255,.72)}
  .picker__btn.is-filled .picker__value{color:#fff}
  .picker__label{
    color:var(--muted);font-size: calc(9 * var(--u));font-weight:500;
    line-height:1;
    /* поднят на ~2px (2·u = 2.23px на 402px). relative — сдвиг чисто визуальный,
       высота кнопки и flex-центрирование не едут (как у .picker__value). */
    position:relative;top: calc(-2 * var(--u));
  }
  .picker__value{
    color:var(--ink-2);font-size: calc(11 * var(--u));font-weight:700;
    line-height:1;white-space:nowrap;
    /* опущено на ~3px (3·u = 3.35px на 402px). relative — сдвиг чисто визуальный:
       лейбл и высота кнопки не едут, центрирование flex не пересчитывается. */
    position:relative;top: calc(3 * var(--u));
  }

  /* Слоты времени — горизонтальная сетка с переносом */
  .slots{
    display:grid;grid-template-columns:repeat(3,1fr);
    gap: calc(5 * var(--u));
    width:100%;
  }
  /* hidden из UA-стилей проигрывает .slots{display:grid} — гасим явно, иначе
     свёрнутая сетка (после выбора слота) осталась бы видимой. */
  .slots[hidden]{display:none}
  .slot{
    background:var(--card);
    border:0;border-radius: calc(10 * var(--u));
    height: calc(28 * var(--u));
    padding: 0 calc(8 * var(--u));
    font-family:inherit;
    font-size: calc(10 * var(--u));font-weight:700;
    color:var(--ink-2);cursor:pointer;
    display:grid;place-items:center;
    transition: background .12s ease, color .12s ease;
  }
  .slot:hover{background:#f7f8fa}
  /* Выбранный слот НЕ подсвечиваем (владелец): сетка — разовый выбор, после тапа
     она сворачивается, а результат видно в пикере «Время». Синяя плашка успевала
     мигнуть и читалась как постоянное состояние. Исключение — «Очередь»: она
     остаётся в сетке, и своя жёлтая подсветка ей нужна (правило ниже). */
  .slot--disabled,.slot[disabled]{
    background:transparent;color:var(--muted);
    text-decoration:line-through;cursor:not-allowed;
    opacity:.5;
  }
  /* Занятый слот — выбранный пользователем, но недоступен.
     Внешний вид как у time-pick--taken в выпадающем меню + перечёркнутое время.
     «занято» подпись внутри слота на 2px ниже перечёркнутого времени. */
  .slot--taken,
  .slot.slot--taken[disabled]{
    background:var(--warn);color:#fff;cursor:not-allowed;
    text-decoration:line-through;text-decoration-thickness: calc(1.5 * var(--u));
    opacity:.92;
  }
  /* Депозитный слот — ₽ справа, время остаётся по центру, ₽ наследует цвет */
  .slot--dep{position:relative}
  .slot--dep::after{
    content:'₽';
    position:absolute;top:50%;right:calc(7 * var(--u));
    transform:translateY(-50%);
    font-size:calc(12 * var(--u));font-weight:700;color:inherit;
    line-height:1;
    pointer-events:none;
  }

  /* Кнопка «Очередь» — лист ожидания, как обычный слот, но жёлтая */
  .slot--queue{
    background:#fff5b8;
    color:var(--ink-2);
  }
  .slot--queue:hover{background:#fff0a0}
  .slot--queue[aria-checked="true"]{background:var(--highlight);color:var(--ink-2)}

  /* ─── Picker dropdown (Дата / Гости) ──────────────────────────── */
  .picker{position:relative}
  .picker__dropdown{
    position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:20;
    background:var(--card);
    border-radius: calc(14 * var(--u));
    padding: calc(8 * var(--u));
    box-shadow: 0 8px 28px rgb(0 0 0 / .14), 0 1px 3px rgb(0 0 0 / .06);
    opacity:0;transform:translateY(-6px) scale(.96);transform-origin:top center;
    pointer-events:none;
    transition: opacity .15s ease, transform .18s cubic-bezier(.22,.61,.36,1);
    max-height: calc(180 * var(--u));overflow-y:auto;
  }
  .picker[data-open="true"] .picker__dropdown{
    opacity:1;transform:translateY(0) scale(1);pointer-events:auto;
  }

  /* Date wheel — вертикальный «фокус-зум» пикер дат */
  .date-strip__month{
    font-size: calc(10 * var(--u));font-weight:700;color:var(--ink);
    text-transform:capitalize;
    margin: 0 0 calc(6 * var(--u));
    letter-spacing: calc(.2 * var(--u));
    text-align:center;
  }
  /* Датапикер И пикер гостей: одинаковое вертикальное колесо «фокус-зум».
     Дропдаун поверх кнопки, ЦЕНТР колеса = центр кнопки, плашка ложится на кнопку.
     Заголовок (Июль / Гости) — absolute-overlay над колесом (не смещает центр). */
  .picker[data-pick="date"] .picker__dropdown,
  .picker[data-pick="guests"] .picker__dropdown,
  .picker[data-pick="time"] .picker__dropdown{
    max-height:none;overflow:visible;
    width: 120px;height: 200px;
    display:flex;flex-direction:column;
    left:50%;right:auto;top:50%;margin-left:0;
    transform: translate(-50%, calc(-50% - 6px)) scale(.96);
    transform-origin: center center;
    border-radius: 30px;
  }
  .picker[data-pick="date"][data-open="true"] .picker__dropdown,
  .picker[data-pick="guests"][data-open="true"] .picker__dropdown,
  .picker[data-pick="time"][data-open="true"] .picker__dropdown{
    transform: translate(-50%, -50%) scale(1);
  }
  .picker[data-pick="date"] .date-strip__month,
  .picker[data-pick="guests"] .date-strip__month,
  .picker[data-pick="time"] .date-strip__month{
    position:absolute;top: calc(6 * var(--u));left:0;right:0;
    margin:0;z-index:2;pointer-events:none;
  }
  /* время — число «HH:MM» шире однозначного, снимаем фикс-слот числа */
  .picker[data-pick="time"] .date-day__num{width:auto;margin-right:0}
  /* «13 : 00» — единая центрированная надпись: часы прижаты к двоеточию справа,
     минуты слева. Иначе (центр в своей половине) цифры разъезжаются к краям
     плашки, а двоеточие остаётся с большими зазорами. Зазор до двоеточия = паддинг. */
  .picker[data-pick="time"] #timeHours .date-day{text-align:right;padding-right: calc(5 * var(--u) + 3px)}
  .picker[data-pick="time"] #timeMinutes .date-day{text-align:left;padding-left: calc(5 * var(--u) + 3px)}
  .date-wheel{position:relative;flex:1 1 auto;min-height:0}
  /* мятная плашка выбранной даты — «основной шейп», ровно 112 CSS-px в ширину,
     центрирована по горизонтали (не масштабируется от viewport) */
  .date-wheel__band{
    position:absolute;left:50%;top:50%;
    width: 102px;height: 48px;
    transform:translate(-50%, -50%);
    /* 16·u — тот же радиус, что у .picker__btn; было 18px фикс (не масштабировалось) */
    background:var(--ink);border-radius: calc(16 * var(--u));z-index:0;
  }
  .date-wheel__scroll{
    position:relative;z-index:1;height:100%;overflow-y:auto;
    scroll-snap-type:y mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;
    touch-action:pan-y;
    -webkit-mask-image:linear-gradient(to bottom,transparent,#000 26%,#000 74%,transparent);
            mask-image:linear-gradient(to bottom,transparent,#000 26%,#000 74%,transparent);
  }
  .date-wheel__scroll::-webkit-scrollbar{display:none}
  .date-wheel__pad{height: calc(82 * var(--u))}
  /* строка даты — монолитная надпись «число + ДН» (единый inline-поток,
     центрированный в контейнере). Формат близок к кнопке «Дата». Центр строки
     всегда = центр контейнера у всех дат независимо от их длины — при scale
     строки масштабируются от общей центральной оси и не «гуляют» вбок. */
  .date-day{
    position:relative;
    display:block;width:100%;height: calc(40 * var(--u));
    line-height: calc(40 * var(--u));text-align:center;
    background:transparent;border:0;cursor:pointer;padding:0;
    scroll-snap-align:center;
    font-family:inherit;color:var(--muted);
    will-change:opacity;
  }
  /* число + ДН — inline-группа, центрированная в строке = в шейпе (плашке).
     scale вешается на само число (origin center) → цифра растёт строго на месте
     и не гуляет вбок; ДН статичен (не масштабируется, тоже не качается). */
  .date-day__num{
    display:inline-block;vertical-align:middle;
    width: calc(24 * var(--u));text-align:center;
    margin-right: calc(6 * var(--u));
    font-size: calc(15 * var(--u));font-weight:700;color:var(--ink);
    will-change:transform;transform-origin:center center;
  }
  .date-day__mon,.date-day__dow{
    display:inline-block;vertical-align:middle;
    font-size: calc(11 * var(--u));font-weight:600;
    text-transform:capitalize;color:var(--muted);
  }
  /* Пикер времени: два колеса «часы : минуты» с общей синей плашкой.
     Ширину колёс приравниваем к плашке (110px) и центрируем — иначе колёса уже
     плашки (паддинг карточки), и цифры стягиваются к двоеточию, не попадая в
     центр своих половин. Теперь центр «часов» = середина [левый край плашки … :],
     центр «минут» = середина [: … правый край плашки]. */
  .time2{position:relative;flex:1 1 auto;min-height:0;display:flex;align-items:stretch;width:110px;align-self:center}
  .time2__band{
    position:absolute;left:50%;top:50%;
    width:110px;height:48px;transform:translate(-50%, -50%);
    /* 16·u — как .date-wheel__band и .picker__btn; было 18px фикс */
    background:var(--ink);border-radius: calc(16 * var(--u));z-index:0;
  }
  .time2 .date-wheel__scroll{flex:1 1 0;z-index:1}
  .time2__colon{
    position:relative;z-index:2;
    display:flex;align-items:center;justify-content:center;
    width: calc(8 * var(--u));
    color:#fff;font-weight:700;font-size: calc(15 * var(--u));
  }
  .date-day.is-center{color:#fff}
  .date-day.is-center .date-day__num,
  .date-day.is-center .date-day__mon,
  .date-day.is-center .date-day__dow{color:#fff}

  /* ─── Modal popup для бронирования — bottom sheet ──────────────── */
  .modal{
    position:fixed;inset:0;z-index:1000;
    background:rgb(6 43 71 / .55);backdrop-filter: blur(4px);
    display:flex;align-items:flex-end;justify-content:center;
    padding: 0;
    opacity:0;pointer-events:none;
    transition: opacity .2s ease;
  }
  .modal[data-open="true"]{opacity:1;pointer-events:auto}
  .modal__card{
    background:var(--card);
    border-radius: calc(24 * var(--u)) calc(24 * var(--u)) 0 0;
    width:100%;max-width:100%;
    padding: calc(30 * var(--u)) calc(14 * var(--u)) calc(calc(28 * var(--u)) + env(safe-area-inset-bottom, 0px));
    display:flex;flex-direction:column;gap: calc(12 * var(--u));
    max-height: 90vh;
    max-height: 90dvh;
    max-height: calc(100% - env(safe-area-inset-top, 0px) - calc(20 * var(--u)));
    overflow-y:auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    transform: translateY(100%);
    transition: transform .3s cubic-bezier(.22,.61,.36,1);
    position:relative;
    touch-action: pan-y;
  }
  .modal[data-open="true"] .modal__card{transform:translateY(0)}
  .modal__card.is-dragging{transition:none}
  .modal__grabber{
    position:absolute;top: calc(8 * var(--u));left:50%;
    transform: translateX(-50%);
    width: calc(36 * var(--u));height: calc(4 * var(--u));
    background:#c8cdd6;border-radius: calc(4 * var(--u));
    cursor:grab;flex-shrink:0;
    touch-action: none;
    z-index:2;
  }
  .modal__grabber:active{cursor:grabbing}
  .modal__head{
    display:flex;align-items:center;justify-content:space-between;
    gap: calc(8 * var(--u));
    margin-top: calc(14 * var(--u));
  }
  .modal__title{
    margin:0;font-size: calc(13 * var(--u));font-weight:700;color:var(--ink);
  }
  .modal__title--with-icon{display:inline-flex;align-items:center;gap: calc(6 * var(--u))}
  .modal__title-icon{
    width: calc(16 * var(--u));height: calc(16 * var(--u));
    color: var(--warn);
    flex-shrink:0;
  }
  .modal__close{
    position:absolute;top: calc(14 * var(--u));right: calc(14 * var(--u));
    appearance:none;border:0;background:var(--card-2);
    width: calc(28 * var(--u));height: calc(28 * var(--u));
    border-radius:50%;cursor:pointer;
    display:flex;align-items:center;justify-content:center;
    color:var(--muted-2);
    z-index:3;
    padding:0;
  }
  .modal__close svg{width: calc(14 * var(--u));height: calc(14 * var(--u));display:block}
  .modal__close:hover{background:#e6e9f0;color:var(--ink-2)}
  .modal__summary{
    background:var(--card-2);border-radius: calc(12 * var(--u));
    padding: calc(8 * var(--u)) calc(10 * var(--u));
    display:flex;justify-content:space-around;
    color:var(--ink-2);
    gap: calc(4 * var(--u));
  }
  .modal__summary span{display:flex;flex-direction:column;align-items:center;gap:calc(1 * var(--u))}
  .modal__summary span[hidden]{display:none}
  .modal__summary span small{font-size: calc(9 * var(--u));font-weight:500;color:var(--muted)}
  .modal__summary span b{font-size: calc(12 * var(--u));font-weight:700;font-feature-settings:"tnum" 1}
  .modal__summary span b[data-summary="deposit"]{letter-spacing: calc(-0.4 * var(--u))}

  /* Плашка-уведомление о депозите — мятно-зелёные оттенки */
  .modal__deposit-notice{
    display:flex;align-items:flex-start;gap: calc(10 * var(--u));
    background:#DCFFE7;
    border-radius: calc(12 * var(--u));
    padding: calc(10 * var(--u)) calc(12 * var(--u));
  }
  .modal__deposit-notice[hidden]{display:none}
  .modal__deposit-icon{
    flex-shrink:0;
    width: calc(28 * var(--u));height: calc(28 * var(--u));
    border-radius:50%;
    background:#ACFCC5;color:var(--ink-2);
    font-family:inherit;font-weight:700;font-size: calc(14 * var(--u));
    display:grid;place-items:center;
    margin-top: calc(1 * var(--u));
  }
  .modal__deposit-text{flex:1;min-width:0}
  .modal__deposit-text strong{
    display:block;
    font-size: calc(11 * var(--u));font-weight:700;color:var(--ink);
    margin-bottom: calc(2 * var(--u));
  }
  .modal__deposit-text p{
    margin:0;font-size: calc(10 * var(--u));font-weight:500;color:var(--muted-2);line-height:1.35;
  }
  .modal__field{display:flex;flex-direction:column;gap: calc(4 * var(--u))}
  .modal__label{font-size: calc(11 * var(--u));font-weight:700;color:var(--ink);letter-spacing:.01em}
  .modal__input{
    appearance:none;border:0;
    background:var(--card-2);
    border-radius: calc(12 * var(--u));
    padding: calc(10 * var(--u)) calc(12 * var(--u));
    font-family:inherit;
    /* iOS Safari зумит страницу при фокусе если шрифт < 16px — фиксируем минимум */
    font-size: max(16px, calc(11 * var(--u)));
    font-weight:600;color:var(--ink-2);
    outline:none;
    transition: box-shadow .15s ease;
  }
  .modal__input:focus{box-shadow: 0 0 0 2px var(--ink) inset}
  .modal__input.is-invalid{box-shadow: 0 0 0 2px var(--warn) inset}
  .modal__textarea{
    min-height: calc(60 * var(--u));resize:none;
    font-family:inherit;line-height:1.4;
  }

  /* Phone row: country code + number */
  .phone-row{
    display:grid;grid-template-columns:auto 1fr;gap: calc(6 * var(--u));
  }
  .country-code{position:relative}
  .country-code__btn{
    appearance:none;border:0;cursor:pointer;
    background:var(--card-2);
    border-radius: calc(12 * var(--u));
    height: 100%;min-height: calc(38 * var(--u));
    padding: 0 calc(10 * var(--u));
    display:flex;align-items:center;gap: calc(4 * var(--u));
    font-family:inherit;font-size: calc(11 * var(--u));font-weight:700;color:var(--ink-2);
  }
  .country-code__btn::after{
    content:'';width: calc(8 * var(--u));height: calc(8 * var(--u));
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%233c4f5d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2 2l4 4 4-4'/></svg>");
    background-size:contain;background-repeat:no-repeat;background-position:center;
  }
  .country-code__menu{
    position:absolute;top:calc(100% + 4px);left:0;z-index:30;
    background:var(--card);
    border-radius: calc(12 * var(--u));
    box-shadow: 0 8px 28px rgb(0 0 0 / .18), 0 1px 3px rgb(0 0 0 / .06);
    padding: calc(4 * var(--u));
    display:none;flex-direction:column;gap:2px;
    min-width: calc(140 * var(--u));max-height: calc(220 * var(--u));overflow-y:auto;
  }
  .country-code[data-open="true"] .country-code__menu{display:flex}
  .country-code__option{
    padding: calc(8 * var(--u)) calc(10 * var(--u));
    border-radius: calc(8 * var(--u));
    cursor:pointer;font-size: calc(11 * var(--u));font-weight:500;color:var(--ink-2);
    display:flex;justify-content:space-between;gap: calc(6 * var(--u));
    white-space:nowrap;
  }
  .country-code__option:hover{background:var(--card-2)}
  .country-code__option-flag{font-size: calc(13 * var(--u))}
  .country-code__option-code{color:var(--muted);font-weight:700}

  /* Tag chips — pill-кнопки шириной по содержимому, с переносом */
  .tag-chips{
    display:flex;
    flex-wrap:wrap;
    gap: calc(5 * var(--u));
  }
  .tag-chip{
    appearance:none;border:1px solid var(--card-2);background:var(--card);
    border-radius:9999px;
    padding: calc(6 * var(--u)) calc(12 * var(--u));
    font-family:inherit;font-size: calc(10 * var(--u));font-weight:600;color:var(--muted-2);
    cursor:pointer;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
    white-space:nowrap;
  }
  .tag-chip:hover{border-color:var(--ink-2)}
  .tag-chip[aria-pressed="true"]{
    background:var(--ink-2);border-color:var(--ink-2);color:#fff;
  }

  /* Согласие на обработку персональных данных */
  .modal__consent{
    display:flex;align-items:center;justify-content:center;gap: calc(8 * var(--u));
    margin: calc(-13 * var(--u)) 0 calc(14 * var(--u));
    padding: calc(8 * var(--u)) calc(2 * var(--u));
    cursor:pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .modal__consent input{
    position:absolute;opacity:0;pointer-events:none;width:0;height:0;
  }
  .modal__consent-box{
    flex-shrink:0;
    width: calc(18 * var(--u));height: calc(18 * var(--u));
    border-radius: calc(6 * var(--u));
    background:var(--card-2);
    display:flex;align-items:center;justify-content:center;
    color:transparent;
    transition: background .15s ease, color .15s ease;
    margin-top: calc(1 * var(--u));
  }
  .modal__consent-box svg{width: calc(11 * var(--u));height: calc(11 * var(--u));display:block}
  .modal__consent input:checked + .modal__consent-box{
    background:var(--accent);color:var(--ink-2);
  }
  .modal__consent-text{
    font-size: calc(10 * var(--u));font-weight:500;color:var(--muted-2);line-height:1.45;
  }
  .modal__consent-text a{color:var(--ink);text-decoration:underline;text-underline-offset:2px}

  /* Modal CTA — отцентрирован, не растягивается на всю ширину */
  .modal__cta{
    align-self:center;
    display:flex;align-items:center;justify-content:center;
    gap: calc(6 * var(--u));
    height: calc(40 * var(--u));
    padding: 0 calc(24 * var(--u));
    min-width: calc(160 * var(--u));
    border:0;border-radius: calc(20 * var(--u));
    background:var(--accent);color:var(--ink-2);
    font-family:inherit;font-size: calc(12 * var(--u));font-weight:700;
    cursor:pointer;
    margin: calc(-10 * var(--u)) auto 0;
  }
  .modal__cta:disabled{opacity:.5;cursor:not-allowed}
  .modal__cta--link{
    text-decoration:none;
    margin: calc(12 * var(--u)) auto 0;
  }
  /* иконка в submit-кнопке (в landing.css правило живёт в секции карты) */
  .modal__cta svg{width: calc(14 * var(--u));height: calc(16 * var(--u))}

  /* Ф9-1: дефицит на чипе слота */
  .slot{position:relative}
  .slot__left{display:block;font-style:normal;font-size:9px;line-height:1.1;color:var(--warn);font-weight:800;letter-spacing:.01em}
}
@supports (width: 1cqw) {
  /* 100cqw/320, кап 1.5px = монолитный @media-cap (480/320): внутри .hb-sizebox
     cqw — от контейнера; в модалке (вне контейнера) cqw фолбэчится в svw —
     тоже под капом */
  .hb-root { --u: min(0.3125cqw, 1.5px); }
}

/* 5) новые классы модуля (единственный НЕ-донорский блок).
   .hb-skeleton живёт ВНЕ .hb-root (плейсхолдер в [data-hb-box] до mount,
   index.js удаляет его при монтировании) — поэтому размеры в px, без --u. */
/* mount-узел: во flex-родителе (booking-inner лендинга) flex-item сайзится по
   контенту, а inline-size containment sizebox'а обнуляет intrinsic-вклад —
   без явной ширины узел схлопывается в 0 (фикс BW-14). */
[data-hb-box] [data-hb-mount] { width: 100%; }
/* Своего верхнего отступа у формы больше нет. Он появился, когда пикеры лежали
   прямо на карточке и форму надо было чем-то отбить; теперь между ними стоит
   белый шейп .hb-dynamic, и отступ складывался с gap карточки в тройную щель
   (10·u + 8·u + 10·u = 39px). Единственный разделитель — gap .booking-inner--book. */
.hb-skeleton { padding: 16px; }
.hb-skeleton__title { height: 20px; width: 40%; margin: 0 auto 12px; background: #e3e6ec; border-radius: 12px; animation: hbPulse 1.2s ease-in-out infinite; }
.hb-skeleton__row { display: flex; gap: 8px; margin-bottom: 12px; }
.hb-skeleton__row span { flex: 1; height: 46px; background: #dfe3ea; border-radius: 14px; animation: hbPulse 1.2s ease-in-out infinite; }
.hb-skeleton__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.hb-skeleton__grid span { height: 34px; background: #eceef3; border-radius: 10px; animation: hbPulse 1.2s ease-in-out infinite; }
@keyframes hbPulse { 50% { opacity: .55; } }
/* Фолбэк отказа загрузки: mount удаляет скелетон целиком, поэтому сообщение
   (появляется через 8с чистым CSS) видно ТОЛЬКО если бандл не загрузился/не
   смонтировался — гость не остаётся навсегда с пульсирующими плашками. */
.hb-skeleton::after {
  content: 'Не удалось загрузить форму бронирования. Обновите страницу.';
  display: block; text-align: center; color: #6b7a88;
  font: 500 13px/1.4 system-ui, -apple-system, sans-serif;
  padding: 10px 8px 0; opacity: 0;
  animation: hbSkeletonFail .4s ease 8s forwards;
}
@keyframes hbSkeletonFail { to { opacity: 1; } }
