/* mod_tb_event_booking · frontend */
/* Ширину НЕ ограничиваем: ею управляет контейнер темы / настройки элемента
   в билдере (зашитые 900px делали блок уже контента при max-width: none) */
.tbev { width: 100%; margin: 0 auto; padding: 8px 0; font: 14px/1.4 -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }

.tbev-flash { padding: 12px 16px; border-radius: 10px; margin: 0 0 16px; }
.tbev-flash--ok      { background: #dcfce7; color: #166534; }
.tbev-flash--pending { background: #fef9c3; color: #854d0e; }
.tbev-flash--err     { background: #fee2e2; color: #991b1b; }

.tbev-header { text-align: center; margin-bottom: 24px; }
.tbev-cover { max-width: 100%; max-height: 260px; border-radius: 14px; margin: 0 auto 12px; display: block; object-fit: cover; }
.tbev-title { margin: 0 0 6px; font-size: 22px; font-weight: 700; }
.tbev-when  { color: #666; font-size: 15px; }
.tbev-desc  { margin-top: 12px; color: #333; }

.tbev-h3 { font-size: 16px; font-weight: 700; margin: 0 0 12px; }
.tbev-h4 { font-size: 14px; font-weight: 600; margin: 18px 0 10px; color: #6b7280; }

.tbev-tables__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 12px;
}
.tbev-table {
    background: #fff; border: 2px solid #e5e7eb; border-radius: 12px;
    padding: 14px 10px; text-align: center;
    cursor: pointer; transition: transform .1s, border-color .1s, box-shadow .1s;
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    color: inherit; font: inherit;
}
.tbev-table:hover:not(:disabled) { border-color: #3b82f6; transform: translateY(-2px); box-shadow: 0 6px 20px rgba(59,130,246,.12); }
.tbev-table.is-active { border-color: #16a34a; background: #f0fdf4; box-shadow: 0 6px 20px rgba(22,163,74,.15); }
.tbev-table--taken { opacity: .5; cursor: not-allowed; filter: grayscale(.4); }

.tbev-table__num   { font-size: 18px; font-weight: 700; }
.tbev-table__seats { font-size: 12px; color: #6b7280; }
.tbev-table__price { font-size: 15px; color: #2563eb; font-weight: 700; margin-top: 4px; }
.tbev-table__label { font-size: 11px; color: #9ca3af; }
/* Зона стола в карточке списка — мелкий текст, как __label */
.tbev-table__zone  { font-size: 11px; color: #9ca3af; }
.tbev-table__taken { margin-top: 6px; font-size: 11px; padding: 2px 8px; background: #f3f4f6; border-radius: 999px; }

/* ===== Фильтр по зонам (v1.6.0): чипы над картой/списком ===== */
.tbev-zones { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.tbev-zones__btn {
    padding: 6px 14px; border-radius: 999px;
    border: 1px solid #d1d5db; background: #fff; color: #374151;
    font: inherit; font-size: 13px; font-weight: 600; line-height: 1.2;
    cursor: pointer; transition: border-color .1s, background .1s, color .1s;
}
.tbev-zones__btn:hover { border-color: #3b82f6; }
.tbev-zones__btn.is-active { background: #16a34a; border-color: #16a34a; color: #fff; }

/* ===== Карта зала =====
   Селекторы вида .tbev-table.tbev-table--map — намеренно: перебивают
   базовые стили .tbev-table независимо от порядка в файле. */

/* Обёртка карты (v1.6.0). На десктопе НАМЕРЕННО без overflow: карта 100%
   ширины, скроллить нечего, а overflow-x:auto здесь принудительно включил бы
   и overflow-y — стулья, выступающие за края карты, начали бы обрезаться и
   плодить внутренний скроллбар (сейчас overflow:visible). Скролл включается
   только в мобильном @media ниже, где карта фиксированной ширины. */
.tbev-map-scroll { }

.tbev-map {
    position: relative;
    width: 100%;
    margin: 0 0 16px;
    border-radius: 12px;
    /* НЕ hidden: стулья у краёв карты выходят за бокс стола и не должны обрезаться.
       Скругление картинки — на .tbev-map__bg. */
    overflow: visible;
    border: 1px solid #e5e7eb;
}
.tbev-map__bg { display: block; width: 100%; height: auto; border-radius: 11px; }

/* Кнопка стола поверх фото: полупрозрачный тёмный чип, читаемый на любом фоне */
.tbev-table.tbev-table--map {
    position: absolute;
    box-sizing: border-box;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0; padding: 2px; margin: 0;
    min-width: 0; min-height: 0;
    background: transparent;
    color: #fff;
    border: none;
    border-radius: 8px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
    line-height: 1.2;
    /* Стулья рисуются СНАРУЖИ контура стола (координаты за 0–100%) */
    overflow: visible;
    /* Поворот через переменную (--rot ставит inline-style из tmpl):
       одно и то же значение во ВСЕХ состояниях, включая :hover/.is-active */
    transform: rotate(var(--rot, 0deg));
    /* Всегда выше слоя декора (.tbev-decor, z-index:0). transform уже создаёт
       stacking context, поэтому явный z-index ничего внутри кнопки не меняет;
       :hover/.is-active по-прежнему перебивает своим z-index:2. */
    z-index: 1;
}
/* Визуал стола на ::before: стулья с z-index:-1 прячутся под него,
   наружу торчат только спинки (transform кнопки создаёт stacking context) */
.tbev-table.tbev-table--map::before {
    content: "";
    position: absolute; inset: 0;
    z-index: 0;
    /* Кастомный цвет стола (контракт v2.3): --tbev-table-color ставит tmpl
       инлайном ТОЛЬКО из нормализатора (строгий hex); без переменной —
       прежний дефолт. Занятый стол: .tbev-table--taken::before ниже
       специфичнее (3 класса против 2) — серый побеждает кастомный цвет. */
    /* дефолт выровнен с конструктором (синий) — раньше тёмно-серый
       rgba(17,17,17,.72) выглядел «не подтянувшимся» цветом */
    background: var(--tbev-table-color, rgba(30, 64, 175, .82));
    border: 2px solid rgba(255, 255, 255, .35);
    border-radius: inherit;
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}
/* контент кнопки — над визуальным слоем */
.tbev-table--map .tbev-table__inner { position: relative; z-index: 1; }

/* Увеличенная зона касания на мелких столах (тап-таргет) */
.tbev-table--map::after {
    content: "";
    position: absolute;
    inset: -6px;
}
.tbev-table.tbev-table--map:hover:not(:disabled),
.tbev-table.tbev-table--map.is-active {
    /* не «подпрыгиваем» (translateY сломает позицию на карте),
       но поворот стола сохраняем — иначе hover сбрасывал бы rotate() */
    transform: rotate(var(--rot, 0deg));
    z-index: 2;
}
.tbev-table.tbev-table--map:hover:not(:disabled)::before,
.tbev-table.tbev-table--map.is-active::before {
    border-color: #16a34a;
    /* при кастомном цвете (v2.3) hover/выбор НЕ затемняет фон — иначе
       YIQ-чёрный текст на светлом столе стал бы нечитаем; без переменной —
       прежнее затемнение .82 (легаси 1:1) */
    background: var(--tbev-table-color, rgba(30, 64, 175, .92));
    box-shadow: 0 0 0 3px rgba(22, 163, 74, .4);
}

/* КРИТИЧНО (анти-овал): у square/circle высота — ТОЛЬКО через aspect-ratio.
   height:h% считается от другой стороны контейнера и даёт овал/прямоугольник,
   поэтому inline height для них не выводится, а на всякий случай гасится. */
.tbev-table.tbev-table--map.tbev-table--square,
.tbev-table.tbev-table--map.tbev-table--circle {
    aspect-ratio: 1 / 1;
    height: auto !important;
}
.tbev-table.tbev-table--map.tbev-table--circle { border-radius: 50%; }

/* Внутренний блок контр-вращается: № и цена остаются горизонтальными */
.tbev-table--map .tbev-table__inner {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 0; line-height: 1.2; min-width: 0;
    transform: rotate(calc(var(--rot, 0deg) * -1));
    pointer-events: none;
}

/* Стул: вид сверху «со спинкой» — скруглённое сиденье + дужка ::before сверху.
   Вращается ВМЕСТЕ со столом (не контр-вращается); каждый стул дополнительно
   повёрнут инлайн-transform'ом так, чтобы спинка смотрела наружу от стола.
   Размер фиксирован относительно КАРТЫ (cqw), НЕ масштабируется со столом. */
.tbev-map { container-type: inline-size; }
.tbev-chair {
    position: absolute;
    /* под визуальным слоем стола (::before): видна только выступающая часть */
    z-index: -1;
    width: 14px;                 /* фолбэк для браузеров без cqw */
    width: max(10px, 2.2cqw);
    aspect-ratio: 1 / 1;
    /* сиденье */
    border-radius: 38%;
    /* transform (translate+rotate) ставится инлайном из JS */
    background: rgba(255, 255, 255, .7);
    border: 1px solid rgba(17, 17, 17, .55);
    box-sizing: border-box;
    pointer-events: none;
}
/* спинка: дужка над сиденьем */
.tbev-chair::before {
    content: '';
    position: absolute;
    left: 4%; right: 4%; top: -26%;
    height: 30%;
    background: rgba(255, 255, 255, .88);
    border: 1px solid rgba(17, 17, 17, .55);
    border-radius: 999px;
    box-sizing: border-box;
}
/* Размер стула из карты (контракт v2.3): --tbev-chair-size (в cqw) ставит tmpl
   на .tbev-map; без переменной — прежний дефолт 2.2cqw. Внутри @supports
   НАМЕРЕННО: декларация с var() «валидна» на парсинге и перебила бы px-фолбэк
   выше, а в браузере без cqw вычислилась бы в invalid → width:auto. */
@supports (width: 1cqw) {
    .tbev-chair { width: max(10px, var(--tbev-chair-size, 2.2cqw)); }
}

/* ===== Декор карты (контракт v2.2): слой ПОД столами =====
   Рендерится из tmpl ДО кнопок столов; кнопки (.tbev-table--map) имеют
   z-index:1, декор — 0, поэтому столы всегда кликабельны поверх декора. */
.tbev-decor {
    position: absolute;
    box-sizing: border-box;
    pointer-events: none;
    z-index: 0;
}
/* Прямоугольник (сцена, бар, гардероб…): left/top/width/height/background —
   inline из tmpl; поворот — той же переменной --rot, что и у столов. */
.tbev-decor--rect {
    transform: rotate(var(--rot, 0deg));
    border-radius: 6px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .15);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
/* Подпись ВНУТРИ прямоугольника: вращается вместе с ним, цвет (белый/чёрный
   по яркости фона) ставит tmpl инлайном. Размер — от ширины карты (cqw,
   контейнер .tbev-map уже container-type: inline-size). */
.tbev-decor__label {
    font-size: 12px;                       /* фолбэк для браузеров без cqw */
    font-size: clamp(9px, 1.8cqw, 16px);
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    padding: 0 4px;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Надпись: left/top — ЦЕНТР (контракт), поэтому translate(-50%,-50%);
   color и font-size:<size>cqw — inline из tmpl. */
.tbev-decor--text {
    transform: translate(-50%, -50%) rotate(var(--rot, 0deg));
    white-space: nowrap;
    font-weight: 600;
    line-height: 1;
    /* фолбэк: без поддержки cqw inline-декларация невалидна и игнорируется */
    font-size: 16px;
    /* читаемость на любом фоне плана */
    text-shadow: 0 1px 3px rgba(0, 0, 0, .6), 0 0 2px rgba(0, 0, 0, .4);
}

.tbev-table--map .tbev-table__num {
    font-size: 13px; font-weight: 700; white-space: nowrap;
}
.tbev-table--map .tbev-table__price {
    /* inherit вместо #fff: кнопка и так белая по умолчанию (легаси 1:1),
       но при кастомном цвете стола (v2.3) inline YIQ-цвет текста кнопки
       должен доходить и до цены. */
    font-size: 11px; font-weight: 600; color: inherit; opacity: .9;
    margin-top: 0; white-space: nowrap;
}
.tbev-table--map .tbev-table__state {
    font-size: 10px; white-space: nowrap; opacity: .85;
}

/* Занятый стол на карте: серый чип, текст «Занят» */
.tbev-table.tbev-table--map.tbev-table--taken {
    opacity: 1;
    filter: none;
    color: #e5e7eb;
    cursor: not-allowed;
}
.tbev-table.tbev-table--map.tbev-table--taken::before {
    /* занятый стол — бледно-красный (просьба заказчика; был серый) */
    background: rgba(220, 38, 38, .45);
    border-color: rgba(255, 255, 255, .25);
}

/* Фильтр по зонам: стол ЧУЖОЙ зоны на карте приглушается (класс ставит
   booking.js). НАМЕРЕННО ПОСЛЕ правил --taken: у занятого стола opacity:1,
   а --zonedim той же специфичности должен побеждать порядком в файле —
   класс просто ложится поверх, занятые отдельно не обрабатываются. */
.tbev-table.tbev-table--map.tbev-table--zonedim {
    opacity: .25;
    pointer-events: none;
}

.tbev-empty { padding: 20px; text-align: center; color: #6b7280; background: #f9fafb; border-radius: 10px; }

.tbev-form {
    margin-top: 24px; padding: 20px; background: #fff; border-radius: 12px; border: 1px solid #e5e7eb;
    box-shadow: 0 4px 16px rgba(0,0,0,.05);
}
.tbev-form__summary {
    display: flex; justify-content: space-between; align-items: baseline;
    padding: 10px 12px; background: #f3f4f6; border-radius: 8px; margin-bottom: 14px;
    font-size: 15px;
}
.tbev-form__amount { font-weight: 700; color: #2563eb; font-size: 18px; }

.tbev-field { display: block; margin-bottom: 12px; }
.tbev-field span { display: block; margin-bottom: 4px; color: #444; font-size: 13px; font-weight: 500; }
.tbev-field input[type="text"], .tbev-field input[type="tel"], .tbev-field input[type="email"] {
    width: 100%; padding: 10px 12px; border: 1px solid #d1d5db; border-radius: 8px; font-size: 15px; box-sizing: border-box;
}
.tbev-field input:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,.15); }
.tbev-field--check { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: #555; }
.tbev-field--check input { margin-top: 3px; }

.tbev-form__actions { display: flex; gap: 8px; margin-top: 16px; }
.tbev-btn { flex: 1; padding: 12px 16px; border-radius: 8px; border: none; font-size: 15px; font-weight: 600; cursor: pointer; }
.tbev-btn--pay { background: #16a34a; color: #fff; }
.tbev-btn--pay:hover { background: #15803d; }
.tbev-btn--pay:disabled { background: #9ca3af; cursor: not-allowed; }
.tbev-btn--cancel { background: #f3f4f6; color: #374151; }
.tbev-btn--cancel:hover { background: #e5e7eb; }

.tbev-form__status { margin-top: 12px; padding: 10px 12px; border-radius: 8px; font-size: 13px; }
.tbev-form__status.is-error { background: #fee2e2; color: #991b1b; }
.tbev-form__status.is-info  { background: #eff6ff; color: #1e40af; }
/* предупреждение про окно оплаты — под кнопками формы */
.tbev-form__hold-note { margin-top: 10px; font-size: 12.5px; color: #6b7280; }

@media (max-width: 640px) {
    /* Список столов на телефоне — СТРОКИ во всю ширину, не плитки:
       № · мест · зона слева, цена прижата вправо (кроме кнопок карты!) */
    .tbev-tables__grid { display: flex; flex-direction: column; gap: 8px; }
    .tbev-tables__grid .tbev-table {
        flex-direction: row; align-items: center; gap: 10px;
        padding: 10px 14px; text-align: left;
    }
    .tbev-tables__grid .tbev-table__num { font-size: 16px; }
    .tbev-tables__grid .tbev-table__price {
        font-size: 15px; margin: 0 0 0 auto; /* цена — к правому краю */
    }
    .tbev-tables__grid .tbev-table__label,
    .tbev-tables__grid .tbev-table__zone { font-size: 12px; }

    /* Карта на мобильных НЕ ужимается (v1.6.0, требование Бориса): держит
       «десктопную» ширину 1000px и скроллится по горизонтали в обёртке
       .tbev-map-scroll. Прежние мобильные упрощения (мелкие шрифты чипов,
       тонкие рамки) убраны — чипы теперь десктопного размера. Стулья (cqw)
       и повороты считаются от ширины .tbev-map — она фиксированная, всё ОК;
       --fixed-h (inline aspect-ratio) и --nobg тоже работают от этой ширины. */
    /* padding + компенсация margin'ом: стулья/тап-таргеты, выступающие за
       верх/лево карты, не режутся скролл-контейнером (scrollable overflow
       не растёт влево/вверх) — тот же приём, что у канваса конструктора */
    .tbev-map-scroll {
        overflow-x: auto; -webkit-overflow-scrolling: touch;
        padding: 16px 16px 8px;
        margin: -16px -16px -8px;
    }
    .tbev-map { width: 1000px; min-width: 1000px; }
    /* расширенный тап-таргет чипов — оставляем: на телефоне жмут пальцем */
    .tbev-table--map::after { inset: -8px; }
}

/* Режим «без фона» (show_map_bg=0): картинка невидима, но остаётся в потоке —
   держит высоту карты, координаты столов в % не съезжают. Рамку тоже убираем:
   столы висят на чистом фоне страницы. */
.tbev-map--nobg { border: none; background: transparent; }
.tbev-map--nobg .tbev-map__bg { visibility: hidden; }

/* v2.4: фиксированная высота карты (canvas_h) — aspect-ratio:100/<h> ставится
   inline из tmpl; фон absolute ВО ВСЮ ШИРИНУ сверху: contain — дефолт для
   карты ВЫШЕ картинки (снизу рабочее поле), а при карте НИЖЕ картинки JS
   (tbevFixedHFit в booking.js) переключает object-fit на cover — низ картинки
   срезается, план не сжимается. Зеркало редакторского .tbev-hall--fixed-h. */
.tbev-map--fixed-h .tbev-map__bg {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: contain; object-position: top;
}

/* v2.4: numbers_show=false — номера столов на карте скрыты (цена и 👤N остаются);
   плиточный фолбэк не затрагивается: там номер обязателен для выбора стола */
.tbev-map--nonum .tbev-table--map .tbev-table__num { display: none; }

/* Значок вместимости на столе (когда стулья скрыты: chairs_show=false) */
.tbev-table--map .tbev-table__pers {
    font-size: 10px; font-weight: 600; white-space: nowrap; opacity: .95;
}
