/* ═══════════════════════════════════════════════════════════════
   SHELL.CSS — the v1 client's shared sheet: tokens, layout and the
   components every screen imports. Ported from
   docs/ПРОТОТИП-V1/assets/proto.css (gate 33/33, blockers 82/82,
   contrast fixes applied — see docs/2026-09-24---ДИЗАЙН--прототип-v2--
   отчёт.md), with two changes only:
     1. Fonts point at the product's own hosted files (/fonts/*.woff2,
        already served for style.css) instead of a local copy — RULE 1b,
        zero duplication — and carry the same unicode-range/font-display
        tuning style.css already uses in production (FONT-CYRILLIC,
        25.09.2026: `swap`, not `optional` — style.css's own comment on
        its @font-face block has the measured reason; keep both in sync).
     2. The prototype's own tooling bar (`.proto`, the owner's iframe
        catalogue `.owner-grid`/`.frame-wrap`, `.variantb`) is dropped —
        it steered decisions during design and is not part of the product.
   "Report a problem" (RULE table item 9) is NOT styled here — it is
   src/client/v1/assets/report.{js,css} (B1-REPORT), a standalone module
   with its own `v1report-*` class names that never meet this file's
   `.sheet-back > .sheet` card in the cascade; shell.js's boot() links
   report.css and imports report.js on every screen.
   Everything else — including the Russian design-rationale comments —
   is carried over unedited: this is reviewed CSS, not a first draft.
   Zero external requests (RULE 1b): no Google Fonts, no CDN.
   ═══════════════════════════════════════════════════════════════ */

@font-face{
  font-family:'Lato'; font-style:normal; font-weight:400; font-display:swap;
  src:url('/fonts/lato-400.woff2') format('woff2');
  unicode-range:U+0020-007E,U+00A0-00FF,U+2010-2027,U+2030,U+2039-203A,U+2044,U+20AC,U+2116,U+2122,U+2212,U+FEFF,U+0400-045F,U+0490-0491;
}
@font-face{
  font-family:'Lato'; font-style:italic; font-weight:400; font-display:swap;
  src:url('/fonts/lato-400-italic.woff2') format('woff2');
  unicode-range:U+0020-007E,U+00A0-00FF,U+2010-2027,U+2030,U+2039-203A,U+2044,U+20AC,U+2116,U+2122,U+2212,U+FEFF,U+0400-045F,U+0490-0491;
}
@font-face{
  font-family:'Lato'; font-style:normal; font-weight:600; font-display:swap;
  src:url('/fonts/lato-600.woff2') format('woff2');
  unicode-range:U+0020-007E,U+00A0-00FF,U+2010-2027,U+2030,U+2039-203A,U+2044,U+20AC,U+2116,U+2122,U+2212,U+FEFF,U+0400-045F,U+0490-0491;
}
@font-face{
  font-family:'Lato'; font-style:normal; font-weight:700; font-display:swap;
  src:url('/fonts/lato-700.woff2') format('woff2');
  unicode-range:U+0020-007E,U+00A0-00FF,U+2010-2027,U+2030,U+2039-203A,U+2044,U+20AC,U+2116,U+2122,U+2212,U+FEFF,U+0400-045F,U+0490-0491;
}
@font-face{
  font-family:'Bitter'; font-style:normal; font-weight:600; font-display:swap;
  src:url('/fonts/bitter-600.woff2') format('woff2');
  unicode-range:U+0020-007E,U+00A0-00FF,U+2010-2027,U+2030,U+2039-203A,U+2044,U+20AC,U+2116,U+2122,U+2212,U+FEFF,U+0400-045F,U+0490-0491;
}
@font-face{
  font-family:'Bitter'; font-style:normal; font-weight:700; font-display:swap;
  src:url('/fonts/bitter-700.woff2') format('woff2');
  unicode-range:U+0020-007E,U+00A0-00FF,U+2010-2027,U+2030,U+2039-203A,U+2044,U+20AC,U+2116,U+2122,U+2212,U+FEFF,U+0400-045F,U+0490-0491;
}
@font-face{
  font-family:'Cinzel'; font-style:normal; font-weight:700; font-display:swap;
  src:url('/fonts/cinzel-700.woff2') format('woff2');
  unicode-range:U+0020-007E,U+00A0-00FF;
}

