/* ===== LEONIDA HUB — command deck layout ===== */
:root{
  color-scheme: dark;
  --midnight:#0b0620; --indigo:#1a0f3d; --pink:#ff2e88; --orange:#ff9e4f;
  --teal:#24e0d0; --sand:#f5ecd7; --muted:#a99fc4;
  /* Yanone Kaffeesatz/Manrope — кириллические дублёры (Bebas Neue/Space Grotesk без Cyrillic-глифов):
     латиница рендерится первым шрифтом цепочки, кириллица проваливается во второй — как в вики.
     Замену Oswald -> Yanone обосновывает замер метрик, см. комментарий в wiki-src SeoHead.astro */
  --display:'Bebas Neue','Yanone Kaffeesatz',sans-serif; --body:'Space Grotesk','Manrope',sans-serif; --mono:'IBM Plex Mono',monospace;
  --top-h:3.2rem;
}
*{margin:0;padding:0;box-sizing:border-box}
body{color:var(--sand);font-family:var(--body);overflow:hidden;height:100vh;
  display:flex;flex-direction:column;
  background:linear-gradient(180deg,#12082e 0%,#2b0f4d 42%,#7a1d5e 74%,#c2452e 100%)}
body::before{content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
  background:repeating-linear-gradient(180deg,transparent 0 42px,rgba(11,6,32,.14) 42px 46px)}
a{color:inherit;text-decoration:none}
.ph-note{font-family:var(--mono);font-size:.56rem;letter-spacing:.16em;color:rgba(245,236,215,.55);
  border:1px dashed rgba(245,236,215,.3);padding:.2rem .5rem}

/* ===== TOP BAR ===== */
.topbar{flex:0 0 var(--top-h);z-index:900;display:grid;grid-template-columns:1fr auto 1fr;
  align-items:center;gap:1rem;padding:0 1.1rem;background:rgba(11,6,32,.55);backdrop-filter:blur(8px);
  border-bottom:1px solid rgba(255,46,136,.25)}
.topbar-left{display:flex;align-items:center;gap:.6rem}
.logo{font-family:var(--display);font-size:1.5rem;letter-spacing:.08em;
  text-shadow:0 0 14px rgba(255,46,136,.7)}
.logo-a{color:var(--sand)}
.logo-b{color:var(--orange)}
.logo-c{color:var(--pink)}
/* Переключатель языка — дропдаун details/summary без JS, как в вики (LangSwitcher.astro),
   только в масштабе топбара пульта (.68rem против 1.4rem вики) */
.lang-switch{position:relative;font-family:var(--mono);font-size:.68rem;font-weight:700;letter-spacing:.06em}
.lang-switch summary{list-style:none;cursor:pointer;user-select:none;color:var(--sand);
  background:rgba(11,6,32,.6);border:1px solid rgba(255,158,79,.65);
  border-radius:999px;padding:.2rem .55rem}
.lang-switch summary::-webkit-details-marker{display:none}
.lang-switch summary:hover,.lang-switch[open] summary{border-color:var(--orange);color:var(--orange)}
.lang-menu{position:absolute;left:0;top:calc(100% + .3rem);z-index:950;display:flex;
  flex-direction:column;gap:.2rem;padding:.25rem;border-radius:9px;
  border:1px solid rgba(169,159,196,.35);background:var(--indigo,#1a0f3d);
  box-shadow:0 6px 18px rgba(0,0,0,.45)}
.lang-menu a{padding:.2rem .55rem;border-radius:999px;text-decoration:none;color:var(--muted);text-align:center}
.lang-menu a:hover{color:var(--pink);border:1px solid var(--pink);padding:calc(.2rem - 1px) calc(.55rem - 1px)}
.topbar-center{position:relative;display:flex;gap:.6rem;justify-self:center}
.topbar-right{justify-self:end;display:flex;align-items:center;gap:.6rem}
.fan-badge{font-family:var(--mono);font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);background:rgba(11,6,32,.6);border:1px solid rgba(169,159,196,.35);
  border-radius:4px;padding:.25rem .5rem;cursor:pointer}
.fan-badge:hover{border-color:var(--muted);color:var(--sand)}
.guide-btn{width:26px;height:26px;border-radius:50%;background:rgba(255,203,107,.15);
  border:1px solid #ffcb6b;color:#ffcb6b;font-family:var(--mono);font-weight:700;
  font-size:.8rem;cursor:pointer;display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 6px rgba(255,203,107,.35)}
.guide-btn:hover{box-shadow:0 0 10px rgba(255,203,107,.6)}
.btn{display:inline-block;padding:.42rem .95rem;border-radius:6px;font-weight:700;font-size:.82rem;
  border:none;cursor:pointer;font-family:var(--body)}
.btn-discord{background:#5865F2;color:#fff;box-shadow:0 0 14px rgba(88,101,242,.5);display:inline-flex;align-items:center;gap:.4rem}
.btn-ico{width:1.05em;height:1.05em;fill:currentColor;flex:none}
.btn-primary{background:var(--pink);color:#fff;box-shadow:0 0 14px rgba(255,46,136,.5)}
.btn-primary[disabled]{opacity:.55;box-shadow:none;cursor:not-allowed}
.btn-coffee{background:rgba(11,6,32,.6);color:var(--orange);border:1px solid rgba(255,158,79,.5)}

/* ===== DECK GRID ===== */
.deck{flex:1;min-height:0;position:relative;z-index:1;display:grid;gap:.8rem;padding:.8rem 1.1rem;
  grid-template-columns:280px 1fr 280px;
  grid-template-rows:1fr 218px;
  grid-template-areas:"left map right" "dock dock dock"}
/* Колонки скроллятся, а не режут содержимое: высоту у них отбирает раскрытый док (а на низких
   экранах её не хватает и без него), и без прокрутки нижняя карточка просто пропадала — правая
   так теряла билборд целиком (24-08). Полоса тонкая и оранжевая, иначе не видно, что там ещё что-то
   есть. Проверено замером на 1024–1920: скролл включается только когда карточки реально не влезли. */
.col-left,.col-right{overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(255,158,79,.5) transparent}
.col-left{grid-area:left;display:flex;flex-direction:column;gap:.8rem;min-height:0}
.map-frame{grid-area:map;position:relative;min-height:0;border-radius:14px;overflow:hidden;
  border:1px solid rgba(255,158,79,.5);box-shadow:0 0 34px rgba(255,158,79,.18)}
#leafletMap{position:absolute;inset:0;background:transparent}
.col-right{grid-area:right;display:flex;flex-direction:column;gap:.6rem;min-height:0}

/* ===== SUN COUNTDOWN ===== */
.cd-widget{width:100%;flex:0 0 auto;
  background:linear-gradient(135deg,rgba(43,15,77,.9),rgba(122,29,94,.82) 60%,rgba(194,69,46,.75));backdrop-filter:blur(6px);
  border:1px solid rgba(255,158,79,.45);border-radius:12px;padding:.85rem .8rem .6rem;
  box-shadow:0 0 26px rgba(255,46,136,.3);overflow:hidden}
.sun-mini{position:relative;margin:0 auto;width:244px;aspect-ratio:2/1;
  border-radius:244px 244px 0 0;
  background:linear-gradient(180deg,var(--orange) 0%,var(--pink) 80%);
  box-shadow:0 0 26px rgba(255,120,80,.55);
  display:flex;flex-direction:column;justify-content:flex-end;align-items:center;
  padding-bottom:.6rem;overflow:hidden}
.sun-mini::before{content:"";position:absolute;inset:0;
  background:repeating-linear-gradient(180deg,transparent 0 15px,rgba(11,6,32,.28) 15px 18px);
  background-size:100% 18px;animation:sunstripes 6s linear infinite;pointer-events:none}
@keyframes sunstripes{to{background-position:0 18px}}
@media (prefers-reduced-motion:reduce){.sun-mini::before{animation:none}}
.sun-mini-label{font-family:var(--display);font-size:1.26rem;letter-spacing:.3em;margin-bottom:.15rem;z-index:1;
  background:linear-gradient(180deg,#12082e 10%,#7a1d5e 50%,var(--orange) 95%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 1px 2px rgba(245,236,215,.4))}
/* es/pt-br "LANZAMIENTO/LANÇAMENTO DE GTA VI" — вдвое длиннее EN "GTA VI RELEASE", с
   letter-spacing:.3em не помещается в 244px .sun-mini и обрезается overflow:hidden контейнера.
   Уже сжаты font-size и letter-spacing, а не подпись — правило завязано на теге <html lang>,
   который ставит build-locale-home.js, а не на длину строки. */
html[lang="es"] .sun-mini-label,html[lang="pt-br"] .sun-mini-label{font-size:.95rem;letter-spacing:.12em}
.countdown{display:flex;gap:.42rem;font-family:var(--mono)}
.cd-cell{display:flex;align-items:baseline;gap:.12rem}
.cd-num{font-size:1.75rem;font-weight:600;line-height:1;z-index:1;
  background:linear-gradient(180deg,var(--orange) 0%,var(--pink) 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  -webkit-text-stroke:1px rgba(255,196,107,.25);
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.5));transition:filter .18s}
.cd-num.pulse{filter:drop-shadow(0 0 1.8px #ff9e4f) drop-shadow(0 0 3px rgba(255,158,79,.36))}
.cd-unit{font-size:.79rem;text-transform:uppercase;color:#12082e;font-weight:700;z-index:1}
.horizon-mini{height:2px;margin:.35rem auto 0;width:92%;
  background:linear-gradient(90deg,transparent,var(--pink),transparent);box-shadow:0 0 10px var(--pink)}
.cdw-trailer{font-family:var(--mono);font-size:.7rem;letter-spacing:.06em;font-weight:600;
  margin-top:.4rem;text-align:center;color:var(--pink);
  text-shadow:0 0 8px rgba(255,46,136,.6)}
.sun-mini.pulse-min{animation:sunpulse .8s ease}
@keyframes sunpulse{
  0%{box-shadow:0 0 26px rgba(255,120,80,.55)}
  40%{box-shadow:0 0 40px rgba(255,120,80,.75),0 0 60px rgba(255,46,136,.35)}
  100%{box-shadow:0 0 26px rgba(255,120,80,.55)}
}

/* ===== VIDEO OF THE DAY ===== */
.votd{flex:0 0 auto;display:flex;flex-direction:column;
  background:rgba(11,6,32,.55);backdrop-filter:blur(6px);
  border:1px solid rgba(255,158,79,.5);border-radius:12px;overflow:hidden}
.votd-head{font-family:var(--display);letter-spacing:.12em;font-size:.9rem;color:var(--orange);
  background:rgba(255,158,79,.12);padding:.4rem .75rem;border-bottom:1px solid rgba(255,158,79,.35);
  display:flex;justify-content:space-between;align-items:center}
.votd-thumb{position:relative;aspect-ratio:16/8;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,#12082e,#2b0f4d 55%,#7a1d5e);cursor:pointer;
  border:none;border-radius:0;overflow:hidden}
/* votd-thumb — <button>, без явного border браузер рисует свой default outset (толстая светлая
   рамка) — отсюда и была "толстая белая обводка". Первая попытка чинить — постоянный прозрачный
   2px border — сама стала артефактом: реально резервировала 2px зазор вокруг картинки на всех
   сторонах (замерено getBoundingClientRect — ровно 2px везде), в котором просвечивал тёмный фон
   панели. inset box-shadow на hover не занимает layout-пространство — зазора нет вообще никогда. */
.votd-thumb:hover{box-shadow:inset 0 0 0 2px rgba(255,158,79,.7)}
.votd-thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.votd-play{position:absolute;width:36px;height:36px;border-radius:50%;background:var(--pink);
  color:#fff;display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 18px rgba(255,46,136,.6);transition:transform .15s;
  /* Раньше был текстовый глиф ▶ — его "чернила" не центрированы в своём боксе ни у одного шрифта
     одинаково (расхождение между браузерами/ОС), никакой padding-фикс не решал это универсально.
     Теперь inline SVG (тот же приём, что map-player-btn в map.js) — геометрически точный
     треугольник, центрируется тем же flex без хаков. */}
.votd-thumb:hover .votd-play{transform:scale(1.1)}
.votd-title{font-size:.78rem;font-weight:700;line-height:1.3;padding:.55rem .75rem;background:rgba(255,158,79,.12);
  border-top:1px solid rgba(255,158,79,.35)}

/* ===== RIGHT COLUMN ===== */
/* z-index выше .hero-card-overlay (2000) — по запросу прогресс-бар справа не должен затемняться
   при открытой карточке плитки, панель остаётся поверх скрима. */
/* max-height + скролл (16-08(3)): с четвёртой секцией панель выросла до 504px, а кадр карты на
   ноутбучном окне 1280x860 — 491px. Разницу съедал .map-frame{overflow:hidden}, и низ панели
   (кнопка OPEN COLLECTION) на такой высоте окна был физически недостижим. Тот же приём, что уже
   стоял в мобильной ветке. */
.map-panel{position:absolute;top:3.4rem;right:.6rem;z-index:2001;width:200px;
  max-height:calc(100% - 4rem);overflow-y:auto;
  background:rgba(11,6,32,.78);backdrop-filter:blur(8px);
  border:1px solid rgba(255,46,136,.3);border-radius:10px;padding:.8rem .85rem;
  transition:transform .22s ease}
/* Тонкая полоса прокрутки вместо системной (16-08(4)). Системная забирала 17px ВНУТРЕННЕЙ ширины
   панели (offsetWidth 200 → clientWidth 183), и строка «День|Ночь» переставала помещаться во всех
   шести локалях — именно это видно как «луна упирается в край». 6px возвращают 11px строке и
   при этом полосу видно: прятать её совсем нельзя, она единственный признак, что панель скроллится
   (низ с OPEN COLLECTION иначе не найти). */
.map-panel{scrollbar-width:thin;scrollbar-color:rgba(255,158,79,.5) transparent}
.map-panel::-webkit-scrollbar{width:6px}
.map-panel::-webkit-scrollbar-track{background:transparent}
.map-panel::-webkit-scrollbar-thumb{background:rgba(255,158,79,.5);border-radius:3px}
.map-panel::-webkit-scrollbar-thumb:hover{background:var(--orange)}
.map-frame.night-ui .map-panel{scrollbar-color:rgba(177,140,255,.5) transparent}
.map-frame.night-ui .map-panel::-webkit-scrollbar-thumb{background:rgba(177,140,255,.5)}
.map-panel h3{font-family:var(--display);letter-spacing:.1em;font-size:.95rem;color:var(--orange)}
/* Шапка панели: стрелка-сворачивание + заголовок + служебная Legend-кнопка справа */
.panel-head{display:flex;justify-content:space-between;align-items:center;gap:.35rem;margin-bottom:.2rem}
.panel-head h3{margin-right:auto}
/* Сворачивание ВБОК (js/map.js): панель уезжает за правый край кадра, наружу торчит только сама
   стрелка. Прежний вариант «схлопнуть до шапки» оставлял поверх карты полосу с заголовком и
   Legend — на узком кадре это была та же помеха, только ниже. Уводим transform'ом, а не right:
   так .map-frame{overflow:hidden} честно обрезает уехавшую часть, и ширина панели (её читает
   applyHeroLOD в hero-tiles.js) остаётся прежней.
   Вкладка увеличена («сделай чуть крупнее вкладку, в которую сворачивается панель»): стрелка
   стала квадратной кнопкой с центрированным глифом. Кегль растили дважды по фидбэку —
   08-09(3) 1.05→1.35rem, 08-09(4) «чуть больше» → 1.6rem (бокс 1.9→2.1rem под него). */
.panel-collapse{flex:none;width:2.1rem;height:2.1rem;display:flex;align-items:center;justify-content:center;
  padding:0;background:none;border:0;cursor:pointer;line-height:1;
  font-size:1.6rem;color:var(--orange);opacity:.75}
.panel-collapse:hover{opacity:1}
/* Свёрнутая панель — это уже не «панель со стрелкой», а сам язычок, и стрелка в нём единственное
   содержимое: кегль вдвое против развёрнутого состояния («в свёрнутом можно в 2 раза больше»).
   Раунд 08-09(4) «сам язычок сделай как другие [контролы кадра], а треугольничек оставь как есть»:
   глиф 2.1rem не трогаем, а коробку подгоняем под .map-fs — тот же радиус 8px (у панели 10px),
   тот же тугой отступ вокруг иконки и то же свечение, что у .map-fs:hover (фидбэк «в свёрнутом
   можно добавить небольшую подсветку ярлыка»). Фон и блюр у панели и так совпадают с .map-fs
   с точностью до сотой — не переопределяем.
   Ширина торчащей части считается от содержимого: padding .1 + кнопка 2.3 + padding .1 = 2.5rem,
   иначе глиф упрётся в край кадра и подрежется. Ужато дважды («язычок чуть меньше, треугольник
   внутри не меняй», 08-09(6) «ещё чуть меньше»): глиф 2.1rem зафиксирован, коробка 2.3rem —
   минимальная, куда он влезает с line-height:1, дальше резать нечего. */
.map-panel.collapsed{transform:translateX(calc(100% - 2.5rem));padding:.1rem;border-radius:8px;
  border-color:var(--orange);box-shadow:0 0 16px rgba(255,158,79,.7)}
.map-panel.collapsed .panel-collapse{width:2.3rem;height:2.3rem;font-size:2.1rem;opacity:1}
.map-panel.collapsed > *:not(.panel-head),
.map-panel.collapsed .panel-head > *:not(.panel-collapse){display:none}
.map-panel.collapsed .panel-head{margin:0}
/* Legend переехал из шапки панели в .map-credits-stack (16-08(4)) — стиль кнопки уехал туда же */
/* Атрибуция тайлов/маркеров (PROMPT_map_implementation.md §4) — мелкий текст, не перекрывает
   элементы управления (bottom-left, controls живут top-right/bottom-left отдельно) */
/* Столбец служебных подписей в левом низу: кнопка Legend, AI-бэйдж, кредиты (см. .ai-compare-badge).
   z-index поднят с 1000 до 1003 (16-08(4)): столбец обязан оставаться НАД открытой панелью легенды
   (.map-ui-panel, 1002) — иначе она накрывала бы и кнопку, которой её закрывают, и обязательную
   строку атрибуции. Сама панель для этого ещё и не доходит до низа кадра, см. её правило. */
.map-credits-stack{position:absolute;left:.6rem;bottom:.5rem;z-index:1003;width:200px;
  display:flex;flex-direction:column;gap:.35rem}
/* Legend — служебная подпись карты, а не контрол пульта: тот же мелкий кегль и та же оранжевая
   обводка, что была у неё в шапке панели, но по ширине содержимого и прижата влево, чтобы не
   притворяться кнопкой во всю колонку. */
.map-credits-stack .map-ui-btn{align-self:flex-start;width:auto;padding:.16rem .5rem;
  font-size:.58rem;letter-spacing:.04em;
  color:var(--sand);border-color:rgba(255,158,79,.55);background:rgba(255,158,79,.08)}
.map-credits-stack .map-ui-btn:hover{color:var(--orange);border-color:var(--orange)}
.map-credits-stack .map-ui-btn.active{color:var(--orange)}
/* Узкий бокс ~квадратом (раунд-11), не длинная полоса на полкарты */
.map-attribution{background:rgba(11,6,32,.7);backdrop-filter:blur(4px);border:1px solid rgba(255,158,79,.5);
  border-radius:6px;padding:.3rem .5rem;
  font-family:var(--mono);font-size:.55rem;line-height:1.4;color:rgba(245,236,215,.6)}
.map-attribution-note{margin-top:.25rem;color:rgba(255,158,79,.8)}

/* ===== OFFICIAL CARD (left column) — trailer loop + скриншоты Rockstar, вход в MEDIA → OFFICIAL ===== */
.official-card{flex:1;min-height:0;display:flex;flex-direction:column;border-radius:12px;overflow:hidden;
  background:rgba(11,6,32,.55);backdrop-filter:blur(6px);border:1px solid rgba(255,158,79,.5)}
.official-head{flex:0 0 auto;display:flex;justify-content:space-between;align-items:center;
  font-family:var(--display);letter-spacing:.12em;font-size:.9rem;color:var(--orange);
  background:rgba(255,158,79,.12);padding:.4rem .75rem}
.official-head .feed-expand,.votd-head .feed-expand{border-color:rgba(255,158,79,.5);color:var(--orange)}
.official-head .feed-expand:hover,.votd-head .feed-expand:hover{background:rgba(255,158,79,.15);box-shadow:0 0 8px rgba(255,158,79,.4)}
.pip-video{position:relative;flex:1;min-height:0;display:flex;align-items:center;justify-content:center;cursor:pointer;
  background:linear-gradient(135deg,#2b0f4d,#7a1d5e 60%,#c2452e);transition:box-shadow .15s ease;overflow:hidden}
.pip-video:hover{box-shadow:inset 0 0 0 2px rgba(255,158,79,.6)}
/* iframe — только фоновый луп (mute, pointer-events:none), клик всё равно ловит .pip-video (news.js) */
.pip-video iframe{position:absolute;inset:0;width:100%;height:100%;border:0;pointer-events:none}
.official-shots{flex:0 0 auto;display:flex;gap:.4rem;padding:.5rem}
.official-shots .shot{flex:1;min-width:0;aspect-ratio:1;cursor:pointer;transition:transform .15s ease,box-shadow .15s ease}
.official-shots .shot:hover{transform:translateY(-2px);box-shadow:0 4px 10px rgba(0,0,0,.4),0 0 10px rgba(255,158,79,.5)}
.official-shots .shot.breathe{animation:shotBreathe 1.2s ease}
@keyframes shotBreathe{0%,100%{box-shadow:none}50%{box-shadow:0 0 12px rgba(255,158,79,.7)}}

/* ===== COMMUNITY CARD ===== */
/* Раунд-17: возврат к одной колонке (фидбэк "не получается впихнуть в одну панель и респект, и
   онлайн, и лидерборд — возвращай как было"). Порядок сверху вниз: respect -> online + credits ->
   раскрывающийся лидерборд. Двухколоночный вариант раунда-14 (respect | лидерборд) убран вместе
   с центральным разделителем: в узкой колонке обе половины были слишком тесные. Высоту держит
   свёрнутый по умолчанию лидерборд — раскрывается только по клику. */
.community-card{background:linear-gradient(135deg,rgba(43,15,77,.85),rgba(122,29,94,.55));backdrop-filter:blur(6px);
  /* Раунд-20: верх подтянут к низу (.7rem -> .25rem) — отступ вокруг панели респекта
     симметричный, карточка не «висит» на верхнем воздухе. */
  border:1px solid rgba(36,224,208,.45);border-radius:10px;padding:.25rem .8rem;
  display:flex;flex-direction:column;position:relative}
.cc-main,.cc-board{display:flex;flex-direction:column;gap:.35rem}
/* Кнопка-раскрывашка лидерборда, слитого в общий COMMUNITY-блок (раньше был отдельным табом) —
   тот же градиент, что раньше был только на активном табе. Крупный шрифт (1.17rem) — это
   заголовок блока на уровне .ccr-label, а не мелкая служебная кнопка. Высота урезана через
   line-height, не font-size: у Yanone Kaffeesatz большой дефолтный line-height, а сам размер
   шрифта владелец утвердил отдельно и трогать его не нужно. */
.cc-lb-toggle{display:flex;align-items:center;justify-content:center;gap:.35rem;margin-top:.45rem;
  font-family:var(--display);letter-spacing:.06em;font-size:1.17rem;text-align:center;line-height:1.1;
  padding:.13rem .2rem;border-radius:7px;border:1px solid transparent;
  background:linear-gradient(90deg,var(--orange),var(--pink));color:#0b0620;cursor:pointer;width:100%}
.cc-lb-toggle:hover{box-shadow:0 0 12px rgba(255,158,79,.45)}
/* Строки лидерборда/шкалы уровней теперь рисуются внутри окна RESPECT (.aw-body), не в
   community-card — см. js/render.js leaderboardPanel/ranksPanel. */
/* Кегль удвоен по всей вкладке ("в табличке top respect всё в 2 раза крупнее"): окно широкое
   (до 1000px), а строки читались как петит-сноска. Растёт всё сразу — размеры внутри строки
   заданы в em от неё, отдельно подгонять бейдж/медали не нужно.
   Раунд 08-09(3) «шрифты меньше на 15%»: все абсолютные кегли вкладки умножены на 0.85
   (1.44→1.22, 1.2→1.02, 1.16→.99, 1.24→1.05, 2.3→1.95), пропорции между ними сохранены.
   Раунд 08-09(4) «ещё минус 10%»: те же кегли ×0.9 (1.22→1.1, 1.02→.92, .99→.89, .85→.77,
   1.05→.95, 1.95→1.76). Итог от исходных — 0.765. Кнопка .cc-lb-toggle на пульте сюда не входит:
   её размер владелец утвердил отдельно (см. комментарий над ней). */
.cc-leaderboard{list-style:none;margin:.55rem 0 0;padding:0;display:flex;flex-direction:column;gap:.3rem}
.cc-lb-row{display:flex;align-items:center;gap:.5rem;font-family:var(--mono);font-size:1.1rem;
  padding:.26rem .45rem;border-radius:6px;background:rgba(11,6,32,.4)}
.cc-lb-rank{width:1.3em;text-align:center;color:var(--muted);font-weight:700}
.cc-lb-name{flex:1;color:var(--sand);overflow:hidden}
.cc-lb-pts{color:var(--orange);font-weight:700}
.cc-lb-row.you{background:rgba(255,46,136,.18);border:1px solid rgba(255,46,136,.55)}
.cc-lb-row.you .cc-lb-name{color:var(--pink)}
/* Подвал таблицы: замок + фраза + кнопка логина (render.js leaderboardPanel). Заменил прежнюю
   строку «Preview data — real rankings after login» — та объясняла, почему таблица ненастоящая,
   эта предлагает это исправить. Кнопка гашеная до Supabase Auth. */
.cc-lb-login{display:flex;align-items:center;justify-content:center;gap:.6rem;flex-wrap:wrap;
  margin-top:.55rem;font-size:.89rem;color:var(--muted)}
.cc-lb-login-btn{font-family:var(--mono);font-size:.77rem;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;padding:.3rem .8rem;border-radius:8px;cursor:pointer;
  color:var(--orange);background:rgba(255,158,79,.1);border:1px solid var(--orange)}
.cc-lb-login-btn:hover{color:#0b0620;background:var(--orange)}
.cc-lb-login-btn:disabled{cursor:not-allowed;opacity:.55}
.cc-lb-login-btn:disabled:hover{color:var(--orange);background:rgba(255,158,79,.1)}

/* ===== Гангстерские звания (SITE_CONFIG.RESPECT_RANKS) =====
   Бейдж звания рядом с именем и в шкале RANKS. Цвет ставит JS из конфига — здесь только форма,
   иначе палитра разъедется между шкалой и лидербордом. */
.cc-rank-badge{display:inline-flex;align-items:center;gap:.28em;margin-left:.45em;
  border:1px solid currentColor;border-radius:4px;padding:0 .3em;font-size:.86em;
  vertical-align:middle;line-height:1.5}
.cc-rank-badge b{font-family:var(--display);font-weight:700;letter-spacing:.08em;font-size:.85em}
/* Имя больше не однострочный ellipsis: бейдж рядом с ником должен переноситься, а не срезаться */
.cc-lb-name{display:flex;align-items:center;flex-wrap:wrap;gap:.15em;white-space:normal}
/* Подписи-разделители секций внутри вкладки */
.cc-lb-caption{font-family:var(--display);font-size:.92rem;letter-spacing:.14em;color:var(--muted);
  margin:.7rem 0 -.15rem;padding-bottom:.25rem;border-bottom:1px solid rgba(255,255,255,.08)}
.cc-lb-caption:first-child{margin-top:.15rem}
/* Прирост за сегодня — зелёный "вверх", чтобы не путать с общим счётом в оранжевом */
.cc-lb-pts.up{color:#5fe08a}
.cc-lb-today .cc-lb-row{background:rgba(95,224,138,.07)}
/* Текущее звание над шкалой RANKS */
.cc-rank-now{display:flex;align-items:center;justify-content:space-between;gap:.5rem;
  flex-wrap:wrap;padding:.5rem .55rem;border-radius:7px;background:rgba(11,6,32,.55);
  border:1px solid rgba(255,255,255,.1)}
.cc-rank-now .cc-rank-badge{margin-left:0;font-size:1.76rem;padding:.15em .45em}
.cc-rank-next{font-family:var(--mono);font-size:.95rem;color:var(--muted)}
/* Полоса прогресса до следующего звания — между бейджем и подписью «N / M RP»
   (раунд 08-09(3) «справа от текущего ранга должна быть полоса прогресса»). Трек не свой:
   переиспользуем .coll-head-track из витрины COLLECTION, только --tier ставит цвет звания,
   а не редкости. Высота там 6px — рядом с крупным бейджем это ниточка, поэтому здесь толще. */
.cc-rank-now .coll-head-track{height:10px;border-radius:5px;min-width:80px}
.cc-rank-now .coll-head-track i{border-radius:5px;transition:width .5s ease-out}
/* Уже взятые уровни — приглушены, текущий по-прежнему подсвечен .you */
.cc-lb-row.done:not(.you){opacity:.5}
/* Перенос разрешён (раунд-16): nowrap ставился под короткое EN "online now", а RU "сейчас на
   сайте" в узкой колонке вылезал за разделитель. Точка/число и подпись — отдельные flex-элементы,
   перенос ложится ровно между ними. */
.cc-online{font-family:var(--mono);font-size:.86rem;color:var(--sand);display:flex;align-items:center;
  gap:.4rem;flex-wrap:wrap;justify-content:center;text-align:center;line-height:1.3}
#onlineNum{font-size:1rem;font-weight:700}
.cc-dot{width:8px;height:8px;border-radius:50%;background:#4ade80;box-shadow:0 0 8px #4ade80;
  animation:ccblink 2.2s infinite}
@keyframes ccblink{50%{opacity:.45}}

/* ===== BOTTOM DOCK ===== */
/* Ноутбук (23-08): при небольшой высоте экрана боковые колонки (≈490px контента) не влезали в первую
   строку грида (1fr при фиксированных 218px дока) и уходили ПОД док — док их перегораживал. Здесь
   док стартует свёрнутым в строку заголовков (аккордеон тот же, что на телефоне: [data-open] ставит
   windows.js, клик по .feed-head раскрывает ячейку), строка грида — auto. Раскрытая ячейка
   забирает высоту у карты, а не у колонок. STREAMS/SECRET под плашкой COMING SOON: в свёрнутом виде
   плашку прячем, иначе её текст ложился поверх заголовка.
   Порог 800px -> 920px (24-08): на 1600x900 — обычном ноутбучном окне — правила не включались, и
   правая колонка резала билборд на 124px (замер). 1920x1080 остаётся в десктопном режиме, там всё
   влезает и без аккордеона. */
/* Аккордеон дока — телефон и ноутбук: свёрнутая ячейка = один заголовок ([data-open] ставит
   windows.js, клик по .feed-head). На широком высоком экране атрибут ничего не значит — всё раскрыто. */
@media (max-width:900px), (min-width:901px) and (max-height:920px){
  .dock-cell .feed-head,.votd-head,.official-head{cursor:pointer}
  /* 24-08 (владелец, разгрузка телефона): мёртвые полосы дока скрыты — SECRET пуст до Трейлера 3,
     STREAMS на паузе (COMING SOON, ключей Twitch нет). На ноутбуке (второй раунд 24-08) — по той
     же причине: рядом с раскрытой лентой они стояли двумя пустыми прямоугольниками в полдока.
     Вернуть: удалить блок (SECRET — к запуску секретного раздела, STREAMS — вместе с
     streamsEnabled:true) и колонки дока ниже. */
  .dock-cell.dock-secret,.dock-cell.dock-streams{display:none} /* .dock-cell. — специфичность: базовый .dock-cell{display:flex} лежит ниже по файлу */
  .dock-cell:not([data-open="true"]) .feed-scroll,
  .dock-cell:not([data-open="true"]) .streams-body,
  .dock-cell:not([data-open="true"]) .secret-cell,
  .dock-cell:not([data-open="true"]) .secret-soon{display:none}
  /* VIDEO OF THE DAY / OFFICIAL — тот же аккордеон, что у дока (windows.js ставит [data-open]).
     Свёрнутая карточка = одна строка заголовка. */
  .votd:not([data-open="true"]) .votd-thumb,
  .votd:not([data-open="true"]) .votd-title{display:none}
  .official-card:not([data-open="true"]) .pip-video,
  .official-card:not([data-open="true"]) .official-shots{display:none}
}
@media (min-width:901px) and (max-height:920px){
  .deck{grid-template-rows:1fr auto}
  /* Две живые ленты вместо четырёх колонок: STREAMS и SECRET скрыты выше, а треки 1fr .62fr
     остались бы пустыми — display:none убирает элемент, но не колонку грида. */
  .deck .dock{grid-template-columns:1fr 1fr} /* .deck — специфичность: базовый .dock лежит ниже по файлу */
  /* Раскрытая карточка левой колонки забирает всю оставшуюся высоту, свёрнутая — ровно заголовок.
     Без этого при закрытом доке под OFFICIAL висела пустая полоса (у карточки flex:1), а при
     открытом колонке не хватало высоты и OFFICIAL сплющивало в 2px (замер 24-08). Превью видео
     тянется вместе с карточкой — картинка внутри и так object-fit:cover, aspect-ratio не нужен. */
  .votd:not([data-open="true"]),.official-card:not([data-open="true"]){flex:0 0 auto}
  .votd[data-open="true"]{flex:1;min-height:0}
  .votd[data-open="true"] .votd-thumb{flex:1;min-height:60px;aspect-ratio:auto}
  /* Трейлер-луп при раскрытом доке получал 35px и читался как полоска брака — ниже этого лучше
     проскроллить колонку (flex-shrink:0 у карточки: расти на остаток можно, ужиматься — нет). */
  .official-card[data-open="true"]{flex:1 0 auto}
  .official-card[data-open="true"] .pip-video{min-height:120px}
  .dock-cell .feed-head > span:first-child::after{content:" ▾";opacity:.55;font-size:.75em}
  .dock-cell[data-open="true"] .feed-head > span:first-child::after{content:" ▴"}
  .dock-cell[data-open="true"] .feed-scroll{max-height:190px}
  /* Правая колонка на той же высоте: плитки вики 2:1 вместо 4:3 (−60px). Разрешение billboard'у
     сжиматься до нуля (min-height:0, 23-08) снято 24-08 — при раскрытом доке рекламный слот просто
     исчезал; нижний предел теперь стоит в базовом правиле .billboard, а не влезло — колонка
     скроллится. */
  .col-right .wiki-tile{aspect-ratio:2/1} /* .col-right — специфичность: базовые правила плиток лежат ниже по файлу */
  .col-right .wt-label{font-size:.8rem}
}
.dock{grid-area:dock;display:grid;grid-template-columns:280px 1fr 1fr .62fr;gap:0;min-height:0;
  background:rgba(11,6,32,.62);backdrop-filter:blur(8px);
  border:1px solid rgba(255,158,79,.5);border-radius:14px;overflow:hidden}
.dock-cell{display:flex;flex-direction:column;min-height:0;min-width:0}
.dock-cell+.dock-cell{border-left:1px solid rgba(232,185,35,.55)}
.feed-head{font-family:var(--display);letter-spacing:.12em;font-size:.92rem;padding:.4rem .75rem;flex:0 0 auto;
  display:flex;align-items:center;justify-content:space-between}
.feed-head-intel{background:rgba(36,224,208,.14);color:var(--teal)}
.feed-head-weazel{background:rgba(255,46,136,.16);color:var(--pink)}
.feed-head em{font-family:var(--mono);font-style:normal;font-size:.55rem;color:var(--orange);letter-spacing:.08em}
.feed-scroll{overflow-y:auto;overflow-x:hidden;position:relative;flex:1;min-height:0}
.feed-scroll::-webkit-scrollbar{width:6px}
.feed-scroll::-webkit-scrollbar-thumb{background:rgba(169,159,196,.35);border-radius:3px}
.feed-inner{display:flex;flex-direction:column;gap:.55rem;padding:.6rem .75rem;
  animation:feedscroll 36s linear infinite}
.feed-scroll:hover .feed-inner{animation-play-state:paused}
@keyframes feedscroll{from{transform:translateY(-50%)}to{transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){.feed-inner{animation:none}}
.feed-item{border-bottom:1px solid rgba(169,159,196,.15);padding-bottom:.5rem;cursor:pointer}
.feed-item-meta{display:flex;align-items:center;gap:.35rem;font-family:var(--mono);
  font-size:.56rem;letter-spacing:.08em;margin-bottom:.15rem}
.fi-cat{color:var(--teal);text-transform:uppercase}
.dock-weazel .fi-cat{color:var(--pink)}
.fi-time{color:var(--muted);margin-left:auto}
.fi-ad-badge{color:var(--orange);border:1px solid rgba(255,158,79,.5);border-radius:3px;padding:0 .25rem}
.feed-item-title{font-size:.8rem;font-weight:700;line-height:1.3}
.feed-item-body{font-size:.7rem;color:var(--muted);margin-top:.15rem;
  display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;transition:opacity .2s}
.shot{position:relative;flex:0 0 150px;border-radius:8px;overflow:hidden;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,#12082e,#2b0f4d 55%,#7a1d5e);
  border:1px solid rgba(169,159,196,.25)}
.shot:hover{border-color:var(--orange)}
.shot img{width:100%;height:100%;object-fit:cover;display:block}
.shot-actions{position:absolute;bottom:.25rem;left:.3rem;margin-top:0}
.shot-actions .fa-btn{background:rgba(11,6,32,.75)}

/* Хвост мобильной вёрстки: сюда скрипт index.html переносит Support и fan-badge.
   На десктопе контейнер пуст — держим его скрытым, чтобы не давал отступ. */
.mobile-tail{display:none}

/* ===== FOOTER ===== */
.site-footer{font-size:10px;letter-spacing:.05em;text-align:center;padding:6px 12px;
  color:rgba(255,255,255,.45);background:#0d0620}
.site-footer a{color:rgba(255,105,180,.7);text-decoration:none}
.site-footer a:hover{color:#ff69b4}
.site-footer .footer-contact{color:#ffcb6b}
.site-footer .footer-contact:hover{color:#ffdb94}

/* ===== Leaflet ===== */
/* Табличка маркера ужата на ~30% («таблички у маркеров меньше»): в ней три коротких строки —
   название, регион, статус, — а дефолтный попап Leaflet отводил под них 13px/1.4 с отступами
   13/20px. Ужимаем и содержимое, и сам бокс, иначе меньше становится только текст. */
.leaflet-popup-content-wrapper{background:#160b33;color:var(--sand);border:1px solid var(--pink);border-radius:8px}
.leaflet-popup-content{margin:9px 14px;font-size:.62rem;line-height:1.35}
.leaflet-popup-tip{background:#160b33}
.popup-title{font-family:var(--display);font-size:.74rem;letter-spacing:.05em;color:var(--pink)}

/* T0 — подписи районов (PROMPT_map_lod_finalize.md §3): текст поверх растра, без подложки,
   читаемость через обводку/тень. pointer-events:none — клик по подписи не решён, не должен
   перехватывать клики по маркерам под собой. */
.district-label{pointer-events:none;white-space:nowrap;transform:translate(-50%,-50%);
  font-family:var(--display);color:var(--orange);
  -webkit-text-stroke:2px var(--pink);paint-order:stroke fill;
  text-shadow:0 0 6px #000,0 0 10px rgba(11,6,32,.9)}
/* Родительские подписи (LEONIDA и крупные зоны) — крупнее + фиолетово-розовый градиент (раунд-11).
   background-clip:text несовместим с text-stroke родителя — строд убираем, тень оставляем. */
.district-label-parent{font-size:1.82rem;letter-spacing:.12em;text-transform:uppercase;
  background:linear-gradient(105deg,#b18cff 15%,var(--pink) 85%);
  -webkit-background-clip:text;background-clip:text;color:transparent;-webkit-text-stroke:0;
  filter:drop-shadow(0 0 8px rgba(11,6,32,.95)) drop-shadow(0 2px 4px #000)}
.district-label-region{font-size:.98rem;letter-spacing:.04em;-webkit-text-stroke:1.5px var(--pink)}

/* ===== T1 — photo-tile слой (PROMPT_map_hero_tiles.md §4-6) ===== */
/* БЕЗ translate(-50%,-50%) (фикс 14-08, та же грабля, что у .frag-marker). L.divIcon с
   iconSize:[size,size] и без iconAnchor уже центрирует контейнер иконки на точке (margin -size/2,
   см. Icon._setIconStyles) — свой translate сверху уводил ВИДИМУЮ плитку на полразмера вверх-влево
   от её игровых координат. Клик от этого не страдал (клик по DOM-элементу там, где он нарисован),
   а вся дистанционная математика езды — magnet/наезд/раздвижка — считалась от настоящей точки, то
   есть от правого нижнего угла того, что видит игрок. Замер до фикса: смещение -36/-36 px при
   плитке 72 и радиусе наезда 46.5м.
   .district-label в этом файле translate оставляет намеренно: у неё iconSize:null, Leaflet полей
   не ставит и центрировать некому. */
.hero-tile{position:relative;border-radius:8px;overflow:hidden;
  border:2px solid var(--pink);box-shadow:0 0 14px rgba(255,46,136,.55);cursor:pointer}
.hero-tile img{width:100%;height:100%;object-fit:cover;display:block;
  filter:grayscale(1) brightness(.45);transition:filter .3s}
.hero-tile.explored img{filter:none}
.hero-tile-lock{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:1.3rem;text-shadow:0 0 6px #000;pointer-events:none;transition:opacity .3s}
.hero-tile.explored .hero-tile-lock{opacity:0}
/* ===== Интеграция карточек с режимом езды (docs/qa-cards-integration.md) ===== */
/* Открытая карточка — спокойная: оранжевая обводка, без пульса и без повторного бонуса (раунд-9) */
.hero-tile.explored{border:2px solid var(--orange)}
/* Кольцо "near" (треть экрана до машинки, раунд-8) — ЗАКРЫТАЯ карточка мягко пульсирует, "зовёт" */
.hero-tile.card-near:not(.explored){animation:cardNear 1.2s ease-in-out infinite}
@keyframes cardNear{
  0%,100%{transform:scale(1)}
  50%{transform:scale(1.1)}
}
/* Появление из тумана: scale-in + вспышка кромки; класс снимает animationend в hero-tiles.
   Ниже card-near — при одновременных классах играет reveal */
.hero-tile.tile-reveal{animation:tileReveal .45s cubic-bezier(.2,1.4,.4,1)}
@keyframes tileReveal{
  0%{transform:scale(.25);box-shadow:0 0 0 0 rgba(255,158,79,0)}
  55%{box-shadow:0 0 18px 4px rgba(255,158,79,.85)}
  100%{transform:scale(1);box-shadow:0 0 0 0 rgba(255,158,79,0)}
}
/* Намагничивание при подъезде: увеличение + розовая подсветка. Подсказка "E — open" убрана
   (раунд-9): наезд сам открывает карточку, лейбл стал лишним; E/Enter работают молча.
   animation:none — магнит-скейл перебивает пульс card-near */
.hero-tile{transition:transform .15s ease}
.hero-tile.card-magnet{animation:none;transform:scale(1.25);
  box-shadow:0 0 14px 3px rgba(255,46,136,.8)}
.leaflet-marker-icon:has(> .hero-tile.card-magnet){z-index:1000!important}
/* Наезд машинкой = взятый бонус (раунд-8): вспышка-столкновение перед автооткрытием модалки.
   Последним в каскаде — перебивает и card-near, и card-magnet */
.hero-tile.card-pickup{animation:cardPickup .35s ease-out}
@keyframes cardPickup{
  0%{transform:scale(1.25)}
  40%{transform:scale(1.55);box-shadow:0 0 28px 10px rgba(255,158,79,.95)}
  100%{transform:scale(1.1);box-shadow:0 0 0 0 rgba(255,158,79,0)}
}

/* ===== Редкость карточек (тиры) =====
   Generic-палитра рарности, без стилистики Rockstar. Дублирует SITE_CONFIG.CARD_TIERS (config.js):
   там источник для бейджа в модалке, здесь — для колец маркеров; менять надо в обоих местах.
   Кольцо тира перебивает и исходную розовую рамку, и оранжевую .explored: редкость — постоянное
   свойство карточки, а «открыта» и без того читается по расцвеченному фото и снятому замку. */
.hero-tile.tier-common{--tier:#9aa4b8}
.hero-tile.tier-rare{--tier:#4aa3ff}
.hero-tile.tier-epic{--tier:#b06cff}
.hero-tile.tier-legendary{--tier:#ff9e4f}
.hero-tile[class*="tier-"]{border-color:var(--tier);box-shadow:0 0 14px color-mix(in srgb, var(--tier) 55%, transparent)}
/* Открытая — то же кольцо, но свечение плотнее: «собрана» видно и не приглядываясь */
.hero-tile[class*="tier-"].explored{box-shadow:0 0 18px 2px color-mix(in srgb, var(--tier) 75%, transparent)}
/* Магнит подъезда в езде — СОСТОЯНИЕ, а не свойство карточки: розовая подсветка обязана
   перебивать кольцо тира. Правило .card-magnet стоит выше по файлу и с той же специфичностью
   (0,2,0), поэтому кольцо тира его гасило — подсветка подъезда пропала бы разом у всех 88 плиток.
   card-near/card-pickup/tile-reveal чинить не надо: они анимации, а те бьют обычные объявления. */
.hero-tile[class*="tier-"].card-magnet{box-shadow:0 0 14px 3px rgba(255,46,136,.8)}
/* Бейдж редкости — крупная марка у правого края карточки, а не мелкая метка под заголовком
   ("бейдж epic и прочие надо делать крупно справа"). float, а не absolute: заголовок сам
   обтекает бейдж и не залезает под него на длинных названиях. Цвет/бордер ставит JS из
   SITE_CONFIG.CARD_TIERS, поэтому здесь currentColor и подсветка через drop-shadow. */
/* .95rem -> 1.9rem и без свечения ("без свечения и в 2 раза крупнее"): drop-shadow+text-shadow
   на таком кегле размазывали буквы в цветное пятно, читаемость важнее ореола. */
.hero-card-tier{float:right;margin:0 0 .3rem .6rem;font-family:var(--display);font-size:1.9rem;
  font-weight:700;letter-spacing:.14em;border:2px solid currentColor;border-radius:6px;
  padding:.22rem .6rem;line-height:1.15}
.hero-card-tier[hidden]{display:none}
/* Вспышка редкости при открытии карточки (14-08, «как в лутбоксах»): наезд из мелкого с
   перелётом + ореол цветом тира. Свечение здесь допустимо — оно живёт 0.75с и гаснет до
   слабого контура, постоянного размазывания букв (см. коммент выше) не возникает.
   currentColor = цвет тира, его ставит инлайном hero-tiles.js. */
/* Без scale («бейдж без скейла»): вспышка теперь только светом — проявление из невидимости и
   ореол цветом тира. Наезд размером на кегле 1.9rem дёргал всю строку заголовка. */
@keyframes tierPop{
  0%{opacity:0;filter:drop-shadow(0 0 0 currentColor)}
  35%{opacity:1;filter:drop-shadow(0 0 18px currentColor)}
  70%{filter:drop-shadow(0 0 8px currentColor)}
  100%{opacity:1;filter:drop-shadow(0 0 0 currentColor)}
}
/* Третий такт открытия карточки. Порядок задан владельцем: полосы -> расшторивание фото -> бейдж.
   Задержка живёт в CSS, а не в setTimeout (был 220мс): перезапуск делает hero-tiles.js рефлоу, а
   animation-fill-mode:both держит бейдж невидимым всю паузу — без него он успевал показаться
   заранее и вспыхивать было уже нечему. */
.hero-card-tier.tier-pop{animation:tierPop .9s cubic-bezier(.2,.9,.25,1.2) 1.15s both}
@media (prefers-reduced-motion:reduce){.hero-card-tier.tier-pop{animation:none}}
/* Полоса «собрано таких же» — три колонки, как .tier-bars в панели Map Info; сами треки
   переиспользуют .tier-bar-* оттуда, здесь только раскладка строки и её отступ.
   Кегль и трек крупнее панельных («чуть крупнее»): в панели 200px ширины, тут модалка на 480. */
.hero-card-tier-row{display:grid;grid-template-columns:auto 1fr auto;gap:.5rem;align-items:center;
  margin-top:.5rem}
.hero-card-tier-row .tier-bar-name{font-size:.78rem;letter-spacing:.08em}
.hero-card-tier-row .tier-bar-num{font-size:.78rem;color:var(--sand)}
.hero-card-tier-row .tier-bar-track{height:9px;border-radius:5px}
.hero-card-tier-row .tier-bar-track i{border-radius:5px}
.hero-card-tier-row[hidden]{display:none}
/* Первое открытие: фото проявляется из блюра («на карте плитка залочена и заблюрена — просится
   расшторивание»). Класс вешает hero-tiles.js только когда ProgressStore.add вернул true, то есть
   ровно один раз за карточку. */
@keyframes cardImgReveal{
  0%{filter:blur(22px) saturate(.35) brightness(.6);transform:scale(1.08)}
  100%{filter:none;transform:none}
}
/* Второй такт: стартует после того, как полосы (.5s transition) доехали — фото до этого момента
   держится заблюренным через fill-mode:both, как оно и лежало плиткой под замком. */
.hero-card img.card-img-reveal{animation:cardImgReveal .55s ease-out .55s both}
@media (prefers-reduced-motion:reduce){.hero-card img.card-img-reveal{animation:none}}
/* Повторное открытие: раньше не происходило ничего вовсе, и это читалось как «прогресс не
   засчитался». Строка спокойная, без цвета награды — это статус, а не событие. */
.hero-card-owned{font-family:var(--mono);font-size:.62rem;letter-spacing:.1em;color:var(--muted);
  border:1px solid rgba(169,159,196,.35);border-radius:4px;padding:.12rem .4rem;
  display:inline-block;margin-bottom:.5rem}
.hero-card-owned[hidden]{display:none}
/* Заголовок больше не должен упираться в бейдж — оставляем ему воздух справа */
.hero-card-body h4{overflow-wrap:anywhere}
/* Хвост флоата не должен вылезать за тело карточки */
.hero-card-progress{clear:both}

/* ===== Фрагменты legendary (js/card-fragments.js) =====
   Кусок изображения на маркере не показываем (спойлер) — общая иконка-пазл в золотом кольце
   плюс счётчик собранного. Название сета всплывает только при намагничивании. */
/* Размер: 30 ("не очевидны") -> 90 ("в 3 раза крупнее") -> 72 ("меньше на 20%"). Пульсирует и сам
   маркер (scale + ореол), и отдельный расходящийся круг ::after — на статичной карте движение
   ловит глаз лучше размера. Ореол наружу, поэтому overflow не режем и Leaflet-иконку не распирает.
   Цвет — оранжевый вместо золотого ("обводку сделай оранжевой, а не жёлтой"), диск серый вместо
   почти чёрного ("на сером, а не чёрном фоне"): на тёмных тайлах чёрный диск сливался с картой. */
/* БЕЗ translate(-50%,-50%) (фикс 14-08). L.divIcon с iconSize:[72,72] и без iconAnchor уже
   центрирует САМ контейнер иконки на точке (margin -36/-36, см. Icon._setIconStyles) — второй
   сдвиг внутри уводил видимый кружок на 36px вверх-влево от реальной точки подбора. Игрок ехал
   ровно по пазлу, а хитбокс лежал в его правом нижнем углу: «фрагменты плохо берутся». */
.frag-marker{position:relative;width:72px;height:72px;
  border-radius:50%;border:3px solid var(--orange);background:rgba(108,114,130,.85);
  display:flex;align-items:center;justify-content:center;
  animation:fragPulse 1.6s ease-in-out infinite}
/* Свой SVG вместо эмодзи 🧩: эмодзи рисует системный шрифт, он зелёно-жёлтый и не перекрашивается */
.frag-ico{width:60%;height:60%;color:var(--orange);filter:drop-shadow(0 0 6px rgba(11,6,32,.9))}
/* Расходящийся круг — вторая, более медленная волна поверх пульса самого маркера */
.frag-marker::after{content:"";position:absolute;inset:-3px;border-radius:50%;
  border:2px solid rgba(255,158,79,.7);animation:fragRipple 1.6s ease-out infinite;pointer-events:none}
@keyframes fragPulse{
  0%,100%{transform:scale(1);box-shadow:0 0 18px 2px rgba(255,158,79,.55)}
  50%{transform:scale(1.08);box-shadow:0 0 34px 8px rgba(255,158,79,.85)}
}
/* Появление из тумана: под туманом фрагмента нет, а на скорости он всплывает секунды за две до
   того, как машинка до него доедет — без вспышки его просто не успеваешь заметить. Один раз на
   кусок, как .tile-reveal у плиток (js/card-fragments.js). */
@keyframes fragReveal{
  0%{transform:scale(.2);opacity:0}
  60%{transform:scale(1.25);opacity:1}
  100%{transform:scale(1);opacity:1}
}
.frag-marker.frag-reveal{animation:fragReveal .45s cubic-bezier(.2,.9,.25,1.2),
  fragPulse 1.6s ease-in-out .45s infinite}
@keyframes fragRipple{
  0%{transform:scale(1);opacity:.75}
  100%{transform:scale(1.6);opacity:0}
}
.frag-count{position:absolute;bottom:-11px;left:50%;transform:translateX(-50%);
  font-family:var(--mono);font-size:.72rem;font-weight:700;color:var(--orange);
  background:rgba(11,6,32,.95);border:1px solid rgba(255,158,79,.6);border-radius:4px;
  padding:.05rem .35rem;white-space:nowrap}
.frag-label{position:absolute;top:-1.6rem;left:50%;transform:translateX(-50%);
  font-family:var(--display);font-size:.72rem;letter-spacing:.06em;color:var(--orange);
  background:rgba(11,6,32,.92);border-radius:4px;padding:.1rem .4rem;white-space:nowrap;
  opacity:0;transition:opacity .15s}
/* Магнит перебивает пульс (animation:none), как .card-magnet у плиток */
.frag-marker.frag-magnet{animation:none;transform:scale(1.18);
  box-shadow:0 0 30px 10px rgba(255,158,79,.95);background:rgba(140,146,162,.92)}
.frag-marker.frag-magnet::after{animation:none;opacity:0}
.frag-marker.frag-magnet .frag-label{opacity:1}
@media (prefers-reduced-motion: reduce){
  .frag-marker{animation:none;box-shadow:0 0 24px 4px rgba(255,158,79,.7)}
  .frag-marker::after{animation:none;opacity:.5}
}

/* Экран набора (js/card-fragments.js fragScreen) — ОДИН и тот же на подбор куска и на сборку сета:
   затемнённый кадр, целая карточка по центру, собранные четверти в цвете, недостающие серые
   ("лучше показывать всю картинку полностью, а неоткрытые части закрашены серым"). Отдельной
   сетки-индикатора нет — картинка сама показывает прогресс, подпись дублирует его числом.
   Маленькой плашки в углу на подборе больше нет: она не читалась как событие.
   Время жизни экрана держит таймер в js, а не 'animationend' — см. комментарий там. */
.frag-screen{position:absolute;inset:0;z-index:2100;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:1rem;cursor:pointer;
  background:rgba(11,6,32,.78);animation:fragScreenIn .25s ease-out}
@keyframes fragScreenIn{from{opacity:0}to{opacity:1}}
/* Четыре куска встык (gap:0) — швов между ними быть не должно, это одна картинка */
.frag-screen-grid{display:grid;grid-template-columns:1fr 1fr;width:min(480px,86%);
  aspect-ratio:16/9;border-radius:8px;overflow:hidden;box-shadow:0 0 40px rgba(255,197,66,.5)}
.frag-sp{width:100%;height:100%;display:block;object-fit:cover;
  filter:grayscale(1) brightness(.16)}
.frag-sp.got{filter:none}
/* Только что подобранный кусок ПОСТЕПЕННО проявляется из тёмного серого — и всё: вспышку в конце
   («можно убрать вспышку») сняли, вместе с ней ушёл и хвост анимации, который она держала
   (2.4с -> 1.6с). Стартовый фильтр совпадает с .frag-sp (серый, brightness .16) — кусок вырастает
   ровно из того состояния, в котором лежали остальные. */
.frag-sp.now{animation:fragPieceIn 1.6s ease-out both}
@keyframes fragPieceIn{
  0%{filter:grayscale(1) brightness(.16) blur(12px);transform:scale(1.06)}
  100%{filter:none;transform:none}
}
@media (prefers-reduced-motion:reduce){.frag-sp.now{animation:none}}
/* Ширина блока = ширине карточки: полоса прогресса под счётчиком должна кончаться ровно там же,
   где кончается картинка, иначе она читается как отдельный элемент, а не как её шкала. */
.frag-screen-info{display:flex;flex-direction:column;align-items:center;gap:.3rem;
  text-align:center;width:min(480px,86%)}
/* Тот же трек, что у полос редкости (.tier-bar-track), только крупнее — тут не панель, а
   полноэкранная подача. Ширина/цвет приходят из js/card-fragments.js.
   Селектор через родителя не для красоты: базовые .tier-bar-track/.tier-bar-track i объявлены
   НИЖЕ по файлу, и при равной специфичности они перебивали бы высоту обратно на панельные 5px. */
.frag-screen-info .frag-screen-bar{width:100%;height:10px;border-radius:6px;margin-top:.2rem}
.frag-screen-info .frag-screen-bar i{border-radius:6px}
.frag-screen-info b{font-family:var(--display);font-size:clamp(1.3rem,3.4vw,2.2rem);
  letter-spacing:.08em;color:var(--sand)}
.frag-screen-info span{font-family:var(--mono);font-size:clamp(1rem,2.4vw,1.6rem);
  font-weight:700;letter-spacing:.08em;color:var(--orange)}
/* Сборка: 4 куска слетаются с разных сторон. Полёт .95с -> 1.8с и разбег кусков .12 -> .22с
   («появление медленнее»): при прежней скорости куски вставали на место раньше, чем глаз находил
   их на экране. */
.frag-screen-fly .frag-sp{animation:fragFly 1.8s cubic-bezier(.2,.9,.3,1) both}
@keyframes fragFly{
  0%{transform:translate(var(--dx),var(--dy)) rotate(var(--rot)) scale(.6);opacity:0}
  60%{opacity:1}
  100%{transform:translate(0,0) rotate(0) scale(1);opacity:1}
}
@media (prefers-reduced-motion: reduce){.frag-screen-fly .frag-sp{animation-duration:.01s}}
/* Последний кусок встаёт на 2.46с (полёт 1.8 + разбег .22×3) — сразу за ним карточка на секунду
   загорается целиком и гаснет до нормальной. Тот же такт «проявилось -> вспыхнуло -> норма», что
   у одиночного куска, только теперь про всю карточку: собранный сет обязан выглядеть как событие. */
.frag-screen-fly .frag-screen-grid{animation:fragAssembled 1.6s ease-out 2.5s both}
@keyframes fragAssembled{
  0%{filter:none}
  20%{filter:brightness(2.5) saturate(1.25)}
  70%{filter:brightness(2.5) saturate(1.25)}
  100%{filter:none}
}
@media (prefers-reduced-motion:reduce){.frag-screen-fly .frag-screen-grid{animation:none}}
/* Салют — три залпа искр поверх собранной карточки, только на сборке сета. Позиции залпов, углы и
   длину разлёта раздаёт js/card-fragments.js, здесь — движение: искра улетает по своему углу
   (rotate + translateY), а весь залп одновременно оседает вниз (fwFall), поэтому фонтан заваливается
   к земле, а не висит ровным кольцом. Гравитацию так дают одним правилом на залп вместо покадровой
   анимации каждой искры. */
.frag-fw{position:absolute;inset:0;overflow:hidden;pointer-events:none}
.frag-fw i{position:absolute;width:0;height:0;animation:fwFall 1.5s ease-in var(--t) both}
.frag-fw b{position:absolute;width:5px;height:5px;margin:-2.5px;border-radius:50%;
  color:var(--orange);background:currentColor;box-shadow:0 0 9px currentColor;
  animation:fwSpark 1.5s ease-out var(--t) both}
.frag-fw b:nth-child(3n){color:var(--sand)}
.frag-fw b:nth-child(3n+1){color:var(--pink)}
@keyframes fwSpark{
  0%{transform:rotate(var(--a)) translateY(0) scale(1.6);opacity:0}
  12%{opacity:1}
  100%{transform:rotate(var(--a)) translateY(calc(var(--d) * -1)) scale(.35);opacity:0}
}
@keyframes fwFall{from{transform:translateY(0)}to{transform:translateY(26px)}}
@media (prefers-reduced-motion:reduce){.frag-fw{display:none}}

.hero-explored{margin-top:.6rem;font-family:var(--mono);font-size:.78rem;font-weight:700;color:var(--orange);
  letter-spacing:.04em}
/* Строка Cards в панели — тоже вход в COLLECTION (раунд 08-09): пока счётчик на нуле, открывает
   сразу HOW TO PLAY (см. windows.js). Курсор — единственный намёк, кнопка ниже остаётся главной. */
#heroExploredRow{cursor:pointer}
#heroExploredRow:hover{filter:brightness(1.18)}
/* Полосы по редкости — три колонки: название, трек, счётчик. Цвет тира приходит инлайном
   (--tier из SITE_CONFIG.CARD_TIERS, js/hero-tiles.js), тут только геометрия. */
.tier-bars{display:grid;grid-template-columns:auto 1fr auto;gap:.2rem .4rem;align-items:center;margin-top:.45rem}
.tier-bar-name{font-family:var(--mono);font-size:.55rem;font-weight:700;letter-spacing:.06em;color:var(--tier)}
.tier-bar-track{height:5px;border-radius:3px;overflow:hidden;
  background:color-mix(in srgb, var(--tier) 18%, transparent)}
.tier-bar-track i{display:block;height:100%;background:var(--tier);border-radius:3px;transition:width .5s ease-out}
.tier-bar-num{font-family:var(--mono);font-size:.55rem;color:var(--muted)}

/* OPEN COLLECTION — единственный вход в витрину собранного. Своего счётчика на кнопке нет: Cards
   N/M стоит над полосой прямо над ней, и второй раз то же число читалось бы как другое. */
.panel-collect{display:flex;align-items:center;gap:.4rem;width:100%;margin-top:.6rem;
  padding:.4rem .55rem;cursor:pointer;text-align:left;
  font-family:var(--mono);font-size:.62rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--orange);background:rgba(255,158,79,.08);
  border:1px solid rgba(255,158,79,.5);border-radius:8px;
  box-shadow:0 0 7px rgba(255,158,79,.35)} /* лёгкое свечение и в покое (фидбэк 08-09) */
.panel-collect:hover{color:var(--sand);border-color:var(--orange);background:rgba(255,158,79,.16)}
.hero-explored-expand{margin-left:auto;opacity:.65;font-size:.7rem}
.panel-collect:hover .hero-explored-expand{opacity:1}
/* Привлекалка новичка (раунд 08-09 «добавить свечение и бегающую подсветку»): пока не открыто
   ни одной карточки, кнопка пульсирует свечением и по ней пробегает блик. Класс вешает/снимает
   renderCounter() в hero-tiles.js — первая открытая карточка гасит её навсегда.
   --ac — цвет свечения через var: ночная тема меняет одну переменную, не свои keyframes. */
.panel-collect{position:relative}
.panel-collect.attract{--ac:255,158,79;border-color:var(--orange);
  animation:collectGlow 1.7s ease-in-out infinite}
/* Подсветка бежит ПО КОНТУРУ, а не поперёк кнопки («бегущая подсветка должна бегать по контуру,
   как обводка у плеера»): тот же приём, что .hero-card-readmore::before ниже — conic-gradient
   крутится через @property --chase-angle и вырезается маской в рамку. transform:rotate здесь не
   работает: прямоугольник при повороте вылезает углами. overflow:hidden с кнопки снят — inset:-2px
   обязан выходить за её бокс, иначе обводку срежет. */
.panel-collect.attract::after{content:'';position:absolute;inset:-2px;border-radius:inherit;
  padding:2px;box-sizing:border-box;pointer-events:none;
  background:conic-gradient(from var(--chase-angle),transparent 0%,
    rgba(var(--ac),.7) 8%, rgba(255,240,210,.95) 12%, rgba(var(--ac),.7) 16%, transparent 35%);
  -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  mask-composite:exclude;
  animation:heroReadmoreChase 5.2s linear infinite} /* 08-09(4): вдвое медленнее, было 2.6s */
.map-frame.night-ui .panel-collect.attract{--ac:177,140,255;border-color:#b18cff}
@keyframes collectGlow{
  0%,100%{box-shadow:0 0 5px rgba(var(--ac),.3)}
  50%{box-shadow:0 0 16px rgba(var(--ac),.8)}
}
@media (prefers-reduced-motion: reduce){.panel-collect.attract,.panel-collect.attract::after{animation:none}}
.hero-explored-bar{position:relative;margin-top:.5rem;height:19px;border-radius:8px;background:rgba(255,158,79,.15);
  overflow:visible;border:2px solid rgba(255,158,79,.5)}
.hero-explored-bar-fill{height:100%;width:0%;background:linear-gradient(90deg,var(--orange),var(--pink));
  border-radius:6px;transition:width .5s ease-out;box-shadow:0 0 16px rgba(255,46,136,.7)}
/* Туман (Explored, только в окне COLLECTION) — второй вид заливки: плоская дымчато-лиловая.
   Градиент занят карточками, две одинаковые полосы подряд слились бы в одну разрезанную. */
.hero-explored-bar-fill.fog{background:#c9bfe8;box-shadow:0 0 14px rgba(201,191,232,.55)}
.hero-explored-bar:has(.fog){background:rgba(201,191,232,.14);border-color:rgba(201,191,232,.45)}
/* Метки (369 точек, тоже только в окне COLLECTION) — третий вид: песочный. Оранжевый занят
   карточками, лиловый туманом; сама точка на карте — оранжевая с белой обводкой, светлая заливка
   читается как её продолжение. */
.hero-explored-bar-fill.dots{background:var(--sand);box-shadow:0 0 14px rgba(245,236,215,.45)}
.hero-explored-bar:has(.dots){background:rgba(245,236,215,.12);border-color:rgba(245,236,215,.4)}
/* Round 3 переделка (после 1.8s ease -> .6s -> .95s bounce, всё мимо): раньше весь акцент был на
   ЧИСЛЕ (scale 1.5x + вспышка) — сама полоса при этом просто тихо ехала transition:width, без
   собственной реакции. Число прыгало эффектнее, чем реально рос прогресс, отсюда "криво, не вижу
   прогресс". Теперь наоборот: полоса — главный индикатор (вспышка свечения ровно на приросте
   ширины), число — короткий "тик" сдвигом вверх (как одометр), без масштабирования. */
@keyframes barPulse{
  0%{box-shadow:0 0 16px rgba(255,46,136,.7)}
  35%{box-shadow:0 0 30px rgba(255,46,136,1),0 0 12px #fff}
  100%{box-shadow:0 0 16px rgba(255,46,136,.7)}
}
.bar-pulse{animation:barPulse .7s ease-out}
/* Была версия с уходом числа вверх через opacity:0 и возвратом снизу (одометр) — с двумя
   позициями смены глазом читалось как "число показывается дважды" (баг-репорт). Заменена на
   вспышку свечения — но одного свечения оказалось не видно ("как будто статичное"). Добавлен
   лёгкий scale (1 -> 1.25 -> 1, БЕЗ opacity/translate) — масштаб в одной и той же точке не создаёт
   второй позиции для глаза, в отличие от прошлой версии, так что баг "дважды" не возвращается. */
/* Round-5 фидбек: глоу+scale всё ещё "не наврисят" (недостаточно заметно) — добавлен цвет: число
   на пару секунд перекрашивается в белый, потом плавно возвращается к своему обычному (наследуется
   от родителя — var(--orange) что у сайдбара, что у карточки, поэтому color не задан на 0%/100% и
   просто доезжает обратно до унаследованного значения). */
@keyframes countTick{
  0%{text-shadow:none;transform:scale(1)}
  15%{color:#fff;text-shadow:0 0 8px #fff,0 0 18px var(--pink),0 0 30px var(--pink);transform:scale(1.25)}
  55%{color:#fff;text-shadow:0 0 8px #fff,0 0 14px var(--pink);transform:scale(1)}
  100%{text-shadow:none;transform:scale(1)}
}
.count-pulse{display:inline-block;animation:countTick 2s ease-out}

.hero-card-overlay{position:absolute;inset:0;z-index:2000;background:rgba(11,6,32,.82);
  display:flex;align-items:center;justify-content:center;padding:1rem}
.hero-card-overlay[hidden]{display:none}
/* Карточка живёт внутри .map-frame, а не на всю страницу: на телефоне кадр ~410px, и низ
   карточки (Read more, прогресс, полоса редкости) уезжал под обрез — overflow:hidden держал
   скругление и молча резал контент.
   Каркас: колонка с max-height по кадру. Место отдаёт ТОЛЬКО картинка (flex:1 1 auto), текст
   не сжимается (flex:none) — иначе оба ужимаются пропорционально и в теле всё равно остаётся
   скрытая полоса. min-height картинки — предел, ниже которого честнее прокрутить карточку
   целиком (overflow:hidden auto), чем показывать полоску вместо кадра. */
.hero-card{position:relative;width:min(480px,100%);max-height:100%;display:flex;flex-direction:column;
  background:var(--indigo);border-radius:10px;
  border:1px solid rgba(255,46,136,.4);overflow:hidden auto;box-shadow:0 10px 40px rgba(0,0,0,.6)}
.hero-card img{width:100%;aspect-ratio:16/9;object-fit:cover;display:block;flex:1 1 auto;min-height:56px}
.hero-card-body{padding:.85rem 1rem 1rem;flex:none}
.hero-card-body h4{font-family:var(--display);letter-spacing:.06em;font-size:1.1rem;color:var(--sand);margin-bottom:.25rem}
.hero-card-location{font-family:var(--display);letter-spacing:.06em;font-size:.75rem;
  color:var(--orange);margin-bottom:.15rem}
.hero-card-location:empty{display:none}
.hero-card-attr{font-family:var(--mono);font-size:.6rem;color:var(--muted);letter-spacing:.04em;margin-bottom:.6rem}
.hero-card-progress{font-family:var(--mono);font-size:.68rem;font-weight:700;color:var(--orange);
  letter-spacing:.04em;margin-bottom:.6rem}
/* Обводка вместо заливки, тот же язык, что акцентные хлебные крошки в вики (Breadcrumbs.astro,
   [aria-current='page']: цвет-бордер вместо сплошной кнопки) — просто оранжевая версия здесь.
   Тот же класс переиспользует tp-wiki-link (кнопка View on wiki у трейлер-плеера). */
.hero-card-readmore{position:relative;display:inline-block;font-family:var(--body);font-weight:700;font-size:.8rem;
  color:var(--orange);background:rgba(255,158,79,.12);border:1px solid var(--orange);
  border-radius:6px;padding:.4rem .8rem;text-decoration:none;margin-bottom:.6rem}
.hero-card-readmore:hover{background:rgba(255,158,79,.22);box-shadow:0 0 10px rgba(255,158,79,.4)}
/* Бегущая подсветка по краю — тот же приём, что активная хлебная крошка в вики
   (Breadcrumbs.astro [aria-current='page']::before): conic-gradient крутится через @property,
   не transform:rotate (прямоугольник при повороте вылетает углами за пределы плашки).
   Потребителей у --chase-angle и heroReadmoreChase ДВА: эта кнопка и .panel-collect.attract
   (привлекалка OPEN COLLECTION, раунд 08-09(3)) — при удалении одного второй не трогать. */
@property --chase-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
.hero-card-readmore::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  padding: 2px;
  box-sizing: border-box;
  /* Золотой (#ffcb6b — тот же акцент, что кнопка Guide), не оранжевый: подсветка на оранжевой
     обводке кнопки была не видна, глазу не за что зацепиться — золотой даёт контраст. */
  background: conic-gradient(
    from var(--chase-angle),
    transparent 0%,
    color-mix(in srgb, #ffcb6b 65%, transparent) 8%,
    color-mix(in srgb, #fff 85%, transparent) 12%,
    color-mix(in srgb, #ffcb6b 65%, transparent) 16%,
    transparent 35%
  );
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  animation: heroReadmoreChase 10s linear infinite;
}
@keyframes heroReadmoreChase { to { --chase-angle: 360deg; } }
@media (prefers-reduced-motion: reduce) { .hero-card-readmore::before { animation: none; } }
.hero-card-close{position:absolute;top:.5rem;right:.5rem;z-index:1;width:28px;height:28px;
  border-radius:50%;border:none;background:rgba(11,6,32,.7);color:var(--sand);font-size:1rem;cursor:pointer}

/* ===== Fullscreen map mode ===== */
.deck.fs{grid-template-columns:0 1fr 0;grid-template-rows:1fr 0;gap:0}
.deck.fs .col-left,.deck.fs .col-right,.deck.fs .dock{display:none}

:focus-visible{outline:2px solid var(--teal);outline-offset:2px}


/* ===== RESPECT ===== */
/* .respect-toast/.respect-pop теперь инжектятся самим js/respect.js (self-contained CSS) —
   единая точка правды, работает и на пульте, и на вики без этого файла */

/* ===== FEED EXPAND ===== */
.feed-expand{background:none;border:1px solid rgba(36,224,208,.5);border-radius:4px;color:var(--teal);
  font-size:.75rem;line-height:1;padding:.15rem .4rem;cursor:pointer}
.feed-expand:hover{background:rgba(36,224,208,.15);box-shadow:0 0 8px rgba(36,224,208,.4)}
.feed-head-weazel .feed-expand{border-color:rgba(255,46,136,.5);color:var(--pink)}
.feed-head-weazel .feed-expand:hover{background:rgba(255,46,136,.15);box-shadow:0 0 8px rgba(255,46,136,.4)}
.support-soon{text-align:center;padding:2.5rem 1rem}
.support-thanks{font-family:var(--display);font-size:1.4rem;letter-spacing:.08em;color:var(--orange)}
.support-note{margin-top:.6rem;color:var(--muted)}
.support-how{display:inline-block;margin-top:.9rem;padding:.6rem .9rem;border:1.5px solid rgba(255,158,79,.7);border-radius:8px;
  background:rgba(255,158,79,.14);color:var(--orange);font-weight:600;box-shadow:0 0 10px rgba(255,158,79,.25)}
.feed-head-streams .feed-expand,.feed-head-streams .votd-refresh{border-color:rgba(169,112,255,.5);color:#a970ff}
.feed-head-streams .feed-expand:hover,.feed-head-streams .votd-refresh:hover{background:rgba(169,112,255,.15);box-shadow:0 0 8px rgba(169,112,255,.4)}

/* ===== APP WINDOW (окно = приложение) ===== */
.app-win{position:fixed;inset:0;z-index:1100;display:none;align-items:center;justify-content:center;
  background:rgba(11,6,32,.45);backdrop-filter:blur(4px);padding:2rem}
.app-win.open{display:flex}
.aw-panel{width:min(1000px,100%);height:min(82vh,100%);display:flex;flex-direction:column;
  background:rgba(18,8,46,.97);border:1px solid var(--win-accent,var(--teal));border-radius:14px;overflow:hidden;
  box-shadow:0 0 8px var(--win-accent,rgba(36,224,208,.3))}
.aw-head{flex:0 0 auto;display:flex;justify-content:space-between;align-items:center;gap:.5rem;
  padding:.6rem 1rem;background:rgba(36,224,208,.1);border-bottom:1px solid var(--win-accent,rgba(36,224,208,.3))}
.aw-title{font-family:var(--display);letter-spacing:.14em;font-size:1.1rem}
.aw-close,.aw-refresh{background:none;border:1px solid var(--win-accent,var(--pink));border-radius:4px;color:var(--win-accent,var(--pink));
  font-size:.9rem;padding:.2rem .55rem;cursor:pointer}
.aw-close:hover,.aw-refresh:hover{background:color-mix(in srgb,var(--win-accent,var(--pink)) 15%,transparent)}
/* Показывается только для вкладок MEDIA -> VIDEOS/SHORTS (windows.js renderTab, tab.onRefresh) */
.aw-refresh{margin-left:auto}
.aw-tabs{flex:0 0 auto;display:flex;gap:1rem;padding:0 1rem;background:rgba(36,224,208,.1);
  border-bottom:1px solid var(--win-accent,rgba(36,224,208,.3))}
.aw-tab{background:none;border:none;border-bottom:2px solid transparent;color:var(--muted);
  font-family:var(--display);letter-spacing:.1em;font-size:1rem;padding:.4rem .1rem;cursor:pointer}
.aw-tab:hover{color:var(--sand)}
.aw-tab.active{color:var(--win-accent,var(--teal));border-bottom-color:var(--win-accent,var(--teal))}
.aw-body{flex:1;min-height:0;overflow-y:auto;padding:1rem}
.aw-body::-webkit-scrollbar{width:8px}
.aw-body::-webkit-scrollbar-thumb{background:rgba(36,224,208,.4);border-radius:4px}
.aw-grid{display:flex;flex-direction:column;gap:.6rem}
.aw-grid-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:.9rem}
.aw-card{background:rgba(11,6,32,.6);border:1px solid rgba(169,159,196,.25);border-radius:10px;
  padding:.75rem .85rem;display:flex;flex-direction:column;gap:.4rem}
.aw-card-meta{display:flex;justify-content:space-between;font-family:var(--mono);
  font-size:.58rem;letter-spacing:.08em}
.aw-card-title{font-size:.92rem;line-height:1.3}
.aw-card-body{font-size:.74rem;color:var(--muted)}
.aw-card-src{font-family:var(--mono);font-size:.6rem;color:var(--teal);letter-spacing:.08em}
.aw-card-src a{text-decoration:underline;text-underline-offset:2px}
.aw-legal-links{margin-top:.4rem;font-size:.82rem}
.aw-legal-links a{color:var(--orange);text-decoration:underline;text-underline-offset:2px}
.aw-body .fa-btn{font-size:1.24rem;padding:.25rem .85rem;border-radius:6px}
/* ===== TRAILER PLAYER (p2-10) — MEDIA -> OFFICIAL, над сеткой скриншотов ===== */
.trailer-player{margin-bottom:1rem}
.tp-wiki-link{margin-top:.6rem}
.tp-tabs{display:flex;gap:.5rem;margin-bottom:.6rem}
.tp-tab{background:none;border:1px solid rgba(169,159,196,.35);color:var(--muted);border-radius:6px;
  padding:.3rem .9rem;font-family:var(--display);letter-spacing:.08em;font-size:.85rem;cursor:pointer}
.tp-tab:hover{border-color:var(--pink);color:var(--sand)}
.tp-tab.active{background:linear-gradient(90deg,var(--pink),var(--orange));border-color:transparent;color:#0b0620}
.tp-video{position:relative;aspect-ratio:16/9;border-radius:10px;overflow:hidden;background:#000}
.tp-video iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.tp-video-channel{margin-top:.5rem;font-family:var(--mono);font-size:.9rem;color:var(--muted);letter-spacing:.04em}
/* Плеер VIDEOS/SHORTS/VOTD открывается на всю ширину окна — крестик закрытия в шапке легко не
   заметить, поэтому под видео дублируем явную кнопку возврата (windows.js openVideoPlayer). */
.tp-back-btn{display:block;margin:.7rem auto 0;background:none;border:1px solid var(--orange);
  color:var(--orange);border-radius:6px;padding:.4rem 1.1rem;font-family:var(--body);font-weight:700;
  font-size:.8rem;cursor:pointer}
.tp-back-btn:hover{background:rgba(255,158,79,.15);box-shadow:0 0 10px rgba(255,158,79,.4)}
.tp-soon{aspect-ratio:16/9;border-radius:10px;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,#12082e,#2b0f4d 55%,#7a1d5e);border:1px dashed rgba(169,159,196,.4)}

.aw-shot-group{grid-column:1/-1;font-family:var(--display);letter-spacing:.1em;font-size:.9rem;
  color:var(--orange);margin:.4rem 0 -.2rem;text-transform:uppercase}
.aw-shot-group:first-child{margin-top:0}
/* MORE VIDEOS под Go back (windows.js openVideoPlayer) — общий -.2rem снизу у .aw-shot-group тут
   подтягивал сетку слишком близко к надписи, нужен обычный отступ, не для shotGrid() трогаем. */
.tp-more-heading{margin-top:1rem;margin-bottom:.6rem}

/* ===== Окно COLLECTION (js/render.js collectionPanel) — витрина карточек карты =====
   Секция на тир, цвет заголовка/рамки берётся из CARD_TIERS инлайном (--tier). Закрытая карточка
   — тот же квадрат, но пустой с замком: витрина показывает, СКОЛЬКО ещё не найдено, но не что
   именно (иначе коллекция сама себя спойлерит). */
.coll-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));gap:.5rem;
  margin:.55rem 0 1.1rem}
.coll-card{position:relative;aspect-ratio:1;padding:0;overflow:hidden;border-radius:8px;
  display:flex;align-items:center;justify-content:center;
  background:rgba(11,6,32,.6);border:2px solid color-mix(in srgb, var(--tier) 35%, transparent)}
.coll-card.open{cursor:pointer;border-color:var(--tier);
  box-shadow:0 0 12px color-mix(in srgb, var(--tier) 45%, transparent)}
.coll-card.open:hover{box-shadow:0 0 18px color-mix(in srgb, var(--tier) 80%, transparent)}
.coll-card img{width:100%;height:100%;object-fit:cover;display:block}
.coll-card-title{position:absolute;left:0;right:0;bottom:0;padding:.5rem .35rem .25rem;
  background:linear-gradient(transparent,rgba(11,6,32,.92));
  font-family:var(--mono);font-size:.55rem;letter-spacing:.02em;color:var(--sand);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left}
.coll-card-lock{font-size:1.1rem;opacity:.35;filter:grayscale(1)}
.coll-count{font-family:var(--mono);font-size:.7rem;opacity:.8}
/* Заголовок тира в витрине = название + полоса прогресса + счётчик («рядом с названием тира
   делать слайдер»). Полоса тянется на всё свободное место между ними, цвет — тир.
   .coll-head-track переиспользован во вкладке RANKS (.cc-rank-now, раунд 08-09(3)): там --tier
   несёт цвет ЗВАНИЯ, а не редкости. Имя осталось от первого места — правя эти два правила,
   помни про второго потребителя. */
.coll-head{display:flex;align-items:center;gap:.6rem}
.coll-head-track{flex:1;min-width:40px;height:6px;border-radius:3px;
  background:color-mix(in srgb, var(--tier) 18%, transparent);overflow:hidden}
.coll-head-track i{display:block;height:100%;background:var(--tier);border-radius:3px}
/* Пояснение механики под заголовком тира — сейчас только у legendary (render.js collectionPanel).
   Отрицательный margin-bottom съедает верхний отступ .coll-grid: строка должна читаться как
   подпись к заголовку, а не как отдельный абзац между ним и сеткой. */
.coll-tier-note{margin:.3rem 0 -.25rem;font-size:.72rem;line-height:1.35;color:var(--muted)}
/* Шапка витрины — те же две полосы, что раньше стояли в панели Map Info */
/* auto-fit вместо фиксированных колонок: третья полоса (метки) встала без своего медиазапроса,
   а на узком окне все три переносятся сами. */
.coll-summary{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:.2rem 1rem;margin-bottom:.9rem}
.coll-summary .hero-explored{margin-top:0}
/* HOW TO PLAY — обычный текст окна, только строки чуть плотнее заголовков-разделов */
.aw-goals p{margin:.15rem 0 .45rem}
/* MEDIA -> VIDEOS/SHORTS — реальные видео с YouTube, см. render.js videoCard() */
.video-card{display:block;width:100%;text-align:left;text-decoration:none;color:inherit;
  font-family:inherit;background:rgba(11,6,32,.6);cursor:pointer;padding:0;
  border:1px solid rgba(169,159,196,.25);border-radius:10px;overflow:hidden;transition:border-color .15s}
.video-card:hover{border-color:var(--orange)}
.video-card-thumb{position:relative;aspect-ratio:16/9;background:#000}
.video-card-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.video-card-play{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-size:1.4rem;color:#fff;background:rgba(0,0,0,.15);opacity:0;transition:opacity .15s}
.video-card:hover .video-card-play{opacity:1}
.video-card-title{padding:.6rem .7rem .2rem;font-size:.8rem;font-weight:700;line-height:1.3}
.video-card-channel{padding:0 .7rem .6rem;font-size:.68rem;color:var(--muted)}
.aw-shot{position:relative;border-radius:8px;overflow:hidden;cursor:pointer}
.aw-shot img{width:100%;display:block;transition:transform .2s}
.aw-shot:hover img{transform:scale(1.04)}
/* Respect.popup() (js/respect.js, .respect-pop) по умолчанию всплывает НАД анкором (bottom:100%) —
   рассчитано на кнопку с запасом места сверху. Тут анкор — вся плашка .aw-shot (см. windows.js,
   round-5 фикс), а не маленькая кнопка лайка у самого низа превью с overflow:hidden: "+3 RESPECT"
   то не помещался по высоте до верхнего края превью, то обрезался им. Центр по центру изображения
   всегда внутри границ превью независимо от его размера в сетке. */
.aw-shot .respect-pop{bottom:auto;top:50%;margin-bottom:0;transform:translate(-50%,-50%)}
.aw-shot .respect-pop.show{transform:translate(-50%,-50%)}
/* Деп-линк из превью-виджета (левая колонка OFFICIAL) — короткая подсветка найденной карточки/плеера */
.aw-focus-pulse{animation:awFocusPulse 1.6s ease;border-radius:8px}
@keyframes awFocusPulse{0%,100%{box-shadow:none}25%,75%{box-shadow:0 0 0 3px var(--win-accent,var(--orange))}}

/* ===== SCREENSHOT LIGHTBOX (p2-9) ===== */
.lightbox{position:fixed;inset:0;z-index:1300;display:none;flex-direction:column;align-items:center;justify-content:center;
  gap:.9rem;background:rgba(5,2,20,.9)}
.lightbox.open{display:flex}
.lb-img{max-width:90vw;max-height:85vh;border-radius:8px;display:block;box-shadow:0 0 40px rgba(0,0,0,.6)}
.lb-close{position:absolute;top:1.1rem;right:1.3rem;background:none;border:1px solid var(--pink);color:var(--pink);
  border-radius:4px;font-size:1rem;padding:.3rem .6rem;cursor:pointer}
.lb-close:hover{background:rgba(255,46,136,.15)}
.lb-arrow{position:absolute;top:50%;transform:translateY(-50%);background:none;border:1px solid rgba(255,46,136,.5);
  color:var(--pink);font-size:1.5rem;line-height:1;width:2.4rem;height:2.4rem;border-radius:50%;cursor:pointer}
.lb-arrow:hover{background:rgba(255,46,136,.15)}
.lb-prev{left:1.3rem}
.lb-next{right:1.3rem}
.lb-caption{display:flex;align-items:center;gap:1rem;color:var(--sand);font-family:var(--mono);font-size:.8rem}
#lightboxTitle{font-size:1.15rem;font-weight:700;letter-spacing:.03em}
.lb-caption .fa-btn{font-size:.78rem;padding:.2rem .6rem}
.lb-map-btn{background:none;border:1px solid var(--teal);color:var(--teal);border-radius:4px;padding:.25rem .6rem;
  font-family:var(--mono);font-size:.68rem;letter-spacing:.08em;cursor:pointer}
.lb-map-btn:hover{background:rgba(36,224,208,.15);box-shadow:0 0 8px rgba(36,224,208,.4)}
.lb-wiki-btn{display:inline-block;background:none;border:1px solid var(--orange);color:var(--orange);
  border-radius:4px;padding:.25rem .6rem;font-family:var(--mono);font-size:.68rem;letter-spacing:.08em;
  cursor:pointer;text-decoration:none}
.lb-wiki-btn:hover{background:rgba(255,158,79,.15);box-shadow:0 0 8px rgba(255,158,79,.4)}
@media (max-width:900px){.lb-arrow{width:2rem;height:2rem;font-size:1.2rem}}

/* ===== COUNTDOWN OVERLAY (раскрытая версия .cd-widget, клик открывает) ===== */
.cd-overlay{
  --cdo-pink:#ff4d8d; --cdo-violet:#7b2ff7; --cdo-deep:#0a0520;
  --cdo-cyan:#39e6ff; --cdo-text:#fdeedd; --cdo-horizon:62%;
  --ra-c:255,46,136; /* дублирует акцент плеера (см. .radio-widget) — cdoViz не потомок виджета, свою переменную не унаследует */
  position:fixed;inset:0;z-index:1150;display:flex;align-items:center;justify-content:center;
  visibility:hidden;pointer-events:none;
  overflow:hidden;font-family:"Segoe UI",system-ui,sans-serif;color:var(--cdo-text);
  background:linear-gradient(180deg,#1c0640 0%,#5b1fd6 32%,#c93d9a 52%,#ff7a4d var(--cdo-horizon));
}
/* visibility, не display:none — display останавливает и СБРАСЫВАЕТ CSS-анимации (самолёт/вертолёт/яхта
   и фон катались заново с нуля при каждом открытии); visibility их не трогает — крутятся в реальном
   времени и с закрытым оверлеем, при открытии видно ровно то положение, в котором они сейчас были бы. */
.cd-overlay.open{visibility:visible;pointer-events:auto}
.cd-overlay::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:8;
  background:repeating-linear-gradient(0deg,rgba(0,0,0,.13) 0 1px,transparent 1px 3px)}
.cdo-close{position:absolute;top:1.1rem;right:1.3rem;z-index:9;background:none;border:1px solid var(--cdo-violet);
  color:var(--cdo-violet);border-radius:4px;font-size:1rem;padding:.3rem .6rem;cursor:pointer}
.cdo-close:hover{background:rgba(123,47,247,.2)}
.cdo-sun{position:absolute;left:50%;top:var(--cdo-horizon);transform:translate(-50%,-58%);
  width:min(56vmin,430px);height:min(56vmin,430px);border-radius:50%;
  background:radial-gradient(circle at 50% 35%,#ffedb8 0%,#ffb347 45%,#ff5e62 100%);
  filter:blur(1px);z-index:0;box-shadow:0 0 90px 30px rgba(255,140,80,.45);
  -webkit-mask-image:linear-gradient(0deg,#000 0 12px,transparent 12px 18px);
          mask-image:linear-gradient(0deg,#000 0 12px,transparent 12px 18px);
  -webkit-mask-size:100% 18px;mask-size:100% 18px;
  animation:cdoStripes 7s linear infinite}
@keyframes cdoStripes{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:0 18px;mask-position:0 18px}}
.cdo-horizon{position:absolute;left:0;right:0;top:var(--cdo-horizon);height:2px;z-index:3;
  background:linear-gradient(90deg,transparent 5%,var(--cdo-cyan) 35%,#fff 50%,var(--cdo-cyan) 65%,transparent 95%);
  box-shadow:0 0 16px var(--cdo-cyan),0 0 44px rgba(57,230,255,.55)}
.cdo-sea{position:absolute;left:0;right:0;top:var(--cdo-horizon);bottom:0;z-index:2;
  background:linear-gradient(180deg,#241052 0%,#140a34 45%,var(--cdo-deep) 100%);
  overflow:hidden;perspective:280px;perspective-origin:50% 0%}
.cdo-sea .cdo-glow{position:absolute;left:50%;top:0;transform:translateX(-50%);
  width:min(120vmin,900px);height:60%;
  background:radial-gradient(ellipse 50% 100% at 50% 0%,rgba(255,130,90,.4) 0%,rgba(255,77,141,.18) 40%,transparent 72%);
  filter:blur(6px);animation:cdoShimmer 5s ease-in-out infinite}
@keyframes cdoShimmer{0%,100%{opacity:.65}50%{opacity:1}}
.cdo-sea .cdo-waves{position:absolute;left:-50%;top:-2%;width:200%;height:320%;
  background:repeating-linear-gradient(0deg,rgba(57,230,255,.2) 0 1.5px,transparent 1.5px 42px);
  transform:rotateX(56deg);transform-origin:50% 0%;animation:cdoWaves 8s linear infinite;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 12%);
          mask-image:linear-gradient(180deg,transparent 0,#000 12%)}
.cdo-sea .cdo-waves.back{background:repeating-linear-gradient(0deg,rgba(123,47,247,.14) 0 1px,transparent 1px 26px);
  animation-duration:13s}
@keyframes cdoWaves{from{background-position:0 0}to{background-position:0 42px}}
/* Дальние силуэты — редкие пролёты, большую часть цикла спрайт стоит за кадром.
   --cdo-off-l/-r — общая точка парковки (своя ширина+запас слева / 110vw справа), одна на все
   3 keyframes ниже, чтобы off-screen позиция не могла разъехаться между самолётом/вертолётом/яхтой.
   fill-mode:backwards обязателен у всех, кто использует animation-delay — иначе элемент на время
   задержки сидит на неанимированной позиции (left:0, в кадре), а не на позиции из 0%-кадра. */
.cdo-plane,.cdo-heli,.cdo-yacht{position:absolute;left:0;width:26px;height:auto;z-index:2;
  fill:rgba(18,8,46,.55);pointer-events:none;
  --cdo-off-l:calc(-100% - 20px);--cdo-off-r:110vw}
.cdo-plane{top:calc(var(--cdo-horizon) - 14%);width:23.2px;animation:cdoFlyPlane 72s linear infinite}
/* Второй самолёт — высокий пролёт, обязательно НИЖЕ рамки "Leonida Interactive" (её нижний край
   ~210px при любой ширине экрана — упирается в clamp-потолок font-size у h1), top в px, не в %. */
.cdo-plane-high{top:230px;width:19px;animation:cdoFlyPlane 99s linear infinite backwards;animation-delay:40s}
/* -4% (не -15%) — вертолёт всегда заметно ниже нижнего самолёта (-14%), без риска пересечься. */
.cdo-heli{top:calc(var(--cdo-horizon) - 4%);width:22.5px;animation:cdoFlyHeli 81s linear infinite backwards;animation-delay:20s}
.cdo-yacht{top:calc(var(--cdo-horizon) - 9.5px);width:15px;animation:cdoSailYacht 135s linear infinite backwards;animation-delay:60s}
/* animation-play-state ОБЯЗАН стоять после правил выше — шорткод "animation:" в них неявно сбрасывает
   play-state обратно в running, более ранняя запись paused просто затиралась бы. До первого открытия
   оверлея спрайты стоят на месте, иначе за секунды до первого клика самолёт уже успевает куда-то улететь.
   .cdo-started ставит JS при первом openCdOverlay() (timer.js) и больше не убирает — дальше спрайты
   крутятся всегда, даже с закрытым оверлеем (см. visibility на .cd-overlay). */
.cdo-plane,.cdo-heli,.cdo-yacht{animation-play-state:paused}
.cd-overlay.cdo-started .cdo-plane,.cd-overlay.cdo-started .cdo-heli,.cd-overlay.cdo-started .cdo-yacht{animation-play-state:running}
/* Периоды укорочены ×0.9 (частота пролётов +11%), доля кадров под сам пролёт увеличена ровно на
   обратный коэффициент (×1/0.9) — время самого пролёта (скорость) не меняется, экономия только
   из паузы. Delay 0/20/40/60s разносит старт видимости по всем 4 спрайтам, чтобы не совпадали
   в одном окне и не давали подряд долгих пустых пауз (жалоба: "секунд по 20 ничего не появлялось"). */
@keyframes cdoFlyPlane{
  0%{transform:translate(var(--cdo-off-l),0)}
  30%{transform:translate(var(--cdo-off-r),0)}
  100%{transform:translate(var(--cdo-off-r),0)}
}
@keyframes cdoFlyHeli{
  0%{transform:translate(var(--cdo-off-r),0)}
  36.7%{transform:translate(var(--cdo-off-l),0)}
  100%{transform:translate(var(--cdo-off-l),0)}
}
@keyframes cdoSailYacht{
  0%{transform:translate(var(--cdo-off-l),0)}
  33.3%{transform:translate(var(--cdo-off-r),0)}
  100%{transform:translate(var(--cdo-off-r),0)}
}
@media (prefers-reduced-motion:reduce){.cdo-plane,.cdo-heli,.cdo-yacht{display:none}}
.cdo-wrap{position:absolute;top:2.2rem;left:50%;transform:translateX(-50%);z-index:5;text-align:center;padding:0 24px}
.cdo-frame{display:inline-block;padding:clamp(18px,4vw,32px) clamp(26px,6vw,58px);
  border:2px solid var(--cdo-cyan);border-radius:6px;position:relative;
  background:rgba(10,5,32,.4);backdrop-filter:blur(3px);
  box-shadow:0 0 12px rgba(57,230,255,.55),inset 0 0 24px rgba(57,230,255,.12),0 0 60px rgba(123,47,247,.35);
  animation:cdoFrameglow 3.5s ease-in-out infinite}
@keyframes cdoFrameglow{
  0%,100%{box-shadow:0 0 12px rgba(57,230,255,.55),inset 0 0 24px rgba(57,230,255,.12),0 0 60px rgba(123,47,247,.35)}
  50%{box-shadow:0 0 22px rgba(57,230,255,.85),inset 0 0 30px rgba(57,230,255,.2),0 0 80px rgba(255,77,141,.45)}
}
.cdo-frame::before,.cdo-frame::after{content:"";position:absolute;width:16px;height:16px;border:2px solid var(--cdo-pink)}
.cdo-frame::before{top:-2px;left:-2px;border-right:0;border-bottom:0}
.cdo-frame::after{bottom:-2px;right:-2px;border-left:0;border-top:0}
.cdo-frame h1{font-size:clamp(2rem,7vw,4.3rem);font-weight:800;letter-spacing:.06em;text-transform:uppercase;line-height:1.05;
  background:linear-gradient(90deg,var(--cdo-cyan),#fff 45%,var(--cdo-pink));
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 0 18px rgba(57,230,255,.4))}
.cdo-frame h1 span{display:block;font-size:.42em;letter-spacing:.5em;margin-top:4px;
  -webkit-text-fill-color:var(--cdo-text);color:var(--cdo-text);text-shadow:0 0 18px rgba(255,77,141,.7)}
.cdo-foot{position:absolute;left:0;right:0;bottom:16px;z-index:6;text-align:center;padding:0 16px}
.cdo-player-slot{display:flex;justify-content:center;margin-bottom:10px}
.cdo-player-slot .radio-widget{width:100%;max-width:280px}
.cdo-player-slot .radio-widget[data-state="playing"] .radio-chill{display:none}
/* Высота кубов задаётся напрямую из JS (radio.js, реальный спектр через AnalyserNode) — transition только сглаживает кадры */
.cd-overlay[data-station="leonida-talk"]{--ra-c:255,158,79}
.cdo-viz{display:flex;gap:3px;justify-content:center;align-items:flex-end;height:24px;margin-bottom:10px}
.cdo-viz span{width:5px;height:3px;border-radius:1px;background:rgb(var(--ra-c));box-shadow:0 0 4px rgba(var(--ra-c),.6);transition:height .06s linear}
@media (prefers-reduced-motion:reduce){.cdo-sun,.cdo-frame,.cdo-sea .cdo-waves,.cdo-sea .cdo-glow{animation:none}}

/* ===== SECRET DOCK CELL ===== */
.feed-head-secret{background:rgba(122,29,94,.35);color:#d98fff}
/* STREAMS (data/streams.js): плитка канала Twitch в доке и сетка «ещё стримы» в окне плеера */
.feed-head-streams{background:rgba(169,112,255,.16);color:#a970ff}
.streams-body{flex:1;min-height:0;padding:.5rem .6rem;display:flex}
.stream-tile{position:relative;display:block;width:100%;min-height:0;border:1px solid rgba(169,112,255,.45);border-radius:8px;
  overflow:hidden;background:#120a2a;cursor:pointer;padding:0;color:inherit;text-align:left;aspect-ratio:16/9}
.stream-tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.stream-tile:hover{box-shadow:inset 0 0 0 2px rgba(169,112,255,.8)}
.stream-live{position:absolute;top:.4rem;left:.4rem;font-family:var(--mono);font-size:.58rem;letter-spacing:.1em;
  padding:.12rem .4rem;border-radius:3px;background:#a970ff;color:#120a2a;font-weight:700}
.stream-cap{position:absolute;left:0;right:0;bottom:0;padding:.35rem .5rem;font-size:.72rem;line-height:1.2;
  background:linear-gradient(transparent,rgba(11,6,32,.92));color:#fff}
.stream-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:.6rem}
/* position:relative на всей секции (не только .secret-cell) — оверлей ниже должен закрывать
   ВСЮ плашку целиком, включая заголовок "SECRET", не только тело под ним. */
.dock-secret,.dock-streams{position:relative} /* оверлей COMING SOON на всю ячейку (STREAMS — пока Twitch на паузе) */
.secret-cell{flex:1;min-height:0}
/* Полный оверлей всей панели (по запросу — раньше был маленький блок с отступами внутри),
   светло-серая заливка поверх тёмной панели дока — читается как "заблокировано/недоступно",
   а не просто пустая тёмно-фиолетовая ячейка с текстом внутри. */
.secret-soon{position:absolute;inset:0;z-index:1;display:flex;align-items:center;justify-content:center;
  background:rgba(205,205,212,.2)}

/* ===== RESPECT в Community (фокус) ===== */
.cc-respect{text-align:center;padding:.6rem .4rem .55rem;margin-bottom:.2rem;
  border:1px solid rgba(255,46,136,.35);border-radius:8px;
  background:linear-gradient(135deg,rgba(43,15,77,.9),rgba(122,29,94,.7))}
.ccr-label-row{display:flex;align-items:center;justify-content:center;gap:.4rem}
.ccr-label{font-family:var(--display);letter-spacing:.34em;font-size:.8rem;color:var(--pink);
  text-shadow:0 0 10px rgba(255,46,136,.6);position:relative;top:2px}
.ccr-num{font-family:var(--mono);font-size:2rem;font-weight:700;line-height:1.1;color:#fff;
  text-shadow:0 0 12px rgba(255,46,136,.8),0 0 30px rgba(255,46,136,.4)}
.ccr-level-bar{width:80%;max-width:160px;height:5px;margin:.5rem auto 0;border-radius:3px;
  background:rgba(255,46,136,.15);overflow:hidden}
.ccr-level-fill{height:100%;width:0%;background:linear-gradient(90deg,var(--orange),var(--pink));
  box-shadow:0 0 8px rgba(255,46,136,.6);transition:width .3s}
.ccr-level-label{font-family:var(--mono);font-size:.6rem;letter-spacing:.14em;color:var(--muted);margin-top:.25rem}
/* «ТЕКУЩИЙ РАНГ · НАБЛЮДАТЕЛЬ» — своё звание под полосой (16-08(8)). Раньше тут стояла цель
   («→ RUNNER · 25 RP») и читалась как своё звание. Подпись и название приходят переведёнными из
   словаря пульта (см. respect.js). Крупнее подписи уровня: это имя игрока, а не служебная строка. */
/* Подпись «текущий ранг» — обычным весом, жирным только само звание (16-08(9)). */
.ccr-rank{font-family:var(--mono);font-size:.66rem;letter-spacing:.08em;color:var(--orange);
  margin-top:.2rem;font-weight:400;text-transform:uppercase}
.ccr-rank b{font-weight:700}
.ccr-rank[hidden]{display:none}
.ccr-login-note{font-family:var(--mono);font-size:.6rem;color:var(--muted);margin-top:.3rem;opacity:.85}

/* ===== Fullscreen поверх карты ===== */
.map-fs{position:absolute;top:.6rem;right:.6rem;z-index:1001;width:34px;height:34px;
  border-radius:8px;border:1px solid var(--orange);cursor:pointer;font-size:1rem;
  background:rgba(11,6,32,.75);backdrop-filter:blur(6px);color:var(--orange)}
.map-fs:hover{box-shadow:0 0 14px rgba(255,158,79,.5)}
/* Подпись DAY/NIGHT слева от ⛶ (24-08). Днём оранжевая, ночью фиолетовая заодно со всей ночной
   темой кадра (25-08, владелец) — цвет сам по себе говорит, в каком ты режиме. Правый отступ —
   .6rem кнопки + её 34px + зазор. */
.map-daynight{position:absolute;top:.6rem;right:calc(.6rem + 34px + .35rem);z-index:1001;
  display:flex;align-items:center;height:34px;padding:0 .55rem;border-radius:8px;
  font-family:var(--mono);font-size:.62rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--orange);background:rgba(11,6,32,.75);backdrop-filter:blur(6px);
  border:1px solid rgba(255,158,79,.5);pointer-events:none}
.map-daynight [hidden]{display:none}

/* ===== AI-слой сравнения — шторка-ручка + плашка маркировки (PROMPT_map_ai_realistic_layer_v2.md §6-7) ===== */
.ai-compare-handle{position:absolute;top:0;bottom:0;width:3px;z-index:2010;
  background:var(--orange);box-shadow:0 0 10px rgba(255,158,79,.7);cursor:ew-resize;
  transform:translateX(-50%);touch-action:none}
.ai-compare-handle[hidden]{display:none}
.ai-compare-handle::after{content:"⇔";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:32px;height:32px;line-height:30px;text-align:center;border-radius:50%;
  background:rgba(11,6,32,.85);border:2px solid var(--orange);color:var(--orange);
  box-shadow:0 0 10px rgba(255,158,79,.6);font-size:.9rem}
.map-ui-btn:disabled{opacity:.4;cursor:not-allowed}
/* Левый низ, прямо над кредитами (по запросу — раньше висел по центру верхней полосы кадра).
   Оба бокса — служебные подписи про происхождение картинки, стоять им логично рядом; заодно
   верхняя полоса кадра освободилась целиком. Живут в общем столбце .map-credits-stack, а не
   каждый со своим absolute: высота атрибуции гуляет от языка, и подпирать бэйдж вручную
   посчитанным отступом пришлось бы заново после каждой правки текста. */
.ai-compare-badge{background:rgba(11,6,32,.78);backdrop-filter:blur(6px);
  border:1px solid rgba(255,158,79,.6);border-radius:6px;padding:.3rem .5rem;
  font-family:var(--mono);font-size:.55rem;line-height:1.4;color:rgba(245,236,215,.85)}
.ai-compare-badge[hidden]{display:none}
/* ===== Ночная тема UI карты: акценты рамки переключаются с оранжевого на фиолетовый, весь кадр
   "переходит в ночь". Раньше та же тема висела на Realistic-слое (.ai-ui) — получался рассинхрон:
   днём в Realistic всё фиолетовое, ночью на обычном слое всё оранжевое, хотя фиолетовый читается
   именно как ночь. Класс .night-ui вешает/снимает js/night-mode.js на .map-frame. ===== */
.map-frame.night-ui .map-panel{border-color:rgba(177,140,255,.45)}
/* Свёрнутый язычок и ночью держит полную яркость обода и свою подсветку — см. .map-panel.collapsed */
.map-frame.night-ui .map-panel.collapsed{border-color:#b18cff;box-shadow:0 0 16px rgba(177,140,255,.7)}
.map-frame.night-ui .map-panel h3,
.map-frame.night-ui .panel-caption,
.map-frame.night-ui .hero-explored{color:#b18cff}
/* Секции ночью цвета НЕ теряют (08-09(5)) — прежнее фиолетовое правило на .panel-sect снято */
.map-frame.night-ui .map-ui-btn{border-color:rgba(177,140,255,.4)}
.map-frame.night-ui .map-ui-btn:hover{border-color:#b18cff}
.map-frame.night-ui .map-ui-btn.active{background:rgba(177,140,255,.22);border-color:#b18cff;color:#b18cff}
.map-frame.night-ui .ai-seg:has(.ai-seg-btn:last-child.active) .ai-seg-btn:first-child{border-right-color:#b18cff}
.map-frame.night-ui .leaflet-control-zoom a{color:#b18cff!important;border-color:rgba(177,140,255,.5)!important}
.map-frame.night-ui .leaflet-control-layers{border-color:rgba(177,140,255,.5)!important}
.map-frame.night-ui .map-recenter{border-color:rgba(177,140,255,.5)}
.map-frame.night-ui .leaflet-control-scale-line{border-color:#b18cff!important}
.map-frame.night-ui .map-attribution{border-color:rgba(177,140,255,.5)}
.map-frame.night-ui .ai-compare-badge{border-color:rgba(177,140,255,.6)}
.map-frame.night-ui .hero-explored-bar{background:rgba(177,140,255,.15);border-color:rgba(177,140,255,.5)}
.map-frame.night-ui .hero-explored-bar-fill{background:linear-gradient(90deg,#b18cff,var(--pink))}
/* Добор раунда 08-08(4) («точно посмотри, чтобы цвета панелей соответствовали ночному режиму»):
   в ночи оставались оранжевыми стрелка-вкладка, кнопка OPEN COLLECTION и галочки Show cards /
   Fog of war — три элемента панели против фиолетовой рамки вокруг них. */
/* 08-09(6): и в свёрнутом язычке тоже — раньше :not(.collapsed) оставлял треугольник оранжевым
   на фиолетовом язычке. */
.map-frame.night-ui .panel-collapse{color:#b18cff}
.map-frame.night-ui .panel-collect{color:#b18cff;background:rgba(177,140,255,.1);border-color:rgba(177,140,255,.5);
  box-shadow:0 0 7px rgba(177,140,255,.35)}
.map-frame.night-ui .panel-collect:hover{color:var(--sand);background:rgba(177,140,255,.2);border-color:#b18cff}
.map-frame.night-ui .fog-row input{accent-color:#b18cff}
/* Раунд-11 "не все элементы меняются": добор — fullscreen-кнопка, разделители, note, ручка
   шторки и SVG-иконки контролов (слои/прицел — data-uri перекрашены в фиолетовый) */
.map-frame.night-ui .map-fs,
.map-frame.night-ui .map-daynight{border-color:rgba(177,140,255,.6);color:#b18cff}
/* .panel-note удалён в 08-09(4) вместе с разметкой — строка живёт в .map-attribution-note */
.map-frame.night-ui .map-credits-stack .map-ui-btn{border-color:rgba(177,140,255,.55);background:rgba(177,140,255,.08)}
.map-frame.night-ui .ai-compare-handle{background:#b18cff;box-shadow:0 0 10px rgba(177,140,255,.7)}
.map-frame.night-ui .drive-hud{border-color:rgba(177,140,255,.6)}
.map-frame.night-ui .ds-arc-fill{stroke:url(#dsGradNight);filter:drop-shadow(0 0 4px rgba(177,140,255,.6))}
.map-frame.night-ui .ds-ticks line{stroke:rgba(177,140,255,.35)}
.map-frame.night-ui .ds-ticks line.major{stroke:rgba(177,140,255,.75)}
.map-frame.night-ui .ds-needle{filter:drop-shadow(0 0 3px rgba(177,140,255,.8))}
.map-frame.night-ui .leaflet-control-layers-toggle{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><polygon points="12,3 21,8.5 12,14 3,8.5" fill="none" stroke="%23b18cff" stroke-width="1.7"/><polygon points="12,10.5 21,16 12,21.5 3,16" fill="none" stroke="%23b18cff" stroke-width="1.7" opacity="0.55"/></svg>')!important}
.map-frame.night-ui .map-recenter{background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="7" fill="none" stroke="%23b18cff" stroke-width="1.8"/><line x1="12" y1="0.5" x2="12" y2="5" stroke="%23b18cff" stroke-width="1.8"/><line x1="12" y1="19" x2="12" y2="23.5" stroke="%23b18cff" stroke-width="1.8"/><line x1="0.5" y1="12" x2="5" y2="12" stroke="%23b18cff" stroke-width="1.8"/><line x1="19" y1="12" x2="23.5" y2="12" stroke="%23b18cff" stroke-width="1.8"/><circle cx="12" cy="12" r="1.8" fill="%23b18cff"/></svg>')}

/* ===== Режим езды — туман, машинка, приборная панель (PROMPT_map_drive_mode_step1.md) ===== */
/* Canvas растянут на весь .map-frame через паны Leaflet — сам не позиционируется, живёт внутри
   .leaflet-fog-pane (position:absolute;inset:0 уже задаёт Leaflet своим панам). filter:blur —
   дешёвый мягкий край без пересчёта градиента по ячейке (см. комментарий в drive-mode.js).
   3px->8px по фидбэку "мягкая кромка шире" — читается как свет, не штамп. */
.drive-fog-canvas{position:absolute;top:0;left:0;filter:blur(8px)}
/* Без transition: угол уже лерпится в JS каждый кадр (drive-mode.js spriteLerp) — CSS-transition
   поверх уже сглаженного значения даёт двойное запаздывание ("едем через кисель"), убрано. */
.drive-car-rot{position:relative;width:13px;height:21px;transform-origin:50% 50%}
/* Режим катера: на воде показывается второй силуэт из той же иконки (drive-mode.js iconHtml),
   класс on-water ставит updateCarMarker по маске поверхностей. Кильватерный след — расходящееся
   кольцо под корпусом, только на воде: без него смена силуэта на общем плане почти незаметна. */
.drive-car-rot .dc-boat{display:none}
.drive-car-rot.on-water .dc-car{display:none}
.drive-car-rot.on-water .dc-boat{display:block}
.drive-car-rot.on-water::after{content:'';position:absolute;left:50%;top:50%;width:22px;height:22px;
  margin:-11px 0 0 -11px;border-radius:50%;border:1px solid rgba(255,255,255,.45);
  animation:boatWake 1.4s ease-out infinite;pointer-events:none}
@keyframes boatWake{
  0%{transform:scale(.35);opacity:.55}
  100%{transform:scale(1);opacity:0}
}
@media (prefers-reduced-motion:reduce){.drive-car-rot.on-water::after{animation:none;opacity:.3}}
/* Режим самолёта (бонус, 15 сек): третий силуэт из той же иконки. Тень под корпусом — весь
   намёк на высоту: масштабом играть нельзя, transform у .drive-car-rot занят поворотом из JS. */
.drive-car-rot .dc-plane{display:none}
.drive-car-rot.flying .dc-car,.drive-car-rot.flying .dc-boat{display:none}
/* Самолёт крупнее машинки (21x33 против 13x21) — иконка та же, поэтому центрируем его поверх
   бокса, а не растим сам бокс: иначе поворот пошёл бы вокруг сдвинутой точки. */
.drive-car-rot.flying .dc-plane{display:block;position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%)}
.drive-car-rot.flying{filter:drop-shadow(0 7px 5px rgba(0,0,0,.6))}
/* Полоска ударов до ареста — НАД машинкой (js/police.js renderHp). Сегментов = police.hitsToBust,
   строит их police.js. Сестра .drive-car-rot, а не потомок: её нельзя вращать вместе с корпусом.
   Висит только на удар (класс on снимается через HP_SHOW_MS) — постоянный индикатор над капотом
   был бы мусором в кадре ровно там, куда игрок смотрит всё время. */
/* Счётчик секунд полёта — под машинкой, пишет drive-mode.js. Пустая строка = не летим, и тогда
   :empty убирает плашку целиком — иначе под машинкой висел бы пустой прямоугольник.
   Голым текстом .5rem («подпись с секундами не видна») он тонул в тайлах карты: у него нет своего
   фона, а летим мы как раз над пёстрым городом. Теперь это плашка тех же цветов, что бонус. */
/* Плашка «SECURED +N RP» — та же оранжевая табличка, но НАД машинкой (16-08(6) «SECURED лучше
   показывать оранжевой плашкой над машиной»): фиксация происходит у дома на карте, туда и смотрит
   игрок, а угловой тост в этот момент вне поля зрения. Выше полоски ударов (top:-14px), чтобы
   зафиксироваться прямо под сиреной было видно оба. Текст пишет drive-mode.js carNote(). */
.drive-car-timer,.drive-car-note{position:absolute;left:50%;transform:translateX(-50%);
  font-family:var(--mono);font-size:.62rem;font-weight:700;font-style:normal;letter-spacing:.08em;
  color:#0b0620;background:var(--orange);border-radius:6px;padding:2px 6px;
  box-shadow:0 2px 6px rgba(11,6,32,.75);white-space:nowrap;pointer-events:none}
.drive-car-timer{top:30px}
.drive-car-note{top:-32px;animation:driveNote .3s ease-out}
@keyframes driveNote{from{opacity:0;transform:translate(-50%,6px)}}
.drive-car-timer:empty,.drive-car-note:empty{display:none}
@media (prefers-reduced-motion:reduce){.drive-car-note{animation:none}}
/* Бонус-самолёт на карте (drive-mode.js spawnBonus) — одна точка за раз, пульсирует, чтобы её
   было видно за полкадра; наезд включает полёт. 26 -> 32px вместе со спрайтом полёта. */
.drive-bonus{width:32px;height:32px;display:grid;place-items:center;
  border-radius:50%;border:2px solid var(--orange);background:var(--orange);
  color:#0b0620;font-size:18px;line-height:1;animation:driveBonus 1.1s ease-in-out infinite}
@keyframes driveBonus{50%{box-shadow:0 0 14px rgba(255,158,79,.75);transform:scale(1.12)}}
@media (prefers-reduced-motion:reduce){.drive-bonus{animation:none}}
/* Сейф-хаус (16-08(4), drive-mode.js updateHouses) — 34 точки на карте, наезд фиксирует
   заработанное за заезд. В спокойном состоянии приглушённый значок: он не приз и не сюрприз,
   он всегда там. Класс .armed вешает JS, когда есть что фиксировать — тогда дом «зажигается»
   бирюзовым (свой цвет: оранжевый уже у самолёта, красный у полиции, розовый у карточек) и
   начинает дышать. Ни одной подписи: 34 подписи на карте — это шум, а форма дома читается сама. */
/* 26px — ровно как .police-outpost («сделай такими же, как полицейские участки», 16-08(9)).
   Множитель --house-scale, ужимавший значок на отдалении, убран: «вся карта из домов» на общем
   плане теперь не случается потому, что неразведанные дома скрыты туманом. */
.drive-safehouse{width:26px;height:26px;color:rgba(36,224,208,.55);
  filter:drop-shadow(0 1px 3px rgba(11,6,32,.9));transition:color .25s}
.drive-safehouse.armed{color:var(--teal);animation:driveHouse 1.4s ease-in-out infinite}
@keyframes driveHouse{50%{filter:drop-shadow(0 0 9px rgba(36,224,208,.85));transform:scale(1.14)}}
@media (prefers-reduced-motion:reduce){.drive-safehouse.armed{animation:none}}
.map-frame.night-ui .drive-safehouse{color:rgba(177,140,255,.55)}
.map-frame.night-ui .drive-safehouse.armed{color:#b18cff}
.drive-car-hp{position:absolute;left:50%;top:-14px;transform:translateX(-50%);display:flex;gap:3px;
  opacity:0;transition:opacity .2s;pointer-events:none}
.drive-car-hp.on{opacity:1}
.drive-car-hp b{width:13px;height:5px;border-radius:2px;background:#ff2e2e;
  box-shadow:0 0 5px rgba(0,0,0,.85);transition:background-color .2s}
.drive-car-hp b.spent{background:rgba(120,110,140,.75)}
/* Остался один сегмент — он мигает: последний шанс не должен выглядеть так же, как первый. */
.drive-car-hp.dch-last b:not(.spent){animation:dchLast .55s ease-in-out infinite}
@keyframes dchLast{50%{background:#fff;box-shadow:0 0 8px #ff2e2e}}
@media (prefers-reduced-motion:reduce){.drive-car-hp.dch-last b:not(.spent){animation:none}}
.drive-trail-dot{position:absolute;top:0;left:0;width:6px;height:6px;margin:-3px 0 0 -3px;
  border-radius:50%;background:var(--pink);box-shadow:0 0 6px rgba(255,46,136,.7);pointer-events:none}
/* Приборная панель низа кадра — один бокс на радар и спидометр ("на единую панель со спидометром
   слева от него"). Раньше это были две отдельные плашки со своими рамками, стоявшие рядом.
   Плашка explored из этого угла уехала в окно COLLECTION — это статистика, а не прибор. */
.drive-hud{position:absolute;left:50%;bottom:.6rem;transform:translateX(-50%);z-index:1300;
  display:flex;align-items:center;gap:.7rem;
  background:rgba(11,6,32,.78);backdrop-filter:blur(6px);
  border:1px solid rgba(255,46,136,.6);border-radius:14px;padding:.4rem .8rem .3rem;
  font-family:var(--mono);color:var(--sand)}
.drive-hud[hidden]{display:none}
/* Спидометр — радиальный полукруг (2x прежнего размера по фидбэку); рамку и фон теперь несёт
   общая панель, здесь остались только размер и центровка цифры. */
/* position:relative — якорь для плашки уведомлений заезда: пока приборка на экране, js/respect.js
   переселяет её сюда и она встаёт ровно над спидометром (16-08(7)). */
.drive-speedo{width:168px;text-align:center;position:relative}
.ds-gauge{display:block;width:100%}
.ds-arc-bg{fill:none;stroke:rgba(169,159,196,.25);stroke-width:7;stroke-linecap:round}
/* Длина дуги PI*42 ~ 131.9 — dashoffset выставляет JS (drive-mode.js) по доле vMax */
.ds-arc-fill{fill:none;stroke:url(#dsGrad);stroke-width:7;stroke-linecap:round;
  stroke-dasharray:131.9;stroke-dashoffset:131.9;filter:drop-shadow(0 0 4px rgba(255,46,136,.6))}
/* Риски шкалы (раунд-11) — тонкие деления по полукругу, major (0/100/200) ярче и толще */
.ds-ticks line{stroke:rgba(245,236,215,.3);stroke-width:1;stroke-linecap:round}
.ds-ticks line.major{stroke:rgba(245,236,215,.65);stroke-width:1.8}
/* Стрелка-сегмент внешнего обода (раунд-10) — чуть толще, читается как метка на шкале */
.ds-needle{stroke:#fff;stroke-width:3;stroke-linecap:round;
  filter:drop-shadow(0 0 3px rgba(255,46,136,.8))}
/* Цифра — в свободном центре полукруга, стрелка туда физически не заходит */
.ds-readout{margin-top:-2.6rem;padding-bottom:.5rem}
.ds-value{font-size:1.7rem;font-weight:700;letter-spacing:.04em;line-height:1}
.ds-unit{font-size:.62rem;margin-left:.3rem;color:var(--muted);text-transform:uppercase}
/* ===== Радар-сонар (js/radar.js) — левый прибор той же панели, что спидометр =====
   Разметка на месте всегда, показывает/прячет JS. Развертка крутится постоянно (дежурный ход),
   пинг-кольца добавляются по одному на каждый пинг и снимают себя сами по animationend.
   58 -> 76 -> 92px ("чуть крупнее"). Свой тонкий обод остался: это отдельный циферблат
   внутри общей панели, как радар и спидометр на одной приборке. */
/* --rd-heat (0 на границе радиуса, 1 вплотную) ставит radar.js на каждом скане: циферблат
   наливается оранжевым по мере приближения к цели. Это по-прежнему «холодно/горячо», направления
   в нём нет. */
.drive-radar{position:relative;flex:none;
  width:92px;height:92px;padding:8px;box-sizing:border-box;
  border:1px solid rgba(169,159,196,.35);border-radius:50%;
  background:rgba(255,158,79,calc(var(--rd-heat,0) * .3));
  transition:box-shadow .3s,border-color .3s,background-color .3s}
.drive-radar[hidden]{display:none}
/* RESET — третий элемент приборки, появляется только когда машина застряла в воде (см.
   drive-mode.js, триггер по времени). Не переводится, как DRIVE/STOP. Пульс — «спасательный
   круг», кнопка обязана быть заметнее обычных контролов: игрок в этот момент раздражён. */
/* Кнопка стоит НАД приборкой, а не в её ряду («должна появляться над общим интерфейсом, над
   спидометром, а не внутри него»): внутри она раздвигала панель в момент, когда игрок и так
   растерян, и читалась как ещё один прибор. bottom:100% от .drive-hud — приборка уже
   position:absolute, отдельная привязка к кадру не нужна и не разъедется с её высотой. */
.drive-reset{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:.4rem;
  padding:.35rem .6rem;cursor:pointer;
  font-family:var(--mono);font-size:.68rem;font-weight:700;letter-spacing:.08em;
  color:var(--orange);background:rgba(255,158,79,.12);
  border:1px solid var(--orange);border-radius:8px;
  animation:collectGlow 1.2s ease-in-out infinite;--ac:255,158,79}
.drive-reset:hover{color:#0b0620;background:var(--orange)}
.drive-reset[hidden]{display:none}
.map-frame.night-ui .drive-reset{--ac:177,140,255;color:#b18cff;border-color:#b18cff;
  background:rgba(177,140,255,.12)}
.map-frame.night-ui .drive-reset:hover{color:#0b0620;background:#b18cff}
/* Есть кто-то в радиусе — обод чуть теплее. Ни направления, ни числа: только «слышно/тихо». */
.drive-radar.rd-hot{border-color:rgba(255,158,79,.85);box-shadow:0 0 14px rgba(255,158,79,.4)}
/* Погоня перебивает нагрев: пока висит WANTED, приборка красная (radar.js слушает
   leonida:policechange). Специфичность .drive-radar.rd-chase выше базового правила —
   !important не нужен. Лёгкое приглушение осталось: главное в кадре сейчас копы, не поиск. */
.drive-radar.rd-chase{opacity:.8;border-color:rgba(255,46,46,.9);
  background:rgba(255,46,46,.22);box-shadow:0 0 16px rgba(255,46,46,.45)}

/* ===== ПОЛИЦИЯ (js/police.js) =====
   Юр. рамка всей секции: ничего от Rockstar. Никакого Pricedown, никаких узнаваемых силуэтов
   машин серии, никаких шестиконечных звёзд — WANTED это слово плюс обычные пятиконечные ★
   шрифтом пульта, коп — тот же абстрактный силуэт сверху, что машинка игрока. */
/* WANTED — четвёртый прибор той же панели, что спидометр/радар/RESET, и висит там ВЕСЬ заезд
   (раньше появлялся только с первой звездой — до неё игрок не знал ни про розыск, ни про длину
   шкалы). Спокойное состояние .dw-calm — погашенные ★ и серая рамка; красный включается вместе
   с первой звездой и ровно поэтому читается как «опасность» без единой подписи.
   Кегль поднят («покрупнее»): это второй по важности прибор после спидометра. */
/* Колонка розыска: счётчик заработанного за заезд, под ним сама плашка. Плашка от этого стоит
   чуть ниже соседних приборов — так и просили. */
/* gap 4 -> 9px («чуть подними эту строчку, чтобы был отступ от WANTED»): счётчик и плашка —
   два разных прибора, а не двухстрочная надпись. */
.drive-wanted-col{flex:none;display:flex;flex-direction:column;align-items:center;gap:9px}
/* Заработано за заезд (js/drive-mode.js). Именно эту сумму забирает арест, поэтому она крупная
   и первая, а общий баланс — мелкой серой цифрой рядом. Рост подсвечивается розовым, списание —
   красным: увидеть, как копы забирают заработанное, и есть весь смысл счётчика. */
/* Кегль подписи поднят с .5rem («RUN сделать крупнее, как и цифру»). .72rem, а не как у WANTED
   (.9rem): подпись всё равно длиннее соседской, и в один кегль с ней перетянула бы на себя всю
   колонку. Заработанное остаётся самым крупным элементом строки.
   Кнопкой фиксации счётчик побыл ровно один заход (16-08(4)) — фиксация уехала на карту,
   в сейф-хаусы, и это снова просто подпись. */
.drive-respect{font-family:var(--mono);font-size:.72rem;font-weight:700;letter-spacing:.14em;
  color:var(--muted);line-height:1;display:flex;align-items:baseline;gap:.3rem}
.drive-respect b{font-size:.95rem;color:var(--pink)}
.drive-respect b.dsr-up{animation:dsrUp .5s ease-out}
.drive-respect b.dsr-down{animation:dsrDown .6s ease-out}
@keyframes dsrUp{0%{color:#fff;text-shadow:0 0 10px var(--pink)}}
@keyframes dsrDown{0%,60%{color:#ff2e2e;text-shadow:0 0 10px #ff2e2e}}
@media (prefers-reduced-motion:reduce){.drive-respect b.dsr-up,.drive-respect b.dsr-down{animation:none}}
.drive-wanted{flex:none;display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:.35rem .7rem;border:1px solid rgba(255,46,46,.7);border-radius:8px;
  background:rgba(255,46,46,.1);transition:border-color .4s,background-color .4s}
.drive-wanted[hidden]{display:none}
/* .72 -> .9rem и звёзды 1.5 -> 1.75rem («WANTED можно крупнее»): плашка снова растёт, потому что
   на неё смотрят в самый нервный момент заезда, когда цифры спидометра уже не важны. */
.dw-label{font-size:.9rem;font-weight:700;letter-spacing:.14em;color:#ff6b6b}
.dw-stars{font-size:1.75rem;line-height:1;color:#ff2e2e;letter-spacing:.1em;
  animation:wantedPulse 1s ease-in-out infinite}
/* Погашенный хвост шкалы (police.js renderWanted пишет его отдельным <i>) */
.dw-stars i{font-style:normal;color:rgba(255,46,46,.2)}
@keyframes wantedPulse{50%{opacity:.45}}
@media (prefers-reduced-motion:reduce){.dw-stars{animation:none}}
/* Розыска нет: прибор дежурит, но в кадре не кричит */
.drive-wanted.dw-calm{border-color:rgba(169,159,196,.35);background:rgba(169,159,196,.07)}
.dw-calm .dw-label{color:var(--muted)}
.dw-calm .dw-stars{animation:none}
/* Толчок копа: плашка дёргается — тряска камеры одна на весь кадр и про удар конкретно
   по «жизням» ничего не говорила. */
.drive-wanted.dw-hit{animation:dwHit .3s}
@keyframes dwHit{0%,100%{transform:translateX(0)}30%{transform:translateX(-4px)}70%{transform:translateX(4px)}}
@media (prefers-reduced-motion:reduce){.drive-wanted.dw-hit{animation:none}}
/* Арест: плашка заливается красным на BUST_HOLD_MS, звёзды уходят — на их месте
   слово BUSTED (текст подменяет js, чтобы не заводить второй элемент). */
.drive-wanted.dw-bust{background:rgba(255,46,46,.85);border-color:#ff2e2e;
  box-shadow:0 0 18px rgba(255,46,46,.7)}
.dw-bust .dw-label{color:#fff;font-size:.88rem}
.dw-bust .dw-stars{display:none}
/* Вспышка по всему кадру карты в момент ареста — вешается на .map-frame, а не на контейнер
   Leaflet: там уже живёт тряска (drive-shake), две анимации на одном элементе не уживаются. */
.map-frame.drive-bust::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:1500;
  box-shadow:inset 0 0 90px rgba(255,46,46,.9);animation:bustFlash 1s ease-out forwards}
@keyframes bustFlash{0%{opacity:1}100%{opacity:0}}
@media (prefers-reduced-motion:reduce){.map-frame.drive-bust::after{animation:none;opacity:.5}}
/* Тряска камеры при столкновении (drive-mode.js shakeCamera) — вешается на КОНТЕЙНЕР карты,
   HUD рядом в .map-frame и не трясётся. Экрана WASTED нет и на аресте: там красная вспышка кадра
   плюс слово BUSTED в плашке, поездка не прерывается. */
@keyframes driveShake{
  0%,100%{transform:translate(0,0)}
  20%{transform:translate(-4px,2px)}
  40%{transform:translate(3px,-3px)}
  60%{transform:translate(-3px,-1px)}
  80%{transform:translate(2px,3px)}
}
.drive-shake{animation:driveShake .2s}
@media (prefers-reduced-motion:reduce){.drive-shake{animation:none}}
/* Коп: размер и посадка спрайта — один в один машинка игрока (13x21, см. iconHtml в
   drive-mode.js), отличается только тёмным корпусом и мигалкой из двух пикселей. Конуса фар
   у копов нет и ночью — мигалка единственный их свет. */
.cop-rot{position:relative;width:13px;height:21px}
/* Полицейский катер: копы теперь ездят по воде вдвое медленнее своего дорожного потолка
   (js/police.js moveCop, config copWaterFactor), и силуэт переключается ровно как у игрока —
   классом on-water, без пересоздания иконки. Кильватерного кольца тут нет намеренно: у машинки
   игрока оно объясняет смену силуэта, а у копа то же кольцо на трёх машинах превратило бы залив
   в мигающую кашу — мигалки хватает. */
.cop-rot .cop-boat{display:none}
.cop-rot.on-water .cop-car{display:none}
.cop-rot.on-water .cop-boat{display:block}
/* Пиксели мигалки 2 -> 3 -> 5px, свечение 5 -> 8 -> 13px (второй запрос «сделать больше»): огни
   теперь шире самого корпуса и вылезают за него — так задумано, это единственное, чем коп читается
   на ходу издалека. Корпус по-прежнему не растёт: спрайт обязан оставаться того же размера, что
   машинка игрока (юр. чеклист §1). */
.cop-beacon{position:absolute;left:50%;top:3px;transform:translateX(-50%);display:flex;gap:3px}
.cop-beacon b{width:5px;height:5px;border-radius:2.5px}
.cop-beacon b:first-child{background:#ff2e2e;box-shadow:0 0 13px 2px #ff2e2e;
  animation:copBlink .48s steps(1,end) infinite}
.cop-beacon b:last-child{background:#2e6bff;box-shadow:0 0 13px 2px #2e6bff;
  animation:copBlink .48s steps(1,end) infinite;animation-delay:.24s}
@keyframes copBlink{0%,49%{opacity:1}50%,100%{opacity:.15}}
@media (prefers-reduced-motion:reduce){.cop-beacon b{animation:none}}
/* Застава — свой знак-блокпост (шеврон над полосатым барьером). Появляется вместе с открытым
   туманом и дальше видна всегда: игрок учит карту опасных мест. */
.police-outpost{width:26px;height:26px;color:#ff6b6b;filter:drop-shadow(0 0 5px rgba(255,46,46,.55))}
.drive-radar svg{display:block;width:100%;height:100%}
.rd-ring{fill:none;stroke:rgba(169,159,196,.4);stroke-width:1.2}
/* Центр — того же цвета, что развертка: прибор читается одним цветом, розовая точка выбивалась */
.rd-core{fill:#24e0d0}
.rd-sweep{fill:rgba(36,224,208,.28);transform-origin:20px 20px;animation:rdSweep 4s linear infinite}
@keyframes rdSweep{to{transform:rotate(360deg)}}
/* Пинг — расходящееся кольцо от иконки. Цвет ставит JS (--rd-color): холодный на дальней
   дистанции, акцентный по тиру ближайшей цели вплотную. */
.rd-ping{position:absolute;inset:0;border-radius:50%;pointer-events:none;
  border:2px solid var(--rd-color,#cfe6ff);animation:rdPing .9s ease-out forwards}
@keyframes rdPing{
  0%{transform:scale(.65);opacity:.95}
  100%{transform:scale(1.8);opacity:0}
}
/* Пеленг на ПОСЛЕДНИЙ недостающий кусок сета (js/radar.js setBearing) — единственное направление,
   которое выдаёт сонар. Точка сидит на кромке: 34px от центра, между внешним кольцом развертки
   (17/40 × 74px ≈ 31.5px) и ободом прибора (46px). Поворот — rotate вокруг центра прибора, потом
   вынос translateY наружу уже в повёрнутых осях. */
/* Два пеленга, одна геометрия: .rd-bearing — оранжевый, последний кусок сета; .rd-outpost —
   красный, ближайшая открытая застава в radar.outpostWarnM. Различаются цветом и темпом пульса,
   всё остальное общее. Оба могут висеть одновременно — это и есть выбор: кусок в той стороне,
   блокпост в этой. */
/* Общая геометрия всех точек поверх циферблата (js/radar.js dot()): пеленги и копы отличаются
   только тем, чем задана позиция — углом или смещением. */
.rd-bearing,.rd-outpost,.rd-house,.rd-cop{position:absolute;left:50%;top:50%;border-radius:50%;
  pointer-events:none}
.rd-bearing,.rd-outpost,.rd-house{width:8px;height:8px;margin:-4px 0 0 -4px;background:var(--rd-glow);
  transform:rotate(var(--rd-a,0deg)) translateY(-34px);
  box-shadow:0 0 6px var(--rd-glow); /* база — чтобы точка светилась и с animation:none */
  animation:rdBeacon 1.1s ease-in-out infinite}
.rd-bearing{--rd-glow:var(--orange)}
.rd-outpost{--rd-glow:#ff2e2e;animation-duration:.8s} /* опасность пульсирует чаще находки */
/* Третий пеленг — сейф-хаус, бирюзовый в цвет самих домов на карте (.drive-safehouse). Висит,
   только пока есть что фиксировать, поэтому три точки одновременно — редкий случай, а не норма. */
/* Цвет — той же переменной, что и сами дома, а не копией шестнадцатеричного кода: «главное чтобы
   точка соответствовала цвету дома» (16-08(7)), а два одинаковых литерала рано или поздно разъедутся. */
.rd-house{--rd-glow:var(--teal);animation-duration:1.4s} /* спокойнее находки: это не добыча и не угроза */
.map-frame.night-ui .rd-house{--rd-glow:#b18cff}
@keyframes rdBeacon{
  0%,100%{box-shadow:0 0 4px var(--rd-glow)}
  50%{box-shadow:0 0 12px var(--rd-glow)}
}
@media (prefers-reduced-motion:reduce){.rd-bearing,.rd-outpost,.rd-house{animation:none}}
/* Копы — точки ВНУТРИ циферблата (js/radar.js renderCops): позиция по масштабу radar.copRangeM,
   дальние прижаты к кромке. Мигают сине-красным в том же ритме, что мигалка на самом спрайте
   копа (.cop-beacon) — прибор и машина на карте говорят одним языком. transition сглаживает
   скачки: скан радара идёт раз в 300мс, без неё точки телепортировались бы. */
.rd-cop{width:7px;height:7px;margin:-3.5px 0 0 -3.5px;
  background:#2e6bff;box-shadow:0 0 8px #2e6bff;
  transform:translate(var(--cx,0),var(--cy,0));transition:transform .3s linear;
  animation:rdCop .48s steps(1,end) infinite}
@keyframes rdCop{
  0%,49%{background:#ff2e2e;box-shadow:0 0 8px #ff2e2e}
  50%,100%{background:#2e6bff;box-shadow:0 0 8px #2e6bff}
}
@media (prefers-reduced-motion:reduce){.rd-cop{animation:none;transition:none}}
/* Второе кольцо того же пинга — вокруг машинки. Живёт в её divIcon, поэтому едет вместе с ней. */
.drive-car-ping{position:absolute;left:50%;top:50%;width:26px;height:26px;margin:-13px 0 0 -13px;
  border-radius:50%;border:2px solid var(--rd-color,#cfe6ff);opacity:0;pointer-events:none}
.drive-car-ping.on{animation:rdCarPing .9s ease-out forwards}
@keyframes rdCarPing{
  0%{transform:scale(.5);opacity:.85}
  100%{transform:scale(3.2);opacity:0}
}
@media (prefers-reduced-motion: reduce){
  .rd-sweep,.rd-bearing{animation:none}
  .rd-ping,.drive-car-ping.on{animation-duration:.01s}
}
/* Обзор средней кнопкой мыши в езде (drive-mode.js initMiddleDrag) */
.leaflet-container.drive-look{cursor:grabbing}
/* Мигающая подсказка на весь кадр при старте езды — гаснет с первым нажатием газа (раунд-9) */
.drive-start-hint{position:absolute;inset:0;z-index:1350;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.6rem;
  pointer-events:none;font-family:var(--display);font-size:clamp(1.6rem,6vw,3.4rem);letter-spacing:.14em;
  color:#fff;-webkit-text-stroke:1.5px var(--orange);
  text-shadow:0 0 18px rgba(255,46,136,.9),0 2px 10px rgba(0,0,0,.6);
  animation:driveHintBlink 2.2s ease-in-out infinite}
/* Вторая строка — что вообще делает радар. Мельче и без обводки: это пояснение, а не призыв */
.drive-start-hint small{font-family:var(--mono);font-size:clamp(.6rem,1.5vw,.85rem);letter-spacing:.08em;
  text-transform:uppercase;color:var(--sand);-webkit-text-stroke:0;text-shadow:0 2px 8px rgba(0,0,0,.8)}
.drive-start-hint small[hidden]{display:none}
.drive-start-hint[hidden]{display:none}
@keyframes driveHintBlink{0%,100%{opacity:1}50%{opacity:.25}}
/* "+1 RESPECT" у собранной точки (раунд-10: бонус на экране, не в углу) — короткий всплеск вверх */
.dot-respect-pop{position:absolute;z-index:1360;transform:translate(-50%,-120%);pointer-events:none;
  font-family:var(--mono);font-size:.78rem;font-weight:700;letter-spacing:.06em;white-space:nowrap;
  color:#fff;background:var(--pink);border-radius:6px;padding:.25rem .6rem;
  box-shadow:0 0 14px rgba(255,46,136,.7);animation:dotRespectPop 1.8s ease-out forwards}
@keyframes dotRespectPop{
  0%{opacity:0;transform:translate(-50%,-90%)}
  12%{opacity:1;transform:translate(-50%,-130%)}
  75%{opacity:1}
  100%{opacity:0;transform:translate(-50%,-200%)}
}
/* При езде на юг подпись рисуется ПОД точкой (раунд-11): сверху она ложилась ровно на машинку,
   которая в момент сбора как раз чуть ниже точки */
.dot-respect-pop.below{animation-name:dotRespectPopBelow}
@keyframes dotRespectPopBelow{
  0%{opacity:0;transform:translate(-50%,10%)}
  12%{opacity:1;transform:translate(-50%,30%)}
  75%{opacity:1}
  100%{opacity:0;transform:translate(-50%,100%)}
}

/* Kill switch (p2-19) — заглушка вместо Leaflet, см. map.js */
.map-unavailable{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  text-align:center;padding:2rem;font-family:var(--mono);font-size:.8rem;letter-spacing:.06em;
  color:rgba(245,236,215,.55)}

/* ===== Leaflet zoom control — неоновая тема вместо белых квадратов по умолчанию =====
   !important нужен: leaflet.css сам вешает !important на фон .leaflet-disabled и рамку .leaflet-bar */
.leaflet-control-zoom{border:none!important;box-shadow:none!important}
.leaflet-control-zoom a{background:rgba(11,6,32,.78)!important;backdrop-filter:blur(6px);color:var(--orange)!important;
  border:1px solid rgba(255,158,79,.5)!important;width:30px;height:30px;line-height:28px;font-size:1.1rem}
.leaflet-control-zoom a:hover{background:rgba(11,6,32,.92)!important;color:var(--orange)!important;box-shadow:0 0 10px rgba(255,158,79,.5)}
.leaflet-control-zoom a.leaflet-disabled{opacity:.35;background:rgba(11,6,32,.78)!important;color:var(--orange)!important}
.leaflet-control-zoom-in{border-radius:8px 8px 0 0}
.leaflet-control-zoom-out{border-top:none!important;border-radius:0 0 8px 8px}

/* ===== Leaflet layers control (переключатель тайлсетов community/reference) — та же неоновая тема ===== */
.leaflet-control-layers{background:rgba(11,6,32,.78)!important;backdrop-filter:blur(6px);
  border:1px solid rgba(255,158,79,.5)!important;border-radius:8px!important;box-shadow:none!important;
  color:var(--sand);font-family:var(--body);font-size:.78rem}
/* Свой значок вместо дефолтной leaflet-иконки (серые квадратики) — две ромбовидные "плашки"
   в акцентном цвете, тоньше и в тему сайта. */
.leaflet-control-layers-toggle{width:44px!important;height:44px!important;
  background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><polygon points="12,3 21,8.5 12,14 3,8.5" fill="none" stroke="%23ff9e4f" stroke-width="1.7"/><polygon points="12,10.5 21,16 12,21.5 3,16" fill="none" stroke="%23ff9e4f" stroke-width="1.7" opacity="0.55"/></svg>')!important;
  background-size:26px 26px!important;background-position:center!important;background-repeat:no-repeat!important}
.leaflet-control-layers label{margin:.15rem 0}
.leaflet-control-layers-selector{accent-color:var(--orange)}

/* Кнопка возврата камеры — под тумблером слоёв (см. RecenterControl в map.js). Текстовый глиф
   "⌖" не годится — в большинстве шрифтов у него тонкие линии с большими полями внутри em-бокса,
   font-size не спасает (проверено: 28.8px вычисленного размера, символ всё равно читался как
   мелкий). Тот же приём, что leaflet-control-layers-toggle — SVG фоном, гарантированный размер. */
.map-recenter{display:block;width:44px;height:44px;border-radius:8px;
  border:1px solid rgba(255,158,79,.5);background-color:rgba(11,6,32,.78);backdrop-filter:blur(6px);
  background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="7" fill="none" stroke="%23ff9e4f" stroke-width="1.8"/><line x1="12" y1="0.5" x2="12" y2="5" stroke="%23ff9e4f" stroke-width="1.8"/><line x1="12" y1="19" x2="12" y2="23.5" stroke="%23ff9e4f" stroke-width="1.8"/><line x1="0.5" y1="12" x2="5" y2="12" stroke="%23ff9e4f" stroke-width="1.8"/><line x1="19" y1="12" x2="23.5" y2="12" stroke="%23ff9e4f" stroke-width="1.8"/><circle cx="12" cy="12" r="1.8" fill="%23ff9e4f"/></svg>');
  background-size:30px 30px;background-position:center;background-repeat:no-repeat;cursor:pointer}
.map-recenter:hover{background-color:rgba(11,6,32,.92);box-shadow:0 0 10px rgba(255,158,79,.5)}

/* Кнопка-шорткат на радио — над leaflet-control-scale, тот же визуальный язык, что map-recenter.
   --btn-c (rgb-тройка) синхронизируется из --ra-c текущей радио-станции через JS (map.js) — SVG
   currentColor вместо статичного data-URI фона, чтобы цвет мог реально меняться по станции. */
/* Обёртка кнопки и ползунка громкости. --btn-c живёт тут (JS ставит его на неё), чтобы цвет
   станции доставался обоим детям. Ползунок показывается только в играющем состоянии — как и
   точки станций: у выключенного плеера крутить нечего, а в углу карты место дорогое. */
/* Колонка, а не строка («полоску громкости надо под радио, а не в ряд»): в ряд ползунок уезжал
   левее кнопки, в поле карты, и читался как отдельный прибор. Под кнопкой он её ширины и
   очевидно к ней относится. gap:0 и срезанные смежные углы («приклей снизу к плееру, чтобы был
   один квадрат») — два бокса читаются как один прибор 96x56, а не как кнопка и полка под ней.
   Смежные рамки не убираем, а гасим до transparent: убрать значило бы сдвинуть бокс на 1px в
   момент старта радио. */
/* Ползунок виден ВСЕГДА, а не только в играющем состоянии («чтобы кнопка в состоянии play-stop
   не меняла размер»): прибор стоит в нижнем углу и рос вверх на 22px при старте радио — кнопка
   уезжала из-под курсора ровно в момент клика. Громкость до запуска тоже осмысленна: выставил
   заранее — включилось на нужной. */
.map-player{--btn-c:255,158,79;display:flex;flex-direction:column;align-items:stretch;gap:0}
.map-player .map-player-btn{border-radius:8px 8px 0 0;border-bottom-color:transparent}
/* Механика ручки (appearance, дорожка, бегунок) — из .radio-vol (css/radio.css, тот же ползунок,
   что в виджете), здесь только своя пилюля-фон, размер и цвет по станции. Селекторы двухуровневые
   намеренно: у правил radio.css та же специфичность, и файл подключён после — одноуровневые
   .mpb-vol проиграли бы ему по порядку. Цветные правила виджета сюда не дотягиваются вовсе:
   они завязаны на .radio-widget[data-state]. */
/* Ширина ровно как у кнопки (96px): у <input type=range> есть своя внутренняя ширина ~149px,
   и при width:auto растягивался бы контейнер, а не ползунок — колонка выходила лесенкой. */
.map-player .mpb-vol{width:96px;box-sizing:border-box;height:22px;padding:0 9px;
  /* Скруглены только нижние углы, верхняя рамка погашена — ползунок это низ одного прибора
     с кнопкой, а не отдельная плашка (см. комментарий выше про «один квадрат»). */
  border-radius:0 0 8px 8px;
  border:1px solid rgba(var(--btn-c),.5);border-top-color:transparent;
  background-color:rgba(11,6,32,.78);backdrop-filter:blur(6px)}
.map-player .mpb-vol::-webkit-slider-runnable-track{background:linear-gradient(to right,rgb(var(--btn-c)) var(--vol-pct),rgba(255,255,255,.25) var(--vol-pct))}
.map-player .mpb-vol::-moz-range-track{background:linear-gradient(to right,rgb(var(--btn-c)) var(--vol-pct),rgba(255,255,255,.25) var(--vol-pct))}
.map-player .mpb-vol::-webkit-slider-thumb{background:rgb(var(--btn-c))}
.map-player .mpb-vol::-moz-range-thumb{background:rgb(var(--btn-c))}
.map-player-btn{display:flex;align-items:center;justify-content:center;gap:6px;
  /* широкий бокс с эквалайзером (был 34px квадрат); 118->96 по фидбэку "чуть меньше по ширине" */
  width:96px;height:34px;padding:0 7px;border-radius:8px;color:rgb(var(--btn-c));
  border:1px solid rgba(var(--btn-c),.5);background-color:rgba(11,6,32,.78);backdrop-filter:blur(6px);
  cursor:pointer;transition:border-color .2s,color .2s}
.map-player-btn:hover{background-color:rgba(11,6,32,.92);box-shadow:0 0 10px rgba(var(--btn-c),.5)}
.map-player-btn .mpb-pause{display:none}
.map-player-btn.is-playing .mpb-play{display:none}
.map-player-btn.is-playing .mpb-pause{display:block}
/* Мини-эквалайзер на кнопке — высоты кубиков двигает vizLoop radio.js (реальный спектр),
   виден только во время игры */
.map-player-btn .mpb-viz{display:none;align-items:flex-end;gap:2px;height:14px}
.map-player-btn.is-playing .mpb-viz{display:flex}
.map-player-btn .mpb-viz i{width:3px;height:3px;background:currentColor;border-radius:1px}
/* Стрелки переключения станций (16-08, вместо точек: те росли числом вместе со списком станций,
   стрелки занимают фиксированное место при любом их количестве). Шеврон (уголок из двух рамок,
   ::before), а не сплошной треугольник: залитый клин в 10px читался тяжёлой пробкой рядом с
   тонкими палочками эквалайзера. Не символы ‹▲▼›: юникодные стрелки в разных шрифтах разного
   размера и сидят на разной высоте.
   Сам уголок 6x6, но у <i> кликабельные 14x11 — попасть пальцем в 6px нельзя. gap:3px — «между
   ними пробел по вертикали», иначе два шеврона слипались в один знак. */
.map-player-btn .mpb-nav{display:none;flex-direction:column;justify-content:center;gap:3px}
.map-player-btn.is-playing .mpb-nav{display:flex}
.map-player-btn .mpb-nav i{position:relative;width:14px;height:11px;opacity:.8;transition:opacity .2s}
/* Толщина 2.2px и базовая прозрачность .8 (16-08(3) «стрелки пожирнее»): при 1.6px/.6 рядом с
   палочками эквалайзера (3px сплошной заливки) шеврон выглядел бледным намёком. */
.map-player-btn .mpb-nav i::before{content:'';position:absolute;left:50%;top:50%;width:6px;height:6px;
  border-top:2.2px solid currentColor;border-right:2.2px solid currentColor}
.map-player-btn .mpb-nav i[data-station-step="-1"]::before{transform:translate(-50%,-25%) rotate(-45deg)}
.map-player-btn .mpb-nav i[data-station-step="1"]::before{transform:translate(-50%,-75%) rotate(135deg)}
.map-player-btn .mpb-nav i:hover{opacity:1}

/* ===== Leaflet scale control (bottom-right, "500 m") — крупнее, читается на карте.
   border:1px solid var(--orange) — по запросу, рамка отделяет бокс от фона под ним (тот теперь
   прозрачный, см. #leafletMap). text-shadow:none — реальный источник "обводки у цифр": дефолтный
   leaflet CSS вешает text-shadow:1px 1px #fff (рассчитан на светлый фон), на тёмном фоне читался
   как светящийся контур вокруг символов.
   Ширину ставит map.js (SCALE_PX) — box-sizing:border-box, чтобы бокс был ровно этой длины:
   подпись говорит, сколько метров укладывается в него, то есть бокс и есть линейка. ===== */
.leaflet-control-scale-line{box-sizing:border-box;text-align:center;
  font-size:.95rem;font-weight:700;padding:.32rem .55rem;
  border:1px solid var(--orange)!important;border-radius:4px;background:rgba(11,6,32,.78)!important;
  color:var(--sand)!important;text-shadow:none!important}

/* ===== Секции Map Info — три панельки в общей рамке =====
   Раунд 08-09(3) отменяет разделители-линии (.panel-divider / .panel-divider-accent удалены
   вместе с разметкой): линия была тоньше и бледнее самих контролов, и три функции читались одним
   списком. Теперь у каждой своя рамка и своя подложка — «слои», «езда», «коллекция» видно с
   одного взгляда. Подложка чуть светлее панели, а не темнее: панель уже почти чёрная. */
.panel-sect{border:1px solid rgba(var(--ps),.55);border-radius:8px;
  padding:.45rem .5rem .5rem;margin-top:.45rem;background:rgba(var(--ps),.11)}
.panel-sect .panel-caption{margin-bottom:.32rem}
/* Раунд 08-09(4) «мб у каждой мини-панельки фон разным цветом слегка»: своя краска из палитры
   сайта на секцию. 08-09(5) — «чуть более акцентно» (рамка .3→.55, подложка .05→.11).
   Цвет один на рамку и подложку через --ps, оттого правится в одном месте.
   Ключ — data-sect, а не nth-of-type (16-08(9)): на порядковых номерах это уже сломалось —
   COMPARE MAPS встал третьей секцией и утащил себе правила, написанные для DRIVE (в том числе
   мобильное «спрятать секцию, если нет кнопки DRIVE»), а COLLECTION уехал на пятое место, где
   правила --ps не было вовсе, и остался без краски. Имя секции такой сдвижки не боится.
   Ночью краска секций сохраняется («давай попробуем сохранить эти цвета в ночном режиме») —
   общего фиолетового правила на .panel-sect больше нет, ночь красит только рамку самой панели
   и подписи. */
/* YOUR RESPECT (16-08(4) «надо в похожих цветах как на пульте») — плашка повторяет .cc-respect
   из правой колонки: тот же градиент фиолетовый→маджента, та же розовая рамка, та же розовая
   подпись со свечением. Один и тот же счётчик в двух местах экрана должен и выглядеть одинаково,
   иначе читается как два разных виджета. Из-за градиента она не сливается с розовой секцией
   MAP LAYER под собой, хотя --ps у них теперь общий. */
.panel-sect[data-sect="respect"]{--ps:255,46,136;
  background:linear-gradient(135deg,rgba(43,15,77,.9),rgba(122,29,94,.7))}
/* Подпись первой секции — по центру (16-08(7)): под ней и баланс, и строка лимита центрованы,
   левый прижим читался как забытый заголовок над центрованным блоком. */
.panel-sect[data-sect="respect"] .panel-caption{color:var(--pink);
  text-shadow:0 0 10px rgba(255,46,136,.6);text-align:center}
/* Розовый и фиолетовый через одну: две фиолетовые подряд глаз читает как одну панель. */
.panel-sect[data-sect="layer"]{--ps:255,46,136}
.panel-sect[data-sect="compare"]{--ps:177,140,255}
.panel-sect[data-sect="drive"]{--ps:255,46,136}
.panel-sect[data-sect="collection"]{--ps:177,140,255}
/* MAP LAYER и DRIVE занимают одно и то же место панели (вкладки EXPLORE/DRIVE), а COLLECTION под
   ними видна в обоих режимах — и подпрыгивала на разницу их высот при переключении (16-08(11)
   «немного скачет вёрстка collection»). Общая нижняя граница высоты держит её на месте.
   Число — высота более высокой из двух (DRIVE) на английском; если перевод где-то окажется
   длиннее, секция просто перерастёт минимум и вернётся прежнее поведение, ничего не сломав. */
.map-panel .panel-sect[data-sect="layer"],
.map-panel .panel-sect[data-sect="drive"]{min-height:97px}
/* На телефоне у полосы своя сетка с order, десктопный минимум там не нужен. Но именно 0 (было до
   16-08(13)) и ломал вёрстку: полоса — грид фиксированной высоты, и трек с нулевым минимумом
   Leaflet... то есть браузер спокойно сжимал ниже содержимого. Замер: секция MAP LAYER 19px при
   контенте 29px — контролы вылезали за свою рамку («map layer collections всё съезжает»). auto
   возвращает автоматический минимум по контенту: не влезло — полоса скроллится, а не давит секцию. */
@media (max-width:900px){.map-panel .panel-sect[data-sect="layer"],
  .map-panel .panel-sect[data-sect="drive"]{min-height:auto}}
/* Цифра крупная: в фуллскрине это единственный счётчик Respect на экране, он же и заменяет
   бейдж верхнего бара, а тот тоже крупный. По центру (16-08(3)) — в строке всего два слова,
   прижатые влево они висели в углу большой пустой плашки. */
.panel-respect{font-family:var(--mono);line-height:1;color:var(--sand);text-align:center}
/* Белая цифра в розовом свечении — как .ccr-num в пульте (16-08(4)), только кегль под панель */
.panel-respect b{font-size:1.3rem;font-weight:700;letter-spacing:.02em;color:#fff;
  text-shadow:0 0 12px rgba(255,46,136,.8),0 0 30px rgba(255,46,136,.4)}
.panel-respect span{font-size:.62rem;letter-spacing:.14em;color:var(--muted);margin-left:.25rem}
/* Строка дневного потолка (.panel-daily) удалена в 16-08(15) вместе с самим капом. */

/* ===== Legend/Credits/Sources — кнопки в панели + один оверлей на все три (§5.4) ===== */
.map-ui-btns{display:flex;flex-direction:column;gap:.35rem}
.map-ui-btn{width:100%;background:rgba(11,6,32,.6);color:var(--sand);
  border:1px solid rgba(255,158,79,.4);border-radius:6px;padding:.32rem .3rem;
  font-family:var(--body);font-size:.68rem;font-weight:700;cursor:pointer}
.map-ui-btn:hover{border-color:var(--orange)}
.map-ui-btn.active{background:rgba(255,158,79,.22);border-color:var(--orange);color:var(--orange)}
/* Режимы панели EXPLORE / DRIVE / COMPARE (16-08(9), js/map.js). Тот же сегмент, что у
   Original/Realistic, только на три части и на всю ширину пульта: панель стала слишком длинной,
   и одновременно нужен один раздел, а не пять. */
/* 16-08(10) «кнопки Explore / Drive / Compare сделай крупнее, чтобы были акцентными»: это главный
   переключатель панели, а выглядел он мельче кнопок внутри секций. Шрифт .6 -> .78rem, высота
   вдвое, активная — заливка оранжевым с внешним свечением, чтобы читалась как вкладка. */
/* 16-08(11) «проверь разделители у вкладок режимов»: разделитель был, но ценой левой границы
   соседа (border-left:0) — у активной вкладки рамка оказывалась разомкнутой слева, и сегмент
   читался как «кнопка, приклеенная к чему-то». Теперь границы не срезаются, а НАКЛАДЫВАЮТСЯ
   (margin-left:-1px): между вкладками по-прежнему одна линия, но у каждой рамка замкнута, а
   активная поднята z-index'ом — её оранжевый контур рисуется поверх соседского. */
.panel-modes{display:flex;margin:.1rem 0 .55rem}
.panel-modes .pm-btn{flex:1;border-radius:0;padding:.5rem .1rem;font-size:.72rem;letter-spacing:.05em}
.panel-modes .pm-btn:first-child{border-radius:6px 0 0 6px}
.panel-modes .pm-btn:last-child{border-radius:0 6px 6px 0}
.panel-modes .pm-btn+.pm-btn{margin-left:-1px}
.panel-modes .pm-btn.active{position:relative;z-index:1;
  background:rgba(255,158,79,.3);box-shadow:0 0 12px rgba(255,158,79,.35)}
/* «Можно периодически подсвечивать кнопку, сделать больше акцента» (16-08(11)). Подсвечиваются
   НЕвыбранные вкладки — по очереди, коротким проблеском раз в 9 секунд: смысл подсказки в том,
   что кроме текущего режима есть ещё два, а не в том, чтобы мигал уже открытый. Задержка на
   вторую вкладку сдвинута, иначе они вспыхивают хором и это читается как поломка. */
.panel-modes .pm-btn:not(.active){animation:pmHint 9s ease-in-out infinite}
.panel-modes .pm-btn:nth-child(2){animation-delay:1.2s}
.panel-modes .pm-btn:nth-child(3){animation-delay:2.4s}
@keyframes pmHint{
  0%,88%,100%{border-color:rgba(255,158,79,.4);color:var(--sand)}
  93%{border-color:var(--orange);color:var(--orange);background:rgba(255,158,79,.12)}
}
.panel-modes .pm-btn:hover{animation:none}   /* иначе проблеск перебивает отклик на наведение */
@media (prefers-reduced-motion:reduce){.panel-modes .pm-btn{animation:none}}
/* .map-panel .panel-sect в мобильном блоке ниже задаёт display:flex с той же силой селектора и
   стоит позже — поэтому у скрытия на класс больше веса, иначе на телефоне видны все разделы. */
.map-panel .panel-sect.pm-off{display:none}
/* COMPARE MAPS (16-08(8), js/map-compare.js). Списком, по строке на игру (16-08(12): «карты в
   compare расположим списком, тогда и шрифт крупнее и инфы больше»). В строку кнопки лезли по
   две-три в ряд разной ширины, и ради этого шрифт держали на .62rem. Столбик наследуется от
   .map-ui-btns — своего flex-direction тут нет намеренно. */
.cmp-btns .map-ui-btn{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem;
  padding:.32rem .5rem;font-size:.7rem;line-height:1.15;text-align:left}
/* Площадь — правым краем той же строки (16-08(11), вместо общей подписи под списком). Моноширинный
   шрифт: цифры выстраиваются в колонку и сравниваются глазом без включения оверлеев. Оранжевым
   с 16-08(14) («мб цифры площади сделаем оранжевыми?») — серым они читались как подпись к кнопке,
   а это главное, ради чего в список вообще смотрят. */
.cmp-btns .map-ui-btn i{font-family:var(--mono);font-style:normal;font-size:.6rem;
  letter-spacing:.04em;color:var(--orange);white-space:nowrap}
.cmp-btns .map-ui-btn.active i{color:inherit;opacity:.85}
.cmp-btns .map-ui-btn.cmp-broken{opacity:.4;text-decoration:line-through}  /* файл не загрузился */
/* Ползунок прозрачности оверлеев (16-08(10)) — одна строка «Opacity + ручка» под кнопками. */
.cmp-alpha{display:flex;align-items:center;gap:.4rem;margin-top:.4rem;
  font-family:var(--mono);font-size:.58rem;letter-spacing:.06em;color:var(--muted);
  text-transform:uppercase}
.cmp-alpha input{flex:1;min-width:0;accent-color:var(--orange)}
/* Сама карта прошлой части, полупрозрачная поверх полотна (16-08(9), вместо силуэта). Прозрачность
   больше НЕ в CSS: её задаёт ползунок через L.imageOverlay.setOpacity (инлайн-стиль всё равно
   перебил бы правило отсюда — два хозяина у одного свойства не нужны). Ровно по той же причине
   тут нет и pointer-events: с 16-08(13) карту можно ТАЩИТЬ, а кто её ловит и на какой вкладке —
   решает js/map-compare.js (syncGrab), Leaflet пишет это свойство инлайном. Отсюда только курсор-
   хватка и touch-action: без него палец на оверлее прокручивает страницу вместо перетаскивания. */
.cmp-overlay{cursor:grab;touch-action:none;
  /* Розовая пунктирная рамка = габариты наложенной карты. Без неё на пёстрых тайлах не видно,
     где чужая карта кончается, а весь смысл фичи — сравнить именно габариты.
     Альфа .95 -> .5 (16-08(15) «обводку у карт можно сделать чуть менее яркой»): рамка должна
     очерчивать габариты, а не светиться ярче самой карты. */
  outline:2px dashed rgba(255,46,136,.5);outline-offset:0;
  filter:drop-shadow(0 0 6px rgba(11,6,32,.85))}
.cmp-overlay:active{cursor:grabbing}
.map-frame.night-ui .cmp-overlay{outline-color:rgba(177,140,255,.5)}
/* Подписи-заголовки секций панели — акцентнее (раунд 03-08 "Drive/Map layer более акцентно"):
   оранжевые, шире трекинг, читаются как заголовки групп, а не сноски */
.panel-caption{font-family:var(--mono);font-size:.62rem;font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;color:var(--orange);margin:0 0 .38rem}
/* START ENGINE — главный CTA панели, розовый акцент (не рядовая кнопка) */
#driveModeBtn{border-color:rgba(255,46,136,.65);background:rgba(255,46,136,.14)}
#driveModeBtn:hover{border-color:var(--pink)}
#driveModeBtn.active{background:rgba(255,46,136,.32);border-color:var(--pink);color:#fff}
/* Сегмент Original/Realistic — два состояния слоя одним переключателем */
.ai-seg{display:flex}
.ai-seg[hidden]{display:none}
.ai-seg .ai-seg-btn{flex:1;border-radius:0}
.ai-seg .ai-seg-btn:first-child{border-radius:6px 0 0 6px}
.ai-seg .ai-seg-btn:last-child{border-radius:0 6px 6px 0;border-left:0}
/* Активная правая половина сегмента подсвечивает и общий шов (правую границу Original) —
   иначе оранжевая рамка Realistic читалась "обрубленной" слева (раунд-9) */
.ai-seg:has(.ai-seg-btn:last-child.active) .ai-seg-btn:first-child{border-right-color:var(--orange)}
/* Fog of war — чекбокс-переключатель состояния, не действие (отделён от кнопок по фидбэку) */
/* .82rem вместо .68rem: подписи Show cards / Night читались мельче соседних элементов панели
   (запрос владельца). Чекбокс подрос следом — иначе он выглядел точкой рядом с текстом. */
.fog-row{display:flex;align-items:center;gap:.45rem;font-size:.82rem;font-weight:700;
  color:var(--sand);cursor:pointer;padding:.14rem 0}
.fog-row input{accent-color:var(--orange);cursor:pointer;margin:0;width:15px;height:15px}
.fog-row[hidden]{display:none}
/* ===== Время суток — тумблер «День | Ночь» =====
   Слева подпись «День» с солнцем, справа «Ночь» с луной, между ними сам переключатель.
   Иконки — свои SVG, а не эмодзи ☀🌙: эмодзи рисует системный шрифт, перекрасить его нечем. */
/* По центру, а не space-between (16-08(4)): при распорке по краям луна упиралась ровно в кромку
   секции — то, что видно на скриншоте. Остаток ширины честнее отдать в поля по бокам, чем
   растянуть три элемента по всей ширине. */
/* Зазор 0.7rem -> 0.3rem (16-08(6), «верни подписи day night»): подписи вернулись, а место под них
   взято из зазоров, не из слайдера — он остаётся 60px, как просили раньше. Замеры по 6 локалям в
   комментарии к .dn-side. */
/* Строка выходит в паддинг своей секции (margin-inline:-8px) — 16px, которых не хватало подписям.
   Визуально ничего не рвётся: фон секции идёт дальше, а сама строка по-прежнему по центру, так что
   луна не встаёт вплотную к кромке (та самая жалоба 16-08(5)). */
/* Отступ сверху (16-08(11) «в DRIVE отступ побольше между кнопкой и строчкой с днём»): кнопка
   START ENGINE и тумблер суток — разные вещи, вплотную читались одним блоком контролов. */
.daynight-row{gap:.25rem;cursor:default;justify-content:center;margin-inline:-8px;margin-top:.55rem}
/* .58 -> .62rem («шрифт чуть крупнее», 16-08(7)). Запас после выхода в паддинг это позволяет —
   самая длинная локаль ru упирается в 155 из 159 доступных, замеры в docs/qa-drive-mode.md. */
.dn-side{display:flex;align-items:center;gap:.15rem;flex:none;
  font-size:.62rem;letter-spacing:.01em;text-transform:uppercase;color:rgba(245,236,215,.85)}
.dn-ico{flex:none;width:13px;height:13px}   /* 15 -> 13: ещё 4px строке, у ru запас был 4.4px */
.dn-sun{color:var(--orange)}
.dn-sun circle{fill:currentColor}
.dn-sun path{fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round}
.dn-moon{color:#c9bfe8}
.dn-moon path{fill:currentColor}
/* Пилюля-переключатель на голом checkbox: appearance:none + ::after-кнопка, без обёрток в разметке.
   Селектор в два класса намеренно: ниже по файлу лежит .fog-row input{width:15px;height:15px}
   (чекбоксы Show cards / Fog of war), и при равной специфичности он побеждал по порядку —
   переключатель остался бы 15px, сколько его тут ни увеличивай.
   Цвета — те же, что у остальных контролов панели (обводка/заливка как у .panel-head .map-ui-btn),
   а не свой бежево-сиреневый градиент: «слайдер в цвет общей темы». Смысл шкалы теперь несёт
   кнопка — оранжевая днём, лиловая ночью, тем же #b18cff, что и вся ночная тема панели. */
/* Ширина осталась 60px и с вернувшимися подписями (16-08(6)): место нашли не в слайдере, а в
   зазорах строки, кегле подписей, размере иконок и выходе строки в паддинг секции.
   Замер по 6 локалям на 1280px (offscreen-iframe после fonts.ready), доступно 159px:
   en 143 · pt-br 139.6 · es/fr 143.8 · de 145.9 · ru 150.6 — самый тесный ru с запасом 8.4px,
   луна в 5.1px от кромки секции. На 375px строка живёт в полосе Map Info и там шире секции —
   переполнения документа нет ни в одной локали (docOverflow 0). */
.daynight-row .daynight-switch{flex:none;position:relative;width:60px;height:22px;margin:0;padding:0;
  cursor:pointer;-webkit-appearance:none;appearance:none;border-radius:11px;
  border:1px solid rgba(255,158,79,.55);background:rgba(255,158,79,.1);
  transition:background .2s,border-color .2s}
.daynight-switch::after{content:'';position:absolute;top:2px;left:2px;width:16px;height:16px;
  border-radius:50%;background:var(--orange);box-shadow:0 0 8px rgba(255,158,79,.6);
  transition:transform .18s ease,background .2s,box-shadow .2s}
.daynight-switch:checked{border-color:rgba(177,140,255,.65);background:rgba(177,140,255,.14)}
/* Ход кнопки = ширина − 2*2px зазора − 16px кнопки (60px по фидбэку «ещё шире», был 44 → 52) */
.daynight-switch:checked::after{transform:translateX(38px);
  background:#b18cff;box-shadow:0 0 8px rgba(177,140,255,.7)}
.daynight-switch:focus-visible{outline:2px solid var(--sand);outline-offset:3px}
/* Чуть отступает от сегмента Original/Realistic над ней (по фидбэку — сидела слишком плотно) */
#showCardsRow{margin-top:.3rem}

/* ===== Табличка «что меняется ночью» (16-08(4), js/night-mode.js) =====
   Верх кадра по центру: в самом центре живёт «PRESS W TO DRIVE» (16-08(4) «перекрывает press W»),
   низ занимает приборка, углы — панель и кредиты. Висит, пока включена ночь («можно рисовать
   наверху и не убирать»); закрывается кликом или выключением ночи. Краска сразу ночная (#b18cff) —
   она и показывается только ночью, отдельного правила .night-ui ей не нужно.
   Центрирование не через left:50%+translateX(-50%), а через left/right:0 + margin:auto: у
   абсолютного блока ширина shrink-to-fit считается от ОСТАВШЕГОСЯ места, и при left:50% доступной
   оставалась ровно половина кадра — на мобиле табличка сжималась в столбик 169px. */
.night-brief{position:absolute;z-index:1400;left:0;right:0;top:.6rem;margin-inline:auto;
  width:fit-content;transform:scale(.96);
  max-width:min(340px,86%);padding:.7rem .9rem;
  background:rgba(11,6,32,.9);backdrop-filter:blur(8px);
  border:1px solid rgba(177,140,255,.6);border-radius:12px;box-shadow:0 0 30px rgba(0,0,0,.5);
  font-family:var(--mono);color:var(--sand);cursor:pointer;
  opacity:0;transition:opacity .25s,transform .25s}
.night-brief.show{opacity:1;transform:scale(1)}
.night-brief[hidden]{display:none}
.nb-head{font-family:var(--display);letter-spacing:.12em;font-size:.8rem;color:#b18cff;
  margin-bottom:.45rem}
.nb-table{border-collapse:collapse;font-size:.66rem;line-height:1.35}
.nb-table th{text-align:left;vertical-align:top;padding:.12rem .6rem .12rem 0;white-space:nowrap;
  font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#b18cff}
.nb-table td{text-align:left;vertical-align:top;padding:.12rem 0;color:rgba(245,236,215,.85)}
@media (prefers-reduced-motion:reduce){.night-brief{transition:none}}

/* ===== Ночной режим (js/night-mode.js) — nightPane z=300, дети позиционируются JS-ом
   (setPosition/clipPath), тут только blend-режимы и непрозрачность (сама opacity — inline из
   NIGHT_MODE.darkness/emissiveOpacity). Тёмно-синий, не чёрный — см. комментарий в задаче. */
.night-dark{position:absolute;top:0;left:0;background:var(--indigo);mix-blend-mode:multiply}
.night-glow{position:absolute;top:0;left:0;mix-blend-mode:screen}
/* Докается слева (справа уже .map-panel) — слайд, не центр-модалка поверх карты (не должна
   закрывать вид на карту при автооткрытии на переключении base-слоя, см. map.js baselayerchange). */
/* Высота — по содержимому, с потолком (16-08(4)), а не «от верха до низа кадра»: в левый нижний
   угол переехала кнопка Legend и рядом с ней живёт обязательная атрибуция, и панель на всю высоту
   накрывала бы обе. Потолок = высота кадра минус место под столбец кредитов: 11rem считаны по
   самому высокому его состоянию (кнопка Legend + раскрытый AI-бэйдж + две строки атрибуции =
   164px от низа кадра), без AI-слоя столбец ниже и зазор просто больше. Картинка легенды выше
   потолка — уедет во внутренний скролл, он у панели и так был. Если в какой-то локали бэйдж
   вырастет ещё, панель максимум подлезет ПОД столбец: у того z-index выше (1003), кредиты и
   кнопка остаются читаемыми — прячется только низ картинки. */
.map-ui-panel{position:absolute;z-index:1002;left:.6rem;top:.6rem;
  max-height:calc(100% - 11rem);
  width:min(320px,40%);display:flex;flex-direction:column;
  background:rgba(11,6,32,.92);backdrop-filter:blur(10px);
  border:1px solid rgba(255,46,136,.4);border-radius:12px;box-shadow:0 0 40px rgba(0,0,0,.5);
  opacity:0;pointer-events:none;transform:translateX(-110%);transition:opacity .18s,transform .18s}
.map-ui-panel.open{opacity:1;pointer-events:auto;transform:translateX(0)}
.map-ui-panel-head{display:flex;justify-content:space-between;align-items:center;
  padding:.6rem .8rem;font-family:var(--display);letter-spacing:.1em;font-size:.95rem;color:var(--orange);
  border-bottom:1px solid rgba(255,158,79,.3)}
.map-ui-panel-close{background:none;border:none;color:var(--sand);font-size:1rem;cursor:pointer;line-height:1}
.map-ui-panel-close:hover{color:var(--pink)}
.map-ui-panel-body{overflow:auto;padding:.6rem}
.map-ui-panel-body img{width:100%;display:block;border-radius:6px}
.map-ui-panel-body img+img{margin-top:.6rem}
.map-ui-panel-body img[hidden]{display:none}
.map-ui-panel-note{margin-top:.5rem;font-size:.6rem;color:var(--muted)}
.map-ui-panel-note:empty{display:none}

/* ===== VOTD refresh ===== */
.votd-actions{display:flex;align-items:center;gap:.3rem}
.votd-refresh{background:none;border:1px solid rgba(255,158,79,.5);border-radius:4px;
  color:var(--orange);font-size:.8rem;line-height:1;padding:.12rem .4rem;cursor:pointer}
.votd-refresh:hover{background:rgba(255,158,79,.15)}

/* ===== Лента: раскрытие + реакции ===== */
.feed-item.open{background:rgba(36,224,208,.06);border-radius:6px;padding:.35rem .4rem .5rem}
.feed-item.open .feed-item-body{-webkit-line-clamp:unset;overflow:visible}
.feed-actions{display:flex;gap:.5rem;margin-top:.3rem}
.fa-btn{position:relative;background:none;border:1px solid rgba(169,159,196,.3);border-radius:4px;cursor:pointer;
  font-family:var(--mono);font-size:.62rem;padding:.1rem .45rem}
.fa-btn[data-r="up"]{color:rgba(36,224,208,.65);border-color:rgba(36,224,208,.35)}
.fa-btn[data-r="down"]{color:rgba(255,46,136,.65);border-color:rgba(255,46,136,.35)}
.fa-btn[data-r="up"]:hover{border-color:var(--teal);color:var(--teal)}
.fa-btn[data-r="down"]:hover{border-color:var(--pink);color:var(--pink)}
.fa-btn[data-r="up"].active{border-color:var(--teal);color:var(--teal);box-shadow:0 0 6px rgba(36,224,208,.4)}
.fa-btn[data-r="down"].active{border-color:var(--pink);color:var(--pink);box-shadow:0 0 6px rgba(255,46,136,.4)}
.feed-head-weazel em{font-size:.62rem;color:var(--orange)}


/* ===== Ежеминутная подсветка таймера ===== */
.cd-widget.glow-min{border-color:var(--orange);
  box-shadow:0 0 30px rgba(255,158,79,.55),0 0 60px rgba(255,158,79,.25);transition:box-shadow .3s}

/* ===== WIKI PANEL ===== */
/* padding теперь не на самой панели, а распределён по детям (см. #wikiLinks) — иначе плашка
   .wiki-head не смогла бы тянуться на всю ширину карточки, как у VOTD/OFFICIAL */
/* Была смешанная палитра: тёплый (пурпур->розовый) фон панели + бирюзовые рамка/заголовок,
   а пункты списка (#wikiLinks) уже розовые — заголовок с bordertelo клэшил и с фоном, и со
   своими же пунктами. Пересобрано на одном тёплом акценте (розовый), бирюза убрана из панели целиком. */
.wiki-panel{flex:0 0 auto;background:linear-gradient(135deg,rgba(43,15,77,.9),rgba(122,29,94,.7));backdrop-filter:blur(6px);
  border:1px solid rgba(255,46,136,.4);border-radius:12px;overflow:hidden;
  display:flex;flex-direction:column;gap:.15rem}
.wiki-head{display:block;font-family:var(--display);letter-spacing:.14em;font-size:.9rem;color:var(--pink);
  background:rgba(255,46,136,.14);padding:.4rem .7rem;transition:color .15s,background .15s;
  border-bottom:1px solid rgba(255,46,136,.4)}
.wiki-head:hover{color:var(--orange);background:rgba(255,158,79,.16)}
/* Плитки со скринами (было — список из 4 строк-иконок, "не цеплял глаз") — по одной картинке
   на категорию, из обложки её -overview.md статьи (см. data/wiki-meta.js). 4 позиции: Characters/
   Vehicles/Locations/Cheats — сетка 2×2. */
#wikiLinks{display:grid;grid-template-columns:1fr 1fr;gap:.5rem;padding:.5rem .7rem .6rem}
.wiki-tile{position:relative;aspect-ratio:4/3;border-radius:8px;overflow:hidden;display:block;
  box-shadow:inset 0 0 0 1px rgba(255,46,136,.35);transition:box-shadow .15s,transform .15s}
.wt-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.wt-scrim{position:absolute;inset:0;background:linear-gradient(0deg,rgba(11,6,32,.92) 15%,rgba(11,6,32,.1) 65%,transparent 100%)}
.wt-label{position:absolute;left:.5rem;bottom:.35rem;right:.5rem;font-family:var(--display);letter-spacing:.06em;
  font-size:.98rem;color:var(--sand);text-shadow:0 1px 4px rgba(0,0,0,.8)}
.wiki-tile:hover{box-shadow:inset 0 0 0 1px var(--pink),0 0 14px rgba(255,46,136,.55);transform:translateY(-2px)}

/* Вариант "list" (WIKI_TILE_STYLE, на пробу) — строки вместо сетки 2x2, узкая полоса фото фоном
   (та же картинка что в wiki-tile, просто короткая высота строки сама обрезает её в полосу). */
#wikiLinks.wiki-list{display:flex;flex-direction:column;grid-template-columns:none}
.wiki-tile-row{position:relative;height:38px;border-radius:8px;overflow:hidden;display:flex;
  align-items:center;gap:.5rem;padding:0 .7rem;box-shadow:inset 0 0 0 1px rgba(255,46,136,.35);
  transition:box-shadow .15s}
.wiki-tile-row .wt-img{opacity:.75}
.wiki-tile-row .wt-scrim{background:linear-gradient(90deg,rgba(11,6,32,.3) 45%,rgba(11,6,32,.11) 100%)}
.wiki-tile-row .wt-label{position:relative;inset:auto;font-size:.94rem}
.wiki-tile-row:hover{box-shadow:inset 0 0 0 1px var(--pink),0 0 14px rgba(255,46,136,.55)}

/* Мини-плитка ссылок внутри окна GUIDE (windows.js) — те же wiki-tile из render.js, свой grid-
   контейнер вместо #wikiLinks (id-специфичный selector там завязан на боковую панель). Плитки тут
   в разы шире боковой панели (модалка на всю ширину окна), а .wt-label/.wt-badge — фиксированный
   абсолютный rem из render.js, унаследованный от узкой боковой панели — на такой ширине читается
   мелким, хотя в px величина не менялась. Увеличиваем именно тут, под фактический размер плитки. */
.aw-wiki-grid{display:grid;grid-template-columns:1fr 1fr;gap:.5rem;margin-top:.3rem}
.aw-wiki-grid .wt-label{font-size:1.3rem}

/* ===== PROMO BILLBOARD (p2-12) — щит-рамка, ротатор фейковых брендов ===== */
/* min-height — свой обычный рост (64px -> 140px, 24-08): при нехватке высоты флекс ужимал баннер
   в полоску с обрезанной картинкой. Теперь вместо этого скроллится колонка (см. .col-right). */
.billboard{flex:1;min-height:140px;display:flex}
.pb-frame{flex:1;position:relative;display:flex;flex-direction:column;justify-content:center;gap:.25rem;
  text-decoration:none;cursor:default;
  background:linear-gradient(135deg,rgba(43,15,77,.9),rgba(122,29,94,.75) 55%,rgba(194,69,46,.6));backdrop-filter:blur(6px);
  border:2.2px solid var(--pb-accent,var(--orange));border-radius:6px;padding:.5rem .8rem;overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.5);animation:pbFlicker 8s infinite;transition:box-shadow .2s ease}
a.pb-frame{cursor:pointer}
a.pb-frame:hover{box-shadow:inset 0 0 0 1px rgba(0,0,0,.5),0 0 14px var(--pb-accent,var(--orange))}
.pb-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.pb-scrim{position:absolute;inset:0;z-index:0;
  background:linear-gradient(0deg,rgba(11,6,32,.92) 15%,rgba(11,6,32,.25) 65%,transparent 100%)}
.pb-bolt{position:absolute;width:5px;height:5px;border-radius:50%;z-index:1;
  background:var(--pb-accent,var(--orange));
  box-shadow:0 0 4px var(--pb-accent,var(--orange)),0 0 9px var(--pb-accent,var(--orange))}
.pb-bolt-tl{top:5px;left:5px}.pb-bolt-tr{top:5px;right:5px}
.pb-bolt-bl{bottom:5px;left:5px}.pb-bolt-br{bottom:5px;right:5px}
.pb-scanlines{position:absolute;inset:0;pointer-events:none;z-index:1;
  background:repeating-linear-gradient(0deg,rgba(255,255,255,.06) 0 1px,transparent 1px 3px)}
.pb-badge{font-family:var(--mono);font-size:.54rem;letter-spacing:.14em;color:var(--pb-accent,var(--orange));
  border:1px solid var(--pb-accent,var(--orange));border-radius:3px;padding:0 .3rem;width:fit-content;z-index:1}
.pb-brand{font-family:var(--display);letter-spacing:.06em;font-size:1rem;color:var(--sand);line-height:1.15;z-index:1}
.pb-tagline{font-size:.7rem;color:rgba(240,230,255,.75);line-height:1.25;z-index:1}
/* Visual-вариант (img загрузилась): текст прижимается вниз на затемнение, бейдж уходит в угол, заголовок крупнее/uppercase */
.pb-frame.pb-has-img{justify-content:flex-end}
.pb-frame.pb-has-img .pb-badge{position:absolute;top:10px;left:14px}
.pb-frame.pb-has-img .pb-brand{font-size:1.15rem;text-transform:uppercase;text-shadow:0 2px 6px rgba(0,0,0,.85)}
.pb-frame.pb-has-img .pb-tagline{text-shadow:0 1px 4px rgba(0,0,0,.85)}
/* img из R2 ещё не отдаётся (404) — диагональный паттерн вместо фото, метка PHOTO PLACEHOLDER; заменится само реальным фото */
.pb-img-ph{display:none;position:absolute;top:10px;right:14px;z-index:1}
.pb-frame.pb-img-fallback .pb-img-ph{display:block}
.pb-frame.pb-img-fallback{background:
  repeating-linear-gradient(45deg,rgba(255,255,255,.06) 0 10px,transparent 10px 20px),
  linear-gradient(135deg,rgba(43,15,77,.9),rgba(122,29,94,.75) 55%,rgba(194,69,46,.6))}
.billboard.pb-glitch .pb-frame{animation:pbGlitch .3s steps(6)}
@keyframes pbFlicker{0%,96%,100%{opacity:1}97%{opacity:.85}98%{opacity:1}99%{opacity:.7}}
@keyframes pbGlitch{0%{opacity:1;transform:translateX(0)}20%{opacity:.3;transform:translateX(-3px)}
  40%{opacity:.8;transform:translateX(3px)}60%{opacity:.2;transform:translateX(-2px)}
  80%{opacity:.9;transform:translateX(1px)}100%{opacity:0;transform:translateX(0)}}

/* Радио-виджет (Vice FM) — вынесен в css/radio.css, тот же файл грузит и wiki-src (общий плеер,
   переживает переход пульт <-> вики через общие localStorage-ключи, см. RadioDock.astro). */

/* ===== Mobile =====
   Блок специально в САМОМ КОНЦЕ файла, не рядом с десктопными правилами, которые он переопределяет:
   у медиа-запроса нет своей "бонусной" специфичности — при равной специфичности селектора обычное
   правило ниже по файлу побеждает медиа-правило выше по файлу, даже если медиа-условие подходит.
   Наступали на это трижды (.cd-widget.glow-min, .cc-respect margin) — сюда, в конец, добавлять
   дальнейшие мобильные overrides тоже, а не в середину файла рядом с тем, что они переопределяют. */
@media (max-width:900px){
  /* Флаг узкой раскладки для скриптов пульта (js/layout.js). Смысл — чтобы JS не держал свою
     копию числа 900: он спрашивает у браузера, поднят ли флаг, а не сверяет ширину сам. */
  :root{--narrow:1}

  /* --- Base page/scroll ---
     height:100vh (десктопное правило) рассчитан на один экран без прокрутки — .deck там
     ровно flex:1 внутри него. На мобильном контент выше экрана, но body остаётся коробкой
     ровно 100vh, а background-repeat по умолчанию "repeat" — картинка градиента (размером
     в одну эту коробку) начинает мозаично повторяться на прокручиваемых экранах ниже первого
     ("фон рисуется дважды"). min-height вместо height — коробка body растягивается под
     реальную высоту страницы, градиент растягивается на неё один раз, без повтора. */
  body{overflow:auto;height:auto;min-height:100vh}
  /* flex:none — иначе flex:1 (flex-basis:0%) из десктопного правила продолжает сжимать .deck
     в отведённое под 100vh место, а реальный контент переполняет эту рамку и вылезает ПОД
     тикер/футер (у них позиция считается по формальной высоте .deck, не по факту содержимого) */
  .deck{display:flex;flex-direction:column;flex:none;height:auto}
  /* 24-08 (владелец): VIDEO OF THE DAY и OFFICIAL — ПОД картой. display:contents распускает
     .col-left (его gap подхватывает gap самого .deck), дети становятся flex-элементами колонки,
     порядок задаёт order: таймер+радио (0) → карта (0, дальше по DOM) → видео/официальное (1) →
     правая колонка (2) → док (3). Fullscreen не ломается: .deck.fs .col-left{display:none}
     специфичнее и по-прежнему прячет всё разом. */
  .col-left{display:contents}
  .votd,.official-card{order:1}
  .col-right{order:2}
  .dock{order:3}
  .map-frame{height:45vh}
  .pip-video{width:200px}
  .map-ui-panel{width:100%;max-height:90%;left:0;top:auto;bottom:0;transform:translateY(8%);border-radius:12px 12px 0 0}
  .map-ui-panel.open{transform:translateY(0)}
  /* ===== Map Info на телефоне — горизонтальная полоса НАД картой, а не оверлей справа =====
     16-08(3), замер до правки: кадр 340x365, панель 128x344 — она забирала 38% ширины и 94%
     высоты, игровое поле оставалось 212px в ширину. При этом контент панели (503px) в неё всё
     равно не влезал: OPEN COLLECTION доставался только внутренним скроллом. Побочно оверлей
     стоил карточек — фильтр panelBox в hero-tiles.js выбрасывал накрытые панелью плитки (в
     узком виджете это 58 из 85); над картой её прямоугольник в координаты карты не попадает, и
     фильтр отключается сам, без правок JS.
     Высоту полосы (--strip) нужно знать числом, потому что от неё считаются смещения карты и
     fullscreen-кнопки: остальные оверлеи кадра абсолютные и о полосе не знают. Кадр вырастает
     на эту же величину — карта сохраняет свои 45vh, страница на мобиле и так скроллится.
     С 16-08(13) число здесь только СТАРТОВОЕ (до первого замера и на случай, если JS не завёлся):
     фактическую высоту панели пишет в переменную ResizeObserver в js/map.js. До этого констант
     было три — на режим, на французский и почти четвёртая на исчерпанный лимит, и каждая молча
     ломалась от новой строки в панели. Полоса теперь подстраивается под свой контент сама. */
  .map-frame{--strip:220px;height:calc(45vh + var(--strip))}
  #leafletMap{top:var(--strip)}
  /* Верх кадра на телефоне занимает полоса Map Info — кнопка ⛶ и подпись DAY/NIGHT
     начинаются под ней, а не на ней. */
  .map-fs,.map-daynight{top:calc(var(--strip) + .6rem)}
  .ai-compare-handle{top:var(--strip)}
  /* height:auto — источник высоты теперь сама полоса (см. выше). max-height — предохранитель:
     полоса не имеет права съесть больше двух третей экрана, дальше скроллится внутри себя. */
  .map-panel{top:0;left:0;right:0;width:auto;height:auto;max-height:66vh;overflow-y:auto;
    padding:.4rem .5rem;border-width:0 0 1px;border-radius:0;
    display:grid;grid-template-columns:1fr 1fr;gap:.35rem;align-content:start}
  .map-panel h3{font-size:.78rem}
  .map-panel .panel-head{grid-column:1/-1;margin:0}
  /* Сворачивать нечего: полоса больше не лежит на карте, а язычок .collapsed уезжает вбок —
     для строки во всю ширину это бессмысленный жест. */
  .map-panel .panel-collapse{display:none}
  /* Секция = строка «подпись — контролы», а не колонка: по вертикали места нет, по горизонтали
     теперь 340px. Порядок в полосе — respect и drive в одну строку (обе короткие), слои и
     коллекция во всю ширину под ними.
     justify-content:center (16-08(15) «весь текст your respect прилипает к левому краю, а должен
     центрироваться; map layer тоже отцентрируй; drive отцентрируй по плашке»): в строке-секции
     контент короче своей клетки почти всегда, и прижатый влево он читался как обрезанный. Правило
     общее на все секции, а не три частных — иначе следующая секция снова прилипнет. */
  .map-panel .panel-sect{margin:0;padding:.3rem .45rem;
    display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.3rem .45rem}
  /* Подпись секции в строке — мельче и с узким трекингом: на десктопе она стоит над контролами
     и трекинг .18em её украшает, в строке те же 4 подписи съедали 90px из 322 и роняли
     контролы на второй ряд. */
  .map-panel .panel-sect .panel-caption{margin:0;flex:none;font-size:.55rem;letter-spacing:.08em}
  /* Полоса режимов — во всю ширину и своей высотой: как обычный элемент грида она растягивалась
     на высоту соседней ячейки (замер: кнопки 105px). */
  .map-panel .panel-modes{grid-column:1/-1;margin:0;align-self:start}
  /* Правая колонка первой строки — секция ТЕКУЩЕГО режима: DRIVE в езде, MAP LAYER в разведке
     (16-08(13) «может это перекидывать в одну строку с панелькой респекта»). До этого MAP LAYER
     занимал отдельную строку во всю ширину, а рядом с RESPECT пустовала половина полосы — из-за
     этой лишней строки полоса и не сходилась по высоте. Секции соседствовать не могут: каждая
     видна только в своём режиме, значит клетка у них общая. COMPARE — исключение, семь игр в
     полколонки не лягут. */
  .map-panel .panel-sect[data-sect="respect"]{order:1}
  .map-panel .panel-sect[data-sect="drive"]{order:2}
  .map-panel .panel-sect[data-sect="layer"]{order:2}
  .map-panel .panel-sect[data-sect="compare"]{order:3;grid-column:1/-1}
  .map-panel:has(#compareSect:not(.pm-off)) .panel-sect[data-sect="respect"]{grid-column:1/-1;padding:.45rem}
  .map-panel:has(#compareSect:not(.pm-off)) .panel-respect b{font-size:1.7rem}
  .map-panel:has(#compareSect:not(.pm-off)) .panel-respect span{font-size:.7rem}
  .map-panel .panel-sect[data-sect="collection"]{order:4;grid-column:1/-1}
  /* У DRIVE подпись прячем: на телефоне кнопка внутри секции сама подписана «DRIVE», а её 37px
     были ровно теми, из-за которых кнопка и «Fog of war» не вставали в одну строку. Но только
     когда кнопка действительно есть: с 16-08(10) в секции живёт ещё и тумблер День/Ночь, и на
     телефоне (кнопки DRIVE там нет вовсе) он остался бы подписанной ничем строкой. */
  .map-panel .panel-sect[data-sect="drive"]:has(#driveModeBtn:not([hidden])) .panel-caption{display:none}
  /* А совсем пустую секцию (нет ни кнопки DRIVE, ни тумблера ночи) прячем целиком — это был бы
     просто цветной прямоугольник ни о чём. */
  .map-panel .panel-sect[data-sect="drive"]:not(:has(#driveModeBtn:not([hidden]))):not(:has(#nightRow:not([hidden]))){display:none}
  .map-panel .map-ui-btns{flex-direction:row;align-items:center;justify-content:center;gap:.4rem}
  /* Кнопка DRIVE — своей строкой НАД тумблером Дня/Ночи, сегмент Original/Realistic — своей строкой
     под подписью слоя (16-08(14)). Строка секции широкая не везде одинаково: на 375px эти пары и
     так переносились, а на планшетном конце того же медиазапроса (полсекции ~390px) вставали в
     один ряд — кнопка режима читалась как часть тумблера, а переключатель слоя как часть подписи.
     Перенос задаём явно, чтобы вид не зависел от ширины телефона. */
  .map-panel .panel-sect[data-sect="drive"] .map-ui-btns,
  .map-panel .panel-sect[data-sect="drive"] .daynight-row,
  .map-panel .panel-sect[data-sect="layer"] .ai-seg{flex:1 1 100%}
  .map-panel #driveModeBtn{width:auto;padding:.26rem .5rem}
  /* Ужимаем ровно то, что не влезало в строку 322px: сегмент слоя, «Show cards» и кнопку
     коллекции (замер: без этого MAP LAYER переносился в две строки, COLLECTION — в три). */
  .map-panel .panel-collect{width:auto;flex:none;font-size:.58rem;padding:.26rem .4rem;gap:.3rem}
  .map-panel .ai-seg-btn{font-size:.56rem;padding:.24rem .3rem}
  .map-panel .fog-row{font-size:.58rem;gap:.25rem}
  /* margin-inline:-8px с десктопа тут не нужен: в полосе тумблер занимает свою строку целиком и
     отрицательные поля просто вывешивали его на 8px за рамку секции. По центру своей строки —
     как и кнопка DRIVE над ним (16-08(15)). */
  .map-panel .daynight-row{gap:.25rem;margin-inline:0;justify-content:center}
  /* COMPARE списком (16-08(12)): на десктопе это столбик, в полосе телефона семь строк съели бы
     её целиком — тут две колонки во всю ширину секции. Строка «название — площадь» та же. */
  .map-panel .cmp-btns{flex:1 1 100%;display:grid;grid-template-columns:1fr 1fr;gap:.25rem}
  .map-panel .cmp-btns .map-ui-btn{padding:.26rem .38rem;font-size:.68rem}
  .map-panel .cmp-btns .map-ui-btn i{font-size:.6rem}
  .map-panel .cmp-alpha{flex:1 1 100%;margin-top:.15rem}
  .map-ui-btn{font-size:.6rem;padding:.26rem .2rem}
  .hero-explored{font-size:.6rem}
  /* Разбивка по редкости на телефоне ЕСТЬ (16-08(14): «в коллекции другие слайдеры исчезают»).
     19-08 «в мобильной версии раздел коллекций выглядит странновато — мб open collection справа
     и ползунки прогресса слева»: было четыре этажа (подпись+кнопка, счётчик, общая полоса, четыре
     полосы редкости) на 152px высоты. Теперь одна строка: слева счётчик с полосами, справа кнопка.
     Подпись COLLECTION скрыта — на кнопке рядом написано ровно то же слово, а её 60px и роняли
     кнопку в отдельную строку. Тот же приём, что у DRIVE выше. */
  .map-panel .panel-sect[data-sect="collection"]{flex-wrap:nowrap;align-items:center;gap:.4rem}
  /* 23-08 «кнопку open collection на всю плашку»: на телефоне секция — ОДНА широкая кнопка,
     счётчик Cards N/88 и полосы редкости скрыты (все живут в окне COLLECTION). Отменяет 16-08(14),
     где полосы на телефоне просили оставить; вернуть — убрать display:none ниже. */
  .map-panel .tier-bars,
  .map-panel .panel-sect[data-sect="collection"] .hero-explored{display:none}
  /* Кнопка на всю плашку, подпись по центру: первый span растягивается и центрует текст,
     ⤢ остаётся у правого края (margin-left:auto ему больше не нужен — даёт flex-раскладка). */
  .map-panel .panel-sect[data-sect="collection"] .panel-collect{flex:1 1 100%;width:100%;font-size:.66rem;padding:.4rem}
  .map-panel .panel-sect[data-sect="collection"] .panel-collect > span:first-child{flex:1;text-align:center}
  /* ⛶ на телефоне (23-08 «странный переход при раскрытии карты»): раньше .fs лишь прятал колонки,
     а кадр карты оставался на своём месте высотой 45vh + полоса — «полноэкранность» не читалась.
     Теперь кадр становится фиксированным оверлеем на весь экран (полоса Map Info остаётся сверху
     внутри кадра), страница под ним не скроллится; повторный ⛶ возвращает как было. */
  body:has(.deck.fs){overflow:hidden}
  .deck.fs .map-frame{position:fixed;inset:0;height:auto;z-index:1000;border-radius:0;border-width:0}
  .map-panel .panel-sect[data-sect="collection"] .panel-caption{display:none}
  .map-panel .hero-explored{flex:1 1 auto;min-width:0;margin-top:0}
  .map-panel .panel-collect{flex:none;width:auto;margin-top:0}
  .map-panel .tier-bars{margin-top:.3rem;gap:.15rem .3rem}
  .map-panel .tier-bar-name,.map-panel .tier-bar-num{font-size:.5rem}
  /* Верх кадра на мобиле занимает полоса Map Info — табличка начинается под ней, а не на ней.
     И ниже ряда кнопок (34px + зазор): на 390px её 86% ширины перекрывали ⛶ и подпись DAY/NIGHT,
     а табличка ловит клики — кнопка становилась недоступной, пока её не закроешь. */
  .night-brief{top:calc(var(--strip) + .6rem + 34px + .4rem)}
  /* Плитки вики крупнее на ~5% (владелец, 31-08): ряд WIKI | SPOTLIGHT остаётся половинным,
     место берётся из внутренних отступов панели, а не из ширины колонки. Кегль подписи не
     трогаем — на телефоне действует базовые .98rem, правило .8rem лежит в блоке низкого
     ДЕСКТОПА (min-width:901px), к телефону отношения не имеет. */
  #wikiLinks{padding:.5rem .45rem .6rem;gap:.55rem}

  /* --- КАРТОЧКА НАХОДКИ НА ТЕЛЕФОНЕ (31-08, три захода по фидбэку владельца).
     На десктопе карточка живёт ВНУТРИ кадра карты и это правильно: кадр там целиком на экране.
     На телефоне кадр ВЫШЕ вьюпорта (замер 404×874: кадр занимает 425→1039), поэтому
     центрирование по кадру уводило низ карточки на 42px под нижнюю границу экрана — чтобы
     дочитать, приходилось скроллить страницу под затемнением. Отсюда «карточка перекрывает
     весь экран, ничего не влезает».
     Решение: на телефоне это обычная модалка по вьюпорту. Три правки ниже связаны и по
     отдельности не работают — position:fixed без z-index даёт карточку, разрезанную полосой
     Map Info; каркас без fixed даёт карточку за нижним краем экрана. */

  /* z:2002 — выше .map-panel (2001). Панель поднята над оверлеем намеренно: на десктопе она
     сбоку, и прогресс коллекции не должен затемняться рядом с карточкой. На телефоне это
     полоса поперёк кадра, и при модальном оверлее она ложилась ровно на карточку. */
  .hero-card-overlay{position:fixed;z-index:2002}

  /* Ширина и СТАРТОВАЯ высота картинки. Дальше её ужимает flex из базового правила .hero-card
     (место отдаёт только картинка, текст не сжимается). Замеры: 404×874 и 375×812 — 19vh
     хватает целиком; 360×640 — картинка ужимается до 96; 740×360 — до предела 56.
     Скрытого текста ни в одном случае нет. */
  .hero-card{width:min(380px,94vw)}
  .hero-card img{aspect-ratio:auto;height:19vh}

  /* Бейдж редкости в 1.9rem съедал треть ширины и перетягивал внимание с названия находки. */
  .hero-card-tier{font-size:1.15rem;letter-spacing:.1em}
  .hero-card-body h4{font-size:.95rem}

  /* --- Top bar: лого в 2 строки + мельче, узкие кнопки, компактный fan-badge справа.
     minmax(0,auto) 1fr minmax(0,auto) — лого и fan-badge занимают свою естественную ширину, но
     МОГУТ сжаться меньше min-content, если не хватает места (иначе голый auto держит min-content
     жёстко, и вся строка выталкивается за экран — что и происходило: bare auto не давал badge
     ужаться даже с white-space:normal). Вся свободная середина уходит трём кнопкам. */
  /* Топбар в ДВЕ строки (16-08(12), «на мобилках всё едет»). Замер до правки на 375px: в одну
     строку просились лого (104px) + переключатель языка + три кнопки + бейдж — суммарно ~400px
     при экране 375. Грид молча отдавал лишнее соседям, и «HUB» с языком уезжали ПОД кнопку Join
     Discord (см. скриншот раунда). Теперь первая строка — лого/язык слева и бейдж справа, вторая —
     три кнопки во всю ширину. Высота топбара перестаёт быть фиксированной: flex-basis var(--top-h)
     держал 3.2rem, а двум строкам нужно больше. */
  /* 23-08: шапка в ДВЕ строки (владелец: «5 элементов в ряд странновато»): первая — лого ·
     язык · Support (без ☕) · бейдж, вторая — Discord (иконка) + Sign in with Google во всю
     ширину. Обёртки сняты display:contents, раскладку держит грид по явным клеткам; колонка 3 —
     1fr-распорка первой строки. Залогиненное меню (.user-menu, store.js) встаёт в клетку кнопки. */
  .topbar{flex:0 0 auto;display:grid;grid-template-columns:auto auto 1fr auto auto;align-items:center;gap:.3rem;padding:.3rem .5rem}
  .topbar-left,.topbar-center,.topbar-right{display:contents}
  /* 31-08: padding был .42rem при кегле .66rem — кнопки выходили 177×26 с текстом 10.5px.
     Это два главных CTA сайта, по ним и промахиваются пальцем. Высота доведена до 38px,
     кегль до 12.5px; ширина не тронута, её задаёт сетка ниже (#discordTop / #subBtn). */
  .topbar .btn{white-space:nowrap;text-align:center;padding:.6rem .5rem;font-size:.78rem;
    min-height:38px;display:inline-flex;align-items:center;justify-content:center}
  .topbar .logo{grid-row:1;grid-column:1}
  .topbar .lang-switch{grid-row:1;grid-column:2;justify-self:start}
  /* 31-08: summary был 48×22, пункты меню 39×20 — мимо пальца. У summary вид не трогаем
     (padding превращал компактную пилюлю в кружок) — зону нажатия растит прозрачный ::after,
     как у транспорта радио. Слева до логотипа 13px, поэтому −6px по бокам безопасны.
     Пункты выпадающего меню растим по-настоящему: они ничему не мешают. */
  .topbar .lang-switch > summary{position:relative}
  .topbar .lang-switch > summary::after{content:'';position:absolute;inset:-8px -5px}
  .lang-menu a{padding:.5rem .7rem}
  #supportBtn{grid-row:1;grid-column:4}
  .topbar-right .fan-badge{grid-row:1;grid-column:5}
  #discordTop{grid-row:2;grid-column:1/6;justify-self:start;width:calc(50% - .15rem);justify-content:center}
  #subBtn{grid-row:2;grid-column:1/6;justify-self:end;width:calc(50% - .15rem);min-width:0;overflow:hidden;text-overflow:ellipsis}
  .topbar .user-menu{grid-row:2;grid-column:1/6;justify-self:end;max-width:60%}
  .btn-coffee .btn-emoji{display:none}
  /* Подписи вики-плиток: на телефоне панель занимает полширины, плитка внутри неё — 67px, и
     «CHARACTERS» (70px при .98rem) обрезалось прямо посреди слова (16-08(12)). .7rem с узким
     трекингом — 45px, влезает самое длинное из четырёх названий. */
  .wt-label{font-size:.7rem;letter-spacing:.02em}
  .logo{display:block;font-size:.8rem;line-height:1.15;flex:none}
  .logo-a{display:block}
  /* inline-block на частях названия — страховка от наезда: между атомарными инлайнами перенос
     разрешён, поэтому на совсем узком экране (или при крупном системном шрифте) «HUB» уйдёт на
     третью строку, а не под соседа. Слово InteractiveHUB само по себе неразрывное. */
  .logo-b,.logo-c{display:inline-block}
  .fan-badge{display:block;font-size:.52rem;padding:.22rem .4rem;white-space:normal;text-align:center;max-width:6.2rem;line-height:1.3}

  /* --- Countdown widget --- */
  .cd-widget{padding:.6rem .6rem;
    background:radial-gradient(circle at 50% 130%,rgba(255,158,79,.65),rgba(255,46,136,.3) 55%,transparent 75%),
      linear-gradient(135deg,rgba(43,15,77,.9),rgba(122,29,94,.82) 60%,rgba(194,69,46,.75))}
  .sun-mini-label,.horizon-mini,.cdw-trailer{display:none}
  .sun-mini{width:auto;aspect-ratio:auto;border-radius:0;background:none;box-shadow:none;padding:0;
    justify-content:center;overflow:visible}
  .sun-mini::before{display:none}
  .countdown{justify-content:center;width:100%}
  /* ежесекундный glow-фильтр на цифре секунд — на "00" два нуля рядом сливались в один яркий блик;
     на мобильном (и так самая мелкая деталь на экране) просто гасим */
  .cd-num.pulse{filter:none}
  /* ежеминутная вспышка всей карточки таймера — на мобильном фоне это читалось как "загорается
     полупрозрачный прямоугольник" (карточка и так прямоугольная, широкий box-shadow вокруг неё
     смотрится как отдельная плашка, а не акцент) */
  .cd-widget.glow-min{box-shadow:none;border-color:inherit}
  /* .sun-mini.pulse-min — тот самый "тёмный квадрат"/"вертикальная полоса" раз в минуту, который
     не гасился предыдущими правками: это CSS @keyframes-анимация (sunpulse), а не обычное
     правило box-shadow. Анимация всегда выигрывает у обычных объявлений для своего свойства,
     сколько бы ни было "box-shadow:none" рядом — единственный способ погасить именно animation.
     На мобильном .sun-mini растянут на всю ширину виджета (под ним — цифры таймера), поэтому
     этот блик рисовался широкой светящейся полосой через весь экран. */
  .sun-mini.pulse-min{animation:none}

  /* Community-карточка — одна колонка на всех ширинах (см. блок COMMUNITY CARD выше),
     переопределять на мобильном нечего. */

  /* --- LEONIDA WIKI | PROMO — 2 колонки рядом под карточкой Community. Без align-items:start
     (default stretch) — иначе billboard (короче контентом) выглядит сплющенным против wiki-panel;
     обе колонки растягиваются на высоту более высокой — .billboard/.pb-frame уже flex:1 внутри
     под это рассчитаны (см. базовые правила), просто раньше не получали растянутую высоту. */
  .col-right{display:grid;grid-template-columns:1fr 1fr;column-gap:.5rem;row-gap:.6rem}
  .community-card{grid-column:1/-1}
  .wiki-panel{grid-column:1}
  .billboard{grid-column:2}

  /* --- VIDEO OF THE DAY / OFFICIAL: сам аккордеон — в общем блоке у BOTTOM DOCK (телефон+ноутбук).
     Здесь только трейлер-луп: в колонке высоты ему никто не даёт (flex:1 от нулевого остатка), и
     раскрытый OFFICIAL показывал полосу скриншотов и пустоту над ней. */
  .official-card[data-open="true"] .pip-video{flex:0 0 auto;aspect-ratio:16/9}

  /* --- LIVE WIRE/WEAZEL/SECRET — аккордеон вместо трёх сжатых колонок: список строк друг за
     другом, развёрнута только одна (клик по заголовку — см. windows.js) */
  .dock{display:flex;flex-direction:column;height:auto}
  .dock-cell{flex:0 0 auto}
  .dock-cell+.dock-cell{border-left:none;border-top:1px solid rgba(232,185,35,.55)}
  .dock-cell[data-open="true"] .feed-scroll{max-height:44vh} /* сам аккордеон — общий блок у BOTTOM DOCK */

  /* ===== 28-08, правки по мобильной вёрстке (владелец) ===== */

  /* Кадр уходит в position:fixed, его высота пропадает из потока — шапке и подвалу
     в полноэкранном режиме делать нечего. */
  body:has(.deck.fs) .site-footer,
  body:has(.deck.fs) .topbar,body:has(.deck.fs) .mobile-tail{display:none}

  /* Порядок блоков: строка LEONIDA WIKI | SPOTLIGHT переезжает под плеер. .deck из flex-колонки
     становится гридом в две колонки — эта строка единственная, кто делит ширину пополам, всё
     остальное во всю ширину. Обе колонки распущены (display:contents), поэтому порядок задаётся
     поэлементно, а не через порядок обёрток. grid-template-areas/rows с десктопа обязательно
     гасим: без этого именованные области "left map right" продолжают раскладывать элементы. */
  .deck{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:none;grid-template-areas:none;
    padding:.8rem .5rem;gap:.6rem}
  /* grid-area здесь ПЕРВЫМ и только ради сброса именованных областей десктопа: это шорткат,
     он включает в себя grid-column, и стоя следом затирал бы его значением auto. Именно так
     карта и док и уехали в одну колонку из двух (карта 164px на экране 375). */
  .deck > *{grid-area:auto;grid-column:1/-1}
  .col-right{display:contents}
  .cd-widget,#radioWidget,.votd,.official-card,.community-card{grid-column:1/-1}
  .cd-widget{order:1}
  #radioWidget{order:2}
  .wiki-panel{order:3;grid-column:1}
  .billboard{order:4;grid-column:2}
  .map-frame{order:5;grid-column:1/-1}
  .votd,.official-card{order:6}
  .community-card{order:7}
  .dock{order:8;grid-column:1/-1}

  /* Таймер: подпись над цифрами возвращается (на десктопе она лежит на солнце, на телефоне
     солнце сплющено — раньше подпись просто гасили вместе с ним). Градиентная заливка текста
     здесь не читается поверх свечения виджета, поэтому обычный цвет. Цифры крупнее — таймер
     главный элемент первого экрана. */
  .sun-mini-label{display:block;background:none;-webkit-text-fill-color:currentColor;color:var(--sand);
    filter:none;font-size:1.05rem;letter-spacing:.16em;margin-bottom:.45rem;text-align:center}
  html[lang="es"] .sun-mini-label,html[lang="pt-br"] .sun-mini-label{font-size:.82rem;letter-spacing:.08em}
  .cd-widget{padding:.85rem .8rem}
  .cd-num{font-size:2.15rem}
  .cd-unit{font-size:.9rem}
  .countdown{gap:.6rem}

  /* Map Info встречает свёрнутой: над картой одна шапка со стрелкой, кадр целиком под карту.
     Разворот — та же кнопка, что и на десктопе (js/map.js), поэтому её здесь больше не прячем;
     повёрнута на 90°, потому что полоса складывается вверх, а не вбок. Прячем содержимое, а не
     уезжаем transform'ом: у полосы во всю ширину боковой сдвиг бессмыслен — ровно поэтому
     кнопку тут когда-то и убрали. --strip пересчитает ResizeObserver сам. */
  .map-panel .panel-collapse{display:block;transform:rotate(90deg);width:2.6rem;height:2.6rem;font-size:1.9rem;opacity:1}
  /* Десктопный .collapsed уезжает transform'ом вбок и прячет всё, кроме стрелки, — для полосы
     во всю ширину это оставляло голую стрелку у правого края. На телефоне складываем вверх:
     полоса остаётся на месте, в ней подпись и стрелка, содержимое скрыто. */
  .map-panel.collapsed{transform:none;padding-block:.3rem;border-radius:0;border-width:0 0 1px}
  .map-panel.collapsed .panel-head > *:not(.panel-collapse){display:block}
  .map-panel.collapsed .panel-collapse{width:auto;height:auto;font-size:1.9rem;padding:.1rem .5rem;opacity:1}
  .map-panel.collapsed .panel-modes,.map-panel.collapsed .panel-sect{display:none}

  /* Support и бейдж «Independent fan-made» уезжают из шапки в подвал (их переносит скрипт в
     конце index.html). Строка над футером, кнопки во всю ширину — это уже не навигация. */
  .mobile-tail{display:flex;gap:.5rem;justify-content:center;align-items:center;
    padding:.6rem .8rem;flex-wrap:wrap}
  .mobile-tail .btn{flex:1 1 auto;justify-content:center}
  .mobile-tail .fan-badge{max-width:none}
}

/* Меню аккаунта в шапке (js/store.js, Render.userMenu) — поверх .lang-switch/.lang-menu, своего
   дропдауна нет. Аватар — картинка Google, хендл обрезается, чтобы шапка не расползалась. */
.user-menu summary{display:inline-flex;align-items:center;gap:.35rem;max-width:11rem}
.user-avatar{width:18px;height:18px;border-radius:50%;object-fit:cover}
.user-handle{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.user-menu-list{flex-direction:column;align-items:stretch;min-width:11rem;gap:.25rem}
/* Крючок гостя «осталось мест» — в виджете YOUR RESPECT под строкой «Log in to save…» (из шапки
   убран 22-08: читался третьей кнопкой). Полный текст крючка — в окне RESPECT. */
.crew-hook{display:inline-block;margin-top:.35rem;font-family:var(--mono);font-size:.62rem;font-weight:700;letter-spacing:.06em;white-space:nowrap;
  color:var(--muted);background:rgba(11,6,32,.6);border:1px solid rgba(169,159,196,.4);border-radius:999px;
  padding:.22rem .55rem;cursor:pointer}
.crew-hook:hover{color:var(--sand);border-color:var(--muted)}
/* Плашка Vice Crew #N — в виджете YOUR RESPECT (вместо строки «Log in to save…») и в окне RESPECT
   над объяснением. Обводка + фон + жирный: это бейдж, а не подпись. */
.crew-badge{display:inline-block;font-family:var(--mono);font-size:.82rem;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap;color:var(--orange);background:rgba(255,158,79,.14);
  border:1.5px solid var(--orange);border-radius:6px;padding:.3rem .75rem;margin-top:.45rem;cursor:pointer;
  box-shadow:0 0 10px rgba(255,158,79,.25)}
.crew-badge:hover{background:rgba(255,158,79,.26)}
/* Отдельная плашка участника в подвале окна RESPECT: бейдж + объяснение (или «Vice Crew is full») в одной рамке. */
.crew-card{flex-basis:100%;display:flex;flex-direction:column;align-items:center;gap:.35rem;padding:.7rem .9rem;
  border:1px solid rgba(255,158,79,.45);border-radius:10px;background:rgba(255,158,79,.07)}
.crew-card .crew-badge{margin:0}
/* Ник под плашкой (Render.nickForm, 004): summary «Your nick: name · Change nick», раскрытая форма
   одной строкой. Первый вход — раскрыта по умолчанию (details open). */
.nick-edit{flex-basis:100%;text-align:center;font-size:.8rem;color:var(--muted);margin-top:.15rem}
.nick-edit summary{cursor:pointer;list-style:none;padding:.25rem 0}
.nick-edit summary::-webkit-details-marker{display:none}
.nick-cur{color:var(--sand);font-family:var(--mono)}
.nick-change{color:var(--orange);text-decoration:underline dotted;margin-left:.35rem}
.nick-form{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:.5rem;margin-top:.4rem}
.nick-form input{font-family:var(--mono);font-size:.85rem;width:12rem;max-width:100%;padding:.3rem .55rem;color:var(--sand);
  background:rgba(11,6,32,.7);border:1px solid rgba(169,159,196,.45);border-radius:8px;outline:none}
.nick-form input:focus{border-color:var(--orange)}
.nick-msg{flex-basis:100%;color:var(--pink);font-size:.76rem;min-height:1em}
.nick-hint{flex-basis:100%;font-size:.7rem;opacity:.8}
.cc-lb-hook{flex-basis:100%;text-align:center;font-size:.8rem;color:var(--muted);line-height:1.45}
.cc-lb-crew{text-align:center;font-size:.8rem;color:var(--sand);font-weight:600;line-height:1.45}
.user-signout{font:inherit;color:var(--muted);background:none;border:1px solid transparent;border-radius:999px;padding:.2rem .55rem;cursor:pointer;text-align:left}
.user-signout:hover{color:var(--pink);border-color:var(--pink)}