:root{
  --doc-top:40px;
  --gap-actions:16px;
  --wood:#1A1310;  --wood-2:#221913; --wood-3:#2C211A; --wood-4:#3A2C22;
  --felt:#17211C;  --edge:#3E2F24;   --edge-2:#2A1F18;
  --panel:linear-gradient(180deg,#241A14,var(--wood));
  --bone:#EFE7D8;  --bone-2:#B3A692; --bone-3:#A2957F; --bone-4:#9C8F79;
  --brass:#C9A227; --brass-2:#A08320; --brass-dim:#332912;
  --blood:#B4262C; --blood-text:#D66E72; --blood-lit:#E0787C;
  --blood-2:#7E1A1F; --blood-dim:#2E1213;
  --known:#EFE7D8; --known-2:#8A6F1B;
  --alive:#5E9A62;
  --card:5px;
  --lift:0 1px 2px rgba(0,0,0,.5), 0 10px 24px -14px rgba(0,0,0,.95);
  --rule:linear-gradient(90deg,transparent,var(--brass-2) 12%,var(--brass) 50%,var(--brass-2) 88%,transparent);
  --w-page:1120px; --w-read:760px; --w-card:460px;
  --tap:44px;              /* D4 п.8 — пол тач-цели */
}

*{box-sizing:border-box}
html{height:auto;min-height:100%;-webkit-text-size-adjust:100%}
body{margin:0;height:auto;background:var(--wood);color:var(--bone);
  font:16px/1.55 Lato,system-ui,sans-serif;
  background-image:radial-gradient(120% 70% at 50% -10%, #2A1F17 0%, var(--wood) 60%);
  background-repeat:no-repeat}
body.doc{min-height:100dvh;display:flex;flex-direction:column}
body.doc > main{flex:1 0 auto}
/* ⛔ Стол — единственный экран-инструмент: полная высота, футера нет (locked 4). */
body.app{height:100dvh;overflow:hidden;display:flex;flex-direction:column}
body.app > .screen{flex:1 1 auto;min-height:0;overflow:auto}

h1,h2,h3{font-family:Bitter,Georgia,serif;font-weight:700;margin:0 0 8px;line-height:1.25}
h1{font-size:26px} h2{font-size:20px} h3{font-size:17px}
p{margin:0 0 8px}
a{color:var(--bone);text-underline-offset:3px}
small,.quiet{color:var(--bone-3);font-size:14px}
hr.rule{border:0;height:1px;background:var(--rule);margin:24px 0}

/* фокус виден везде и одинаково — 7,6:1 к фону (D4 п.25) */
:focus-visible{outline:3px solid var(--brass);outline-offset:2px;border-radius:3px}
/* ⛔ D4 п.12 / WCAG 2.4.11: навигация липкая и высотой 56 px. Без этой строки
   фокус, приехавший по Tab или по якорю, встаёт ПОД неё и его не видно. */
:target,:focus-visible{scroll-margin-top:72px}
html{scroll-behavior:auto}

.skip{position:absolute;left:-9999px;top:0;background:var(--wood-3);color:var(--bone);
  display:inline-flex;align-items:center;min-height:var(--tap);padding:8px 16px;z-index:60}
.skip:focus{left:8px;top:8px}

/* ── навигация: 5 пунктов + состояние аккаунта (D5 §1.3) ────────── */
.site-nav{position:sticky;top:0;z-index:30;background:#1B1410;border-bottom:1px solid var(--edge-2)}
.site-nav-in{max-width:var(--w-page);margin:0 auto;padding:0 16px;min-height:56px;
  display:flex;align-items:center;gap:10px;flex-wrap:nowrap}
.nav-mark{font-family:Cinzel,Georgia,serif;font-size:19px;letter-spacing:.14em;color:var(--brass);
  text-decoration:none;display:flex;align-items:center;min-height:var(--tap);padding:0 2px}
/* ⚠️ ОДНА СТРОКА, 56 px, НА ЛЮБОЙ ШИРИНЕ. При переносе бар на 390 занимал
   190 px и утаскивал полосу рейсов под сгиб — ровно то, что D5 §2.4 запрещает.
   Лишнее уезжает горизонтальной прокруткой, как в мобильных барах лидеров. */
.nav-links{display:flex;gap:2px;flex-wrap:nowrap;flex:1 1 auto;min-width:0;
  overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}
.nav-links::-webkit-scrollbar{display:none}
.nav-links a{white-space:nowrap}
.nav-links a{color:var(--bone-2);text-decoration:none;font-size:15px;
  display:flex;align-items:center;min-height:var(--tap);padding:0 8px;border-radius:3px;flex:0 0 auto}
.nav-links a:hover{background:var(--wood-4);color:var(--bone)}
.nav-links a[aria-current=page]{color:var(--bone);box-shadow:inset 0 -2px 0 var(--brass)}
/* ⚠️ BAT-FIX-2 #42 — account.js's own nav-me falls back to the raw EMAIL
   when no display name is set (its own comment, account.js), never
   truncated there — a real long address (nothing stops one at signup) blew
   the same 390px budget nav-links already guards above. flex:0 1 auto (not
   0 0) lets it actually shrink under pressure, same as nav-links itself
   (flex:1 1 auto) — the two now share the squeeze the way the row already
   relies on nav-links alone to absorb (its own "ОДНА СТРОКА, 56 px" comment
   above) rather than a hardcoded pixel budget that a translation's own
   nav.play/nav.more width (en vs ru vs uk) would throw off. min-width:0
   lets it shrink below content size at all (flex's own min-width:auto
   default otherwise refuses to); max-width is a ceiling for the ordinary
   case, not the mechanism. The ellipsis lands on the `b` (the name/email
   itself), never the 👤 emoji beside it. */
.nav-me{display:flex;align-items:center;min-height:var(--tap);gap:8px;color:var(--bone-3);
  font-size:14px;text-decoration:none;padding:0 6px;border-radius:3px;flex:0 1 auto;white-space:nowrap;
  min-width:0;max-width:42vw}
.nav-me b{color:var(--bone);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;display:inline-block;vertical-align:bottom;max-width:100%}
/* ⛔ E1-04 (замер E1: «Цены» кончались на 443 px при ширине 390, «Войти» 322–374
   наезжал на «Клубы» 325–387). Горизонтальная прокрутка НЕ решение: пункт за
   краем недостижим, потому что его не видно. На узком экране пять пунктов
   сворачиваются в одну кнопку «Ещё» — шторка со списком в 44 px строками. */
.nav-more{display:none;align-items:center;min-height:var(--tap);gap:8px;background:none;
  border:1px solid var(--edge);color:var(--bone-2);font:600 15px/1 Lato,sans-serif;
  padding:0 12px;border-radius:3px;flex:0 0 auto;white-space:nowrap;cursor:pointer}
.nav-more:hover{background:var(--wood-4);color:var(--bone)}
@media(max-width:700px){
  .nav-links{display:none}
  .nav-more{display:inline-flex}
  .site-nav-in{gap:8px;padding:0 8px}
  /* ⚠️ min-width, not height alone (WebKit sub-pixel, reported by 3 tasks):
     "Play"/"Грати" is short enough that its box width is padding+text, not a
     floor — Safari's CoreText shapes that text about 1 real px narrower than
     Chromium's Skia does (measured: 43.515625px vs 44.515625px at the same
     15px/Lato, same 0 8px padding — getBoundingClientRect, not the rounded
     devtools number), so a rounded audit (Math.round → 44) passed while the
     raw box was genuinely short of the D4 п.8 44px floor. Same min-width +
     justify-content:center pairing .seat-btn/.site-foot a already use for
     exactly this reason. */
  /* V1-REDS-1/item5: the --tap (44px) floor above still left this short of
     44 on WebKit some of the time — CoreText shapes "Play"/"Грати" about a
     real px narrower than Chromium's Skia at the same font/padding (see
     the comment above this rule), so a min-width sized exactly to the
     floor could still measure under it depending on which text won.
     48px is a plain, non-sub-pixel margin above the floor — a fixed
     number, not var(--tap), since this is the one control the manifest
     gate actually observed the boundary bite on; everything else still
     reads the --tap token. */
  .nav-play{display:inline-flex;align-items:center;justify-content:center;
    min-height:48px;min-width:48px;padding:0 8px;
    border-radius:3px;color:var(--bone);text-decoration:none;font-size:15px;flex:0 0 auto;white-space:nowrap}
  .nav-spacer{flex:1 1 auto}
}
@media(min-width:701px){.nav-play{display:none}.nav-spacer{display:none}}
/* список ссылок в шторке «Ещё» — каждая строка 44 px (манифест b) */
.nav-sheet-list{display:flex;flex-direction:column;gap:2px}
.nav-sheet-list a{display:flex;align-items:center;min-height:48px;padding:0 12px;border-radius:var(--card);
  color:var(--bone);text-decoration:none;font-size:16px;border:1px solid var(--edge)}
.nav-sheet-list a:hover{background:var(--wood-4)}

/* ── подвал в потоке (владельца решение 16.09) ────────────────────── */
.site-foot{flex:0 0 auto;border-top:1px solid var(--edge-2);margin-top:32px;
  padding:16px 16px 24px;display:flex;gap:6px 18px;flex-wrap:wrap;align-items:center;
  max-width:var(--w-page);width:100%;margin-left:auto;margin-right:auto}
.site-foot a{color:var(--bone-3);font-size:14px;text-decoration:none;
  display:inline-flex;align-items:center;justify-content:center;
  min-height:var(--tap);min-width:44px;padding:0 6px}
.site-foot a:hover{color:var(--bone)}
.site-foot .foot-c{opacity:.72}
.foot-c{color:var(--bone-4);font-size:13px;margin-left:auto}
.foot-lang{display:flex;gap:2px;align-items:center}

main{width:100%;max-width:var(--w-page);margin:0 auto;padding:var(--doc-top) 16px 0}
main.read{max-width:var(--w-read)}
main.card{max-width:var(--w-card)}
/* N9: документ, у которого нет второй колонки, не растягивается на 1120 px —
   подпись слева и значение справа на весь экран не читаются. Только на широких:
   на 768 читальная колонка 680 px остаётся за locked 27. */
@media(min-width:1100px){main.narrow{max-width:820px}}

/* ── кнопки. Пол 44 px, зазор 8 (D4 п.8) ─────────────────────────── */
.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:var(--tap);padding:8px 16px;border-radius:var(--card);border:1px solid var(--edge);
  background:var(--wood-3);color:var(--bone);font:600 16px/1.2 Lato,sans-serif;
  text-decoration:none;cursor:pointer}
.btn:hover{background:var(--wood-4)}
.btn:disabled,.btn[aria-disabled=true]{opacity:.5;cursor:default}
/* ⛔ ОДНА КРАСНАЯ НА ЭКРАН (locked 15). Рамка — потому что сама заливка
   даёт к фону 2,84:1, а WCAG 1.4.11 требует 3:1 для границы компонента;
   #D66E72 даёт 5,5:1. Текст белым по красному — 6,4:1. */
.btn-red{background:var(--blood);border-color:var(--blood-text);color:#fff;font-weight:700}
.btn-red:hover{background:#C62D33}
.btn-ghost{background:transparent;border-color:var(--edge)}
.btn-wide{width:100%}
.btn-sm{min-height:var(--tap);padding:8px 16px;font-size:14px}
.btn-row{display:flex;gap:var(--gap-actions);flex-wrap:wrap}

/* ── карточка ────────────────────────────────────────────────────── */
.card{background:var(--panel);border:1px solid var(--edge);border-radius:var(--card);
  padding:16px;box-shadow:var(--lift)}
.card + .card{margin-top:16px}
.grid{display:grid;gap:12px}
.pad{padding:16px 0}

/* ── полоса рейсов (D5 §2.2). Список, не карусель — баннеров нет ─── */
.flights{display:grid;gap:8px;margin:8px 0}
/* ⚠️ СТРОКА НЕ ПЕРЕНОСИТСЯ. С `flex-wrap:wrap` кнопка уезжала под текст и
   строка рейса вырастала на 390 px до 151 px вместо заявленных в D5 §2.4
   семидесяти двух — три таких строки уносили красную кнопку под сгиб.
   Замерено, не на глаз. */
.flight{display:flex;align-items:center;gap:8px;flex-wrap:nowrap;
  background:var(--wood-2);border:1px solid var(--edge);border-radius:var(--card);
  padding:8px 10px;min-height:72px}
.flight-main{flex:1 1 auto;min-width:0}
.flight-when{font:700 16px/1.2 Bitter,Georgia,serif;color:var(--bone)}
/* ⚠️ Строка мест несёт ТРИ факта (число живых · боты добирают · старт в любом
   случае) и на 390 занимает три строки. Поэтому она 12,5 px с плотным
   интерлиньяжем, а колонка кнопки ужата до 140 px: иначе первый экран двери
   не укладывается в 640 px, которые D5 §2.4 отвёл ему на iPhone. */
.flight-seats{font-size:12.5px;line-height:1.3;color:var(--bone-2);margin-top:1px}
/* ⛔ НИКОГДА НЕ УДАЛЯТЬ: без второй половины «3 из 10» читается как дефицит,
   что прямо названо незаконным (Competition Bureau Canada 25.11.2024, FTC 2022). */
.flight-guard{color:var(--bone-3)}
.flight-cta{flex:0 0 auto;display:flex;flex-direction:column;align-items:stretch;gap:2px;max-width:152px}
.flight-eta{font-size:12px;color:var(--bone-3);text-align:center} /* серым, не акцентом (D4 п.4–5) */
.flight-cta .btn{padding:10px 10px;font-size:14px;text-align:center;line-height:1.2}

.live{font-size:14px;color:var(--bone-2);margin:8px 0}   /* голый текст, без рамки (D2 §2); V1-REDS-1/item1: bottom was 4px, off the 8px grid */
.live b{color:var(--bone);font-weight:600}

/* ── сегментный контрол (roving tabindex, см. shell.js tabs()) ───── */
.seg{display:inline-flex;gap:4px;border:1px solid var(--edge);border-radius:var(--card);
  padding:4px;background:var(--wood-2);flex-wrap:wrap}
/* Подпись и сегмент в ОДНУ строку: стопкой они стоили 26 px из 640, которые
   D5 §2.4 отвёл первому экрану двери. Подпись обязательна — именно она говорит,
   что это язык СТОЛА, а не язык интерфейса (B4). */
.seg-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.seg-row > .quiet{margin:0 !important;flex:0 0 auto}
.seg button{min-height:var(--tap);min-width:56px;padding:8px 14px;border:1px solid transparent;
  border-radius:3px;background:transparent;color:var(--bone-2);font:600 15px Lato,sans-serif;cursor:pointer}
.seg button[aria-checked=true]{background:var(--wood-4);color:var(--bone);border-color:var(--brass-2)}
.seg button[aria-checked=true]::before{content:"✓ ";color:var(--brass)}  /* не только цветом (WCAG 1.4.1) */

/* ── отсчёт мм:сс, никогда спиннер (D4 п.6) ──────────────────────── */
.countdown{font:700 44px/1 Bitter,Georgia,serif;color:var(--bone);font-variant-numeric:tabular-nums}
.countdown-label{color:var(--bone-3);font-size:14px}

/* ── места ───────────────────────────────────────────────────────── */
.seatlist{display:grid;gap:8px;margin:8px 0}
.seat{display:flex;align-items:center;gap:8px;height:56px;padding:8px;  /* высота фиксирована — строка не прыгает (locked 10) */
  background:var(--wood-2);border:1px solid var(--edge);border-radius:var(--card)}
.seat.empty{background:transparent;border-style:dashed;color:var(--bone-3)}
.seat img{width:40px;height:40px;border-radius:50%;object-fit:cover;background:var(--wood-3);
  border:1px solid var(--edge)}
.seat-no{width:22px;text-align:right;color:var(--bone-3);font-size:14px;font-variant-numeric:tabular-nums}
.seat-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.seat-tag{font-size:13px;color:var(--bone-3);display:flex;align-items:center;gap:4px}
.seat.speaking{border-color:var(--brass);box-shadow:0 0 0 1px var(--brass)}
/* «Сочный» отклик манифеста (§1i) — пульс говорящего места. Только когда
   человек не просил меньше движения (locked 10 «ничего не прыгает»: пульсирует
   свечение, а не размер/позиция). Без media-query остаётся статичная рамка. */
@media(prefers-reduced-motion:no-preference){
  .seat.speaking{animation:speakglow 1.8s ease-in-out infinite}
}
@keyframes speakglow{0%,100%{box-shadow:0 0 0 1px var(--brass)}50%{box-shadow:0 0 0 4px rgba(201,162,39,.38)}}
.seat.speaking .seat-name{font-weight:700;color:var(--bone)}
/* SPEECH-BUDGET (2026-09-24) — the seat holds the floor but no `speech_chunk`
   has arrived yet (table.js's `handleSpeechChunk`). Reuses the `.skel`
   gradient wash (§2g, below) rather than a spinner (manifest gate h: every
   loading element needs a skeleton sibling, and a spinner class is refused
   outright) — a dim, textured pulse the "speaking" brass glow above is
   earned OUT of the moment the first sentence actually lands. */
.seat.thinking{background:linear-gradient(90deg,var(--wood-2) 25%,var(--wood-3) 42%,var(--wood-2) 63%);
  background-size:400% 100%;border-color:var(--edge)}
@media(prefers-reduced-motion:no-preference){
  .seat.thinking{animation:skel 1.4s ease infinite}
}
@media(prefers-reduced-motion:reduce){.seat.thinking{animation:none;background:var(--wood-2)}}
.seat.bot-sub img{filter:grayscale(1) brightness(.8)}
.seat.asleep{opacity:.62}
.seat-btn{min-width:var(--tap);min-height:var(--tap);display:inline-flex;align-items:center;
  justify-content:center;background:transparent;border:1px solid var(--edge);border-radius:3px;
  color:var(--bone-2);font-size:17px;cursor:pointer}
.seat-btn:hover{background:var(--wood-4);color:var(--bone)}

/* кольцо таймера речи + цифры (D5 §4.2) */
.ring{position:relative;width:40px;height:40px;flex:0 0 40px}
.ring img{width:40px;height:40px}
.ring svg{position:absolute;inset:0}
.speech-time{font:700 15px/1 Lato,sans-serif;color:var(--brass);font-variant-numeric:tabular-nums}

/* ── статус строкой: иконка + слово, никогда только цвет ─────────── */
.status{display:inline-flex;align-items:center;gap:6px;font-size:14px;color:var(--bone-2)}
.status .dot{width:10px;height:10px;border-radius:50%;background:var(--alive);flex:0 0 10px}
.status .dot.warm{background:var(--brass)}
.status .dot.red{background:var(--blood-text)}

/* ── лента реплик ────────────────────────────────────────────────── */
.feed{background:var(--felt);border:1px solid var(--edge);border-radius:var(--card);
  padding:12px;max-height:230px;overflow:auto;flex:1 1 auto;min-height:180px}
.feed p{margin:0 0 9px;font-size:15px}
.feed b{color:var(--brass-2)}
.feed .nom{color:var(--blood-text)}
.feed-col{display:flex;flex-direction:column;min-height:0;min-width:0}
@media(min-width:900px){.feed{max-height:none}}
.feed-note{font-size:12px;margin:0 0 8px;border-bottom:1px solid var(--edge);padding-bottom:8px}
.feed-gesture{margin:8px 0 0;padding:8px;border:1px solid var(--brass-2);border-radius:4px;
  background:var(--brass-dim);color:var(--bone);font-size:14px}
.feed-gesture[hidden]{display:none}
.seat.seat-gesture{border-color:var(--brass-2);box-shadow:0 0 0 2px rgba(201,162,39,.3)}

/* ── панель ходов ────────────────────────────────────────────────── */
.actions{flex:0 0 auto;background:#1B1410;border-top:1px solid var(--edge);padding:8px 16px 16px}
.actions-in{max-width:var(--w-page);margin:0 auto;display:flex;gap:var(--gap-actions);flex-wrap:wrap;align-items:center}

/* ═══ СТОЛ НА ТЕЛЕФОНЕ ═══════════════════════════════════════════════
   D5 §4.1: «10 мест в два столбца по 5». Два столбца, компактная строка
   44 px (портрет 32 px + номер + ник + иконка состояния). */
.seats2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:6px}
@media(min-width:900px){.seats2{grid-template-columns:minmax(0,1fr)}}
@media(max-width:899px){
  .seats2 .seat{height:44px;padding:4px 8px;gap:8px;border-radius:4px}
  .seats2 .seat img,.seats2 .ring,.seats2 .ring img{width:32px;height:32px}
  .seats2 .ring{flex:0 0 32px}
  .seats2 .ring svg{width:32px;height:32px}
  .seats2 .seat-no{width:13px;font-size:11px}
  .seats2 .seat-name{font-size:14px}
  .seats2 .seat{overflow:hidden}
  .seats2 .seat-tag{font-size:11px;gap:3px;white-space:nowrap;flex:0 0 auto}
  .seats2 .speech-time{font-size:12px}
  .seats2 .seat-btn{display:none}
}

/* ── жесты: плитки 48 dp, каждый жест — тап (D4 п.8, 14) ─────────── */
.gestcol{display:none}
@media(min-width:900px){.gestcol{display:block}}
#gestbtn{display:inline-flex}
@media(min-width:900px){#gestbtn{display:none}}
.gestures{display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:8px}
.gesture{min-height:56px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:2px;background:var(--wood-3);border:1px solid var(--edge);border-radius:var(--card);
  color:var(--bone);font-size:12px;cursor:pointer;padding:6px 4px}
.gesture span:first-child{font-size:20px;line-height:1}
.gesture:hover{background:var(--wood-4)}

/* ── шторка вместо нативного диалога (locked 11) — shell.js sheet() ── */
.sheet-back{position:fixed;inset:0;background:rgba(8,5,3,.72);display:flex;align-items:flex-end;
  justify-content:center;z-index:70}
@media(min-width:768px){.sheet-back{align-items:center}}
.sheet-back > .sheet{width:100%;max-width:var(--w-card);background:var(--wood-2);border:1px solid var(--edge);
  border-radius:var(--card) var(--card) 0 0;padding:18px 16px 22px;box-shadow:var(--lift)}
@media(min-width:768px){.sheet-back > .sheet{border-radius:var(--card)}}
.sheet-back > .sheet h3{margin-bottom:6px}
/* ⛔ N7: пока шторка открыта, красная под затемнением гасится — иначе на экране
   видно ДВЕ красные («Отправить жалобу» и «Выставить»), что ломает locked 15. */
body.sheet-open .actions .btn-red{visibility:hidden}
.sh-list{display:grid;gap:6px;margin:4px 0 0}
.sh-list button{display:flex;align-items:center;gap:10px;min-height:var(--tap);width:100%;
  padding:6px 10px;background:var(--wood-3);border:1px solid var(--edge);border-radius:var(--card);
  color:var(--bone);font:600 15px Lato,sans-serif;cursor:pointer;text-align:left}
.sh-list button:hover{background:var(--wood-4)}
.sh-list img{width:28px;height:28px;border-radius:50%;object-fit:cover}
/* BAT-FIX-3, 24.09 — 12px top/bottom was off the 8px spacing grid
   (manifest-gate-test.mjs §1c); 8px keeps the same visual weight relative
   to the 16px sides without adding a new spacing value to the page. */
.toast{position:fixed;left:50%;transform:translateX(-50%);bottom:22px;z-index:80;
  background:var(--wood-3);border:1px solid var(--brass-2);border-radius:var(--card);
  padding:8px 16px;color:var(--bone);box-shadow:var(--lift);max-width:min(92vw,420px)}

/* ── BETA-BADGE — in-flow, first child of <body> (shell.js's own comment
   explains why: pushes nav/main or .screen down instead of covering it,
   no fixed positioning, no z-index, no overlap math needed at any width).
   Not red — manifest §1d/"one danger action per screen" reads any red hue
   as a danger action; this is a notice, so brass/bone, the same family
   .toast already uses. padding 8/16 and the pill's 4/8 are both on the
   8px/4px grid (manifest §1c: block-level containers use 8, inline-like
   ones use 4 — the pill is inline-flex). Height budget at 390: ~28px
   tallest child (.beta-x) + 8+8 padding ≈ 44px, under the task's 48px
   ceiling with room to spare. */
.beta-banner{display:flex;align-items:center;gap:8px;flex-wrap:nowrap;
  padding:8px 16px;background:var(--wood-3);border-bottom:1px solid var(--brass-2);
  color:var(--bone-2)}
.beta-pill{flex:0 0 auto;display:inline-flex;align-items:center;
  padding:4px 8px;border-radius:var(--card);border:1px solid var(--brass);
  color:var(--brass);font:700 12px Lato,sans-serif;letter-spacing:.04em;white-space:nowrap}
.beta-msg{flex:1 1 auto;min-width:0;font-size:13px;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.beta-x{flex:0 0 auto;width:28px;height:28px;display:inline-flex;align-items:center;
  justify-content:center;background:transparent;border:0;border-radius:3px;
  color:var(--bone-2);font-size:18px;line-height:1;cursor:pointer}
.beta-x:hover,.beta-x:focus-visible{color:var(--bone);background:var(--wood-4)}

/* ── вкладки аккаунта ────────────────────────────────────────────── */
.tabs{display:flex;gap:4px;border-bottom:1px solid var(--edge);flex-wrap:wrap;margin-bottom:16px}
.tabs button{min-height:var(--tap);padding:10px 14px;background:transparent;border:0;
  border-bottom:2px solid transparent;color:var(--bone-2);font:600 15px Lato,sans-serif;cursor:pointer}
.tabs button[aria-selected=true]{color:var(--bone);border-bottom-color:var(--brass)}
.tabs button[aria-selected=true]::before{content:"● ";color:var(--brass);font-size:11px}

/* ── пейволл: приглушён, не спрятан, и говорит, что он пейволл ───── */
.paywall{position:relative;border:1px solid var(--brass-2);border-radius:var(--card);overflow:hidden}
.paywall-body{padding:16px;filter:blur(2.5px);opacity:.42;user-select:none;pointer-events:none}
.paywall-cap{padding:14px 16px;background:#241A14;border-top:1px solid var(--brass-2)}
.paywall-cap h3{color:var(--brass);margin-bottom:4px}

/* ── карточка «поделиться» — квадраты по кругам, без ролей и итога ─ */
.sharecard{background:var(--wood-2);border:1px solid var(--edge);border-radius:var(--card);padding:14px}
.sq{display:inline-block;width:22px;height:22px;border-radius:3px;margin:2px;vertical-align:middle;
  border:1px solid rgba(0,0,0,.4)}
.sq-hit{background:var(--alive)}   .sq-miss{background:var(--blood)}   .sq-pass{background:var(--bone-4)}
.sq-key{font-size:13px;color:var(--bone-3)}

/* ── таблицы и тарифы ────────────────────────────────────────────── */
table.t{width:100%;border-collapse:collapse;font-size:15px}
table.t th,table.t td{text-align:left;padding:9px 10px;border-bottom:1px solid var(--edge-2);vertical-align:top}
table.t th{color:var(--bone-3);font-weight:600;font-size:14px}
.plans{display:grid;gap:12px;grid-template-columns:1fr}
@media(min-width:768px){.plans{grid-template-columns:repeat(3,1fr)}}
.plan{background:var(--panel);border:1px solid var(--edge);border-radius:var(--card);padding:16px}
.plan.pick{border-color:var(--brass-2)}
.price{font:700 28px/1 Bitter,Georgia,serif;color:var(--bone)}
.steps{list-style:none;padding:0;margin:10px 0 0;counter-reset:s}
.steps li{position:relative;padding:8px 0 8px 34px;border-bottom:1px solid var(--edge-2);font-size:15px}
.steps li::before{counter-increment:s;content:counter(s);position:absolute;left:0;top:8px;
  width:24px;height:24px;border-radius:50%;background:var(--wood-3);border:1px solid var(--brass-2);
  color:var(--brass);font:700 13px/22px Lato,sans-serif;text-align:center}

input[type=text],input[type=password],input[type=email],select,textarea{
  width:100%;min-height:var(--tap);padding:10px 12px;background:#140E0B;color:var(--bone);
  border:1px solid var(--edge);border-radius:var(--card);font:16px Lato,sans-serif}
label{display:block;font-size:14px;color:var(--bone-3);margin:12px 0 4px}
.field-bad{border-color:var(--blood-text)}
.field-msg{font-size:14px;color:var(--blood-lit);margin-top:6px}

.hidden{display:none !important}
.nowrap{white-space:nowrap}
.mt0{margin-top:0}.mb0{margin-bottom:0}
.tag{display:inline-flex;align-items:center;gap:5px;font-size:13px;color:var(--bone-3);
  border:1px solid var(--edge);border-radius:99px;padding:3px 9px}
.note{border-left:2px solid var(--brass-2);padding:8px 0 8px 16px;color:var(--bone-2);font-size:15px;margin:16px 0}

/* чекбоксы: пол 24×24 (WCAG 2.5.8 AA); сама строка-label держит 44 px */
input[type=checkbox]{width:24px;height:24px;flex:0 0 24px;accent-color:var(--brass)}

@media(min-width:900px){
  .two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px;align-items:start}
  .table-3{display:grid;grid-template-columns:minmax(0,320px) minmax(0,1fr) minmax(0,300px);
    gap:16px;align-items:stretch}
  .table-3 > *{min-width:0}
}
@media(max-width:899px){
  .table-3{display:grid;gap:10px;min-height:0;align-content:start}
  .feed{max-height:230px}
  .feed-col{overflow:hidden}
}
/* 768 — одна читальная колонка (locked 27) */
@media(min-width:768px) and (max-width:1099px){
  main{max-width:680px}
}

/* ═══ манифест УХ поверх закрытых решений (D11) ══════════════════════ */

/* ── дверь: заголовок-ценность (правка a) ─────────────────────────── */
.doorh1{font-size:19px;line-height:1.3;max-width:34ch;color:var(--bone);margin:0 0 10px}

/* ── «Ближайшие столы» / «Идёт сейчас» на одной верхней линии (правка b) */
.now-h{margin:0 0 8px;display:flex;align-items:center;gap:8px;
  font-family:Bitter,Georgia,serif;font-weight:700;font-size:16px;line-height:1.25;color:var(--bone)}

/* ── язык стола фильтрует список (правка h) ───────────────────────── */
.othertables{margin:8px 0 0}
.othertables summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:6px;
  min-height:var(--tap);color:var(--bone-2);font-size:14px}
.othertables summary::-webkit-details-marker{display:none}
.othertables summary::before{content:'▸';color:var(--brass);display:inline-block;width:10px}
.othertables[open] summary::before{content:'▾'}
.othertables .flights{margin-top:4px}

/* ── удержание 600 мс с кольцом-заливкой для критических действий
   (манифест §1a: выставление, ночной выстрел, жалоба). Кольцо — оверлей
   поверх кнопки, конус по --p (0→1). Без JS кнопка работает как обычно. ── */
.hold-ring{position:absolute;inset:-4px;border-radius:calc(var(--card) + 4px);pointer-events:none;
  opacity:0;background:conic-gradient(var(--bone) calc(var(--p,0)*360deg),transparent 0);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 3px));
  mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 3px))}
.btn.holding{background:var(--wood-4)}
.btn.holding .hold-ring{opacity:1}
@media(prefers-reduced-motion:reduce){.hold-ring{transition:none}}

/* ── Hick: пока место говорит, второстепенное хромает (манифест §1b) ── */
body.someone-speaks .hostrow,body.someone-speaks .gestcol{opacity:.45;transition:opacity .3s}
@media(prefers-reduced-motion:reduce){body.someone-speaks .hostrow,body.someone-speaks .gestcol{transition:none}}

/* ── планка фазы: говорящий + таймер видны за 1 с (манифест §2e) ─────── */
.statusbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:13px;color:var(--bone-3);
  border-top:1px solid var(--edge);margin-top:8px;padding-top:8px}
.statusbar b{color:var(--bone-2)}
.phase-who{font-weight:700;color:var(--brass)}
.foulbar{background:var(--blood-dim);border:1px solid var(--blood-text);border-radius:var(--card);
  padding:8px 16px;font-size:14px;color:var(--bone);margin:0 0 8px;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.helpers{font-size:13px;color:var(--bone-3);border-left:2px solid var(--edge);padding-left:8px;margin:8px 0 0}
@media(max-width:899px){.helpers{display:none}}
.helpers b{color:var(--bone-2)}
.votecard{display:flex;align-items:center;gap:10px;min-height:56px;width:100%;position:relative;
  background:var(--wood-2);border:1px solid var(--edge);border-radius:var(--card);color:var(--bone);
  padding:0 12px;font:600 15px/1.2 Lato,sans-serif;cursor:pointer;margin-bottom:6px}
.votecard img{width:36px;height:36px;border-radius:50%;object-fit:cover}
.votecard.holding{background:var(--wood-4)}
.heldrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap;background:var(--wood-2);
  border:1px solid var(--brass-2);border-radius:var(--card);padding:10px 12px;margin:10px 0}
.heldrow b{color:var(--brass);font-variant-numeric:tabular-nums}

/* ── обрыв связи: состояние стола сохраняется, баннер уходит < 2 с (§2f) ── */
.reconn{background:var(--blood-dim);border:1px solid var(--blood-text);border-radius:var(--card);
  padding:8px 12px;font-size:14px;color:var(--bone);margin:0 0 8px;display:flex;align-items:center;gap:8px}
.reconn::before{content:'⟳';color:var(--blood-lit)}

/* ── skeleton screens вместо пустых зон (§2g) — shell.js skeleton() ──── */
.skel{background:linear-gradient(90deg,var(--wood-2) 25%,var(--wood-3) 42%,var(--wood-2) 63%);
  background-size:400% 100%;animation:skel 1.4s ease infinite;border-radius:var(--card);
  border:1px solid var(--edge)}
@keyframes skel{0%{background-position:100% 0}100%{background-position:0 0}}
@media(prefers-reduced-motion:reduce){.skel{animation:none;background:var(--wood-2)}}
.skel-seat{height:56px}
@media(max-width:899px){.skel-seat{height:44px}}
.skel-row{height:16px;margin:8px 0}
.skel-block{height:56px}

/* ── тренажёр: карточки, вид по мотивам memory.html (тренажёр сам не тронут) ─ */
.trainer-cards{display:grid;gap:12px;grid-template-columns:1fr}

/* ── словарь терминов: подсказка у первого употребления (RULE 4, shell.js glossary()) ── */
.gl-term{border-bottom:1px dotted var(--brass-2)}
.gl-hint{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;
  margin:-16px -8px -16px 0;background:none;border:0;color:var(--brass);cursor:pointer;
  font:700 13px/1 Lato,sans-serif;vertical-align:middle}
.gl-hint:hover{color:var(--bone)}

/* ── вход и регистрация: один экран, без второго поверх ────────────── */
.auth{max-width:420px;margin:0 auto}
.auth label{display:block;font-size:14px;color:var(--bone-2);margin:12px 0 4px}
.auth input[type=email],.auth input[type=password]{width:100%;min-height:48px;padding:0 12px;
  background:var(--wood-2);border:1px solid var(--edge);border-radius:var(--card);color:var(--bone);
  font:400 16px/1 Lato,sans-serif}
.auth input:focus{outline:2px solid var(--brass);outline-offset:1px}
.checkrow{display:flex;gap:10px;align-items:flex-start;min-height:44px;margin:14px 0;cursor:pointer}
/* ⚠️ V1-REDS-1/item2 (manifest-gate-test.mjs "tap-targets-bottom-third",
   signin.html 390): the native input[type=checkbox] above is a fixed
   24×24 box — padding does not enlarge a native checkbox's own hit area
   in Chromium or WebKit (measured: width/height stay 24×24 regardless of
   padding or box-sizing) — only setting width/height directly does, and
   that also inflates the VISUAL box, which the task forbids. So this
   overrides the shared rule with `appearance:none` and paints the same
   24×24 square itself (::before), on a --tap (44px) invisible hit box —
   the WCAG 2.5.8 "target offset" technique: bigger to the finger, not to
   the eye. Scoped to .checkrow only — the sitewide input[type=checkbox]
   rule above is untouched for any other checkbox in the app. */
.checkrow input[type=checkbox]{
  appearance:none; -webkit-appearance:none;
  position:relative;
  width:var(--tap); height:var(--tap); flex:0 0 var(--tap);
  margin:0; padding:0;
  display:flex; align-items:center; justify-content:center;
  background:transparent; border:0; border-radius:var(--card);
  cursor:pointer;
}
.checkrow input[type=checkbox]::before{
  content:''; width:24px; height:24px; box-sizing:border-box;
  border-radius:var(--card); border:2px solid var(--edge); background:var(--wood-2);
}
.checkrow input[type=checkbox]:checked::before{background:var(--brass);border-color:var(--brass)}
.checkrow input[type=checkbox]:checked::after{
  content:''; position:absolute; left:50%; top:47%;
  width:5px; height:10px;
  border:solid var(--wood); border-width:0 2px 2px 0;
  transform:translate(-50%,-60%) rotate(45deg);
}
.checkrow input[type=checkbox]:focus-visible{outline:3px solid var(--brass);outline-offset:2px}
.checkrow span{font-size:14px;color:var(--bone-2);padding-top:8px}

/* ── набор портретов в аккаунте (все 36 — скроллится внутри карточки) ── */
.faces{display:grid;grid-template-columns:repeat(auto-fill,minmax(56px,1fr));gap:8px;margin:10px 0 0;
  max-height:268px;overflow-y:auto;padding-right:2px}
.face{aspect-ratio:1;min-height:var(--tap);border-radius:50%;overflow:hidden;border:2px solid var(--edge);
  background:var(--wood-3);padding:0;cursor:pointer}
.face img{width:100%;height:100%;object-fit:cover;display:block}
.face[aria-pressed="true"]{border-color:var(--brass);box-shadow:0 0 0 3px rgba(201,162,39,.3)}
.face:focus-visible{outline:2px solid var(--brass);outline-offset:2px}

