/* ДетекторСбоев.рф v3 — «ситуационный экран».
   Тёмная диспетчерская: нефтяная синева, светящиеся статус-огни,
   Unbounded для крупных цифр, Inter для текста, JetBrains Mono для данных.
   Сервер рендерит всё; JS — островок (карта-тултипы, живое обновление). */

/* ── Шрифты (self-host, subset-split: браузер качает только нужный) ──
   ФОРМАТ ТОЛЬКО 'woff2' (v5.50). Стояло 'woff2-variations' — устаревший
   синтаксис, который Firefox НЕ ПОНИМАЕТ: он отбрасывал такой @font-face
   целиком, страница показывалась системным шрифтом, а предзагруженные файлы
   висели неиспользованными (в консоли — «ресурс, загруженный по ссылке для
   предварительной загрузки, не был использован»). Вариативные оси прекрасно
   работают и с обычным format('woff2') во всех живых браузерах. */
@font-face{font-family:'Unbounded';font-style:normal;font-weight:200 900;font-display:swap;
  src:url('/assets/fonts/unbounded-cyrillic-wght-normal.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'Unbounded';font-style:normal;font-weight:200 900;font-display:swap;
  src:url('/assets/fonts/unbounded-latin-wght-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2212}
@font-face{font-family:'InterV';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('/assets/fonts/inter-cyrillic-wght-normal.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'InterV';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('/assets/fonts/inter-latin-wght-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+2000-206F,U+20AC,U+2122,U+2212}
@font-face{font-family:'JBMono';font-style:normal;font-weight:400;font-display:swap;
  src:url('/assets/fonts/jetbrains-mono-cyrillic-400-normal.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+2116}
@font-face{font-family:'JBMono';font-style:normal;font-weight:400;font-display:swap;
  src:url('/assets/fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+2000-206F}
@font-face{font-family:'JBMono';font-style:normal;font-weight:700;font-display:swap;
  src:url('/assets/fonts/jetbrains-mono-cyrillic-700-normal.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+2116}
@font-face{font-family:'JBMono';font-style:normal;font-weight:700;font-display:swap;
  src:url('/assets/fonts/jetbrains-mono-latin-700-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+2000-206F}

:root{
  /* ОДНА ШИРИНА СТРАНИЦЫ (7.11, просьба владельца «без ступенек»). Шапка,
     карта-шапка, main и подвал берут поле и максимум ОТСЮДА. Раньше числа
     жили в четырёх правилах порознь, и карта внутренних страниц была на 32 px
     шире содержимого с каждой стороны, а на ширине 640–760 px шапка уже
     сузила поле до 14 px, когда main ещё держал 32. */
  --page-max:1400px; --gutter:32px;
  --bg:#0a0f1a; --bg2:#0d1424;
  --panel:#111a2e; --panel2:#152039;
  --line:rgba(148,163,190,.13); --line2:rgba(148,163,190,.26);
  --ink:#e9eef7; --muted:#93a1b8; --faint:#5b6a84;
  --ok:#31d98a; --warn:#ffb224; --part:#ff8a3d; --down:#ff5063;
  /* «нет связи» — не красный: до сервиса не достучались, и виновата может быть
     наша сеть. Приглушённый сине-серый читается как «данных нет», а не «упало». */
  --nolink:#7c8bb0;
  --ok-dim:rgba(49,217,138,.12); --warn-dim:rgba(255,178,36,.12); --part-dim:rgba(255,138,61,.13); --down-dim:rgba(255,80,99,.13);
  /* ── ДВЕ ПЕРЕМЕННЫЕ, КОТОРЫХ НЕ БЫЛО ВОВСЕ (v6.95) ────────────────────
     `--card` и `--accent` использовались с запасным значением — var(--card,#fff),
     var(--accent,#2b6cb0) — но НИГДЕ не объявлялись. Запасное значение поэтому
     работало ВСЕГДА, в обеих темах. Для полей ввода это давало БЕЛЫЙ фон при
     тёмной теме, а цвет текста наследовался светлый: белым по белому — ровно
     то, что владелец прислал на скриншотах регистрации, входа и восстановления
     пароля. Заодно кнопка «Выслать ссылку» красилась чужим синим, к палитре
     сайта отношения не имеющим.
     Теперь обе объявлены и, как всё остальное, переопределяются светлой темой. */
  --card:#0f1729;
  --accent:#31d98a; --accent-ink:#06210f;
  --display:'Unbounded','InterV',system-ui,sans-serif;
  --sans:'InterV',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --mono:'JBMono',ui-monospace,Consolas,monospace;
  --r:14px;
}
*{box-sizing:border-box}
html{color-scheme:dark;scroll-behavior:smooth}
body{margin:0;color:var(--ink);font:16px/1.6 var(--sans);background:var(--bg);
  background-image:
    radial-gradient(1000px 460px at 78% -160px, rgba(255,80,99,.09), transparent 60%),
    radial-gradient(760px 420px at 8% -140px, rgba(72,132,255,.10), transparent 60%);
  background-repeat:no-repeat}
main{max-width:var(--page-max);margin:0 auto;padding:0 var(--gutter) 56px}
a{color:inherit;text-decoration-color:var(--faint);text-underline-offset:3px}
a:hover{text-decoration-color:var(--ink)}
a:focus-visible,button:focus-visible,select:focus-visible,input:focus-visible{
  outline:2px solid var(--ok);outline-offset:2px;border-radius:4px}
::selection{background:rgba(255,80,99,.35)}

/* ── Шапка ── */
/* ── Герой: текст + кольцо индекса ── */
.hero{display:flex;gap:32px;align-items:center;margin:14px 0 8px}
.hero-txt{flex:1;min-width:0}
h1{font-size:clamp(25px,3.8vw,36px);line-height:1.18;letter-spacing:-.6px;
  margin:.25em 0 .4em;font-weight:700}
h2{font-size:14px;font-family:var(--display);font-weight:500;letter-spacing:.6px;
  text-transform:uppercase;color:var(--muted);margin:2.1em 0 .8em}
/* ТЕКСТОВЫЕ КОЛОНКИ — ВО ВСЮ ШИРИНУ СОДЕРЖИМОГО (7.11, просьба владельца
   «везде одна ширина, без ступенек»). Лид в 58ch, «прозу» в 68ch и вопросы в
   80ch когда-то сузили ради читаемости строки; но на широком экране они
   рисовали второй, узкий край страницы под первым, широким. Владелец уже
   решал этот спор в 7.05 для /proverka — лид во всю ширину панели; теперь то
   же правило для всех. Читаемость держим межстрочным, а не шириной. */
.lead{color:var(--muted);margin:0 0 16px;max-width:none;line-height:1.55}
.lead-sm{font-size:14px;max-width:none}
.board{font-family:var(--mono);font-size:13px;color:var(--muted);
  display:inline-flex;align-items:center;gap:9px;flex-wrap:wrap;
  border:1px solid var(--line);border-radius:99px;padding:8px 16px;background:rgba(255,255,255,.02)}

/* кольцевой гейдж индекса стабильности */
.ring{flex-shrink:0;position:relative;width:172px;height:172px}
.ring svg{transform:rotate(-90deg);display:block;width:100%;height:100%}
.ring .tr{fill:none;stroke:var(--panel2);stroke-width:11}
.ring .vl{fill:none;stroke-width:11;stroke-linecap:round;transition:stroke-dashoffset .9s cubic-bezier(.2,.7,.2,1);
  filter:drop-shadow(0 0 4px currentColor)}
.ring .vl.ok{stroke:var(--ok);color:var(--ok)} .ring .vl.warn{stroke:var(--warn);color:var(--warn)}
.ring .vl.part{stroke:var(--part);color:var(--part)}
.ring .vl.down{stroke:var(--down);color:var(--down)}
@media (prefers-reduced-motion:no-preference){
  .ring .vl{animation:ringpulse var(--pulse,6s) ease-in-out infinite}
}
@keyframes ringpulse{50%{filter:drop-shadow(0 0 8px currentColor);opacity:.82}}

.ring-c{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center}
.ring-num{font-family:var(--display);font-size:44px;font-weight:700;line-height:1;letter-spacing:-1px;
  font-variant-numeric:tabular-nums}
.ring-num.ok{color:var(--ok)} .ring-num.warn{color:var(--warn)} .ring-num.part{color:var(--part)} .ring-num.down{color:var(--down)}
.ring-lbl{font-size:10.5px;letter-spacing:.4px;color:var(--muted);max-width:118px;line-height:1.4;margin-top:7px;
  text-transform:uppercase}

/* ── Панели ── */
.panel{background:linear-gradient(180deg,var(--panel2),var(--panel));
  border:1px solid var(--line);border-radius:var(--r);padding:18px 20px;margin:20px 0;
  box-shadow:0 20px 44px -24px rgba(0,0,0,.6)}
.panel>h2:first-child{margin-top:2px}
.panel-cap{font-size:13px;color:var(--muted);margin:8px 0 0}

/* ── Лампы, чипы ── */
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;vertical-align:1px;flex-shrink:0}
.dot.ok{background:var(--ok);box-shadow:0 0 8px var(--ok)}
.dot.warn{background:var(--warn);box-shadow:0 0 8px var(--warn)}
.dot.part{background:var(--part);box-shadow:0 0 9px var(--part)}
.dot.down{background:var(--down);box-shadow:0 0 10px var(--down)}
.chip{display:inline-flex;align-items:center;gap:7px;font-size:13.5px;font-weight:600;
  padding:5px 13px;border-radius:99px;white-space:nowrap}
/* ФАКТЫ РЕСУРСА В СТРОКУ (7.11). Чип держит текст в одну строку (nowrap) — это
   правильно для «ОК» и «64 дня», но чип с фразой «Чёрные списки: не
   проверялось 16 часов — прежний ответ устарел» на 400 px уезжал за край и
   тянул за собой всю страницу вбок (замер: 533 px при окне 400). Длинные чипы
   в этой строке — с переносом и без нижнего радиуса-«таблетки». */
.svc-facts{display:flex;flex-wrap:wrap;gap:8px}
.svc-facts .chip{white-space:normal;max-width:100%;border-radius:12px;line-height:1.35;text-align:left}
.chip.ok{color:var(--ok);background:var(--ok-dim)}
.chip.warn{color:var(--warn);background:var(--warn-dim)}
.chip.part{color:var(--part);background:var(--part-dim)}
.chip.down{color:var(--down);background:var(--down-dim)}

/* ── Таблица сервисов ── */
table.svc{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}
table.svc td{padding:11px 8px;border-bottom:1px solid var(--line);vertical-align:middle}
table.svc tr:last-child td{border-bottom:0}
table.svc tr:hover td{background:rgba(255,255,255,.025)}
table.svc td:first-child{width:52%}
table.svc a{text-decoration:none;font-weight:550}
table.svc a:hover{color:#fff;text-decoration:underline}
.num{font-family:var(--mono);font-size:12.5px;color:var(--muted)}
.st{text-align:right;white-space:nowrap}

/* ── Категории сервисов (сворачиваемые, работают без JS) ── */
/* Категории на главной — такие же плитки, как сервисы, в сетке 2–4 колонки.
   Свёрнуты по умолчанию; при раскрытии плитка занимает всю ширину строки. */
.cats:not(.admin-cats){display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:12px;margin-top:8px;align-items:start}
@media (min-width:900px){.cats:not(.admin-cats){grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (min-width:1200px){.cats:not(.admin-cats){grid-template-columns:repeat(4,minmax(0,1fr))}}
/* даже на самых узких экранах — две колонки (как просил пользователь) */
@media (max-width:420px){
  .cats:not(.admin-cats){gap:9px}
  .cats:not(.admin-cats) .cat>summary{padding:10px 11px;gap:5px 8px}
  .cats:not(.admin-cats) .cat>summary .cat-title{font-size:13px}
  .cats:not(.admin-cats) .cat>summary .cat-num{font-size:10.5px}
  .cats:not(.admin-cats) .cat-chip .chip{font-size:11px;padding:2px 8px}
}
/* раскрытая категория растягивается на всю строку — плитки внутри дышат */
.cats:not(.admin-cats) .cat[open]{grid-column:1/-1}

/* админка остаётся колонкой */
.admin-cats{display:flex;flex-direction:column;gap:10px;margin-top:8px}
.cat{border:1px solid var(--line);border-radius:12px;overflow:hidden;
  background:linear-gradient(180deg,rgba(255,255,255,.02),transparent)}
/* --- Плитка-категория (главная): компактно, в две строки --- */
.cats:not(.admin-cats) .cat{border:1.5px solid var(--line2);background:var(--panel2);
  transition:border-color .15s,box-shadow .15s,transform .15s}
.cats:not(.admin-cats) .cat:hover{border-color:var(--accent,#5b8bd6);
  box-shadow:0 6px 18px -10px rgba(0,0,0,.6)}
.cats:not(.admin-cats) .cat>summary{display:grid;gap:6px 10px;padding:13px 14px;cursor:pointer;
  list-style:none;user-select:none;
  grid-template-columns:20px minmax(0,1fr) 14px;
  grid-template-areas:'ico title arrow' 'spark spark spark' 'chip chip num'}
.cats:not(.admin-cats) .cat>summary .cat-ico{grid-area:ico}
.cats:not(.admin-cats) .cat>summary .cat-title{grid-area:title;font-size:14.5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cats:not(.admin-cats) .cat>summary .cat-spark{grid-area:spark;min-width:0}
.cats:not(.admin-cats) .cat>summary .cat-chip{grid-area:chip;justify-self:start}
.cats:not(.admin-cats) .cat>summary .cat-num{grid-area:num;justify-self:end;font-size:11.5px}
.cats:not(.admin-cats) .cat>summary::after{grid-area:arrow;align-self:center}

/* админская шапка категории — прежняя широкая раскладка */
.admin-cats .cat>summary{display:grid;align-items:center;gap:14px;padding:13px 15px;cursor:pointer;
  list-style:none;user-select:none;transition:background .15s;
  grid-template-columns:18px 22px minmax(150px,1fr) 1fr 118px 132px 16px}
.admin-cats .cat>summary{grid-template-columns:18px 22px minmax(150px,1fr) 1fr 118px 132px 16px}
.cat>summary::-webkit-details-marker{display:none}
.cat>summary::after{content:'▾';color:var(--faint);font-size:13px;text-align:right;
  transition:transform .2s}
.cat[open]>summary::after{transform:rotate(180deg)}
.cat>summary:hover{background:rgba(255,255,255,.03)}
.cat-ico{font-size:17px;line-height:1;flex-shrink:0;filter:saturate(.9)}
/* Заголовок группы — флекс-строка: имя, пинг, лампа (v6.35). Текст в своём
   span, мобильное двухстрочное обрезание целится в него. */
.cat-title{font-weight:650;font-size:15px;white-space:nowrap;
  display:flex;align-items:center;gap:8px;min-width:0}
.cat-title-txt{overflow:hidden;text-overflow:ellipsis;min-width:3em}
.cat-ms{margin-left:auto;font:600 11px/1 var(--mono);color:var(--muted);
        white-space:nowrap;flex:0 0 auto}
.cat-lamp{width:12px;height:12px;flex:0 0 auto}
.cat-spark{display:block;min-width:0}
.cat-spark .spark{height:26px;opacity:.85;width:100%}
/* в плитке-категории график во всю ширину */
.cats:not(.admin-cats) .cat-spark .spark{height:22px}
.cat-chip{justify-self:start}
.cat-chip .chip{font-size:12px;padding:3px 10px;white-space:nowrap}
.cat-num{justify-self:end;white-space:nowrap}
.cat-warn{border-color:rgba(255,178,36,.32)}
.cat-part{border-color:rgba(255,138,61,.34)}
.cat-down{border-color:rgba(255,80,99,.38);box-shadow:0 0 26px -14px rgba(255,80,99,.6)}
.cat[open]>summary{border-bottom:1px solid var(--line)}
.cat .tiles{padding:14px}
.cats:not(.admin-cats) .cat[open]>summary{border-bottom:1px solid var(--line)}

@media (max-width:760px){
  .admin-cats .cat>summary{grid-template-columns:18px 22px 1fr auto 16px;gap:10px;row-gap:8px}
  .admin-cats .cat-spark{grid-column:1/-1;grid-row:2}
  .admin-cats .cat-num{font-size:12px}
}

p.footer-nav{margin-bottom:10px}
p.footer-nav a{color:var(--muted);text-decoration:none}
p.footer-nav a:hover{color:var(--ink);text-decoration:underline}

.svc-off{opacity:.5}
.active-tgl{display:inline-flex;align-items:center;gap:4px;font-size:12px;color:var(--muted);white-space:nowrap}
.active-tgl input{margin:0}

/* Drag-and-drop в админке */
.drag-h{cursor:grab;color:var(--faint);font-size:15px;user-select:none;padding:0 2px}
.drag-h:active{cursor:grabbing}
.admin-cats .cat.dragging{opacity:.45}
.admin-cats .cat.drop-target{border-color:var(--ok);box-shadow:0 0 0 1px var(--ok) inset}
.svc-sort tr.dragging{opacity:.4}
.svc-sort tr.drop-target td{box-shadow:inset 0 2px 0 var(--ok)}
.dnd-saved{position:fixed;right:18px;bottom:18px;z-index:50;background:var(--ok-dim);color:var(--ok);
  border:1px solid rgba(49,217,138,.4);border-radius:9px;padding:8px 14px;font-size:13px;
  opacity:0;transition:opacity .2s}
.dnd-saved.show{opacity:1}

/* Админка: категории */
.admin-cats .cat-body{padding:12px 15px 16px}
.admin-cats table.svc{margin-bottom:14px}
.add-form{border-top:1px dashed var(--line2);padding-top:14px}
.add-form>b{display:block;margin-bottom:10px;font-size:14px}
.add-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px;margin-bottom:12px}
.add-grid label{display:flex;flex-direction:column;gap:4px;font-size:12.5px;color:var(--muted)}
.add-grid input,.add-grid select{font:inherit;font-size:13.5px;color:var(--ink);padding:8px 10px;
  border:1px solid var(--line2);border-radius:8px;background:var(--bg2);width:100%}
.add-form>button{font:600 14px var(--sans);color:#fff;border:0;cursor:pointer;border-radius:9px;
  padding:10px 20px;background:linear-gradient(180deg,#5b8bd6,#3c6cb8)}

/* ── Плитки сервисов ── */
/* Сетка плиток: две колонки, с 700 px — четыре. Ширина решением владельца
   оставлена прежней, поэтому всё, что должно поместиться внутрь плитки,
   обязано укладываться в ~130 px на телефоне и ~150 px при четырёх колонках. */
.tiles{display:grid!important;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:6px}
@media (min-width:700px){.tiles{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media (max-width:420px){.tiles{gap:9px}
  .tile{padding:11px;gap:7px}
  .tile-name{font-size:13px}}
.tile-kids{font-size:11.5px;color:var(--muted);border-top:1px dashed var(--line);padding-top:7px;
  display:flex;align-items:center;gap:5px}
.tile-kids::before{content:'▤';opacity:.6}
.kids-tiles .tile{background:linear-gradient(180deg,rgba(255,255,255,.04),rgba(255,255,255,.01))}
/* ПЛИТКА ТЕМНЕЕ СВОЕЙ КАТЕГОРИИ (v6.30). Здесь стояла подсветка белым
   (rgba(255,255,255,.03)) поверх панели категории — то есть плитка была
   СВЕТЛЕЕ подложки на три процента, и граница между ними держалась на одной
   тонкой рамке. Тёмная заливка разводит слои по-настоящему: карточка читается
   как отдельный предмет, а текст на ней — контрастнее. */
.tile{display:flex;flex-direction:column;gap:9px;text-decoration:none;
  background:linear-gradient(180deg,var(--bg2),var(--bg));
  border:1px solid var(--line);border-radius:12px;padding:13px 14px;
  transition:border-color .15s,transform .15s,box-shadow .15s}
/* ЦИФРА ПИНГА В ЗАГОЛОВКЕ ПЛИТКИ (v6.33, заказ владельца). Раньше её рисовал
   канвас в углу графика — мелко, и рядом с лампой возникала ВТОРАЯ мерцающая
   точка. Теперь цифра стоит в строке с именем, а мерцает сама лампа: одна
   точка, её постоянный размер. Создаётся живым модулем — без JS цифры нет,
   как не было и раньше. */
.tile-ms{margin-left:auto;font:600 11px/1 var(--mono);color:var(--muted);
         white-space:nowrap;flex:0 0 auto}
/* Дыхание лампы — знак «график живой»; вспышка — «пришли свежие данные».
   Мерцает прозрачностью, а не размером: дрожащая геометрия дёргает глаз. */
/* Имя сервиса в H1 — живая ссылка на адрес проверки (v6.35): подчёркивание
   точками, чтобы читалось «можно нажать», но заголовок не выглядел синим. */
.h1-link{color:inherit;text-decoration:underline dotted;text-underline-offset:4px}
.h1-link:hover{color:var(--accent,#5b8bd6)}
.cl-res-title{display:inline-flex;align-items:center;gap:8px;min-width:0;max-width:100%}
.cl-url{color:inherit}
/* Виды проблемы — плитками, как выбор сервиса у карты (v6.35). Радио остаётся
   видимым: выбор читается и там, где :has не поддержан. */
.kind-tiles{display:flex;flex-wrap:wrap;gap:8px;border:0;padding:0;margin:0 0 6px}
.kind-tiles legend{width:100%;margin-bottom:6px}
.kind-tiles label{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  border:1px solid var(--line);border-radius:11px;background:var(--bg2);
  padding:9px 14px;transition:border-color .15s,background .15s}
.kind-tiles label:hover{border-color:var(--line2)}
.kind-tiles label:has(input:checked){border-color:var(--accent,#5b8bd6);
  background:var(--panel2);box-shadow:0 0 0 1px var(--accent,#5b8bd6) inset}
.kind-tiles input[type=radio]{accent-color:var(--accent,#5b8bd6)}
.kind-tiles .aspect-note{width:100%}

/* ИМЕНА КЛАССОВ ЛАМПЫ — С ПРЕФИКСОМ (v6.34). Первая версия вешала классы
   `live` и `flash`, а `.flash` в этом проекте давно занят плашками
   уведомлений (padding 11px 15px, radius 10px, полупрозрачный фон) — и лампа
   превращалась в мини-плашку: тот самый «овал вместо точки» с боевых
   скриншотов. Правило `.flash.ok` стоит ниже `.dot.ok` и потому побеждало. */
.tile-dot.lamp-live{animation:lamp-breathe 1.8s ease-in-out infinite}
.tile-dot.lamp-ping{animation:lamp-flash .7s ease-out 1,lamp-breathe 1.8s ease-in-out .7s infinite}
@keyframes lamp-breathe{50%{opacity:.55}}
@keyframes lamp-flash{0%{box-shadow:0 0 0 0 rgba(255,255,255,.35)}100%{box-shadow:0 0 0 9px rgba(255,255,255,0)}}
@media (prefers-reduced-motion: reduce){
  .tile-dot.lamp-live,.tile-dot.lamp-ping{animation:none}}

/* ЛАМПА — В СТРОКЕ ЗАГОЛОВКА, НА ЛИНИИ ТЕКСТА (v6.34, заказ владельца).
   С 6.30 она жила в углу карточки абсолютом и оказывалась ВЫШЕ строки с
   именем и пингом — глаз читал её как отдельный элемент, а на одном из
   браузеров вспышка вокруг пустого места выглядела «овалом». Теперь лампа —
   обычный член флекс-строки после цифры пинга: центрируется той же осью, что
   текст, и вспышке всегда есть вокруг чего рисоваться.
   Имени гарантирован минимум ширины: без него на узкой плитке пинг и лампа
   выталкивали название целиком (поймано на боевых снимках). */
.tile{position:relative}
.tile-dot{width:14px;height:14px;margin-left:8px;flex:0 0 auto;align-self:center}
/* ШАПКА ПЛИТКИ НЕ ИМЕЕТ ПРАВА ВЫЛЕЗАТЬ ЗА КАРТОЧКУ (v6.39, заказ владельца:
   «не помещаются время загрузки и точка-индикатор — поместить в карточку»).
   Здесь стояло `min-width:3em` — пол ширины имени, заведённый в 6.34, чтобы
   пинг и лампа не выталкивали название целиком. Но пол ничем не уравновешен:
   имя не сжимается ниже него, цифра и лампа не сжимаются вовсе, и на узкой
   плитке строка просто ПЕРЕПОЛНЯЛА карточку — лампа уезжала за её правый
   край. Замер сохранённой страницы владельца: при окне 900 px лампа торчала
   на 4 px, при 800 — на 29, при 700 — на 54.
   Теперь пол задан через flex-basis, а не min-width: имя по-прежнему
   старается занять 3em, но при нехватке места СЖИМАЕТСЯ (min-width:0 и
   многоточие), и цифра с лампой остаются внутри. */
.tile-top .tile-name{flex:1 1 3em;min-width:0}
/* Логотип тоже перестаёт быть неприкосновенным: он украшение, а лампа —
   состояние. При самой тесной раскладке ужимается он, а не смысл. */
.tile-top .logo-a,.tile-top .logo-i{flex:0 1 auto;min-width:0}
.tile:hover{border-color:var(--line2);transform:translateY(-2px);
  box-shadow:0 14px 30px -18px rgba(0,0,0,.7)}
.tile-top{display:flex;align-items:center;gap:10px;min-width:0;overflow:hidden}
.tile-name{font-weight:600;font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Светлая плашка нужна: большинство брендовых логотипов — прозрачные PNG под
   светлую подложку, и на тёмной теме без неё они пропадают.
   ДО v5.24 плашка была #fff, и это давало «белый квадратик»: логотип,
   нарисованный БЕЛЫМ под тёмный фон (таких у брендов много), на белом фоне
   невидим целиком — плитка выглядела так, будто картинка не загрузилась.
   Разницы «белое на белом» средствами CSS не создать, поэтому плашка сделана
   чуть серой: тёмные логотипы на ней читаются как и раньше, а белые наконец
   видны. Обводка отделяет плашку от карточки, когда логотип светлый и по
   краям прозрачный. outline, а не border: не меняет размер коробки и рисуется
   поверх картинки, поэтому не зависит ни от box-sizing, ни от object-fit. */
.logo-i{width:34px;height:34px;border-radius:9px;object-fit:contain;background:#eef1f6;flex-shrink:0;
  outline:1px solid rgba(15,23,42,.10);outline-offset:-1px}
/* Логотип-надпись: вдвое шире, иначе 240×48 сжимается в полоску в 7 пикселей
   высотой — файл есть, а логотипа на экране нет. Ширину задаёт и атрибут
   width у <img>, чтобы плитка не прыгала до загрузки картинки. */
.logo-wide{width:68px}
.logo-a{width:34px;height:34px;border-radius:9px;display:inline-flex;align-items:center;
  justify-content:center;font:700 16px var(--display);flex-shrink:0}
.spark{width:100%;height:30px;display:block}
.spark{overflow:visible}
/* Базовые столбики (ss1/ss2) — это удачные пробы, и красятся они ВСЕГДА
   зелёным. Раньше цвет брался из класса ТЕКУЩЕГО статуса (.spark-warn .ss1
   и т.д.), поэтому при первом же инциденте желтела или краснела вся история
   целиком: график переставал показывать прошлое и просто дублировал плитку.
   Состояние каждой корзины несут .sf (сбой), .sw (медленно) и .sn (нет данных). */
.spark .ss1{stop-color:var(--ok);stop-opacity:.85}
.spark .ss2{stop-color:var(--ok);stop-opacity:.22}
.spark .sb.hot{fill:var(--down)}
.spark .sf,.spark .sw{opacity:.95}   /* цвет — градиентом из defs, см. выше */
.spark .sf1{stop-color:var(--down);stop-opacity:1}
.spark .sf2{stop-color:var(--down);stop-opacity:.25}
.spark .sw1{stop-color:var(--warn);stop-opacity:1}
.gpp1{stop-color:var(--part);stop-opacity:1}
.gpp2{stop-color:var(--part);stop-opacity:.25}
.spark .sw2{stop-color:var(--warn);stop-opacity:.25}
/* класс статуса больше НЕ меняет цвет истории — только лёгкий акцент рамки */
.spark.spark-down,.spark.spark-part,.spark.spark-warn{filter:saturate(1.05)}
.spark .sp1{stop-color:var(--part);stop-opacity:1}
.spark .sp2{stop-color:var(--part);stop-opacity:.25}
.spark .sp{opacity:.95}
.spark .sn1{stop-color:var(--nolink);stop-opacity:.95}
.spark .sn2{stop-color:var(--nolink);stop-opacity:.22}
.spark .sn{opacity:.9}
.spark .se{fill:var(--line2);opacity:.5}
/* ПОДВАЛ ПЛИТКИ — ОДНА СТРОКА, КАК В ШАПКЕ КАТЕГОРИИ (v6.30).
   История вопроса (v5.99): в подвале стоял чип-плашка со своей лампой, и на
   390 px «Доступен не отовсюду» + «нет жалоб» не помещались — приходилось
   разрешать перенос на вторую строку. Плашка была шире своего текста из-за
   padding'а и собственной лампы; теперь лампа уехала в правый верхний угол,
   а состояние осталось простым цветным словом. Ширины хватает, и подвал
   устроен как шапка категории: слева состояние, справа счёт.
   Перенос запрещён намеренно — на случай длинного слова обе половины умеют
   ужиматься с многоточием, а состояние важнее счётчика и потому тянется. */
.tile-foot{display:flex;justify-content:space-between;align-items:baseline;gap:6px;
           flex-wrap:nowrap;min-width:0;overflow:hidden}
/* Кегль подвала компактный ВЕЗДЕ, а не только на телефоне: при четырёх
   колонках плитка на 768 px выходит те же 150 px, что и на телефоне, и
   десктопный размер обрезал «Не отовсюду» ровно так же. Замерено в браузере
   по семи ширинам. */
.tile-foot .st{min-width:0;flex:1 1 auto;text-align:left;
               font:600 11.5px/1.35 var(--sans);
               white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tile-foot .st-ok{color:var(--ok)}
.tile-foot .st-warn{color:var(--warn)}
.tile-foot .st-part{color:var(--part)}
.tile-foot .st-down{color:var(--down)}
.tile-foot .num{white-space:nowrap;flex:0 0 auto;min-width:0;font-size:10.5px;
                overflow:hidden;text-overflow:ellipsis}
/* УЗКИЙ ЭКРАН. Блок стоит ЗДЕСЬ, после определений .tile-foot и .tile-top, и
   это не вкусовщина: медиазапрос не добавляет веса селектору, поэтому раньше
   он проигрывал обычным правилам, объявленным ниже по файлу, — кегль и отступы
   молча оставались десктопными. Поймано замером ширины в браузере. */
@media (max-width:480px){
  .tile-dot{width:12px;height:12px;margin-left:6px}
  .tile-top{gap:8px}
  .logo-i,.logo-a{width:30px;height:30px}
  .logo-wide{width:60px}
  /* На две колонки в 390 px плитке остаётся около 120 px: «Не отовсюду» рядом
     со счётчиком умещается только мелким кеглем. Обрезать состояние нельзя —
     это главное слово карточки. */
  .tile-foot .st{font-size:11px}
  .tile-foot .num{font-size:10px}
  .tile{padding:11px 10px}
}
.tile-note{font-size:12px;color:var(--warn);border-top:1px dashed var(--line);padding-top:8px}
table.svc.admin td{vertical-align:top}
.row-form{flex-wrap:wrap}

/* ── Карта ── */
.rumap{position:relative}
.rumap svg{width:100%;height:auto;display:block}
.rumap .rg{fill:#2f6e51;stroke:var(--bg);stroke-width:.7;
  transition:fill .15s,filter .15s}
.rumap a .rg{cursor:pointer}
.rumap a:hover .rg,.rumap a:focus-visible .rg{fill:#3d8a66}
.rumap .rg.h1{fill:#4ca877}
.rumap .rg.h2{fill:#8a5a24}
.rumap .rg.h3{fill:var(--down)}
.rumap a:hover .rg.h1,.rumap a:hover .rg.h2{filter:brightness(1.3)}
.rumap a:hover .rg.h3{filter:brightness(1.2) drop-shadow(0 0 6px var(--down))}
.rumap-legend{display:flex;gap:18px;align-items:center;flex-wrap:wrap;
  font-size:12.5px;color:var(--muted);margin-top:12px}
.rumap-legend i{display:inline-block;width:12px;height:12px;border-radius:3px;margin-right:6px;vertical-align:-1px}

/* свой регион (по IP): контур-пульс */
.rumap .rg.me{fill-opacity:1}

.me-chip{display:inline-flex;align-items:center;gap:8px;font-size:13.5px;margin:12px 0 2px;
  padding:6px 13px;border-radius:99px;background:var(--ok-dim);border:1px solid rgba(49,217,138,.3)}

/* блик по карте: цвет и период задаются с сервера (--sweep, --sweepdur) */
.rumap{overflow:hidden;border-radius:8px;position:relative}
.rumap::after{content:'';position:absolute;inset:-12% auto -12% -45%;width:34%;
  transform:skewX(-14deg);pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--sweep,rgba(49,217,138,.12)),transparent)}
@media (prefers-reduced-motion:no-preference){
  .rumap::after{animation:sweep var(--sweepdur,22s) linear infinite}
  @keyframes sweep{0%{left:-45%}55%{left:120%}100%{left:120%}}
}
@media (prefers-reduced-motion:reduce){.rumap::after{display:none}}

/* Баннер деградации проверок */
.banner-warn{display:block;font-size:13.5px;color:var(--warn);background:var(--warn-dim);
  border:1px solid rgba(255,178,36,.3);border-radius:10px;padding:9px 14px;margin:10px 0}

/* Чип региона: вариант-предупреждение */
.me-chip.warn{background:var(--warn-dim);border-color:rgba(255,178,36,.3)}

/* Бейдж ИСССР в футере */
.footer-badge{display:flex;gap:18px;align-items:center;flex-wrap:wrap;
  border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin-bottom:16px;
  background:linear-gradient(180deg,rgba(255,255,255,.03),transparent)}
.fb-txt{flex:1;min-width:240px;font-size:13px;color:var(--muted);line-height:1.55}
.fb-txt b{color:var(--ink)}
.fb-img{flex-shrink:0}
.fb-img img{display:block;max-width:100%;height:auto;transition:transform .2s}
.fb-img:hover img{transform:translateY(-2px)}
.report.blocked{border-color:rgba(255,178,36,.35)}

/* Демонстрация бейджей ИСССР */
.badge-demo{display:grid;gap:16px;grid-template-columns:1fr;margin:14px 0}
@media(min-width:720px){.badge-demo:not(.badge-demo-stack){grid-template-columns:1fr 1fr}}
/* вариант «друг над другом»: большой сверху, мини снизу */
/* 7.11: демо бейджей — во всю ширину содержимого, две колонки на широком
   экране. Прежний ящик в 640px был единственным узким блоком на странице. */
.badge-demo-stack{grid-template-columns:1fr;max-width:none}
@media(min-width:900px){.badge-demo-stack{grid-template-columns:1fr 1fr}}
.badge-demo img{display:block;margin-bottom:8px;max-width:100%;height:auto}

/* QR в «О проекте» */
.tg-qr{display:flex;align-items:center;gap:16px;margin:14px 0}
.tg-qr #tg-qr svg{display:block;border-radius:10px;background:#fff;padding:6px}
.tg-qr-cap{font-size:13px;color:var(--muted);line-height:1.5}

/* опасная кнопка */
button.danger{background:var(--down-dim);color:var(--down);border:1px solid rgba(255,80,99,.35)}
button.danger:hover{background:rgba(255,80,99,.22)}
.del-form{margin-top:4px}

/* ── График жалоб ── */
.chart{width:100%;height:104px;display:block;margin:12px 0 4px;overflow:visible}
.chart .gs1{stop-color:#5c7cc0;stop-opacity:.95}
.chart .gs2{stop-color:#5c7cc0;stop-opacity:.30}
.chart.chart-ok .gs1{stop-color:var(--ok);stop-opacity:.9}
.chart.chart-ok .gs2{stop-color:var(--ok);stop-opacity:.25}
.chart.chart-warn .gs1{stop-color:var(--warn);stop-opacity:.95}
.chart.chart-warn .gs2{stop-color:var(--warn);stop-opacity:.3}
.chart.chart-down .gs1{stop-color:var(--down);stop-opacity:.95}
.chart.chart-down .gs2{stop-color:var(--down);stop-opacity:.32}
.chart.chart-down .env,.chart.chart-warn .env{stroke:currentColor}
.chart .bar{transition:opacity .2s}
.chart .bar.hot{--hot:1}
.chart .bar.hot{fill:var(--down);filter:drop-shadow(0 0 6px rgba(255,80,99,.45))}
.chart .barp{opacity:.95;transition:opacity .2s}
/* цвет столбиков задаётся градиентом через fill='url(#…)' в разметке;
   НЕ объявлять здесь fill — CSS перебивает presentation-атрибут и градиент пропадает */
.chart .barp-none{fill:var(--line2);opacity:.45}
.chart .gpo1{stop-color:var(--ok);stop-opacity:1}
.chart .gpo2{stop-color:var(--ok);stop-opacity:.18}
.chart .gpf1{stop-color:var(--down);stop-opacity:1}
.chart .gpf2{stop-color:var(--down);stop-opacity:.22}
.chart .gpw1{stop-color:var(--warn);stop-opacity:1}
.chart .gpw2{stop-color:var(--warn);stop-opacity:.22}
/* Ступени перехода жёлтый → красный. Цвет СМЕШИВАЕТСЯ из двух базовых, а не
   задаётся третьим: так он остаётся в теме и не разъедется при её правке.
   Запасное значение перед color-mix обязательно — старый браузер, не знающий
   этой функции, иначе получит недопустимый stop-color и закрасит столбик
   чёрным. */
.chart .gpl1a{stop-color:var(--warn);stop-color:color-mix(in srgb,var(--warn) 45%,var(--ok));stop-opacity:1}
.chart .gpl1b{stop-color:var(--warn);stop-color:color-mix(in srgb,var(--warn) 45%,var(--ok));stop-opacity:.22}
.chart .gpm1a{stop-color:var(--warn);stop-color:color-mix(in srgb,var(--down) 30%,var(--warn));stop-opacity:1}
.chart .gpm1b{stop-color:var(--warn);stop-color:color-mix(in srgb,var(--down) 30%,var(--warn));stop-opacity:.22}
.chart .gpm2a{stop-color:var(--warn);stop-color:color-mix(in srgb,var(--down) 55%,var(--warn));stop-opacity:1}
.chart .gpm2b{stop-color:var(--warn);stop-color:color-mix(in srgb,var(--down) 55%,var(--warn));stop-opacity:.22}
.chart .gpm3a{stop-color:var(--down);stop-color:color-mix(in srgb,var(--down) 80%,var(--warn));stop-opacity:1}
.chart .gpm3b{stop-color:var(--down);stop-color:color-mix(in srgb,var(--down) 80%,var(--warn));stop-opacity:.22}
.chart .gpn1{stop-color:var(--nolink);stop-opacity:.95}
.chart .gpn2{stop-color:var(--nolink);stop-opacity:.2}
.chart:hover .barp{opacity:.6}
.chart .barp:hover{opacity:1}
.chart .grid{stroke:var(--line);stroke-width:1;stroke-dasharray:3 5}
.chart .env{fill:none;stroke:var(--down);stroke-width:1.6;stroke-opacity:.5;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
.chart .ax{font:11px var(--mono);fill:var(--faint)}
.chart:hover .bar{opacity:.55}
.chart .bar:hover{opacity:1}
@media (prefers-reduced-motion:no-preference){
  .chart .bar,.chart .barp{animation:grow .55s cubic-bezier(.2,.8,.25,1) both;animation-delay:var(--d,0s);
    transform-box:fill-box;transform-origin:bottom}
  .chart .env{stroke-dasharray:2000;animation:draw 1.6s ease-out both .25s}
  .spark .sb,.spark .sf,.spark .sw{animation:grow .45s cubic-bezier(.2,.8,.25,1) both;animation-delay:var(--d,0s);
    transform-box:fill-box;transform-origin:bottom}
  @keyframes grow{from{transform:scaleY(0);opacity:.2}to{transform:scaleY(1);opacity:1}}
  @keyframes draw{from{stroke-dashoffset:2000}to{stroke-dashoffset:0}}
}

/* ── Статус-баннер, заметки ── */
.status-line{display:flex;align-items:center;gap:11px;flex-wrap:wrap;font-size:16.5px;
  padding:15px 18px;border-radius:var(--r);margin:14px 0;border:1px solid}
.status-line.ok{background:var(--ok-dim);border-color:rgba(49,217,138,.3)}
.status-line.warn{background:var(--warn-dim);border-color:rgba(255,178,36,.3)}
.status-line.down{background:var(--down-dim);border-color:rgba(255,80,99,.35)}
.admin-note{background:var(--warn-dim);border:1px solid rgba(255,178,36,.3);
  padding:11px 15px;border-radius:10px;font-size:15px}

/* ── Форма жалобы ── */
.report{background:linear-gradient(180deg,var(--panel2),var(--panel));
  border:1px solid var(--line);border-radius:var(--r);padding:20px;margin:20px 0}
.aspect-note{display:block;width:100%;margin-top:8px;font:inherit;font-size:14px;
  color:var(--ink);background:var(--bg2);border:1px solid var(--line2);border-radius:8px;padding:9px 11px}
.report fieldset{border:0;padding:0;margin:0 0 12px}
.report legend{font-weight:650;margin-bottom:8px}
.report label{display:inline-block;margin:4px 16px 4px 0;font-size:15px;color:var(--muted)}
.report input[type=radio]{accent-color:var(--down)}
.report .sel{display:block;margin:10px 0 16px}
.report select,.report input[type=text],.report input:not([type]){
  font:inherit;color:var(--ink);padding:9px 12px;border:1px solid var(--line2);
  border-radius:9px;background:var(--bg2);max-width:100%}
.report button{font:650 16px/1 var(--sans);color:#fff;border:0;cursor:pointer;
  border-radius:10px;padding:14px 28px;
  background:linear-gradient(180deg,#ff6b78,#e33f50);
  box-shadow:0 10px 26px -10px rgba(255,80,99,.7)}
.report button:hover{filter:brightness(1.07)}
.hp{position:absolute;left:-5000px;width:1px;height:1px;opacity:0}

/* ── Выбор сервиса плитками (форма региона) ──
   Заменил выпадающий список: на телефоне выбор из трёх десятков пунктов —
   прокрутка вслепую, логотипов не видно, взглядом не окинуть.
   Переключатель НЕ прячется display:none — так поле выпадает из обхода
   клавиатурой; уводим за край экрана, оставляя фокусируемым.
   Подсветка выбранного — соседним селектором `input:checked ~`, а не :has и
   не классом от скрипта: форма обязана показывать выбор там, где скриптов
   нет вовсе. */
.pick{margin:0 0 18px}
.pick-find{display:block;width:100%;max-width:340px;margin:0 0 12px;font:inherit;font-size:15px;
  color:var(--ink);background:var(--bg2);border:1px solid var(--line2);border-radius:9px;padding:9px 12px}
.pick-group{margin:0 0 8px;border:1px solid var(--line);border-radius:12px;background:var(--bg2)}
.pick-cat{list-style:none;cursor:pointer;padding:11px 13px;display:flex;align-items:center;gap:9px;
  font:650 13px/1.2 var(--sans);letter-spacing:.02em;text-transform:uppercase;color:var(--muted)}
.pick-cat::-webkit-details-marker{display:none}
.pick-cat::before{content:'›';font-size:17px;line-height:1;transition:transform .15s;display:inline-block}
.pick-group[open] .pick-cat::before{transform:rotate(90deg)}
.pick-cat .num{margin-left:auto;font-size:12px}
.pick-group .pick-tiles{padding:0 13px 13px}
.pick-tiles{margin-top:0}
.pick-tile{display:block;margin:0;position:relative;cursor:pointer}
/* Свой display перебивает браузерное [hidden]{display:none} — без этих двух
   строк поиск «прятал» плитки, а на экране не менялось ничего. */
.pick-tile[hidden],.pick-group[hidden]{display:none}
.pick-tile input{position:absolute;left:-5000px;width:1px;height:1px;opacity:0}
.pick-body{display:flex;align-items:center;gap:10px;min-width:0;min-height:52px;
  background:linear-gradient(180deg,rgba(255,255,255,.03),rgba(255,255,255,0));
  border:1px solid var(--line);border-radius:12px;padding:11px 12px;
  transition:border-color .15s,background .15s,transform .15s}
/* Название переносится на две строки, а не обрезается многоточием:
   «Мобильн…» и «Яндекс Ма…» на телефоне неразличимы между собой. */
.pick-name{font-weight:600;font-size:14.5px;color:var(--ink);line-height:1.25;min-width:0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  overflow-wrap:break-word}
.pick-tile:hover .pick-body{border-color:var(--line2);transform:translateY(-1px)}
.pick-tile input:checked ~ .pick-body{border-color:var(--down);
  background:linear-gradient(180deg,var(--down-dim),rgba(255,255,255,0))}
.pick-tile input:focus-visible ~ .pick-body{outline:2px solid var(--down);outline-offset:2px}
.pick-none{margin:4px 0 0;color:var(--muted);font-size:14px}
@media (max-width:420px){.pick-body{padding:9px 10px;gap:8px}
  .pick-name{font-size:13px}
  .pick-body .logo-i,.pick-body .logo-a{width:28px;height:28px}}

.flash{padding:11px 15px;border-radius:10px;font-size:15px;border:1px solid}
.flash.ok{background:var(--ok-dim);border-color:rgba(49,217,138,.3)}
.flash.warn{background:var(--warn-dim);border-color:rgba(255,178,36,.3)}
/* .bad — отказ, а не предупреждение: «жёлтым» такое читалось как «ничего
   страшного», хотя площадки в этот момент не устанавливаются вовсе (v5.53). */
.flash.bad{background:var(--down-dim);border-color:rgba(255,80,99,.35)}

/* ── Разбивка по типам ── */
ul.aspects{list-style:none;padding:0;margin:0}
ul.aspects li{display:flex;align-items:center;gap:12px;padding:6px 0}
.a-name{width:180px;flex-shrink:0;font-size:15px;color:var(--muted)}
.a-track{flex:1;height:8px;background:var(--panel2);border-radius:4px;overflow:hidden}
.a-fill{display:block;height:100%;border-radius:4px;
  background:linear-gradient(90deg,#ff9350,var(--down))}
ul.aspects .num{width:44px;text-align:right}

/* ── Регионы / похожие / история ── */
ul.regions{list-style:none;padding:0;margin:0;columns:2;column-gap:28px}
ul.regions li{padding:8px 0;border-bottom:1px solid var(--line);break-inside:avoid;
  display:flex;justify-content:space-between;gap:10px;align-items:center}
ul.regions li:last-child{border-bottom:0}
ul.regions a{text-decoration:none}
ul.regions a:hover{text-decoration:underline}
table.hist td{padding:7px 8px}
table.hist td.num{width:120px}

/* ── Плейсхолдеры картинок ── */
.ph-img{max-width:100%;height:auto;border-radius:var(--r);margin:18px 0}

code.embed{display:inline-block;font:13px var(--mono);background:var(--bg2);
  border:1px solid var(--line);border-radius:8px;padding:9px 12px;margin-top:6px;
  word-break:break-all;max-width:100%;color:var(--muted)}

.crumbs{font-size:13px;color:var(--muted);margin:18px 0 0}
.note{font-size:14px;color:var(--muted);border-top:1px solid var(--line);
  padding-top:16px;margin-top:30px}
footer{max-width:var(--page-max);margin:0 auto;padding:24px var(--gutter);border-top:1px solid var(--line);
  font-size:13px;color:var(--faint)}
@media (max-width:760px){footer{padding:18px var(--gutter)}}

.inline{display:inline-flex;gap:5px;margin:2px 0}
.inline input,.inline select{font-size:13px;color:var(--ink);padding:4px 7px;
  background:var(--bg2);border:1px solid var(--line);border-radius:6px}
.inline button{font-size:13px;padding:4px 10px;border:1px solid var(--line2);
  background:var(--panel2);color:var(--ink);border-radius:6px;cursor:pointer}

@keyframes beat{50%{opacity:.45}}
@media (prefers-reduced-motion:no-preference){
  .status-line.down .dot,.chip.down .dot{animation:beat 1.6s ease-in-out infinite}
}
@media (prefers-reduced-motion:reduce){
  .logo::before{animation:none}
  .ring .vl{transition:none}
  html{scroll-behavior:auto}
}

/* ПОЛЕ СТРАНИЦЫ СУЖАЕТСЯ ОДИН РАЗ И ДЛЯ ВСЕХ (7.11): шапка, карта, main и
   подвал переключаются в одной точке, а не в трёх разных. */
@media (max-width:760px){:root{--gutter:14px}}

/* ── Мобильная вертикаль ── */
@media (max-width:640px){
  main{padding:0 var(--gutter) 44px}
  .hero{flex-direction:column-reverse;gap:16px;align-items:flex-start}
  .ring{width:140px;height:140px;align-self:center}
  .ring-num{font-size:36px}
  ul.regions{columns:1}
  table.svc td:first-child{width:auto}
  .panel{padding:15px 14px}
  .a-name{width:124px;font-size:14px}
  .report button{width:100%;padding:15px}
  .report select{width:100%}
}

/* ── Светлая тема ── */
:root[data-theme=light]{
  --bg:#f5f6f8; --bg2:#eef0f4; --panel:#ffffff; --panel2:#f3f5f9;
  --line:rgba(20,32,54,.12); --line2:rgba(20,32,54,.24);
  --ink:#151a22; --muted:#5b6778; --faint:#8b97a8;
  --card:#ffffff;
  --accent:#12a05f; --accent-ink:#ffffff;
}
:root[data-theme=light] body{background-image:
  radial-gradient(1000px 460px at 78% -160px, rgba(255,80,99,.06), transparent 60%),
  radial-gradient(760px 420px at 8% -140px, rgba(72,132,255,.07), transparent 60%)}
:root[data-theme=light]{color-scheme:light}
:root[data-theme=light] .board{background:rgba(0,0,0,.03)}
:root[data-theme=light] .tile{background:linear-gradient(180deg,rgba(0,0,0,.055),rgba(0,0,0,.02))}
:root[data-theme=light] .rumap .rg{stroke:#fff}
/* Авто-тема. ВАЖНО: раньше здесь стояло `:root[data-theme=light] @media (…){`
   — селектор, за которым сразу идёт @media без открывающей скобки. Такое
   правило браузер отбрасывает целиком, и светлая системная тема НЕ работала:
   срабатывал только ручной переключатель. Плюс последнее правило обрывалось
   на списке селекторов без объявлений. */
@media (prefers-color-scheme: light){
  :root:not([data-theme=dark]):not([data-theme=light]){
    --bg:#f5f6f8; --bg2:#eef0f4; --panel:#ffffff; --panel2:#f3f5f9;
    --line:rgba(20,32,54,.12); --line2:rgba(20,32,54,.24);
    --ink:#151a22; --muted:#5b6778; --faint:#8b97a8; color-scheme:light}
  :root:not([data-theme=dark]):not([data-theme=light]) body{background-image:
    radial-gradient(1000px 460px at 78% -160px, rgba(255,80,99,.06), transparent 60%),
    radial-gradient(760px 420px at 8% -140px, rgba(72,132,255,.07), transparent 60%)}
  :root:not([data-theme=dark]):not([data-theme=light]) .board{background:rgba(0,0,0,.03)}
  :root:not([data-theme=dark]):not([data-theme=light]) .tile{background:linear-gradient(180deg,rgba(0,0,0,.055),rgba(0,0,0,.02))}
  :root:not([data-theme=dark]):not([data-theme=light]) .rumap .rg{stroke:#fff}
}


/* ── Подсветка своего региона (слой поверх карты; правила последние в файле,
      чтобы их не затирали стили тем) ── */
.rumap .rg-me-glow{
  fill:none;stroke:var(--ok);stroke-width:7;stroke-opacity:.28;
  stroke-linejoin:round;filter:blur(3px)}
.rumap .rg-me-line{
  fill:var(--ok);fill-opacity:.14;stroke:var(--ok);stroke-width:2.2;
  stroke-linejoin:round;vector-effect:non-scaling-stroke}
@media (prefers-reduced-motion:no-preference){
  .rumap .rg-me-glow{animation:meglow 2.4s ease-in-out infinite}
  .rumap .rg-me-line{animation:meline 2.4s ease-in-out infinite}
  @keyframes meglow{0%,100%{stroke-opacity:.18;stroke-width:6}50%{stroke-opacity:.5;stroke-width:9}}
  @keyframes meline{0%,100%{fill-opacity:.10}50%{fill-opacity:.24}}
}


/* ═══ Единая шапка + сцена карты ═══ */
.sitehead{position:relative;z-index:3}
.sitehead-bar{max-width:var(--page-max);margin:0 auto;padding:16px var(--gutter);display:flex;
  align-items:center;justify-content:space-between;gap:16px}
.sitehead .logo{font-family:var(--display);font-weight:800;font-size:20px;color:var(--ink);
  text-decoration:none;letter-spacing:-.01em;display:inline-flex;align-items:center;gap:9px}
.sitehead .logo b{color:var(--down)}
.sitehead .logo::before{content:'';width:9px;height:9px;border-radius:50%;flex-shrink:0;
  background:var(--ok);box-shadow:0 0 8px var(--ok)}
.sitehead .logo.logo-warn::before{background:var(--warn);box-shadow:0 0 8px var(--warn)}
.sitehead .logo.logo-down::before{background:var(--down);box-shadow:0 0 10px var(--down)}
@media (prefers-reduced-motion:no-preference){
  .sitehead .logo.logo-warn::before{animation:beat 2.2s ease-in-out infinite}
  .sitehead .logo.logo-down::before{animation:beat 1.1s ease-in-out infinite}
}
.sitehead-right{display:flex;align-items:center;gap:14px}
.sitehead-right[data-hide-isr] .mini-isr{display:none}
.mini-isr{display:inline-flex;align-items:center;gap:8px;text-decoration:none;
  padding:5px 12px 5px 6px;border:1px solid var(--line);border-radius:99px;background:var(--panel2)}
.mini-isr svg{width:34px;height:34px;display:block}
.mini-isr .tr{fill:none;stroke:var(--line2);stroke-width:6}
.mini-isr .vl{fill:none;stroke-width:6;stroke-linecap:round;transition:stroke-dasharray .6s}
.mini-isr .vl.ok{stroke:var(--ok)} .mini-isr .vl.warn{stroke:var(--warn)} .mini-isr .vl.down{stroke:var(--down)}
.mini-isr-txt{display:flex;flex-direction:column;line-height:1;gap:1px}
.mini-isr-num{font:700 15px var(--mono);text-align:center}
.mini-isr-cap{font:600 8px var(--sans);letter-spacing:.06em;color:var(--faint);text-align:center}
.mini-isr.ok .mini-isr-num{color:var(--ok)} .mini-isr.warn .mini-isr-num{color:var(--warn)} .mini-isr.down .mini-isr-num{color:var(--down)}

/* Сцена карты на главной: помещается в первый экран десктопа */
.mapstage{position:relative;margin:0 0 22px;border-radius:var(--r);overflow:hidden;
  border:1px solid var(--line);background:var(--panel)}
.mapstage-top{position:absolute;top:0;left:0;right:0;z-index:2;padding:16px 18px;
  display:flex;flex-direction:column;align-items:flex-start;gap:10px;pointer-events:none}
/* Заголовок теперь под картой, над графиком */
.stage-title{font-size:clamp(19px,2.2vw,30px);margin:0 0 14px}
.status-flag{display:inline-flex;align-items:center;gap:8px;font:600 13px/1 var(--mono);
  padding:7px 13px;border-radius:99px;
  background:color-mix(in srgb, var(--panel) 72%, transparent);
  border:1px solid var(--line);pointer-events:auto;backdrop-filter:blur(6px)}
.status-flag.ok{color:var(--ok)} .status-flag.warn{color:var(--warn)} .status-flag.down{color:var(--down)}
.status-flag .sf-date{color:var(--faint);font-weight:400}
.mapstage .rumap{margin:0;border-radius:0;
  /* высота карты = высота вьюпорта минус шапка, но в разумных рамках */
  height:min(72vh,760px);display:flex;align-items:center;justify-content:center}
/* SVG вписывается в контейнер по высоте — иначе снизу оставалась пустота */
.mapstage .rumap svg{width:100%;height:100%;max-height:100%;
  object-fit:contain;display:block}
.mapstage-foot{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:14px 18px;
  display:flex;align-items:flex-end;justify-content:space-between;gap:10px;flex-wrap:wrap;
  pointer-events:none}
/* КОЛОНКА ЧИПОВ НАД КАРТОЙ ОБЯЗАНА УМЕТЬ УЖИМАТЬСЯ (v6.30). Без min-width:0
   элемент флекса шириной идёт по max-content: с однострочными чипами это
   694 пикселя при экране в 390, и чип «Сроки истекают» уезжал за край карты.
   Ширина колонки теперь ограничена подложкой, а лишнее внутри чипа
   срезается многоточием. */
.mapstage-foot-left{display:flex;flex-direction:column;gap:8px;align-items:flex-start;
  min-width:0;max-width:100%;flex:1 1 auto}
.mapstage-foot>*{pointer-events:auto}
.mapstage-foot .me-chip{margin:0}
.mapstage-foot .rumap-legend{margin:0;padding:7px 12px;border-radius:10px;
  background:color-mix(in srgb, var(--panel) 72%, transparent);
  border:1px solid var(--line);backdrop-filter:blur(6px)}
.mapstage-foot .me-chip{padding:7px 12px;border-radius:10px;
  background:color-mix(in srgb, var(--panel) 72%, transparent);
  border:1px solid var(--line);backdrop-filter:blur(6px)}
.mapstage .banner-warn{position:absolute;top:70px;left:22px;right:22px;z-index:2}

@media (max-width:760px){
  .sitehead-bar{padding:10px var(--gutter)}
  .sitehead .logo{font-size:16px}
  /* Всё остаётся ПОВЕРХ карты, только компактнее — ничего не уезжает вверх */
  .mapstage{min-height:62vh}
  .mapstage-top{padding:10px 12px;gap:7px}
  .mapstage-h1{font-size:16px;padding:5px 10px;border-radius:9px;line-height:1.25}
  .status-flag{font-size:11px;padding:5px 10px;gap:6px;max-width:calc(100% - 76px)}
  .status-flag .sf-txt{white-space:normal;line-height:1.3}
  .status-flag .sf-date{display:none}
  .mapstage-reports{font-size:11px;padding:4px 9px}
  .stage-isr{top:10px;right:10px;padding:4px 9px 4px 4px;gap:5px}
  .stage-isr svg{width:30px;height:30px}
  .stage-isr-num{font-size:15px}
  .mapstage .rumap{height:min(48vh,420px);padding:52px 6px 62px}
  .mapstage-foot{padding:10px 12px;gap:8px}
  .mapstage-foot .me-chip,.mapstage-foot .rumap-legend{padding:5px 10px;font-size:11.5px}
  .mapstage .banner-warn{top:auto;bottom:64px;left:12px;right:12px;font-size:12px}
  .map-tip{max-width:180px;font-size:12px}
}
@media (max-width:520px){
  .sitehead .logo{font-size:15px}
  .mini-isr{padding:4px 9px 4px 4px}
  .rumap-legend{flex-wrap:wrap;gap:8px 14px;font-size:12px}
}


.stage-isr{position:absolute;top:16px;right:16px;z-index:3;
  display:inline-flex;align-items:center;gap:8px;text-decoration:none;
  padding:6px 13px 6px 6px;border-radius:99px;
  background:color-mix(in srgb, var(--panel) 78%, transparent);
  border:1px solid var(--line);backdrop-filter:blur(6px);
  box-shadow:0 6px 22px -8px rgba(0,0,0,.45)}
.stage-isr svg{width:38px;height:38px;display:block}
.stage-isr .tr{fill:none;stroke:var(--line2);stroke-width:6}
.stage-isr .vl{fill:none;stroke-width:6;stroke-linecap:round;transition:stroke-dasharray .6s}
.stage-isr .vl.ok{stroke:var(--ok)} .stage-isr .vl.warn{stroke:var(--warn)} .stage-isr .vl.down{stroke:var(--down)}
.stage-isr-txt{display:flex;flex-direction:column;line-height:1;gap:2px}
.stage-isr-num{font:800 18px var(--mono);text-align:center}
.stage-isr.ok .stage-isr-num{color:var(--ok)} .stage-isr.warn .stage-isr-num{color:var(--warn)} .stage-isr.down .stage-isr-num{color:var(--down)}
.stage-isr-cap{font:600 8px var(--sans);letter-spacing:.08em;color:var(--faint);text-align:center}

/* строка жалоб в шапке карты */
/* «Всего жалоб …» — левый нижний угол карты, полупрозрачно */
.mapstage-reports{padding:5px 12px;border-radius:9px;
  background:color-mix(in srgb, var(--panel) 72%, transparent);
  border:1px solid var(--line);font-size:12.5px;pointer-events:auto;
  backdrop-filter:blur(6px);white-space:nowrap}
.mapstage-reports b{color:var(--ink)}

/* Кастомный тултип карты (нативный <title> нечитаем и не стилизуется) */
.map-tip{position:fixed;z-index:60;pointer-events:none;opacity:0;transform:translateY(4px);
  transition:opacity .12s,transform .12s;max-width:240px;
  padding:8px 12px;border-radius:10px;font-size:13px;line-height:1.4;
  background:var(--panel);color:var(--ink);border:1px solid var(--line2);
  box-shadow:0 10px 30px -10px rgba(0,0,0,.5)}
.map-tip.show{opacity:1;transform:translateY(0)}
.map-tip b{display:block;margin-bottom:2px}
.map-tip .num{color:var(--muted);font-size:12px}

/* Светлая тема: mapstage-плашки и читаемость */
:root[data-theme=light] .mapstage{background:#eef1f6}
:root[data-theme=light] .mapstage-h1,
:root[data-theme=light] .mapstage-foot .rumap-legend,
:root[data-theme=light] .mapstage-foot .me-chip,
:root[data-theme=light] .status-flag,
:root[data-theme=light] .map-tip{background:#fff;border-color:#d3dae6}
:root[data-theme=light] .mini-isr{background:#fff;border-color:#d3dae6}
:root[data-theme=light] .status-flag{backdrop-filter:none}


/* Футер-бейдж ИСССР: тёмный/светлый вариант по теме сайта */
.fb-img img.fb-badge-light{display:none}
.fb-img img.fb-badge-dark{display:block}
:root[data-theme=light] .fb-img img.fb-badge-dark{display:none}
:root[data-theme=light] .fb-img img.fb-badge-light{display:block}
@media (prefers-color-scheme:light){
  :root:not([data-theme=dark]):not([data-theme=light]) .fb-img img.fb-badge-dark{display:none}
  :root:not([data-theme=dark]):not([data-theme=light]) .fb-img img.fb-badge-light{display:block}
}


/* ═══ Шапка-карта на внутренних страницах (та же конструкция, что на главной) ═══ */
/* Шапка внутренних страниц = та же mapstage, только ниже ростом */
/* Карта лежит ВНЕ main (между шапкой и содержимым) и потому не наследует его
   полей — до 7.11 она была на --gutter шире содержимого с каждой стороны
   (измерено: карта 100–1500, содержимое 132–1468 при 1600 px). Считаем ей ту
   же ширину, что получает содержимое main: максимум минус два поля. */
.headmap{display:block;text-decoration:none;color:inherit;
  width:calc(100% - 2*var(--gutter));max-width:calc(var(--page-max) - 2*var(--gutter));
  margin:0 auto 20px}
.mapstage-mini{position:relative}
.mapstage-mini .rumap{height:200px}
.mapstage-mini .mapstage-top{padding:12px 14px}
.mapstage-mini .mapstage-foot{padding:12px 14px}
.headmap-cta{padding:5px 12px;border-radius:9px;font-size:12.5px;color:var(--muted);
  background:color-mix(in srgb, var(--panel) 72%, transparent);
  border:1px solid var(--line);backdrop-filter:blur(6px);
  transition:color .15s,border-color .15s}
.headmap:hover .headmap-cta{color:var(--ink);border-color:var(--line2)}
.headmap:hover .mapstage-mini,.headmap.mapstage-mini:hover{border-color:var(--line2)}

/* Заголовок под картой + подпись под графиком */
.stage-title{font-size:clamp(19px,2.2vw,30px);margin:0 0 14px}
.chart-cap{font-size:13px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);margin:10px 0 0;text-align:center}
.chart-legend{display:flex;gap:18px;justify-content:center;margin:8px 0 2px;
  font-size:12px;color:var(--muted)}
.chart-legend span{display:inline-flex;align-items:center;gap:6px}
.chart-legend i{width:11px;height:11px;border-radius:3px;display:inline-block}
.chart-legend .lg-rep{background:#5c7cc0}
.chart-legend .lg-prb{background:transparent;box-shadow:none;width:0;margin-right:-4px}
.chart-legend .lg-ok{background:var(--ok)}
/* ШКАЛА, А НЕ ОТТЕНОК (v6.31). Мягкие состояния красятся непрерывно — от
   зелёного к своему цвету по доле затронутых, — и квадратик одного оттенка
   об этом врёт. Полоска с градиентом показывает ровно то, что увидят на
   графике. */
.chart-legend .lg-warn{background:linear-gradient(90deg,var(--ok),#ffd98a,var(--warn));width:24px}
.chart-legend .lg-part{background:linear-gradient(90deg,var(--ok),#ffc490,var(--part));width:24px}
.chart-legend-note{margin:2px 0 0;text-align:center;font-size:11.5px;color:var(--faint)}
.chart-legend .lg-down{background:var(--down)}
.chart-legend .lg-net{background:var(--nolink)}
.chart-legend .lg-sep{margin-left:8px;padding-left:16px;border-left:1px solid var(--line2)}

/* Мобильные: переносы длинных заголовков сервисов и категорий */
@media (max-width:760px){
  .headmap{margin-bottom:14px}
  .mapstage-mini{min-height:0}
  .mapstage-mini .rumap{height:150px;padding:44px 6px 46px}
  .mapstage-mini .mapstage-top{padding:10px 12px}
  .mapstage-mini .mapstage-foot{padding:10px 12px}
  .headmap-cta{display:none}
  .stage-title{font-size:19px;margin-bottom:12px}
  /* заголовки не обрезаем — переносим на две строки */
  .cats:not(.admin-cats) .cat>summary .cat-title-txt{white-space:normal;overflow:visible;
    text-overflow:clip;line-height:1.25;display:-webkit-box;-webkit-line-clamp:2;
    -webkit-box-orient:vertical;overflow:hidden}
  .tile-name{white-space:normal;line-height:1.25;display:-webkit-box;
    -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
}

.diag-block{margin:12px 0;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--panel2)}
.diag-out{background:var(--bg2);border:1px solid var(--line2);border-radius:9px;
  padding:12px 14px;font:12.5px/1.55 var(--mono);color:var(--ink);
  white-space:pre-wrap;overflow-x:auto;margin:10px 0}


/* Инлайн-редактирование категории в дереве админки */
.cat-edit{gap:4px;align-items:center}
.cat-edit input{font-size:12.5px;padding:3px 6px}
.cat-edit input[name=cat_edit_icon]{width:38px;text-align:center;font-size:15px}
.cat-edit button{padding:3px 8px;font-size:12.5px}
.probe-line{opacity:.9}
.status-now{font-weight:600}
.status-now.st-ok{color:var(--ok)}
.status-now.st-warn{color:var(--warn)}
.status-now.st-down{color:var(--down)}

/* B2B-поля в строке сервиса */
.b2b-row{display:flex;flex-wrap:wrap;gap:5px;align-items:center;flex-basis:100%;
  padding-top:6px;margin-top:4px;border-top:1px dashed var(--line)}
.b2b-row select,.b2b-row input{font-size:12px;padding:3px 6px}

.row-saved{color:var(--ok);font-weight:700;opacity:0;transition:opacity .2s;margin-left:4px}
.row-saved.show{opacity:1}

/* Слой тревоги над картой: состояние автопроверок (географии не имеет,
   поэтому показывается плашкой, а не раскраской регионов) */
/* ЧИП — ОДНА СТРОКА (v6.30). Здесь стоял flex-wrap:wrap, и на вертикальном
   экране перечисление имён уезжало на вторую и третью строку: чип «Сроки
   истекают» занимал 85 пикселей высоты вместо 32 и выталкивал карту.
   Теперь главное (значок, слово, число) всегда видно целиком, а перечисление
   ужимается многоточием: на узком экране оно и так подсказка, а не список. */
.alarm-chip{display:inline-flex;align-items:center;gap:8px;flex-wrap:nowrap;max-width:100%;
  white-space:nowrap;
  padding:7px 13px;border-radius:999px;font-size:13px;
  border:1px solid var(--line2);background:var(--panel2);color:var(--ink)}
.alarm-chip>b{flex:0 0 auto}
.me-chip{max-width:100%;white-space:nowrap}
.me-chip>.num,.alarm-chip>.num{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.alarm-chip.down{border-color:color-mix(in srgb,var(--down) 55%,transparent);
  background:color-mix(in srgb,var(--down) 14%,var(--panel2));
  box-shadow:0 0 0 1px color-mix(in srgb,var(--down) 22%,transparent)}
.alarm-chip.warn{border-color:color-mix(in srgb,var(--warn) 50%,transparent);
  background:color-mix(in srgb,var(--warn) 12%,var(--panel2))}
.alarm-chip .num{opacity:.8}
.rumap-legend-cap{opacity:.65;margin-right:2px}

/* Рамки по статусу: проблемную группу и сервис видно, не разворачивая список */
.cat-part{border-color:color-mix(in srgb,var(--part) 56%,transparent)}
.cat-warn{border-color:color-mix(in srgb,var(--warn) 55%,transparent);
  box-shadow:0 0 22px -14px color-mix(in srgb,var(--warn) 70%,transparent)}
.cat-down{border-color:color-mix(in srgb,var(--down) 62%,transparent);
  box-shadow:0 0 26px -12px color-mix(in srgb,var(--down) 75%,transparent)}
.tile-warn{border-color:color-mix(in srgb,var(--warn) 50%,transparent)}
.tile-part{border-color:color-mix(in srgb,var(--part) 52%,transparent)}
.tile-down{border-color:color-mix(in srgb,var(--down) 58%,transparent);
  box-shadow:0 0 22px -14px color-mix(in srgb,var(--down) 65%,transparent)}
.alarm-chip.calm{border-color:var(--line2);background:var(--panel2);opacity:.9}

/* Детальный график «последний час» над суточным */
.chart-detail-wrap{margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid var(--line)}
.chart-detail{height:64px}
.chart-cap-sm{font-size:11px;opacity:.75;margin-top:2px}

/* ══════════════════════════════════════════════════════════════════════════
   Разовая проверка ресурса (/proverka, панель на главной)
   ══════════════════════════════════════════════════════════════════════════ */
.chk-panel{scroll-margin-top:20px}
.chk-home{display:grid;grid-template-columns:minmax(0,1fr);gap:14px}
.chk-home h2{margin:0}
.chk-form{display:flex;gap:10px;flex-wrap:wrap}
.chk-form input[type=text]{flex:1;min-width:220px;font:16px var(--sans);color:var(--ink);
  background:var(--bg2);border:1.5px solid var(--line2);border-radius:11px;padding:13px 15px}
.chk-form input[type=text]::placeholder{color:var(--faint)}
.chk-form input[type=text]:focus{border-color:var(--ok);outline:none}
.chk-form button{font:650 15px var(--sans);color:#08110c;border:0;cursor:pointer;border-radius:11px;
  padding:13px 26px;background:linear-gradient(180deg,#48e6a0,var(--ok));white-space:nowrap}
.chk-form button:hover{filter:brightness(1.07)}
.chk-form button[disabled]{opacity:.6;cursor:progress}
/* Две кнопки направления (v7.03): подпись в две строки, обе одной ширины —
   так они читаются как пара равноправных вопросов, а не «кнопка и приписка».
   Ширины хватает на «Проверка из-за рубежа», вторая подтягивается по ней. */
.chk-dirs{display:flex;gap:10px;flex-wrap:wrap}
.chk-form .chk-dir{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;
  line-height:1.15;padding:9px 20px;min-width:168px;min-height:52px}
/* «Проверяем…» на время проверки (v7.16): одной строкой той же высоты, по центру. */
.chk-form .chk-dir .chk-dir-busy{display:block;font-weight:700;font-size:15px}
/* Обе подписи — БЛОЧНЫЕ: если стили доедут не целиком (старый кэш у
   посетителя), строки всё равно не слипнутся в «Проверкаиз России» — ровно
   это и было на скриншоте владельца (v7.05). */
.chk-form .chk-dir .chk-dir-l1{display:block;font-weight:500;font-size:13px;opacity:.85}
.chk-form .chk-dir .chk-dir-l2{display:block;font-weight:700;font-size:15px}
.chk-form .chk-dir-on{box-shadow:0 0 0 2px var(--bg2),0 0 0 4px rgba(49,217,138,.55)}
@media (max-width:520px){.chk-dirs{width:100%}.chk-form .chk-dir{flex:1;min-width:0;padding:9px 8px}}

/* Прогресс опроса площадок (v7.03): полоса движется на каждом ответе — в
   минутной паузе между «отправили» и готовой таблицей человеку видно, что
   процесс идёт, а не завис. */
.chk-prog{display:flex;align-items:center;gap:10px;margin:0 0 10px}
.chk-prog-bar{flex:1;height:6px;border-radius:4px;background:var(--bg2);overflow:hidden}
.chk-prog-bar i{display:block;height:100%;border-radius:4px;
  background:linear-gradient(90deg,#48e6a0,var(--ok));transition:width .4s ease}
.chk-prog-txt{font-size:13px;color:var(--muted);white-space:nowrap}
.chk-prog-done .chk-prog-txt{color:var(--ok)}
.chk-geo-pend{opacity:.72}

/* Сводная группа «Белый список» (v7.03): те же ресурсы, что в обычных
   категориях, поэтому рамка приглушённая — группа собирает, а не дублирует. */
.cat.cat-virt{border-style:dashed}
.chk-more{margin:2px 0 0}
.chk-slot:empty{display:none}
.chk-hint{margin-top:16px;font-size:14.5px;color:var(--muted)}
.chk-hint b{color:var(--ink)}
.chk-hint ul{margin:8px 0 0;padding-left:20px}
.chk-hint li{margin:5px 0}

.chk-err,.chk-ok{border-radius:11px;padding:12px 15px;margin:14px 0;font-size:14.5px}
.chk-err{background:var(--down-dim);border:1px solid rgba(255,80,99,.35)}
.chk-ok{background:var(--ok-dim);border:1px solid rgba(49,217,138,.35)}
.chk-bad{color:var(--down)}
/* ЦВЕТ ЗНАЧЕНИЯ В ПЛИТКЕ (7.10, просьба владельца): одно правило на все
   строки-плитки сайта — карточки проверки, факты отчёта клиента и будущие
   .fact-rows. Зелёный — как надо, жёлтый — работает, но хуже, чем могло бы
   (IPv6 не настроен, сжатия нет, срок за месяц), красный — беда или срок за
   неделю. Красится ТЕКСТ, не плитка: цветной фон на десятке плиток подряд
   превращается в ёлку, а цветная цифра читается с одного взгляда. */
.chk-card dd.v-ok,.cl-facts dd.v-ok,.fact-rows dd.v-ok{color:var(--ok)}
.chk-card dd.v-warn,.cl-facts dd.v-warn,.fact-rows dd.v-warn{color:var(--warn)}
.chk-card dd.v-bad,.cl-facts dd.v-bad,.fact-rows dd.v-bad{color:var(--down);font-weight:600}
/* Подзаголовки внутри объединённой карточки «Сертификат и домен» (7.10). */
.chk-sub{display:flex;align-items:center;gap:8px;font:600 13.5px var(--sans);color:var(--muted);
  margin:0 0 8px;text-transform:uppercase;letter-spacing:.3px}
.chk-sub-next{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.chk-wrap{overflow-wrap:anywhere}

.chk-result{margin-top:18px;min-width:0;animation:chk-in .35s cubic-bezier(.2,.7,.2,1)}
@keyframes chk-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){.chk-result{animation:none}}
.chk-head{display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:13px;
  border:1.5px solid var(--line2);background:var(--panel2)}
.chk-head .dot{width:13px;height:13px}
.chk-head-txt{flex:1;min-width:0}
.chk-ok-b{border-color:rgba(49,217,138,.4)}
.chk-head.chk-ok{border-color:rgba(49,217,138,.4);background:linear-gradient(180deg,var(--ok-dim),transparent)}
.chk-head.chk-warn{border-color:rgba(255,178,36,.4);background:linear-gradient(180deg,var(--warn-dim),transparent)}
.chk-head.chk-down{border-color:rgba(255,80,99,.45);background:linear-gradient(180deg,var(--down-dim),transparent)}
/* v7.19: нейтральное «ждём ответа из-за рубежа» — до первого ответа площадки */
.chk-head.chk-wait{border-color:var(--line);background:linear-gradient(180deg,rgba(124,139,176,.08),transparent)}
.dot.wait{background:var(--muted);box-shadow:0 0 8px rgba(124,139,176,.5);animation:dotpulse 1.4s ease-in-out infinite}
@keyframes dotpulse{0%,100%{opacity:.45}50%{opacity:1}}
.chk-title{font:700 19px/1.25 var(--display);letter-spacing:-.3px}
.chk-host{display:block;margin-top:3px;overflow-wrap:anywhere}
.chk-total{text-align:right;display:flex;flex-direction:column;gap:2px;flex-shrink:0}
.chk-total-num{font:700 22px var(--display);letter-spacing:-.5px}
.chk-text{color:var(--muted);font-size:14.5px;margin:12px 2px 0;max-width:80ch}

.chk-wf{margin:16px 0 4px}
.wf{width:100%;height:46px;display:block}
.wf-dns{fill:#6f8fd6} .wf-connect{fill:#4fb2c9} .wf-tls{fill:#a97fd6}
.wf-wait{fill:var(--warn)} .wf-load{fill:var(--ok)}
.wf-t{fill:var(--faint);font:400 9px var(--mono)}
.chk-legend{display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:6px;
  font:400 12px var(--mono);color:var(--muted)}
.chk-legend i{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:6px;vertical-align:-1px}
.chk-legend b{color:var(--ink);font-weight:600}
.chk-note{margin:8px 0 0;font-size:13px;line-height:1.5;color:var(--dim)}
.wl-dns{background:#6f8fd6} .wl-connect{background:#4fb2c9} .wl-tls{background:#a97fd6}
.wl-wait{background:var(--warn)} .wl-load{background:var(--ok)}

.chk-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr));gap:12px;margin-top:16px}
.chk-card{border:1px solid var(--line);border-radius:12px;padding:13px 15px;background:var(--panel2);min-width:0}
.chk-card h3{margin:0 0 9px;font-size:14px;font-weight:650;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.chk-card h3 .chip{font-size:11.5px;padding:2px 9px}
/* ФАКТ — СТРОКОЙ-ПЛИТКОЙ (v7.07, просьба владельца: «переделай как чёрные
   списки»). Двухколоночная сетка из <dt>/<dd> читалась хуже: у длинных
   значений (IPv6, заголовок страницы) строки разъезжались, и глаз терял, что
   к чему относится. Плитка держит пару вместе и на любой ширине.

   Разметку не трогаем — только вид: <dl> остаётся <dl>, и все места, где он
   уже стоит, получают новый вид разом. Пара склеивается в одну плитку тем,
   что рамку и фон рисует dt слева, dd справа, а скругления — по краям пары. */
.chk-card dl,.cl-facts,.fact-rows{margin:0;display:grid;
  grid-template-columns:minmax(72px,max-content) minmax(0,1fr);gap:6px 0;font-size:13.5px}
.chk-card dt,.cl-facts dt,.fact-rows dt{color:var(--muted);
  background:var(--bg2);border:1px solid var(--line);border-right:0;
  border-radius:8px 0 0 8px;padding:6px 10px;display:flex;align-items:center;min-width:0;
  overflow-wrap:break-word}
.chk-card dd,.cl-facts dd,.fact-rows dd{margin:0;color:var(--ink);
  background:var(--bg2);border:1px solid var(--line);border-left:0;
  border-radius:0 8px 8px 0;padding:6px 10px;display:flex;align-items:center;
  justify-content:flex-end;text-align:right;min-width:0;overflow-wrap:break-word}
.chk-rdr{margin:0;padding-left:20px;font-size:13px}
.chk-rdr li{margin:4px 0}

.chk-notes{margin-top:16px}
.chk-notes h3{font-size:15px;margin:0 0 8px}
.chk-notes ul{list-style:none;margin:0;padding:0;display:grid;gap:7px}
/* min-width:0 обязателен: элемент grid по умолчанию не сжимается меньше своего
   содержимого, и одна длинная строка в <pre> раздвигала всю страницу вбок. */
.chk-notes li{position:relative;padding:9px 13px 9px 38px;border-radius:10px;font-size:14px;
  background:var(--panel2);border:1px solid var(--line);min-width:0;overflow-wrap:anywhere}
.chk-notes li::before{position:absolute;left:13px;top:9px;font-size:13px}
/* ЦВЕТ УРОВНЯ — РАМКОЙ И ПОЛОСОЙ СЛЕВА (v7.05). Значка мало: пять пунктов
   подряд выглядели одинаково важными, и красное терялось среди жёлтого.
   Рамка красит карточку целиком, полоса слева видна и на телефоне. */
.nt-bad{border-color:rgba(255,80,99,.55);box-shadow:inset 4px 0 0 var(--down);
  background:linear-gradient(90deg,var(--down-dim),var(--panel2) 60%)}
.nt-bad::before{content:'✕';color:var(--down)}
.nt-warn{border-color:rgba(255,178,36,.5);box-shadow:inset 4px 0 0 var(--warn);
  background:linear-gradient(90deg,var(--warn-dim,rgba(255,178,36,.10)),var(--panel2) 60%)}
.nt-warn::before{content:'!';color:var(--warn);font-weight:700}
.nt-ok{border-color:rgba(49,217,138,.35);box-shadow:inset 4px 0 0 var(--ok)}
.nt-ok::before{content:'✓';color:var(--ok)}
.nt-info::before{content:'i';color:var(--faint);font-style:italic}

.chk-sec{margin-top:14px;border:1px solid var(--line);border-radius:12px;overflow:hidden}
.chk-sec>summary{padding:11px 15px;cursor:pointer;font-size:14px;font-weight:600;background:var(--panel2)}
.chk-sec>summary::-webkit-details-marker{display:none}
.chk-sect{width:100%;border-collapse:collapse;font-size:13px}
.chk-sect td{padding:9px 15px;border-top:1px solid var(--line);vertical-align:top}
.chk-sect tr.st-warn td:first-child{box-shadow:inset 3px 0 0 var(--warn)}
.chk-sect tr.st-ok td:first-child{box-shadow:inset 3px 0 0 var(--ok)}
.chk-sect tr.st-off td:first-child{box-shadow:inset 3px 0 0 var(--faint)}

.chk-mon{margin-top:14px;padding:12px 15px;border-radius:11px;background:var(--panel2);
  border:1px solid var(--line);font-size:14px;display:flex;gap:10px;align-items:center;flex-wrap:wrap}

/* ПРОДАЮЩИЙ БЛОК (v7.05, укрупнён в 7.09 по просьбе владельца «сделать
   заметнее, тексты и заголовки крупнее»).

   Заметность здесь делается НЕ яркостью, а размером и воздухом: блок стоит
   последним на длинной странице отчёта, и до него доходит человек, уже
   уставший от таблиц. Кегль довода поднят до 17 px, заголовок — до 21 и с
   собственной строкой, отступы шире прежних. Свечение по краю осталось
   прежним: два усиления сразу превратили бы блок в баннер, который взгляд
   обходит. */
.chk-cta{margin-top:30px;padding:28px 30px;border-radius:16px;
  border:1.5px solid rgba(49,217,138,.45);
  background:linear-gradient(180deg,rgba(49,217,138,.10),rgba(49,217,138,.02))}
.chk-cta-txt{font-size:17px;line-height:1.55;color:var(--muted);max-width:none}
.chk-cta-txt b{color:var(--ink);font-size:21px;line-height:1.25;display:block;margin-bottom:9px}
/* Карточки тарифов под отчётом (v7.07): те же, что на /tariffs, только мельче
   и без действий аккаунта — человек здесь ещё не вошёл. */
.chk-cta-plans{margin-top:22px;padding-top:20px;border-top:1px solid rgba(49,217,138,.25)}
.tar-grid-sm{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  align-items:stretch}
.tar-card-sm{padding:18px 18px 20px;display:flex;flex-direction:column;position:relative}
.tar-card-sm h2{font-size:18px;margin:0 0 8px}
.tar-card-sm .tar-li{font-size:13.5px}
/* Кнопка прижата к низу: карточки разной высоты, а действие у них одно, и
   ступенька из трёх кнопок на разной высоте читается как разная важность. */
.tar-card-sm .tar-go{margin-top:auto}
/* ВЫБРАННЫЙ ТАРИФ (7.09): рамка в цвет действия и подпись сверху. Из трёх
   карточек одна — предложение, две — ответ на вопрос «а дальше?». */
.tar-card-pick{border:1.5px solid var(--ok);
  background:linear-gradient(180deg,rgba(49,217,138,.07),transparent)}
.tar-pick-tag{position:absolute;top:-9px;left:16px;font:700 11px/1 var(--sans);
  letter-spacing:.4px;text-transform:uppercase;color:#08110c;padding:5px 9px;
  border-radius:6px;background:linear-gradient(180deg,#48e6a0,var(--ok))}
.tar-go{display:block;margin-top:14px;text-align:center;text-decoration:none;
  font:650 14.5px var(--sans);color:var(--ink);border:1px solid var(--line2);
  border-radius:9px;padding:11px 14px}
.tar-go:hover{border-color:var(--ok);color:var(--ok)}
.tar-go-free{color:#08110c;border:0;background:linear-gradient(180deg,#48e6a0,var(--ok))}
.tar-go-free:hover{color:#08110c;filter:brightness(1.07)}
/* Служебные ссылки — под карточками (схема владельца 7.09). */
.chk-cta-foot{margin:18px 0 0;color:var(--muted);font-size:13.5px;line-height:1.7}
.chk-cta-foot a{color:var(--muted)}
.chk-cta-foot a:hover{color:var(--ok)}

/* ПРОДАЮЩИЙ БЛОК — ОТДЕЛЬНО ОТ ОТЧЁТА (v7.12, схема владельца). До 7.12 это
   были .chk-cta* классы ВНУТРИ рамки отчёта; теперь — самостоятельный раздел
   страницы (см. plans_sell_block() в plans.php и его вызов в index.php),
   визуально отделённый от отчёта своей секцией, а не подвалом чужой. Крупнее
   прежнего и с собственным заголовком — было заметно, но читалось как
   приписка; отдельный раздел с h2 выглядит как отдельное предложение. */
.sell-cta{margin:20px 0;padding:34px 32px;border-radius:18px;
  border:1.5px solid rgba(49,217,138,.5);
  background:linear-gradient(180deg,rgba(49,217,138,.12),rgba(49,217,138,.02))}
/* Заголовок тарифа в продающем блоке — крупнее (v7.17, просьба владельца):
   карточка на /proverka продаёт, и название тарифа должно читаться сразу. */
.sell-cta .tar-card-sm h2{font-size:23px;margin:0 0 8px}
.sell-cta-h{margin:0 0 12px;font-size:27px;line-height:1.2}
.sell-cta-txt{margin:0;font-size:17px;line-height:1.55;color:var(--muted);max-width:720px}
.sell-cta-plans{margin-top:26px;padding-top:24px;border-top:1px solid rgba(49,217,138,.25)}
.sell-cta-foot{margin:20px 0 0;color:var(--muted);font-size:13.5px;line-height:1.7}
.sell-cta-foot a{color:var(--muted)}
.sell-cta-foot a:hover{color:var(--ok)}

/* Подпись «для кого» под названием тарифа (v7.12) — решение «мне какой»
   человек принимает по себе, не по таблице лимитов; цифры и так ниже. */
.tar-tag{margin:0 0 10px;font-size:12.5px;line-height:1.4;color:var(--muted,#93a2b5)}

/* Цена «от», годовая впереди (v7.12, только в этом блоке — см. комментарий
   у plan_price_html_lead() в plans.php про то, почему не в plan_price_html).
   Ведём дешёвой цифрой, месячная — пояснением, откуда взялось «от». */
.tar-cost-lead{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 0}
.tar-from{font-size:13px;color:var(--muted,#93a2b5);margin-right:4px}
.tar-year-alt{width:100%}
.chk-lead{display:flex;gap:9px;flex-wrap:wrap;margin-top:13px}
.chk-lead input[type=text]{flex:1;min-width:190px;font:14.5px var(--sans);color:var(--ink);
  background:var(--bg2);border:1px solid var(--line2);border-radius:9px;padding:10px 13px}
.chk-lead button{font:650 14.5px var(--sans);color:#08110c;border:0;cursor:pointer;border-radius:9px;
  padding:10px 22px;background:linear-gradient(180deg,#48e6a0,var(--ok))}
.chk-lead .hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
/* ПОДПИСЬ ОТЧЁТА (v7.05): её уносят скриншотом, поэтому она обязана читаться
   на картинке — рамка сверху, имя сервиса обычным кеглем, не серой мелочью. */
.chk-foot{margin-top:16px;padding-top:12px;border-top:1px solid var(--line);
  display:flex;gap:6px 18px;flex-wrap:wrap;align-items:baseline;overflow-wrap:anywhere}
.chk-foot-who{font-size:14.5px;color:var(--ink)}
.chk-foot-who b{color:var(--ok)}
.chk-foot-when{font-size:13.5px;color:var(--muted)}
.chk-foot-url{font-size:12.5px;color:var(--faint);min-width:0}

/* СПИСКИ СТРОКАМИ (v7.05) */
.bl-rows{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.bl-row{display:flex;gap:10px;align-items:baseline;justify-content:space-between;
  padding:6px 9px;border-radius:8px;background:var(--bg2);border:1px solid var(--line);
  font-size:13.5px;min-width:0}
.bl-name{color:var(--ink);text-decoration:none;min-width:0;overflow-wrap:anywhere}
a.bl-name:hover{text-decoration:underline}
.bl-ext{font-style:normal;color:var(--faint);margin-left:4px;font-size:11px}
.bl-ans{white-space:nowrap;font:600 12.5px var(--mono,var(--sans))}
.bl-ans-ok{color:var(--ok)} .bl-ans-warn{color:var(--warn)}
.bl-ans-down{color:var(--down)} .bl-ans-info{color:var(--faint)}
.bl-row.bl-down{border-color:rgba(255,80,99,.45)}
.bl-row.bl-warn{border-color:rgba(255,178,36,.35)}
.bl-hint{margin:9px 0 0;font-size:12px;color:var(--faint)}

/* СПИСОК БРАУЗЕРНЫХ ПРОВЕРОК В ОТЧЁТЕ КЛИЕНТА (v7.06): строка на пробу.
   Цвет — точкой и левой полосой, как у замечаний проверки: одинаковый язык
   на всех витринах дешевле трёх похожих. */
.cl-bp{margin-top:12px;padding:11px 13px;border-radius:11px;
  background:var(--panel2);border:1px solid var(--line)}
.cl-bp-h{font-size:13.5px;font-weight:600;margin-bottom:8px}
.cl-bp-h .num{color:var(--faint);font-weight:400;margin-left:5px}
.cl-bp-row{display:grid;grid-template-columns:minmax(120px,1fr) minmax(0,1.6fr) auto;
  gap:6px 12px;align-items:baseline;padding:7px 9px;border-radius:8px;
  background:var(--bg2);border:1px solid var(--line);margin-bottom:6px;font-size:13px}
.cl-bp-row:last-of-type{margin-bottom:0}
.cl-bp-down{border-color:rgba(255,80,99,.45);box-shadow:inset 3px 0 0 var(--down)}
.cl-bp-warn{border-color:rgba(255,178,36,.4);box-shadow:inset 3px 0 0 var(--warn)}
.cl-bp-ok{box-shadow:inset 3px 0 0 var(--ok)}
.cl-bp-none{box-shadow:inset 3px 0 0 var(--faint);opacity:.85}
.cl-bp-none .dot{background:var(--faint)}
.cl-bp-name{display:flex;gap:6px;align-items:center;min-width:0;overflow-wrap:anywhere}
.cl-bp-name .num{color:var(--faint);font-size:11px}
.cl-bp-say{color:var(--muted);min-width:0;overflow-wrap:anywhere}
.cl-bp-meta{white-space:nowrap;color:var(--faint);font-size:12px}
.cl-bp-note{margin:8px 0 0;font-size:11.5px;color:var(--faint)}
@media (max-width:640px){.cl-bp-row{grid-template-columns:1fr}.cl-bp-meta{white-space:normal}}

/* Заголовок страницы — по тому же отступу, что и панели под ним (v7.05). */
.stage-title-pad{padding-left:20px}
@media (max-width:700px){.stage-title-pad{padding-left:14px}}
/* ЧАСТЫЕ ВОПРОСЫ — АККОРДЕОНОМ (7.09). Закрытая строка обязана выглядеть
   нажимаемой: своя рамка, курсор и знак раскрытия. Родная стрелка <details>
   убрана (list-style:none + ::-webkit-details-marker) — она в разных
   браузерах разного размера и сбивает выравнивание. */
.qa{display:grid;gap:8px;max-width:none}
.qa-item{border:1px solid var(--line);border-radius:11px;background:var(--panel2);
  overflow:hidden}
.qa-item summary{list-style:none;cursor:pointer;padding:13px 42px 13px 16px;
  position:relative;font:600 15px var(--sans);color:var(--ink)}
.qa-item summary::-webkit-details-marker{display:none}
.qa-item summary::after{content:'+';position:absolute;right:16px;top:50%;
  transform:translateY(-50%);font:400 19px/1 var(--sans);color:var(--muted)}
.qa-item[open] summary::after{content:'−'}
.qa-item summary:hover{color:var(--ok)}
.qa-item[open] summary{border-bottom:1px solid var(--line)}
.qa-item p{margin:0;padding:13px 16px 15px;font-size:14.5px;line-height:1.6;color:var(--muted)}
.qa p{font-size:14.5px;color:var(--muted);max-width:80ch}
.qa b{color:var(--ink)}

/* ── Мониторинг для бизнеса ── */
.mon-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(180px,100%),1fr));gap:12px;margin:16px 0}
.mon-stats>div{border:1px solid var(--line);border-radius:12px;padding:15px 17px;background:var(--panel2)}
.mon-stats b{display:block;font:700 27px var(--display);letter-spacing:-.7px;color:var(--ok)}
.mon-stats .num{display:block;margin-top:3px}
.mon-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(250px,100%),1fr));gap:12px;margin-top:10px}
.mon-card{border:1px solid var(--line);border-radius:12px;padding:14px 16px;background:var(--panel2)}
.mon-card h3{margin:0 0 6px;font-size:14.5px}
.mon-card p{margin:0;font-size:13.5px;color:var(--muted)}
.mon-lead input[type=text]{min-width:170px}

/* ══════════════════════════════════════════════════════════════════════════
   Кабинет клиента
   ══════════════════════════════════════════════════════════════════════════ */
.cl-per{display:inline-flex;gap:4px;margin-left:8px}
.cl-per a{font:400 12.5px var(--mono);padding:3px 10px;border-radius:8px;text-decoration:none;
  border:1px solid var(--line2);color:var(--muted)}
.cl-per a.on{background:var(--ok-dim);border-color:rgba(49,217,138,.4);color:var(--ok)}
.cl-kpi{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(150px,100%),1fr));gap:10px;margin:12px 0}
.cl-kpi>div{border:1px solid var(--line);border-radius:12px;padding:11px 13px;background:var(--panel2)}
.cl-kpi .num{display:block;margin-top:3px}
.cl-num{font:700 25px var(--display);letter-spacing:-.6px;line-height:1.1;display:block}
.cl-num.ok{color:var(--ok)}
.cl-num.lo1{color:var(--warn);color:color-mix(in srgb,var(--warn) 45%,var(--ok))}
.cl-num.warn{color:var(--warn)}
.cl-num.mid1{color:var(--warn);color:color-mix(in srgb,var(--down) 30%,var(--warn))}
.cl-num.mid2{color:var(--warn);color:color-mix(in srgb,var(--down) 55%,var(--warn))}
.cl-num.mid3{color:var(--down);color:color-mix(in srgb,var(--down) 80%,var(--warn))}
.cl-num.part{color:var(--part)}
.cl-num.down{color:var(--down)}
/* Карточка ресурса — сворачиваемая, как категории на главной (v6.74). Шапка —
   это <summary>: стрелка справа рисуется через ::after и крутится на [open];
   штатный маркер убран. Тело и URL ушли под summary. */
.cl-res{border:1px solid var(--line2);border-radius:13px;padding:12px 14px;margin-top:10px;background:var(--panel2);position:relative}
.cl-res>summary.cl-res-head{list-style:none;cursor:pointer;padding-right:26px;display:block}
.cl-res>summary.cl-res-head::-webkit-details-marker{display:none}
.cl-res>summary::after{content:'▾';position:absolute;top:14px;right:13px;color:var(--faint);
  font-size:13px;transition:transform .2s}
.cl-res[open]>summary::after{transform:rotate(180deg)}
.cl-res-h-top{display:flex;justify-content:space-between;gap:14px;align-items:flex-start;flex-wrap:wrap}
.cl-res-h-main{min-width:0}
/* Аптайм по дням/часам, вписанный в СВЁРНУТУЮ шапку (v6.75): узкая полоса под
   строкой имени/аптайма — виден и когда карточка свёрнута. */
.cl-res-h-spark{margin-top:8px;min-width:0}
.cl-res-h-spark .uq{height:34px}
.cl-res-h-spark .num{display:block;margin-top:2px}
.cl-res-head .chip{margin-left:8px;font-size:12px;padding:2px 9px}
.cl-res-up{text-align:right}
.cl-res-up .num{display:block}
/* Адрес ресурса — ОДНОЙ строкой с многоточием (v6.76). Длинный адрес (в пределе
   data:-строка целиком) переносился на три строки и вылезал за карточку, ломая
   вёрстку тела. Полный адрес остаётся в подсказке и по ссылке. */
.cl-res-url{margin-top:3px;max-width:100%;overflow:hidden}
.cl-res-url .cl-url{display:inline-block;max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}
/* Шапка панели «Ресурсы» с кнопкой «развернуть/свернуть всё» справа (v6.75) —
   как «Развернуть всё» в админке. */
.cl-res-toph{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
.cl-res-toph h2{margin:0}
.cl-toggle{font-size:12px;padding:5px 13px;border-radius:99px;cursor:pointer;
  border:1px solid var(--line2);background:var(--panel);color:var(--muted)}
.cl-toggle:hover{border-color:var(--ok);color:var(--ink)}
/* Отчёт клиента: слева графики одной колонкой, справа узкой — скриншот и факты.
   Раньше тремя равными детьми грид ставил высокий скриншот в первую колонку,
   графики зависали наверху второй, и рядом зияла пустота во весь список (v6.74). */
.cl-res-body{display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,320px);
  gap:14px 22px;margin-top:12px;align-items:start}
.cl-side{display:flex;flex-direction:column;gap:12px;min-width:0}
.cl-charts{display:flex;flex-direction:column;gap:10px;min-width:0}
.cl-spark .num{display:block;margin-top:2px}
.cl-spark svg{width:100%;display:block}
.uq{width:100%;height:42px;display:block}
/* Шкала аптайма: те же ступени, что на графиках главной, — плавный переход
   зелёный → зелёно-жёлтый → жёлтый → жёлто-красный → красный. Ступень выбирает
   uptime_tier() в lib.php, одна на столбик и на крупную цифру.
   ЗАПАСНОЕ ЗНАЧЕНИЕ ПЕРЕД color-mix ОБЯЗАТЕЛЬНО: браузер, не знающий функцию,
   отбросит всё объявление и закрасит столбик чёрным (поймано ещё в v5.12). */
.uq-ok{fill:var(--ok)}
.uq-lo1{fill:var(--warn);fill:color-mix(in srgb,var(--warn) 45%,var(--ok))}
.uq-warn{fill:var(--warn)}
.uq-mid1{fill:var(--warn);fill:color-mix(in srgb,var(--down) 30%,var(--warn))}
.uq-mid2{fill:var(--warn);fill:color-mix(in srgb,var(--down) 55%,var(--warn))}
.uq-mid3{fill:var(--down);fill:color-mix(in srgb,var(--down) 80%,var(--warn))}
.uq-part{fill:var(--part)}
.uq-down{fill:var(--down)}
.uq-none{fill:var(--faint);opacity:.4}
/* Вид задан общим правилом выше (v7.07) — здесь остаётся только цвет итога. */
/* Итог маршрута в карточке отчёта красится по классу из route_of (v6.94):
   «down» — цепочка оборвалась, «warn» — прошла, но выбор был неоднозначным
   (несколько одноимённых кнопок). Пройденный «не туда» маршрут выглядел бы
   безупречно зелёным, и предупреждение рядом с ним читалось бы как примечание,
   а не как повод поправить шаг. */
.cl-facts dd.down{color:var(--down)}
.cl-facts dd.warn{color:var(--warn)}
.cl-inc{margin-top:10px;border-top:1px solid var(--line);padding-top:8px}
.cl-inc>summary{cursor:pointer;font-size:13.5px;font-weight:600}
.cl-inc>summary::-webkit-details-marker{display:none}
.cl-inct{width:100%;border-collapse:collapse;margin-top:8px;font-size:13px}
.cl-inct td{padding:6px 8px;border-top:1px solid var(--line)}
.cl-noinc{margin:10px 0 0}
.cl-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px}
.cl-btn{display:inline-block;padding:9px 18px;border-radius:10px;text-decoration:none;font-size:14px;
  border:1px solid var(--line2);background:var(--panel2)}
.cl-btn:hover{border-color:var(--ok)}

/* Печать отчёта: клиенты прикладывают его к актам — режем всё лишнее */
@media print{
  :root{--bg:#fff;--bg2:#fff;--panel:#fff;--panel2:#fff;--ink:#000;--muted:#333;--line:#ccc;--line2:#999}
  body{background:#fff;color:#000}
  .sitehead,footer,.cl-actions,.cl-per,.headmap{display:none!important}
  .panel,.cl-res,.cl-kpi>div{border:1px solid #ccc;box-shadow:none;break-inside:avoid}
  .cl-inc{display:block} .cl-inc>summary{list-style:none}
  /* Сворачиваемые карточки/скриншоты (v6.74) в печать идут РАСКРЫТЫМИ: свёрнутый
     ресурс не должен пропасть из акта. */
  .cl-res>.cl-res-open{display:block!important}
  .cl-res>summary::after,.cl-shot-btn{display:none!important}
  .cl-shot-frame{max-height:none!important}
  .cl-shot-frame::after{display:none!important}
  main{max-width:none;padding:0}
}

/* ── Админка: заявки ── */
.mini-btn{font:600 12px var(--sans);color:var(--ink);background:var(--panel2);cursor:pointer;
  border:1px solid var(--line2);border-radius:7px;padding:5px 11px}
.mini-btn:hover{border-color:var(--ok)}
tr.lead-new td{background:rgba(49,217,138,.06)}
tr.lead-done td,tr.lead-spam td{opacity:.55}

@media (max-width:760px){
  .chk-head{align-items:flex-start;flex-wrap:wrap}
  .chk-total{text-align:left}
  .cl-res-head{flex-direction:column}
  .cl-res-up{text-align:left}
}

/* ── Рекомендации в резюме проверки ── */
.chk-notes li{padding-bottom:9px}
.nt-txt{display:block}
.nt-fix{margin-top:7px}
.nt-fix>summary{cursor:pointer;font:600 12.5px var(--sans);color:var(--muted);
  display:inline-block;padding:3px 10px;border:1px solid var(--line2);border-radius:8px}
.nt-fix>summary:hover{border-color:var(--ok);color:var(--ink)}
.nt-fix>summary::-webkit-details-marker{display:none}
.nt-fix[open]>summary{margin-bottom:8px}
.nt-fix-b{font-size:13.5px;color:var(--muted)}
.nt-fix-b p{margin:0 0 7px}
.nt-fix-b{min-width:0}
/* Сниппет переносим, а не прячем в горизонтальную прокрутку: строки конфига
   короткие, а на телефоне боковой скролл внутри карточки не находят. */
.nt-fix-b pre{margin:0 0 7px;padding:10px 12px;border-radius:9px;max-width:100%;
  background:var(--bg2);border:1px solid var(--line);overflow-x:auto}
.nt-fix-b code{font:12.5px/1.5 var(--mono);color:var(--ink);
  white-space:pre-wrap;overflow-wrap:anywhere}
.nt-fix-warn{border-left:2px solid var(--warn);padding-left:10px;margin:0}
.chk-sect .nt-fix{margin-top:8px}
.chk-order{margin:10px 2px 0}

/* ── Узкий экран: телефон в вертикальной ориентации ─────────────────────────
   Главная беда узких экранов — не размеры шрифтов, а элементы, которые
   отказываются сжиматься: определения в две колонки, таблицы и блоки кода.
   Здесь они переводятся в одну колонку, а не ужимаются до нечитаемого. */
@media (max-width:560px){
  .chk-result{font-size:14px}
  .chk-head{padding:13px 14px;gap:11px}
  .chk-title{font-size:17px}
  .chk-total{width:100%;flex-direction:row;align-items:baseline;gap:8px;
    border-top:1px solid var(--line);padding-top:9px;margin-top:2px}
  .chk-total-num{font-size:19px}
  .chk-text{margin:11px 0 0}

  /* На узком экране плитка ЛОМАЕТСЯ ПОПОЛАМ, а не разваливается на два
     отдельных прямоугольника: подпись сверху, значение снизу, рамка одна
     (v7.07). Прежнее правило рвало пару на две строки без рамок — на
     телефоне это была стена текста. */
  .chk-card dl,.cl-facts,.fact-rows{grid-template-columns:1fr;gap:6px 0}
  .chk-card dt,.cl-facts dt,.fact-rows dt{border-radius:8px 8px 0 0;
    border-right:1px solid var(--line);border-bottom:0;font-size:12px;padding:5px 9px}
  .chk-card dd,.cl-facts dd,.fact-rows dd{border-radius:0 0 8px 8px;
    border-left:1px solid var(--line);border-top:0;justify-content:flex-start;
    text-align:left;padding:5px 9px}
  .chk-card{padding:12px 13px}

  .chk-notes li{padding:9px 12px 9px 34px}
  .chk-notes li::before{left:12px}
  .nt-fix-b pre{padding:9px 10px}
  .nt-fix-b code{font-size:11.5px}

  /* Таблица заголовков превращается в карточки: два столбца на 360px нечитаемы */
  .chk-sect,.chk-sect tbody,.chk-sect tr,.chk-sect td{display:block;width:100%}
  .chk-sect td{padding:9px 13px;border-top:0}
  .chk-sect tr{border-top:1px solid var(--line);padding:4px 0}
  .chk-sect tr td:last-child{padding-top:0;color:var(--faint)}
  .chk-sect tr.st-warn td:first-child,.chk-sect tr.st-ok td:first-child,
  .chk-sect tr.st-off td:first-child{box-shadow:inset 3px 0 0 currentColor}
  .chk-sect tr.st-warn td:first-child{color:var(--warn)}
  .chk-sect tr.st-ok td:first-child{color:var(--ok)}
  .chk-sect tr.st-off td:first-child{color:var(--faint)}
  .chk-sect td b{color:var(--ink)}

  .chk-form input[type=text],.chk-form button{width:100%}
  .chk-lead input[type=text],.chk-lead button{width:100%;min-width:0}
  .chk-cta{padding:13px 14px}
  .sell-cta{padding:18px 16px}
  .sell-cta-h{font-size:21px}
  .chk-legend{gap:4px 12px;font-size:11.5px}
  .chk-mon{font-size:13px}

  /* Кабинет клиента */
  .cl-kpi>div{padding:12px 13px}
  .cl-num{font-size:21px}
  .cl-inct,.cl-inct tbody,.cl-inct tr,.cl-inct td{display:block;width:100%}
  .cl-inct tr{border-top:1px solid var(--line);padding:6px 0}
  .cl-inct td{padding:1px 0;border-top:0}
  .cl-actions .cl-btn{width:100%;text-align:center}
  .cl-per{display:flex;flex-wrap:wrap;margin:6px 0 0}
}

/* Ландшафтная ориентация телефона: высоты мало, режем вертикальные отступы */
@media (max-height:520px) and (orientation:landscape){
  .chk-head{padding:11px 14px}
  .chk-result{margin-top:12px}
}

/* ── Поля форм не должны распирать страницу ────────────────────────────────
   Виновник горизонтальной прокрутки на узком экране — почти всегда не текст,
   а элемент формы: <textarea> с атрибутом cols, <select> с длинным пунктом,
   <input size="60">. Свою «естественную» ширину они держат и контейнер не
   слушают, поэтому ограничиваем явно. */
input,select,textarea,button{max-width:100%;box-sizing:border-box}
textarea{width:100%}
select{text-overflow:ellipsis}
label{min-width:0}
@media (max-width:560px){
  .sel,.row-form label,form label{max-width:100%}
  .row-form input,.row-form select{max-width:100%}
}

/* ── Что переполняло страницу на узком экране ──────────────────────────────
   Найдено прогоном настоящего браузера на 360 и 390 px. Виновники не там, где
   ожидалось: не длинный текст, а неразрывные строки в шапке, легенде графика
   и inline-flex формах админки — они не переносятся и распирают страницу. */

/* Легенда графика: разделитель с левой границей не давал строке перенестись */
.chart-legend{flex-wrap:wrap}
@media (max-width:620px){
  .chart-legend .lg-sep{margin-left:0;padding-left:0;border-left:0}
}

/* Шапка: на очень узких экранах прячем то, что дублируется ниже по странице */
.sitehead-right{flex-wrap:wrap;min-width:0}
@media (max-width:400px){
  .sitehead-right{gap:10px}
  .sitehead-right .mini-isr{display:none}
}

/* Формы админки: inline-flex не переносится, поэтому на узком делаем его
   переносимым, а поля — на всю ширину. Атрибут size у input задаёт
   «естественную» ширину, которую контейнер не может уменьшить сам. */
@media (max-width:760px){
  .inline{display:flex;flex-wrap:wrap;max-width:100%}
  .inline input,.inline select{max-width:100%;min-width:0;flex:1 1 140px}
  .row-form{max-width:100%}
  .row-form input,.row-form select{min-width:0}
  table.svc,table.svc tbody{max-width:100%}
  .panel form label{max-width:100%;display:inline-flex;flex-wrap:wrap;gap:4px}
}

/* Админка на телефоне: дерево сервисов — плотный редактор на десяток колонок,
   ужимать его до 360px бессмысленно. Честнее дать таблице собственную
   горизонтальную прокрутку, чем растягивать всю страницу. */
@media (max-width:760px){
  table.svc.admin,.panel table.svc{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
  .panel code,.panel pre{overflow-wrap:anywhere;white-space:pre-wrap;max-width:100%}
  .adm-flash{overflow-wrap:anywhere}
}


/* Признак устаревших данных: страница жива, но обновление не проходит.
   Молча показывать старую картину на сервисе про доступность нельзя. */
.stale-note{margin:10px 0;padding:10px 14px;border-radius:10px;
  background:color-mix(in srgb, var(--warn) 12%, transparent);
  border:1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  color:var(--ink);font-size:14px;line-height:1.45}

/* Диагностика адреса: таблица проб с разбивкой по фазам.
   Задача — не «показать, что медленно», а показать ГДЕ медленно. */
.diag-wrap{overflow-x:auto;margin:10px 0}
.diag-tbl{width:100%;border-collapse:collapse;font-size:13px;min-width:760px}
.diag-tbl th{text-align:left;padding:7px 9px;font-weight:600;color:var(--muted);
  border-bottom:1px solid var(--line2);white-space:nowrap}
.diag-tbl td{padding:7px 9px;border-bottom:1px solid var(--line2);vertical-align:top}
.diag-tbl .num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.diag-tbl .mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;white-space:nowrap}
.diag-tbl .row-bad td{background:color-mix(in srgb, var(--down) 9%, transparent)}
.diag-tbl .row-ok  td{background:color-mix(in srgb, var(--ok) 6%, transparent)}
.diag-tbl .hot{color:var(--warn);font-weight:700}
.diag-tbl tr:last-child td{border-bottom:0}

/* Причина текущего статуса под шапкой сервиса. Нейтральная формулировка:
   объясняем, что видит проба, и не выносим приговор чужому сайту. */
.svc-reason{margin:8px 0 0;padding:9px 13px;border-radius:9px;font-size:14px;line-height:1.45;
  background:var(--panel2);border:1px solid var(--line2);color:var(--ink)}
/* фаза, на которой проба встала: смысл другой, чем «просто долго» */
.diag-tbl .stalled{color:var(--down);font-weight:700}


/* ---------- Площадки проб (админка) ---------- */
/* Строка площадки раньше собиралась из формы, растянутой на две ячейки: таблица
   разъезжалась, названия занимали половину ширины, а статистика переносилась в
   три строки. Каждая форма теперь живёт внутри ОДНОЙ ячейки. */
.ag-now{margin:0 0 12px;padding:10px 12px;border-radius:10px;line-height:1.5;
  background:rgba(90,200,140,.10);border:1px solid rgba(90,200,140,.35)}
.ag-now-host{background:rgba(120,140,200,.10);border-color:rgba(120,140,200,.35)}
.ag-key{margin:0 0 12px;padding:12px;border-radius:10px;
  background:rgba(240,190,60,.10);border:1px solid rgba(240,190,60,.40)}
.ag-key p{margin:6px 0;font-size:13px;opacity:.85;line-height:1.45}
.ag-key textarea{width:100%;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:13px;
  padding:8px;border-radius:8px;resize:vertical}
/* ── Таблица площадок (переработана в v5.48) ────────────────────────────
   Что чинится. Восемь колонок с white-space:nowrap НЕ ВЛЕЗАЛИ даже на
   широком экране: строка «проверено 54, недоступны 0» распирала таблицу, та
   вылезала за пределы панели и закрывала соседние блоки. Теперь:
     • таблица живёт в .tbl-wrap с горизонтальной прокруткой — что бы в неё
       ни попало, за пределы панели это не выйдет;
     • nowrap оставлен только там, где перенос действительно вреден (период,
       роль, кнопки), а тексты про связь и пробы переносятся;
     • карточный режим включается на 1100px, а не на 760: восемь колонок
       перестают читаться гораздо раньше, чем начинается телефон;
     • в карточном режиме подпись колонки берётся из data-l — иначе набор
       чисел без заголовков не читается вовсе. */
.ag-tbl{width:100%;border-collapse:collapse;margin:8px 0;font-size:13.5px;table-layout:auto}
.ag-tbl th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.04em;
  opacity:.6;padding:5px 10px 5px 0;font-weight:600;white-space:nowrap}
.ag-tbl td{padding:7px 10px 7px 0;vertical-align:top;border-top:1px solid rgba(255,255,255,.07);
  overflow-wrap:anywhere}
.ag-tbl td.ag-per,.ag-tbl td.ag-act{white-space:nowrap}
.ag-name{min-width:190px}
.ag-stat,.ag-seen{line-height:1.3;min-width:110px}
.ag-per input{width:60px}
.ag-sub{font-size:11.5px;opacity:.62;line-height:1.35}
.ag-bad{color:var(--warn,#f0be3c)}
.ag-off{opacity:.5}
.ag-edit{display:flex;gap:5px;align-items:center;flex-wrap:wrap;margin:0}
.ag-act .ag-edit{gap:3px;flex-wrap:wrap;justify-content:flex-end}
.ag-act button{padding:3px 7px;line-height:1.2}
.btn-danger{border-color:rgba(255,80,99,.45)!important;color:var(--down)!important}
.btn-danger:hover{background:rgba(255,80,99,.12)!important}
.ag-add{display:flex;gap:7px;align-items:center;flex-wrap:wrap;margin-top:10px}
.ag-add input[type=number]{width:76px}
.ag-h3{margin:14px 0 6px;font-size:15px}
@media(max-width:1100px){
  .ag-tbl,.ag-tbl tbody,.ag-tbl tr,.ag-tbl td{display:block;width:auto}
  .ag-tbl thead,.ag-tbl th{display:none}
  .ag-tbl tr{padding:8px 0;border-top:1px solid rgba(255,255,255,.10)}
  .ag-tbl td{border:0;padding:2px 0;white-space:normal;display:flex;gap:8px;align-items:baseline}
  .ag-tbl td::before{content:attr(data-l);flex:0 0 84px;font-size:11px;text-transform:uppercase;
    letter-spacing:.03em;opacity:.5;padding-top:2px}
  .ag-tbl td.ag-name{display:block}
  .ag-tbl td.ag-name::before{display:none}
  .ag-tbl td.ag-act{justify-content:flex-start}
}

/* Зоны проверки: галочки в строке клиента/ресурса */
.zone-form{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:0}
.zone-box{display:inline-flex;gap:4px;align-items:center;font-size:12px;padding:2px 7px;
  border:1px solid rgba(255,255,255,.14);border-radius:999px;white-space:nowrap;cursor:pointer}
.zone-box input{margin:0}
/* v5.97: BASE — обычная площадка, снимаемая как остальные (не серая-мёртвая) */
.zone-all{border-color:rgba(120,140,200,.45)}
.zone-own{border-color:rgba(240,190,60,.45)}

/* Матрица «ресурс × площадка» — только для чтения */
.mtx-wrap{overflow-x:auto;margin:8px 0}
.mtx{border-collapse:collapse;font-size:13px;min-width:100%}
.mtx th{text-align:center;padding:6px 8px;font-size:12px;font-weight:500;
  border-bottom:1px solid rgba(255,255,255,.12);white-space:nowrap;vertical-align:bottom}
.mtx th.mtx-svc,.mtx td.mtx-svc{text-align:left;max-width:260px}
.mtx td{padding:5px 8px;border-top:1px solid rgba(255,255,255,.06)}
.mtx-c{text-align:center;width:64px}
.mtx-ok{color:var(--ok,#5ac88c)}
.mtx-sum td{border-top:1px solid rgba(255,255,255,.18)}
.mtx-v{min-width:130px;line-height:1.3}
.mtx-down{color:var(--down)}

/* Часовой график по площадкам: одна и та же минута в нескольких полосах.
   Штриховка отвечала на вопрос «было ли расхождение», но не на главный —
   где и когда. Полосы друг под другом отвечают на оба сразу. */
.hr-stack{display:block}
.hr-svg{flex:1 1 auto;min-width:0}
.hr-svg svg{width:100%;height:auto;display:block}
.hr-none{font-size:12px;opacity:.45;padding:12px 0}

/* Проверка с площадок на публичной странице */
.chk-geo{margin-top:16px;padding-top:14px;border-top:1px solid rgba(255,255,255,.08)}
.chk-geo h3{margin:0 0 4px;font-size:16px}
.chk-geo-cap{margin:0 0 10px;font-size:13px;opacity:.7;line-height:1.45}
.chk-geo-verdict{margin:0 0 8px;font-size:14px}
.chk-geo-tbl{width:100%;border-collapse:collapse;font-size:14px}
.chk-geo-tbl th{text-align:left;font-size:12px;opacity:.55;font-weight:500;padding:4px 8px 4px 0}
.chk-geo-tbl td{padding:7px 8px 7px 0;border-top:1px solid rgba(255,255,255,.07);vertical-align:top}
.chk-geo-ok{color:var(--ok,#5ac88c)}
.chk-geo-bad{color:var(--down)}
.chk-geo-err,.chk-geo-wait{font-size:12px;opacity:.6}

/* Полосы по площадкам: подпись НАД графиком, график во всю ширину — как суточный */
.hr-row{display:block;margin:0}
.hr-svg{display:block;width:100%}

/* Подпись полосы внутри графика: тот же кегль, что у оси, но заметнее */
.ax-cap{font-weight:600;letter-spacing:.06em;opacity:.95}
.hr-row{margin:0}

/* На узком экране всё в одну колонку: графики друг над другом, факты под ними */
@media(max-width:760px){
  .cl-res-body{grid-template-columns:1fr;gap:12px}
}

/* Полосы по площадкам вплотную: строк будет много, и каждый лишний отступ
   умножается на число площадок. */
.hr-stack .hr-row+.hr-row{margin-top:1px}
.hr-none{font-size:12px;opacity:.45;padding:4px 0}

/* Полосы по площадкам внутри карточки клиента */
.cl-charts .hr-stack{margin-top:2px}
.cl-charts .hr-stack .num{display:block;margin-top:2px}

/* Индикатор ожидания ответа площадки. Статичное «ждём…» читается как
   зависание: площадка придёт за заданием по своему расписанию, и до минуты
   ждать нормально — но человеку нужно видеть, что процесс идёт. */
.wdot{display:inline-block;width:4px;height:4px;margin-right:3px;border-radius:50%;
  background:currentColor;opacity:.25;animation:wpulse 1.2s ease-in-out infinite}
.wdot:nth-child(2){animation-delay:.2s}
.wdot:nth-child(3){animation-delay:.4s}
@keyframes wpulse{0%,80%,100%{opacity:.25;transform:translateY(0)}40%{opacity:.9;transform:translateY(-2px)}}
@media(prefers-reduced-motion:reduce){.wdot{animation:none;opacity:.6}}

/* Легенда шкалы задержки — рядом с подписью полос, а не отдельной строкой:
   она объясняет ровно эти полосы и в отрыве от них бессмысленна. */
.lat-legend-wrap{display:inline-block;vertical-align:middle;width:290px;max-width:62vw;margin-left:12px}
.lat-legend{width:100%;height:auto;overflow:visible}
.lat-legend text{font-size:9px;fill:var(--muted);text-transform:none;letter-spacing:0}

/* ── Админка v5.44: смысловые группы и свёртывание панелей ── */
.adm-nav{position:sticky;top:0;z-index:40;display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  padding:10px 2px;margin:0 0 6px;background:var(--bg);border-bottom:1px solid var(--line)}
.adm-nav a{font-size:13px;padding:5px 12px;border-radius:99px;border:1px solid var(--line2);
  color:var(--ink);text-decoration:none;background:var(--panel)}
.adm-nav a:hover{border-color:var(--accent,#5b8bd6)}
.adm-nav-btn{margin-left:auto;font-size:12px;padding:5px 12px;border-radius:99px;cursor:pointer;
  background:var(--panel);border:1px solid var(--line2);color:var(--muted)}
.adm-nav-btn:hover{border-color:var(--accent,#5b8bd6);color:var(--ink)}
.agroup{margin:0 0 8px}
.agroup-h{font-weight:600;font-size:12px;line-height:1;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);margin:26px 2px 10px;scroll-margin-top:56px}
details.apanel>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:10px;
  margin:-4px;padding:4px 6px;border-radius:10px;user-select:none}
details.apanel>summary::-webkit-details-marker{display:none}
details.apanel>summary:hover{background:var(--panel2)}
details.apanel>summary h2{margin:0;flex:1}
details.apanel>summary::after{content:'▾';color:var(--muted);font-size:13px;transition:transform .18s}
details.apanel:not([open])>summary::after{transform:rotate(-90deg)}
details.apanel[open]>summary{margin-bottom:8px}
details.apanel{scroll-margin-top:56px}
.agroup-solo .agroup-h{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)} /* якорь остаётся, дубль заголовка не виден */
.subd>summary{cursor:pointer;list-style:none;user-select:none;color:var(--ink)}
.subd>summary::-webkit-details-marker{display:none}
.subd>summary::before{content:'▸';color:var(--muted);margin-right:8px;display:inline-block;transition:transform .15s}
.subd[open]>summary::before{transform:rotate(90deg)}
.subd>summary:hover{color:var(--accent,#5b8bd6)}


/* ── Общая дисциплина админки (v5.48): контент не покидает свой блок ──
   Правило простое: любой блок — контейнер, и всё широкое (таблицы, поля
   ввода, длинные строки установки) либо переносится, либо прокручивается
   ВНУТРИ него. До этого длинная таблица площадок распирала панель и
   наезжала на соседние. */
.apanel,.panel,.agroup,.subd{min-width:0}
.apanel table,.panel table{max-width:100%}
.apanel textarea,.panel textarea,.apanel input,.panel input,.apanel select,.panel select{max-width:100%}
.apanel pre,.panel pre,.apanel code,.panel code{overflow-wrap:anywhere}
.tbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:8px 0;max-width:100%}
.tbl-wrap>table{margin:0}
@media(max-width:1100px){ .tbl-wrap{overflow-x:visible} }

/* Команды установки и снятия: поле + кнопка копирования */
.cmd-row{margin:8px 0}
.cmd-cap{font-size:12px;opacity:.7;margin-bottom:3px}
.cmd-row textarea{width:100%;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12.5px;
  padding:7px 9px;border-radius:8px;resize:vertical;line-height:1.45}
.copy-btn{margin-top:4px;font-size:12.5px;padding:4px 11px}
.copy-btn.copied{border-color:var(--ok);color:var(--ok)}

/* Плотность: панели админки не должны дышать так же, как публичные страницы */
.apanel .panel-cap{margin:5px 0;line-height:1.45}
.apanel h3{margin:12px 0 6px}
.apanel form.inline{margin:6px 0}
.apanel .grid2{gap:8px 14px}
.agroup-h{margin:18px 2px 8px}
/* Блок «строка установки»: свёртка, чтобы несколько площадок не съедали экран */
details.ag-key>summary{cursor:pointer;list-style:none;font-size:14px}
details.ag-key>summary::-webkit-details-marker{display:none}
details.ag-key>summary::before{content:'▸';margin-right:7px;opacity:.6;display:inline-block;transition:transform .15s}
details.ag-key[open]>summary::before{transform:rotate(90deg)}
details.ag-key[open]>summary{margin-bottom:6px}
.ag-tbl td[data-l="Роль"]{white-space:nowrap}
.ag-tbl td.ag-name input{max-width:150px}
/* Готовый дистрибутив площадки — главный путь установки, поэтому заметный */
.pack-box{margin:8px 0 10px;padding:10px 12px;border-radius:10px;
  background:rgba(49,217,138,.08);border:1px solid rgba(49,217,138,.35)}
.pack-btn{display:inline-block;padding:7px 14px;border-radius:9px;text-decoration:none;
  font-weight:600;font-size:14px;color:var(--ok);border:1px solid rgba(49,217,138,.5);
  background:rgba(49,217,138,.10)}
.pack-btn:hover{background:rgba(49,217,138,.18)}

/* ═══ v5.97: карточка сервиса — одна колонка ═══
   На вертикальном экране две колонки не читались: поля уезжали вправо, а
   заголовок терялся. Теперь строка таблицы = карточка во всю ширину:
   заголовок (лого, имя, активность), подпись, строка пробы — и дальше
   строки-группы, каждая с подписью слева и переносом внутри. */
/* Специфичность: `table.svc td` (0-1-2) перебивал одиночный `.svc-card`,
   поэтому селекторы карточки идут с тем же префиксом таблицы. */
table.svc td.svc-card{width:auto;padding:12px 10px}
table.svc td.svc-card:first-child{width:auto}
.svc-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.svc-head .svc-name{flex:1 1 220px;min-width:160px;font-size:15px;font-weight:600;
  background:transparent;border:1px solid transparent;border-radius:8px;padding:3px 7px;color:var(--fg)}
.svc-head .svc-name:hover{border-color:rgba(255,255,255,.14)}
.svc-head .svc-name:focus{border-color:var(--acc);background:var(--panel2);outline:none}
.logo-edit{cursor:pointer;border-radius:10px;display:inline-flex;line-height:0;
  border:1px solid transparent;transition:border-color .15s}
.logo-edit:hover,.logo-edit:focus{border-color:var(--acc);outline:none}
.logo-input{font-size:12px;padding:3px 7px;flex:1 1 240px;min-width:180px}
.svc-sub{margin:4px 0 0 2px}
.svc-card .probe-line{display:block;margin:2px 0 0 2px}
.svc-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:8px}
.svc-lbl{flex:0 0 108px;font-size:11px;color:var(--muted);text-transform:uppercase;
  letter-spacing:.04em;padding-top:3px}
.svc-row input,.svc-row select{font-size:12px;padding:3px 6px}
.svc-actions{margin-top:12px;padding-top:10px;border-top:1px solid var(--line);gap:8px}
/* «Удалить» отодвинут от «Сохранить» (защита от промаха); `.inline` задаёт
   margin шорткатом, поэтому здесь нужен более точный селектор. */
.svc-row.svc-actions form.del-form{margin-left:auto;margin-top:0}
.svc-zone-row{display:block;margin:0}

/* Зоны × «видит за час»: галочка = назначение, обводка = состояние за час. */
.zone-box.zc-ok{border-color:var(--ok);box-shadow:inset 0 0 0 1px rgba(60,200,120,.18)}
.zone-box.zc-down{border-color:var(--down);box-shadow:inset 0 0 0 1px rgba(229,72,77,.18)}
.zone-box.zc-geo{border-color:#8a3b52;color:var(--muted)}
.zone-box.zc-idle{border-color:rgba(255,255,255,.14)}
.zone-box.zc-off{border-color:rgba(255,255,255,.08);opacity:.55}
@media (max-width:820px){
  .svc-lbl{flex-basis:100%;padding-top:0}
  .svc-head .svc-name{flex-basis:100%}
  /* Мобильное правило `.panel form label{flex-wrap:wrap}` ломало галочку и
     подпись на две строки («□» сверху, «TLS 1.2» снизу) — в карточке держим
     их вместе. */
  .svc-card .active-tgl,.svc-card .zone-box{flex-wrap:nowrap}
}

/* ---------- Страница «не найдено» (v6.01) ----------
   Оформление подчинено задаче: посетитель промахнулся и должен как можно
   быстрее понять, куда идти дальше. Крупная цифра — только опознавательный
   знак (aria-hidden: экранному диктору её читать незачем, заголовок ниже
   говорит то же словами), а вес отдан подсказкам и форме проверки. */
.nf{max-width:640px;margin:0 auto;padding:12px 0 8px;text-align:center}
.nf-code{font-family:var(--display);font-weight:800;line-height:1;
         font-size:clamp(64px,18vw,132px);letter-spacing:.02em;
         background:linear-gradient(180deg,var(--down),var(--warn));
         -webkit-background-clip:text;background-clip:text;color:transparent;
         opacity:.9;margin-bottom:2px}
.nf-title{margin:0 0 10px;font-size:clamp(20px,5vw,28px)}
.nf-lead{color:var(--muted);margin:0 auto 18px;max-width:52ch;line-height:1.6}
.nf-url{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;
        vertical-align:bottom;white-space:nowrap;background:var(--line2,rgba(148,163,190,.14));
        border-radius:6px;padding:1px 7px;font-size:.95em}
.nf-sug{margin:0 0 20px;padding:14px 16px;border:1px solid var(--line);border-radius:14px;
        background:linear-gradient(180deg,rgba(255,255,255,.04),rgba(255,255,255,.01))}
.nf-sug-cap{margin:0 0 10px;color:var(--muted);font-size:14px}
.nf-sug-list{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;
             gap:8px;justify-content:center}
.nf-sug-list a{display:inline-block;padding:7px 14px;border-radius:999px;
               border:1px solid var(--line);text-decoration:none;font-weight:600;
               background:var(--ok-dim);color:var(--fg)}
.nf-sug-list a:hover{border-color:var(--ok)}
.nf-check{margin:0 0 20px}
.nf-check-cap{margin:0 0 8px;color:var(--muted);font-size:14px}
.nf-check .chk-form{justify-content:center}
.nf-links{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;
          gap:6px 18px;justify-content:center;font-size:14px}
@media (max-width:560px){
  .nf-sug{padding:12px}
  .nf-links{flex-direction:column;gap:8px}
}

/* --- Онбординг аккаунта (v6.53) --- */
/* ── ЕДИНАЯ КОЛОНКА ТЕКСТА (v6.95) ──────────────────────────────────────
   Читаемость даёт не узкая СТРАНИЦА, а узкая КОЛОНКА в общей рамке: рамка,
   отступы и заголовок у всех страниц одни, а строка длинного текста не
   растягивается на весь экран. 68 знаков — обычная типографская мера. */
.prose{max-width:none;line-height:1.6}
.prose h2{font-size:1.12rem;margin:1.5rem 0 .4rem}
.prose h2:first-child{margin-top:.2rem}
.prose p,.prose li{color:var(--muted)}
.prose p{margin:.55rem 0}
.prose ul,.prose ol{margin:.55rem 0;padding-left:1.2rem}
.prose b,.prose strong{color:var(--fg)}
.prose+.prose{margin-top:1.6rem;padding-top:1.4rem;border-top:1px solid var(--line)}

/* Переключатель периода оплаты (v6.95) — две ссылки, а не форма. */
.per-switch{display:inline-flex;align-items:center;gap:4px;flex-wrap:wrap;
  border:1px solid var(--line);border-radius:999px;padding:4px;margin:2px 0 4px}
.per-opt{padding:7px 16px;border-radius:999px;text-decoration:none;font-size:14px;
  color:var(--muted);white-space:nowrap}
.per-opt:hover{color:var(--fg)}
.per-opt.on{background:var(--ok-dim);color:var(--ok)}
.per-save{font-size:12.5px;color:var(--muted);padding:0 10px 0 6px}
.tar-cost{min-height:3.4em}
.tar-pend{display:flex;flex-direction:column;gap:6px;align-items:center}
.tar-pend>span{font-size:13px;color:var(--warn)}
.tar-muted{color:var(--muted)}
.tar-drop{font:inherit;font-size:12.5px;padding:6px 12px;border-radius:8px;cursor:pointer;
  background:transparent;border:1px solid var(--line2);color:var(--muted);width:100%}
.tar-drop:hover{border-color:var(--down);color:var(--down)}
/* Срок действия тарифа (v6.95): спокойно — серым, неделя до конца — жёлтым. */
.plan-term.soon{color:var(--warn)}
.plan-term.over{color:var(--down)}

.auth-wrap,.auth-doc{max-width:32rem;margin:2rem auto;padding:0 1rem}
.auth-doc{max-width:44rem}
.auth-form{display:flex;flex-direction:column;gap:.75rem;margin:1rem 0}
.auth-form label{display:flex;flex-direction:column;gap:.25rem;font-size:.95rem}
/* ЦВЕТ ТЕКСТА ПОЛЯ — ЯВНО (v6.95). `color:inherit` брал цвет у страницы, и
   стоило фону поля разойтись с фоном страницы (а он расходился: см. --card
   выше), как текст становился невидимым. Пара «фон + цвет» у поля обязана
   задаваться вместе — иначе одна половина меняется, а вторая нет. */
.auth-form input[type=email],.auth-form input[type=password],.auth-form input[type=text],
.auth-form input[type=number],.auth-form input[type=tel],.auth-form input[type=url],
.auth-form textarea,.auth-form select{
  padding:.55rem .7rem;border:1px solid var(--line2);border-radius:.4rem;
  background:var(--card);color:var(--ink);font-size:1rem;font-family:inherit}
.auth-form input::placeholder,.auth-form textarea::placeholder{color:var(--faint)}
.auth-form input:focus,.auth-form textarea:focus,.auth-form select:focus{
  outline:2px solid var(--accent);outline-offset:1px;border-color:transparent}
.auth-form .auth-accept{flex-direction:row;align-items:flex-start;gap:.5rem;font-size:.9rem}
.auth-form button{padding:.6rem 1rem;border:0;border-radius:.4rem;
  background:var(--accent);color:var(--accent-ink);font-size:1rem;cursor:pointer;
  font-family:inherit;font-weight:600}
.auth-form button:hover{filter:brightness(1.08)}
.auth-hint{color:var(--muted,#888);font-weight:400}
.auth-alt,.auth-msg{font-size:.92rem;color:var(--muted,#666)}
.auth-btn{display:inline-block;padding:.5rem .9rem;border-radius:.4rem;
  background:var(--accent,#2b6cb0);color:#fff;text-decoration:none}
.auth-msg{padding:.6rem .8rem;border-radius:.4rem;background:var(--card,#f4f4f4);margin:.6rem 0}
.auth-ok{border-left:3px solid #2f855a}
.auth-err{border-left:3px solid #c53030}
.auth-list{margin:.5rem 0 1rem;padding-left:1.2rem}
.auth-doc h2{font-size:1.1rem;margin:1.2rem 0 .4rem}

/* Кабинет: полоса «привяжите кабинет к аккаунту» (v6.55) */
.cl-claim{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin:0 0 14px;
  padding:11px 14px;border:1px solid rgba(122,162,247,.35);border-radius:10px;
  background:rgba(122,162,247,.08);font-size:13.5px;line-height:1.5}
.cl-claim span{flex:1 1 320px;min-width:0}
.cl-claim form{margin:0}
.cl-claim button{font:inherit;padding:7px 14px;border-radius:8px;cursor:pointer;
  border:1px solid rgba(122,162,247,.5);background:rgba(122,162,247,.16);color:inherit}
.cl-claim button:hover{background:rgba(122,162,247,.26)}
/* Кабинеты в /account: «отвязать» рядом со ссылкой */
.auth-inline{display:inline;margin:0 0 0 8px}
.auth-link{font:inherit;font-size:12.5px;padding:0;border:0;background:none;cursor:pointer;
  color:var(--muted,#93a2b5);text-decoration:underline}
.auth-link:hover{color:inherit}

/* Аккаунт: блок «Мои ресурсы» (v6.57) */
.auth-h2{font-size:16px;margin:18px 0 8px}
.auth-h2 .auth-hint{font-weight:400;font-size:13px}

/* Витрина тарифов (v6.58) */
.tar-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));margin:18px 0}
.tar-card{border:1px solid var(--line,#2a3040);border-radius:12px;padding:16px;display:flex;flex-direction:column;gap:10px}
.tar-card.on{border-color:rgba(49,217,138,.5);background:rgba(49,217,138,.06)}
.tar-card h2{font-size:17px;margin:0}
.tar-price{font:600 26px/1 var(--mono,monospace)}
.tar-per{font-size:13px;color:var(--muted,#93a2b5)}
.tar-year{font-size:12.5px;color:var(--muted,#93a2b5);margin-top:4px}
.tar-li{list-style:none;padding:0;margin:0;font-size:13px;line-height:1.75;flex:1}
/* Цена «по запросу» (v7.00): та же строка, что у цифр, но не моноширинная —
   это слово, а не число, и выравнивать его по цифровой сетке незачем. */
.tar-price.tar-ask{font-family:var(--display,inherit);font-size:22px}
/* «Обсуждаем под задачу» — приглушённо и мелко: это честная оговорка рядом с
   готовым списком, а не второй список того же веса. */
.tar-ask-list{font-size:12px;line-height:1.6;color:var(--muted,#93a2b5);margin:8px 0 0}
.tar-ask-list b{color:var(--ink,#e6ecf5);font-weight:600}
.tar-li li::before{content:"· ";color:var(--muted,#93a2b5)}
.tar-card button{font:inherit;width:100%;padding:9px 14px;border-radius:8px;cursor:pointer;
  border:1px solid rgba(122,162,247,.5);background:rgba(122,162,247,.16);color:inherit}
.tar-card button:hover{background:rgba(122,162,247,.26)}
.tar-cur{text-align:center;font-size:13px;color:var(--ok,#31d98a);padding:9px 0}

/* Вход в кабинет в шапке (v6.60) */
.head-auth{font:500 13px var(--mono,monospace);text-decoration:none;padding:6px 12px;border-radius:8px;
  border:1px solid var(--line,#2a3040);color:inherit;white-space:nowrap}
.head-auth:hover{border-color:rgba(122,162,247,.6);background:rgba(122,162,247,.12)}

/* Регистрация одним полем (v6.65) */
.auth-lead{font-size:13.5px;color:var(--muted,#93a2b5);margin:0 0 14px}
/* Текст согласия — ОДИН флекс-элемент: без этого каждое слово и каждая ссылка
   становились отдельным элементом и строка разъезжалась лесенкой. */
.auth-form .auth-accept > span{flex:1;line-height:1.45}
.auth-form .auth-accept input[type=checkbox]{margin-top:.2rem;flex:none}

/* Скриншот браузерной пробы на странице клиента (v6.66) */
/* Скриншот — сворачиваемый (v6.74). Базово видна только верхняя часть страницы
   (кадр обрезан по высоте, снизу плавное затухание) и полоса с кнопкой; по клику
   [open] снимает обрезку и затухание и показывает страницу целиком. Всё внутри
   <summary>, поэтому кадр виден и в свёрнутом состоянии — обычный <details>
   спрятал бы тело целиком. */
.cl-shot{margin:0;border:1px solid var(--line,#2a3040);border-radius:9px;overflow:hidden;background:var(--panel)}
.cl-shot>summary{list-style:none;cursor:pointer;display:block}
.cl-shot>summary::-webkit-details-marker{display:none}
.cl-shot-frame{display:block;position:relative;max-height:200px;overflow:hidden}
.cl-shot-frame img{width:100%;display:block}
.cl-shot-frame::after{content:'';position:absolute;left:0;right:0;bottom:0;height:72px;
  background:linear-gradient(to bottom,transparent,var(--panel));pointer-events:none;transition:opacity .2s}
.cl-shot[open] .cl-shot-frame{max-height:none}
.cl-shot[open] .cl-shot-frame::after{opacity:0}
.cl-shot-bar{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:6px 9px;border-top:1px solid var(--line)}
.cl-shot-cap{font-size:11.5px;color:var(--muted,#93a2b5);min-width:0}
.cl-shot-btn{font-size:12px;font-weight:600;color:var(--ok);white-space:nowrap;
  display:inline-flex;align-items:center;gap:4px}
.cl-shot-btn::after{content:'▾';font-size:11px;transition:transform .2s}
.cl-shot[open] .cl-shot-btn::after{transform:rotate(180deg)}
.cl-shot-btn .tog-c{display:none}
.cl-shot[open] .cl-shot-btn .tog-o{display:none}
.cl-shot[open] .cl-shot-btn .tog-c{display:inline}
/* v7.27: кадр браузерной пробы в админской карточке и на статус-странице —
   тот же .cl-shot, только ограничен по ширине, чтобы не растягивать карточку. */
.adm-shot{margin:6px 0 4px;flex-basis:100%}
.adm-shot .cl-shot{max-width:560px}
.adm-shot .cl-shot-frame{max-height:140px}
.adm-shot .cl-shot-cap a{color:inherit}
.sp-shot{margin:8px 0 10px}
.sp-shot .cl-shot-frame{max-height:160px}
.cl-shot-fail{border-color:rgba(255,93,93,.55)}

/* Поле маршрута в админке (v6.79): моноширинное, по шагу в строке. */
.rt-box{font:12px/1.45 var(--mono,monospace);background:var(--panel);color:var(--ink);
  border:1px solid var(--line2);border-radius:8px;padding:6px 8px;vertical-align:top;resize:vertical}

/* ── Личный кабинет: вкладки, страница ресурсов, смена тарифа (v6.88) ── */
.cab-tabs{display:flex;gap:6px;margin:0 0 16px;flex-wrap:wrap}
.cab-tab{display:inline-block;padding:7px 14px;border-radius:8px;font-size:13.5px;
  border:1px solid var(--line,#2a3040);color:inherit;text-decoration:none}
a.cab-tab:hover{border-color:rgba(122,162,247,.6);background:rgba(122,162,247,.12)}
.cab-tab.on{border-color:rgba(122,162,247,.7);background:rgba(122,162,247,.16);font-weight:600}
.cab-tab.off{color:var(--muted,#888);cursor:default}
/* Вкладки над отчётом рисуются в общей ширине сцены, а не в узкой auth-рамке */
.stage-title+.cl-claim{margin-top:0}

/* Запертый период: видно, что есть, но откроется на другом тарифе */
.cl-per a.lock{opacity:.55}
.cl-per a.lock:hover{opacity:.85;border-color:rgba(240,177,80,.6)}
.cl-gate{margin-top:-6px}

/* Строки ресурсов на /account/resources */
.res-row{border:1px solid var(--line,#2a3040);border-radius:10px;padding:10px 12px;margin:0 0 10px;
  background:var(--panel,transparent)}
.res-row.res-off{opacity:.75}
.res-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.res-name{font-weight:600}
.res-url{font-size:12px;color:var(--muted,#93a2b5);word-break:break-all;margin-top:2px}
.res-act{margin-left:auto;display:inline-flex;gap:6px;align-items:center}
.res-act form{margin:0;display:inline}
.res-act button{font:inherit;font-size:12.5px;padding:5px 10px;border-radius:7px;cursor:pointer;
  border:1px solid var(--line2,#39415a);background:transparent;color:inherit;white-space:nowrap}
.res-act button:hover{background:rgba(122,162,247,.14)}
.res-act button.danger{border-color:rgba(255,93,93,.5);color:var(--down,#ff5d5d)}
.res-act button.danger:hover{background:rgba(255,93,93,.12)}
.res-zones{margin-top:8px;font-size:13px}
.res-zones summary{cursor:pointer;color:var(--muted,#93a2b5)}
.res-zones form{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:8px 0 2px}
.res-zones label{display:inline-flex;gap:5px;align-items:center;font-size:13px;white-space:nowrap}
.res-zones input[type=checkbox]:disabled+*{opacity:.5}
.res-zones button{font:inherit;font-size:12.5px;padding:5px 12px;border-radius:7px;cursor:pointer;
  border:1px solid var(--line2,#39415a);background:rgba(122,162,247,.12);color:inherit}
.res-zones button:hover{background:rgba(122,162,247,.22)}

/* Смена тарифа в аккаунте: компактные строки */
.acct-sw{margin:10px 0 16px}
.acct-sw>summary{cursor:pointer;font-weight:600}
.acct-plans{display:flex;flex-direction:column;gap:8px;margin:10px 0}
.acct-plan{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  border:1px solid var(--line,#2a3040);border-radius:9px;padding:8px 12px}
.acct-plan.on{border-color:rgba(49,217,138,.5);background:rgba(49,217,138,.06)}
.acct-plan .auth-hint{flex:1 1 160px}
.acct-plan form{margin:0}
.acct-plan button{font:inherit;font-size:12.5px;padding:5px 12px;border-radius:7px;cursor:pointer;
  border:1px solid rgba(122,162,247,.45);background:rgba(122,162,247,.12);color:inherit;white-space:nowrap}
.acct-plan button:hover{background:rgba(122,162,247,.22)}
.acct-cur{font-size:12.5px;color:var(--ok,#31d98a);white-space:nowrap}

/* ── КАБИНЕТ КЛИЕНТА ВО ВСЮ ШИРИНУ, ЯЗЫКОМ ОТЧЁТА (v6.90) ──────────────────
   До 6.90 «Ресурсы» и «Аккаунт» рисовались той же узкой колонкой в 32rem, что
   форма входа: под баннером с картой в 1400px висел столбик в 512, и вкладки
   вели с широкой страницы отчёта на узкую — две страницы одного кабинета
   выглядели двумя разными продуктами. Ширину задаёт <main> (1400 + поля), так
   что кабинету достаточно снять свои ограничения, а не заводить вторую цифру,
   которая потом разъедется с первой. */
.auth-wrap.auth-cab{max-width:none;margin:0;padding:0}
.auth-wrap.auth-cab .panel{margin-top:14px}
.auth-wrap.auth-cab .auth-msg{margin:14px 0 0}

/* Карточка ресурса — та же, что в отчёте (.cl-res), плюс своё содержимое. */
.cab-res{margin-top:10px}
.cab-res.cab-off{opacity:.72}
.cab-res-act{display:flex;flex-direction:column;align-items:flex-end;gap:6px;text-align:right}
.cab-btns{display:inline-flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
.cab-btns form{margin:0}
.cab-chip-br{background:rgba(122,162,247,.14);border-color:rgba(122,162,247,.4)}
/* v7.21: тело карточки — вертикальным стеком во всю ширину (просьба владельца
   «навести вёрсточный порядок»). Прежде это была авто-сетка колонок: площадки
   вставали узким столбцом, браузерные пробы — во всю ширину, секреты — снова
   столбцом; ширины прыгали. Теперь единый порядок сверху вниз: площадки (можно
   свернуть) → браузерные пробы → секреты → мерило аптайма (свёрнуто). */
.cab-body{border-top:1px solid var(--line);margin-top:11px;padding-top:11px;
  display:flex;flex-direction:column;gap:14px}
.cab-sec{border:1px solid var(--line);border-radius:11px;padding:11px 13px;background:var(--panel);min-width:0}
.cab-h3{font-size:14px;margin:0 0 4px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.cab-h4{font-size:13px;font-weight:600;margin:12px 0 2px;display:flex;align-items:center;gap:8px}

/* Галочки площадок и пробы — сеткой, чтобы длинный парк не расползался. */
.cab-zgrid{display:grid;gap:6px 14px;margin:9px 0 4px;
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.cab-z{display:inline-flex;gap:6px;align-items:center;font-size:13.5px;min-width:0}
.cab-z input[type=checkbox]:disabled{cursor:not-allowed}
.cab-z input[type=checkbox]:disabled ~ *{opacity:.55}
.cab-cov{margin:6px 0 9px;min-height:1.5em}
.cab-cov.over{color:var(--warn)}
.cab-cov.none{color:var(--down)}

/* Кнопки кабинета — один вид на всю страницу. */
.cab-btn{font:inherit;font-size:12.5px;padding:5px 12px;border-radius:8px;cursor:pointer;
  border:1px solid var(--line2);background:rgba(122,162,247,.12);color:inherit;white-space:nowrap}
.cab-btn:hover{background:rgba(122,162,247,.24)}
.cab-btn:disabled{cursor:not-allowed;opacity:.5}
.cab-btn:disabled:hover{background:rgba(122,162,247,.12)}
.cab-btn-go{background:rgba(49,217,138,.14);border-color:rgba(49,217,138,.42)}
.cab-btn-go:hover{background:rgba(49,217,138,.24)}
.cab-danger{background:var(--down-dim);border-color:rgba(255,80,99,.42)}
.cab-danger:hover{background:rgba(255,80,99,.26)}
.cab-bad{color:var(--down)}
.cab-warn{color:var(--warn)}
.cl-num-ok{color:var(--ok)}
.cab-lock{background:var(--warn-dim);border-color:rgba(255,178,36,.4)}
.cab-upsell{border-left:3px solid rgba(255,178,36,.5);padding-left:9px}
.cab-usage{margin-top:9px}

/* Конструктор тарифов в админке (v7.13). */
.plan-row{margin:8px 0;padding:8px 12px;border:1px solid var(--line);border-radius:9px}
.plan-row>summary{cursor:pointer;line-height:1.5}
.plan-row>summary code{font-size:12px;opacity:.7;margin:0 6px}
.plan-new{border-style:dashed}
.plan-edit{margin-top:10px}
.plan-edit-grid{display:grid;gap:10px 14px;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));margin-bottom:10px}
.plan-edit fieldset{border:1px solid var(--line);border-radius:8px;padding:8px 12px 10px;margin:0;min-width:0;
  display:flex;flex-direction:column;gap:6px}
.plan-edit legend{font-size:12px;color:var(--muted);padding:0 5px}
.plan-edit label{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:13px}
.plan-edit label.chk{justify-content:flex-start}
.plan-edit input[type=text]{font:inherit;font-size:13px;padding:3px 7px;border-radius:6px;border:1px solid var(--line2);
  background:var(--panel2);color:var(--ink);width:7em}
.plan-edit input[name=title],.plan-edit input[name=new_code]{width:12em}
.plan-edit .ag-sub{display:block}

/* Оповещения кабинета (v7.13): сводка, кнопка привязки, справка шагами. */
.cab-alert-sum b.ok{color:var(--ok)}
.cab-alert-sum b.warn{color:var(--warn)}
.cab-alert-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:6px 0 4px}
.cab-alert-row .panel-cap{margin:0}
.cab-alerts h3{margin:16px 0 6px;font-size:15px}
.cab-alerts h3:first-child{margin-top:8px}
/* v7.22: блок заголовка Telegram стоит ПЕРЕД формой адресатов (не вложен), и
   форма под ним не должна отступать лишний 1rem — плотнее. */
.cab-alerts-head{margin-top:4px}
.auth-cab .auth-form.cab-alerts{margin-top:6px}
.auth-cab .auth-form.cab-alerts label+h3{margin-top:14px}
.cab-alerts .cab-btns{margin-top:12px;justify-content:flex-start}
.cab-tg-link{border:1px solid rgba(49,217,138,.42);background:rgba(49,217,138,.08);
  border-radius:10px;padding:12px 14px;flex:1 1 100%}
.cab-tg-link .cab-btn-go{font-size:14px;padding:8px 16px;display:inline-block;text-decoration:none}
.cab-tg-link .panel-cap{margin:8px 0 0}
.cab-tg-link code{background:rgba(255,255,255,.07);padding:1px 6px;border-radius:5px;user-select:all}
/* v7.26: ВКонтакте и MAX — код привязки крупно, чтобы переписать/скопировать. */
.cab-chan .cab-alert-row form{margin:0}
.cab-chan-code .cab-code{display:inline-block;font-size:22px;letter-spacing:2px;padding:6px 14px;margin:6px 12px 6px 0}
.cab-btn-ghost{background:transparent;border-color:rgba(255,255,255,.18)}
.cab-btn-ghost:hover{background:rgba(255,255,255,.08)}
.cab-steps{margin:8px 0 0;padding-left:22px;line-height:1.6;font-size:14.5px}
.cab-steps li{margin:0 0 9px}
.cab-steps code{background:rgba(255,255,255,.07);padding:1px 5px;border-radius:5px}

/* Конструктор маршрута: строка-шаг = глагол + значение + «убрать». */
.cab-route{margin:4px 0 10px}
.cab-step{display:flex;gap:6px;align-items:center;margin:6px 0;min-width:0}
.cab-step select{font:inherit;font-size:13px;padding:5px 7px;border-radius:7px;flex:none;
  border:1px solid var(--line2);background:var(--panel2);color:inherit}
.cab-step input[type=text]{font:inherit;font-size:13px;padding:5px 9px;border-radius:7px;
  border:1px solid var(--line2);background:var(--panel2);color:inherit;flex:1 1 auto;min-width:0}
.cab-step .cab-x{flex:none;padding:5px 9px}
.cab-brform{margin:0}
.cab-add{max-width:34rem}
@media (max-width:560px){
  .cab-res-act{align-items:flex-start;text-align:left;margin-top:8px}
  .cab-btns{justify-content:flex-start}
  .cab-step{flex-wrap:wrap}
  .cab-step input[type=text]{flex:1 1 100%}
}

/* Форма добавления ресурса — тем же языком, что остальной кабинет. Прежние
   .auth-form-правила рисовали синюю кнопку и БЕЛЫЕ поля (--card не определена
   в теме сайта, срабатывало запасное #fff): на тёмной панели отчёта это
   выглядело вставкой из другого продукта. Селектор с .auth-cab перебивает их
   по весу, не трогая формы входа и регистрации. */
.auth-cab .auth-form input[type=text],
.auth-cab .auth-form input[type=email],
.auth-cab .auth-form input[type=password]{
  background:var(--panel2);border:1px solid var(--line2);color:inherit;
  border-radius:9px;padding:9px 11px;font-size:14px}
.auth-cab .auth-form input::placeholder{color:var(--faint)}
.auth-cab .auth-form label{font-size:13px;color:var(--muted);gap:5px}
.auth-cab .auth-form button{width:auto;align-self:flex-start;font-size:13px;padding:8px 16px;
  border-radius:8px;border:1px solid rgba(49,217,138,.42);background:rgba(49,217,138,.14);color:inherit}
.auth-cab .auth-form button:hover{background:rgba(49,217,138,.24);filter:none}
/* Шеврон карточки (.cl-res>summary::after) стоит в правом верхнем углу —
   правая колонка шапки обязана оставить ему место, иначе «площадок: N»
   упирается в стрелку. */
.cab-res>summary .cl-res-h-top{padding-right:8px}
.auth-logout{margin-top:16px}
.auth-cab .cl-res-toph{margin-bottom:6px}
.auth-cab .cl-res-toph h2{font-size:15px;letter-spacing:.4px;text-transform:uppercase;color:var(--muted)}
.auth-cab .acct-sw{margin:6px 0 0}
.auth-cab .acct-sw>summary{font-size:14px;color:var(--muted)}
.auth-cab .acct-plan .auth-hint{color:var(--muted)}
/* Плитка со СЛОВОМ, а не числом (название тарифа): тот же ряд, но кегль по
   тексту — «Бесплатный» цифровым размером ломал ритм ряда. Цветом не красим:
   зелёное «хорошо» у названия тарифа читалось бы как оценка. */
.cl-num.cl-num-word{font-size:19px;letter-spacing:-.2px}
/* Заголовок со списком площадок: подпись весомая, сам список — спокойный.
   Разделения тегом здесь нет намеренно (см. комментарий в auth_pages.php). */
.cab-h3-zones{font-weight:600;color:var(--muted)}
.cab-select{font:inherit;font-size:13px;padding:6px 9px;border-radius:8px;
  border:1px solid var(--line2);background:var(--panel2);color:inherit;max-width:100%}
.cab-upform{margin:9px 0 0;display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* ── Маршрут: парные шаги, справка, кадры, секреты (v6.92) ─────────────────── */
.cab-step select{max-width:130px}
.cab-step input[type=text]{flex:1 1 140px;min-width:0}
.cab-help{margin:8px 0 0;border:1px solid var(--line);border-radius:9px;padding:8px 11px;background:var(--panel)}
.cab-help>summary{cursor:pointer;font-size:13px;color:var(--muted)}
.cab-vtab{width:100%;border-collapse:collapse;margin:8px 0 0;font-size:13px}
.cab-vtab td{padding:5px 6px;vertical-align:top;border-top:1px solid var(--line)}
.cab-vtab tr:first-child td{border-top:0}
.cab-v{white-space:nowrap;width:1%}
.cab-vtab code{font:12.5px var(--mono);color:var(--ink)}
.cab-ex{color:var(--ok)}
/* Лента кадров: каждый шаг — миниатюра с номером; оборвавшийся в рамке. */
.cab-steps-shots{display:flex;gap:8px;flex-wrap:wrap;margin:8px 0 0}
.cab-shot{position:relative;display:block;width:118px;border:1px solid var(--line2);
  border-radius:8px;overflow:hidden;background:var(--panel2)}
.cab-shot img{display:block;width:100%;height:74px;object-fit:cover;object-position:top left}
.cab-shot-n{position:absolute;left:4px;top:4px;font-size:11px;padding:1px 6px;border-radius:99px;
  background:rgba(10,15,26,.72);color:#e9eef7}
.cab-shot:hover{border-color:rgba(122,162,247,.6)}
.cab-shot-bad{border-color:rgba(255,80,99,.7)}
.cab-shot-bad .cab-shot-n{background:var(--down);color:#fff}
/* Секреты: таблица и форма добавления. */
.cab-sectab td{padding:4px 8px 4px 0;font-size:13px;vertical-align:middle}
.cab-sectab form{margin:0}
.cab-secform{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:10px 0 0}
.cab-secform input{font:inherit;font-size:13px;padding:6px 9px;border-radius:8px;
  border:1px solid var(--line2);background:var(--panel2);color:inherit;flex:1 1 150px;min-width:0}

/* ── Правки вёрстки кабинета (v6.93) ──────────────────────────────────────
   Площадки — ПО ГОРИЗОНТАЛИ: зон обычно шесть-восемь, и колонкой они тянули
   карточку вниз на пол-экрана, оставляя справа пустоту. */
.cab-zgrid{display:flex;flex-wrap:wrap;gap:7px 16px;grid-template-columns:none}
.cab-z{flex:0 0 auto}
/* Мерило аптайма — подвал карточки во всю ширину и под спойлером: настройка
   «выбрал и забыл» не должна занимать колонку, нужную каждый день. */
.cab-wide{grid-column:1/-1}
.cab-fold>summary{cursor:pointer;font-size:14px;font-weight:600;list-style:none;
  display:flex;align-items:center;gap:8px}
.cab-fold>summary::-webkit-details-marker{display:none}
.cab-fold>summary::before{content:'▸';color:var(--faint);font-size:11px}
.cab-fold[open]>summary::before{content:'▾'}
.cab-fold>summary .ag-sub{font-weight:400}
/* Строка управления пробой: период, запуск. */
.cab-brrow{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:6px 0 0}
.cab-runrow{margin:10px 0 0}
.cab-secpick{flex:0 0 auto;max-width:120px}
a.cab-btn{display:inline-block;text-decoration:none;margin-top:6px}
@media (max-width:560px){ .cab-secpick{max-width:100%} }
/* Строка шага не должна сжимать поля до нечитаемости: в узкой колонке она
   переносится, а поля сохраняют минимальную ширину. Иначе подпись поля и
   значение обрезаются до «Элек» и «{логи» (правка 6.93). */
.cab-step{flex-wrap:wrap}
.cab-step select[data-step-verb]{flex:0 0 auto}
.cab-step input[data-step-arg]{flex:1 1 150px;min-width:120px}
.cab-step input[data-step-val]{flex:1 1 150px;min-width:120px}
.cab-secpick{flex:0 0 auto;max-width:110px;min-width:88px}
.cab-step .cab-x{margin-left:auto}

/* ── НЕСКОЛЬКО БРАУЗЕРНЫХ ПРОБ (v6.96) ───────────────────────────────────
   Свёрнутая карточка отвечает на главное не раскрываясь: имя, период, чем
   кончился последний прогон. Раскрытая — полный конструктор маршрута. */
.cab-probes{display:flex;flex-direction:column;gap:8px;margin:10px 0}
.cab-probe{border:1px solid var(--line);border-radius:11px;background:var(--panel2)}
.cab-probe[open]{border-color:var(--line2)}
.cab-probe>summary{cursor:pointer;list-style:none;padding:10px 12px}
.cab-probe>summary::-webkit-details-marker{display:none}
.cab-probe-h{display:flex;align-items:center;gap:9px;flex-wrap:wrap;font-size:13.5px}
.cab-probe-h .dot{flex:0 0 auto}
.cab-probe-name{font-size:14.5px}
.cab-probe-sum{margin-left:auto}
.cab-probe-main{font-size:11px;padding:2px 7px}
.cab-probe-body{padding:2px 12px 12px;border-top:1px solid var(--line)}
.cab-lbl{display:flex;flex-direction:column;gap:4px;font-size:12.5px;color:var(--muted);min-width:0}
.cab-lbl input[type=text],.cab-lbl select{font:inherit;font-size:13.5px;padding:7px 9px;
  border-radius:8px;border:1px solid var(--line2);background:var(--card);color:var(--ink)}
.cab-addprobe input[type=text]{font:inherit;font-size:13.5px;padding:7px 9px;border-radius:8px;
  border:1px solid var(--line2);background:var(--card);color:var(--ink);flex:1 1 14rem;min-width:0}
.cab-addprobe{gap:8px;margin-top:6px}
.cab-x-del{border-color:rgba(255,80,99,.35);color:var(--muted)}
.cab-x-del:hover{border-color:var(--down);color:var(--down)}
@media (max-width:560px){.cab-probe-sum{margin-left:0;flex-basis:100%}}
/* Порог алерта в кабинете (v7.15). */
.cab-level{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.cab-level-row{display:flex;gap:8px;align-items:center}
.cab-level-row input[type=number]{width:5em;font:inherit;font-size:14px;padding:6px 8px;border-radius:8px;border:1px solid var(--line2);background:var(--panel2);color:var(--ink)}

/* Кабинет: статус-страница (v7.15). */
.cab-sp-grid{grid-template-columns:1fr;gap:6px}
.cab-sp .cab-z{flex-direction:row;align-items:center;gap:8px;font-size:14px}
.cab-sp .cab-z input{margin:0}
.cab-code{margin:6px 0 0;padding:10px 12px;border-radius:8px;background:rgba(255,255,255,.05);border:1px solid var(--line);
  font-size:12.5px;white-space:pre-wrap;word-break:break-all;user-select:all}
.cab-upsell{margin:0 0 10px}

/* Публичная статус-страница клиента (v7.15): своя тонкая оболочка, без шапки сайта. */
.sp-body main{max-width:820px;margin:0 auto;padding:28px 18px 40px}
/* v7.23: заглушка статус-страницы для внешних (тариф без опции / не опубликована) */
.sp-stub{text-align:center;padding:48px 12px 24px}
.sp-stub .sp-title{margin:0 0 12px;font-size:26px;line-height:1.2}
.sp-stub-msg{color:var(--muted);font-size:16px;max-width:36em;margin:0 auto 22px}
.sp-btn{display:inline-block;padding:10px 20px;border-radius:10px;font-weight:600;text-decoration:none;
  background:var(--accent,#31d98a);color:var(--accent-ink,#0b1020)}
.sp-btn:hover{filter:brightness(1.08)}
.sp-stub .sp-foot{margin-top:34px;display:block;text-align:center}
.sp-head h1{margin:0 0 6px;font-size:28px;line-height:1.2}
.sp-note{margin:0 0 18px;color:var(--muted);font-size:15.5px}
.sp-banner{display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:14px;border:1.5px solid var(--line);margin:0 0 14px}
.sp-banner .dot{width:14px;height:14px;flex:none}
.sp-banner b{display:block;font-size:18px}
.sp-banner span:not(.dot):not(.sp-upd){display:block;color:var(--muted);font-size:14px;margin-top:2px}
.sp-banner.sp-ok{border-color:rgba(49,217,138,.5);background:rgba(49,217,138,.08)}
.sp-banner.sp-warn{border-color:rgba(255,178,36,.5);background:rgba(255,178,36,.08)}
.sp-banner.sp-part{border-color:rgba(255,138,61,.5);background:rgba(255,138,61,.08)}
.sp-banner.sp-down{border-color:rgba(255,80,99,.5);background:rgba(255,80,99,.08)}
.sp-upd{margin-left:auto;color:var(--muted);font-size:12.5px;white-space:nowrap}
.sp-isr{margin:0 0 12px;padding:10px 14px;border-radius:10px;background:rgba(255,178,36,.1);border:1px solid rgba(255,178,36,.4);font-size:14px}
.sp-compl,.sp-facts{margin:0 0 10px;color:var(--muted);font-size:14px}
.sp-comps{display:flex;flex-direction:column;gap:10px;margin:18px 0 26px}
.sp-comp{padding:14px 16px;border:1px solid var(--line);border-radius:12px;background:var(--panel,rgba(255,255,255,.02))}
.sp-comp-down{border-color:rgba(255,80,99,.45)}
.sp-comp-part{border-color:rgba(255,138,61,.45)}
.sp-comp-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.sp-comp-name{font-size:16px}
.sp-comp-state{color:var(--muted);font-size:13.5px}
.sp-comp-up{margin-left:auto;font-size:15px;font-weight:600}
.sp-comp-bad{margin:8px 0 0;color:#ff8a3d;font-size:13.5px}
.sp-comp-br,.sp-comp-ms{margin:8px 0 0;font-size:13px;color:var(--muted);display:flex;gap:6px;align-items:center}
.sp-comp-br .dot{width:8px;height:8px}
.sp-comp-br{flex-wrap:wrap}
.sp-comp-br-why{color:var(--down,#ff5063);opacity:.9}
/* v7.32: переключатель периода витрины — те же плашки, что в отчёте кабинета (.cl-per) */
.sp-period{margin:-4px 0 14px;color:var(--muted);font-size:12.5px;display:flex;align-items:center;flex-wrap:wrap;gap:6px}
.sp-period .cl-per{margin-left:0}
.sp-foot-badge{display:block}
.sp-bars{margin-top:10px}
.sp-bars svg{width:100%;height:42px;display:block}
.sp-bars-cap{display:flex;justify-content:space-between;color:var(--muted);font-size:11.5px;margin-top:3px}
.sp-incs h2{font-size:18px;margin:0 0 10px}
.sp-inc{list-style:none;margin:0;padding:0}
.sp-inc li{padding:8px 0;border-top:1px solid var(--line);font-size:14px}
.sp-inc li:last-child{border-bottom:1px solid var(--line)}
.sp-inc-open b{color:var(--down)}
.sp-inc-why{color:var(--muted)}
.sp-none{color:var(--muted);font-size:14px}
.sp-sub{margin:26px 0 0;padding:16px 18px;border-radius:12px;border:1px solid rgba(49,217,138,.35);background:rgba(49,217,138,.05)}
.sp-sub b{display:block;margin-bottom:10px}
.sp-sub-list{display:flex;flex-wrap:wrap;gap:8px}
.sp-sub-btn{display:inline-block;padding:7px 14px;border-radius:9px;border:1px solid rgba(49,217,138,.5);background:rgba(49,217,138,.12);color:inherit;text-decoration:none;font-size:14px}
.sp-sub-btn:hover{background:rgba(49,217,138,.24)}
.sp-sub-cap{margin:10px 0 0;color:var(--muted);font-size:12.5px}
.sp-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:34px;padding-top:16px;border-top:1px solid var(--line);color:var(--muted);font-size:13px}
.sp-foot a{color:inherit}
@media (max-width:560px){.sp-upd{margin-left:0;flex-basis:100%}.sp-comp-up{margin-left:0}}
/* v7.25: форма пароля статус-страницы */
.sp-gate-form{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin:0 0 8px}
.sp-gate-form input[type=password]{font:inherit;font-size:15px;padding:10px 14px;border-radius:10px;border:1px solid var(--line2);background:var(--panel2);color:var(--ink);min-width:220px}
.sp-gate-err{color:var(--down,#ff5d5d);margin:-8px 0 12px}

/* v7.30: единый блок «Проверка адреса» в админке — форма как на /proverka, плюс
   операторский выбор площадок и отчёт inspect_render внутри панели. */
.chk-form-adm{margin:6px 0 4px}
.adm-zones{margin:8px 0 0;font-size:13px}
.adm-zones>summary{cursor:pointer;color:var(--muted)}
.adm-zones .zone-form{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:8px}
.adm-chk-report{margin-top:12px}
.adm-chk-actions{margin-top:10px;display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.adm-chk-actions .cab-btn{text-decoration:none}
.chk-geo-tbl td.chk-wrap{max-width:260px;overflow-wrap:anywhere}
.chk-form-adm .adm-zones{flex-basis:100%}
/* v7.33: панель «Браузерные пробы» в админке */
.adm-br-tbl td{vertical-align:top}
.adm-br-tbl .ag-sub{display:block}
.adm-br-err{color:var(--down);font-size:12px}
.adm-br-off{opacity:.55}
.sp-comp-br-off .dot{background:var(--warn,#ffb224)}
.sp-comp-br-okat{color:var(--muted)}

/* ══════════════════════════════════════════════════════════════════════════
   v7.34 — движение на главной
   ══════════════════════════════════════════════════════════════════════════ */
/* Бегущая строка сроков: дорожка из двух одинаковых наборов чипов едет влево на
   ширину одного набора — круг бесшовный. Наведение — пауза (иначе по ссылке не
   попасть); reduced-motion — стоит, прокрутка пальцем. */
.alarm-ticker{max-width:100%;overflow:hidden;border-radius:999px;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 24px,#000 calc(100% - 24px),transparent);
  mask-image:linear-gradient(90deg,transparent,#000 24px,#000 calc(100% - 24px),transparent)}
.alarm-ticker-track{display:inline-flex;gap:10px;white-space:nowrap;will-change:transform;
  animation:alarm-ticker var(--tdur,20s) linear infinite}
.alarm-ticker-set{display:inline-flex;gap:10px;padding-right:10px}
.alarm-ticker .alarm-chip{flex:0 0 auto;max-width:none}
.alarm-ticker:hover .alarm-ticker-track,.alarm-ticker:focus-within .alarm-ticker-track{animation-play-state:paused}
@keyframes alarm-ticker{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
  .alarm-ticker{overflow-x:auto;-webkit-mask-image:none;mask-image:none}
  .alarm-ticker-track{animation:none}
  .alarm-ticker-set[aria-hidden]{display:none}
}
.alarm-ticker .alarm-chip>.num{overflow:visible;text-overflow:clip}
.alarm-link{color:inherit;text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 40%,transparent);
  text-underline-offset:2px}
.alarm-link:hover{text-decoration-color:currentColor}
.alarm-days{opacity:.75}

/* Секундомер на кнопке проверки */
.chk-form .chk-dir .chk-timer{font-variant-numeric:tabular-nums;min-width:4.2em;text-align:center;color:#08110c;font-family:var(--mono);font-size:15px}
.chk-form button[disabled].chk-dir-on{opacity:.92}
/* Переливание адреса: накладка поверх поля тем же шрифтом и отступами; текст
   самого поля прозрачный, каретка скрыта. */
.chk-form{position:relative}
.chk-form input.chk-input-busy{color:transparent;caret-color:transparent;text-shadow:none}
.chk-wave{position:absolute;pointer-events:none;overflow:hidden;white-space:pre;
  display:flex;align-items:center;box-sizing:border-box;padding:13px 15px;border:1.5px solid transparent;
  font:16px var(--sans);color:var(--ink)}
/* v7.39: только оттенок. Подпрыгивание символов (translateY) убрано по решению
   владельца — на строке адреса оно читалось как игрушка, а не как «идёт работа».
   Буквы стоят на месте, по ним слева направо проходит смена цвета. */
.chk-wave span{animation:chk-wave 1.6s ease-in-out infinite}
@keyframes chk-wave{0%,100%{color:var(--ink)}40%{color:var(--ok)}70%{color:var(--muted)}}

/* Блок разовой проверки: заголовок → поле → результат → описание */
.chk-home .chk-home-txt{display:grid;gap:6px}
.chk-home .chk-home-txt .panel-cap{margin:0}
.chk-home .chk-slot:empty{display:none}

/* Подсказка-список на столбиках графиков */
.chart-pop{position:absolute;z-index:60;max-width:min(360px,calc(100vw - 16px));padding:10px 12px;border-radius:12px;
  background:color-mix(in srgb,var(--panel) 96%,transparent);border:1px solid var(--line2);
  box-shadow:0 12px 34px -14px rgba(0,0,0,.7);font-size:13px;color:var(--ink);backdrop-filter:blur(8px)}
.chart-pop-h{font:500 12.5px var(--mono);color:var(--muted);margin-bottom:6px}
.chart-pop-k{display:flex;align-items:center;gap:6px;margin-top:6px;color:var(--muted);font-size:12px}
.chart-pop-k .dot{width:8px;height:8px}
.chart-pop ul{list-style:none;margin:3px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:4px 10px}
.chart-pop li a{color:var(--ink);text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--ink) 30%,transparent);text-underline-offset:2px}
.chart-pop li a:hover{color:var(--ok)}
svg.chart[data-who] rect.barp[data-i]{cursor:pointer}
.chart-pop-more{color:var(--muted)}

/* ══════════════════════════════════════════════════════════════════════════
   v7.35 — ЕДИНЫЙ ЯЗЫК СТРАНИЦ (эталон — главная)
   Одни и те же кегли заголовков, одни «пилюли» второго уровня навигации, одна
   кнопка действия, одна ширина текста, одинаковое поведение на телефоне.
   Правила ниже стоят ПОСЛЕ старых и побеждают порядком — старые блоки не
   вычищались намеренно: каждый когда-то чинил свой боевой случай, и история
   дельт в них остаётся читаемой.
   ══════════════════════════════════════════════════════════════════════════ */

/* 1. Заголовок страницы: везде один кегль и отступ; текст сразу под ним —
      один «лид». Отступ слева выравнивает заголовок с текстом внутри панелей
      (решение 7.05 для главной — теперь для всех). */
main>h1,main .auth-wrap>h1,main .stage-title,.stage-title{
  font-size:clamp(21px,2.3vw,30px);line-height:1.2;letter-spacing:-.4px;margin:6px 0 12px;padding-left:20px}
.stage-title-pad{padding-left:20px}
main>h1+p,main>h1+.lead,main>.stage-title+.lead,main>.stage-title+p,.auth-wrap>h1+p,.auth-wrap>h1+.auth-lead,
.auth-wrap>h1+.lead{padding-left:20px}
.lead,.auth-lead,main>h1+p,.auth-wrap>h1+p{font-size:14px;color:var(--muted);line-height:1.55;margin:0 0 14px;max-width:none}
@media (max-width:700px){
  main>h1,main .auth-wrap>h1,main .stage-title,.stage-title,.stage-title-pad,
  main>h1+p,main>h1+.lead,main>.stage-title+.lead,main>.stage-title+p,.auth-wrap>h1+p,.auth-wrap>h1+.auth-lead,.auth-wrap>h1+.lead{padding-left:12px}
}

/* 2. «Пилюли» второго уровня: вкладки кабинета, группы админки, периоды отчёта
      и витрины, переключатель тарифов — одна форма, один активный цвет (зелёный
      акцент главной вместо синего у вкладок кабинета). */
.cab-tab,.adm-nav a,.adm-nav-btn,.cl-per a,.per-opt,.sp-per a{
  display:inline-flex;align-items:center;gap:6px;padding:6px 13px;border-radius:999px;
  font:500 13px/1.2 var(--sans);text-decoration:none;color:var(--ink);
  border:1px solid var(--line2);background:var(--panel);white-space:nowrap;cursor:pointer}
a.cab-tab:hover,.adm-nav a:hover,.adm-nav-btn:hover,.cl-per a:hover,.per-opt:hover,.sp-per a:hover{
  border-color:rgba(49,217,138,.45);color:var(--ink)}
.cab-tab.on,.cl-per a.on,.per-opt.on,.sp-per a.on{
  background:var(--ok-dim);border-color:rgba(49,217,138,.45);color:var(--ok);font-weight:600}
.cab-tab.off{color:var(--muted);cursor:default;opacity:.7}
.cl-per a.lock{opacity:.55}
.per-switch{border:0;padding:0;gap:6px}
.per-save{padding-left:4px}
.cab-tabs,.cl-per,.per-switch,.sp-per{gap:6px}
.adm-nav-btn{color:var(--muted);font-size:12.5px}

/* 3. Кнопки действия: одна главная (зелёный градиент главной) и одна вторичная
      (контурная). Размер — как у соседних полей, не как у кнопки на главной. */
.auth-form button[type=submit],.cab-btn-go{
  font:600 13.5px var(--sans);color:#08110c;border:0;border-radius:10px;padding:9px 18px;cursor:pointer;
  background:linear-gradient(180deg,#48e6a0,var(--ok))}
.auth-form button[type=submit]:hover,.cab-btn-go:hover{filter:brightness(1.07);background:linear-gradient(180deg,#48e6a0,var(--ok))}
.cab-btn,.cl-btn,.auth-btn,.tar-drop{font:500 13px var(--sans);border-radius:10px}
.auth-btn{background:var(--panel);border:1px solid var(--line2);color:var(--ink);padding:8px 14px}
.auth-btn:hover{border-color:rgba(49,217,138,.45)}

/* 4. Формы входа/регистрации — панель во всю ширину, поля во всю ширину панели,
      подсказки — «лид». Никакой колонки в 32rem по центру. */
.auth-wrap.auth-page,.auth-doc{max-width:none;margin:0;padding:0}
.auth-panel{margin-top:6px}
.auth-panel .auth-form{margin:6px 0 0;gap:12px}
.auth-panel .auth-form label{font-size:13px;color:var(--muted);gap:5px}
.auth-panel .auth-form input[type=text],.auth-panel .auth-form input[type=email],.auth-panel .auth-form input[type=password],
.auth-panel .auth-form input[type=tel],.auth-panel .auth-form input[type=url],.auth-panel .auth-form input[type=number],
.auth-panel .auth-form textarea,.auth-panel .auth-form select{
  width:100%;max-width:none;box-sizing:border-box;font:15px var(--sans);color:var(--ink);background:var(--bg2);
  border:1.5px solid var(--line2);border-radius:11px;padding:11px 14px}
.auth-panel .auth-form input:focus,.auth-panel .auth-form textarea:focus{border-color:var(--ok);outline:none}
.auth-panel .auth-form button[type=submit]{align-self:flex-start;justify-self:start;width:auto;min-width:160px}
.auth-panel .auth-hint,.auth-panel .auth-alt,.auth-panel .auth-msg{font-size:13px;color:var(--muted)}
.auth-panel .auth-msg{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:10px 12px;margin:0 0 10px}
.auth-panel .auth-alt{margin:12px 0 0}
.auth-panel .auth-alt+.auth-alt{margin-top:4px}
@media (min-width:860px){.auth-panel .auth-form{display:grid;grid-template-columns:1fr 1fr;gap:12px 18px;align-items:start}
  .auth-panel .auth-form>p,.auth-panel .auth-form>button,.auth-panel .auth-form>.auth-accept,.auth-panel .auth-form>h3,
  .auth-panel .auth-form>label.auth-wide,.auth-panel .auth-form>textarea,.auth-panel .auth-form>label:has(textarea){grid-column:1/-1}}

/* 5. Текст — во всю ширину своего блока и с переносом: длинные адреса, коды,
      ключи не выталкивают страницу вбок. */
body{overflow-wrap:break-word}
code,.embed,.num,.auth-hint,.cl-claim,.svc-sub,td{overflow-wrap:anywhere}
.sell-cta-txt{max-width:none}
input,select,textarea{max-width:100%;min-width:0;box-sizing:border-box}
.tbl-wrap{max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
img,svg,video{max-width:100%}
svg.chart,.chart svg{max-width:none}

/* 6. Телефон: строки, которые на 390 px вылезали за край или ломались столбиком. */
@media (max-width:640px){
  .cab-level-row{flex-wrap:wrap}
  .cab-level-row .num.ag-sub{flex:1 1 100%}
  .sp-banner{flex-wrap:wrap;gap:10px 12px}
  .sp-banner>div{flex:1 1 200px;min-width:0}
  .sp-banner .sp-upd{flex:1 1 100%;margin-left:26px;font-size:12px}
  .mapstage .banner-warn{position:static;margin:54px 10px 0;font-size:12.5px}
  .chk-form .chk-dir{min-height:46px}
  .adm-nav{position:static}
  .kpi,.cl-kpi{grid-template-columns:1fr 1fr}
}

/* ══════════════════════════════════════════════════════════════════════════
   v7.36 — ЕДИНЫЙ ЯЗЫК СТРАНИЦ, ВТОРОЙ ПРОХОД (решение владельца 07.09:
   «подписи второго уровня внутри панелей — капсом; скругления и отступы
   тарифных карточек — как на главной; во всех спорных случаях — по подобию
   главной»).
   ══════════════════════════════════════════════════════════════════════════ */

/* 1. ПОДПИСЬ ВТОРОГО УРОВНЯ ВНУТРИ ПАНЕЛИ — КАПСОМ.
      На главной подпись раздела — это <h2>: Unbounded, 14px, капс, приглушённый
      («ПРОВЕРИТЬ СВОЙ САЙТ ПРЯМО СЕЙЧАС», «СООБЩЕНИЯ О СБОЯХ ЗА 24 ЧАСА»).
      Внутри панелей же вырос второй сорт — жирный h3 в предложении
      («Telegram», «Адрес и название», «Сеть и адреса»): на одной странице
      получалось два разных языка заголовков. Теперь h3 — та же гарнитура и
      капс, на ступень мельче h2 (12.5 против 14), чтобы иерархия читалась
      кеглем, а не сортом шрифта. */
.panel h3,.apanel h3,.auth-panel h3,.cab-alerts h3,.chk-card h3,.mon-card h3,.chk-geo h3,
.chk-notes h3,.android-block h3,.sp-comps h3,.cab-h3,.ag-h3,
.subd>summary>b,.probe-settings>summary>b,.diag-block>summary>b{
  font-family:var(--display);font-size:12.5px;font-weight:500;letter-spacing:.6px;
  text-transform:uppercase;color:var(--muted);line-height:1.35}
.panel h3,.apanel h3,.auth-panel h3,.cab-alerts h3,.chk-notes h3,.android-block h3,.ag-h3{margin:18px 0 8px}
.panel>h3:first-child,.chk-card h3,.mon-card h3,.chk-geo h3,.cab-h3,
.auth-panel .auth-form>h3:first-child{margin-top:0}
/* В «Оповещениях» над первой подписью стоит сводная строка — ей нужен воздух. */
.cab-alerts h3:first-child{margin-top:12px}
.chk-card h3,.mon-card h3,.chk-geo h3,.cab-h3{margin-bottom:8px}
/* Внутри подписи капсом — только сама подпись: чипы, счётчики и пояснения
   рядом с ней остаются предложением своего кегля (иначе «🔒 тариф» и
   «2 из 15» кричат наравне с заголовком). */
h3 .chip,h3 .ag-sub,h3 .num,h3 .auth-hint,h3 small,h3 .cab-lock,
.subd>summary>b+*,.diag-block>summary>b+*{
  font-family:var(--sans);text-transform:none;letter-spacing:0;color:var(--muted)}
h3 .chip{font-size:11.5px}
/* Подпись, которая сообщает о беде, остаётся цветной: единообразие — про
   гарнитуру и кегль, а не про то, чтобы все строки стали одинаково серыми. */
h3.ag-bad,.cab-h3.ag-bad,.subd>summary>b.ag-bad,.diag-block>summary>b.ag-bad,
details.panel>summary>b.ag-bad,details.apanel>summary>b.ag-bad{color:var(--warn)}
/* Третий уровень в карточке проверки («Сертификат», «Домен») капсом был и
   раньше, но кеглем спорил с заголовком карточки — теперь на ступень мельче. */
.chk-sub{font-size:12px}

/* 2. ЗАГОЛОВОК ПАНЕЛИ АДМИНКИ — ОДИН, КАКИМ БЫ ТЕГОМ НИ БЫЛ НАПИСАН.
      Половина панелей объявлена <summary><h2>, половина — <summary><b>: рядом
      стояли «ПРОВЕРИТЬ АДРЕС» и «⛔ Чёрные списки». Тег — дело разметки,
      вид — дело страницы. */
details.panel>summary>b,details.apanel>summary>b{
  font-family:var(--display);font-size:14px;font-weight:500;letter-spacing:.6px;
  text-transform:uppercase;color:var(--muted)}
details.panel>summary>b+.ag-sub,details.apanel>summary>b+.ag-sub{
  font-family:var(--sans);text-transform:none;letter-spacing:0}

/* 2б. Подписи графиков главной — из той же лестницы: подпись сводного графика
       читается как заголовок раздела панели (14), подпись часовой полосы под
       ним — как второй уровень (12.5). Раньше 13 и 11 — два кегля мимо шкалы. */
.chart-cap{font-size:14px}
.chart-cap-sm{font-size:12.5px;opacity:.8}

/* 3. КАРТОЧКИ — ОДНА СЕМЬЯ, КАК ПЛИТКИ ГЛАВНОЙ.
      Плитка главной: 1px рамка, радиус 12, отступ 13–14, фон панели. Тарифные
      карточки были без фона с отступом 16 и 18/18/20, KPI отчёта — 11/13,
      карточки «Мониторинга» — 14/16: четыре набора чисел для одного и того же
      элемента. */
.tar-card,.tar-card-sm,.mon-card,.chk-card,.cl-kpi>div{
  border:1px solid var(--line);border-radius:12px;padding:14px 16px;background:var(--panel2)}
.tar-card.on,.tar-card-pick{border-color:rgba(49,217,138,.5);
  background-color:var(--panel2);background-image:linear-gradient(180deg,rgba(49,217,138,.10),transparent)}
.tar-card-pick{border-width:1.5px}
/* Название тарифа — подпись раздела, а не второй заголовок страницы: капс
   у него и так был (глобальный h2), теперь и кегль общий. */
.tar-card h2,.tar-card-sm h2,.sell-cta .tar-card-sm h2{font-size:14px;margin:0 0 8px}
.tar-price{font-size:23px}
.tar-card button,.tar-go{border-radius:10px;font:600 13.5px var(--sans);padding:9px 14px}
.tar-card button{border:1px solid rgba(49,217,138,.42);background:rgba(49,217,138,.14);color:var(--ink)}
.tar-card button:hover{background:rgba(49,217,138,.24)}
.tar-go{border:1px solid var(--line2);color:var(--ink);padding:10px 14px}

/* 4. ПРОДАЮЩИЙ БЛОК — ПАНЕЛЬ, А НЕ ОТДЕЛЬНЫЙ ЖАНР.
      Радиус 18 и отступ 34/32 при панельных 14 и 18/20, заголовок 27px рядом с
      h1 страницы в 30 — блок спорил с ней за первое место. Акцент оставляем
      (зелёная рамка и подложка), геометрию берём панельную. */
.sell-cta{padding:18px 20px;border-radius:var(--r);margin:20px 0}
.sell-cta-h{font-size:14px;margin:0 0 8px}
.sell-cta-txt{font-size:14px;line-height:1.55}
.sell-cta-plans{margin-top:16px;padding-top:16px}
.sell-cta-foot{margin:14px 0 0;font-size:13px}
.chk-cta-plans{margin-top:16px;padding-top:16px}
/* Попутно (видно на витрине тарифов и в продающем блоке): строка «при оплате за
   год» — флекс-сосед «/мес» с нулевым горизонтальным зазором, и читалось
   «/меспри оплате за год». Обе поясняющие строки занимают всю ширину. */
.tar-cost-lead .tar-year{width:100%}

/* ══════════════════════════════════════════════════════════════════════════
   v7.37 — ЕДИНЫЙ ЯЗЫК СТРАНИЦ, ТРЕТИЙ ПРОХОД: ТАБЛИЦЫ, ПОЛЯ И КНОПКИ АДМИНКИ
   Замер браузером (tests/fake/ui-ctrl.js) показал, что админка говорит другим
   языком не «немного», а системно: 645 полей и 258 списков рисовались
   Arial (гарнитура браузера по умолчанию для элементов формы), 118 кнопок
   вообще без стилей — серые кнопки движка с белой рамкой в 2 px, — а рядом
   жили ещё пять размеров полей. Здесь одна шкала на всю админку; плотность
   сохранена (12,5 px и узкие отступы: в строке ресурса десяток полей).
   ══════════════════════════════════════════════════════════════════════════ */
.agroup input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]),
.agroup select,.agroup textarea{
  font:12.5px/1.35 var(--sans);color:var(--ink);background:var(--bg2);
  border:1px solid var(--line2);border-radius:8px;padding:5px 9px}
.agroup input:not([type=checkbox]):not([type=radio]):focus,
.agroup select:focus,.agroup textarea:focus{border-color:var(--ok);outline:none}
.agroup input::placeholder,.agroup textarea::placeholder{color:var(--faint)}
.agroup button{font:600 12.5px/1.2 var(--sans);color:var(--ink);background:var(--panel2);
  border:1px solid var(--line2);border-radius:8px;padding:5px 10px;cursor:pointer}
.agroup button:hover{border-color:rgba(49,217,138,.45)}
.agroup button:disabled{opacity:.5;cursor:not-allowed}
/* Действия в строке таблицы и в правках категорий — плотнее: их по три-четыре
   в ячейке, и полноразмерные кнопки ломали бы строку. */
.agroup .ag-act button,.agroup .cat-edit button,.agroup .svc-row button,.agroup .inline button{padding:4px 9px}
/* Опасное действие остаётся красным, «сделать сейчас» — зелёным: единообразие
   про форму, а не про то, чтобы все кнопки стали одинаково серыми (правило 0э). */
.agroup .btn-danger{border-color:rgba(255,80,99,.45);color:var(--down);background:transparent}
.agroup .btn-danger:hover{background:rgba(255,80,99,.12);border-color:rgba(255,80,99,.6)}
.agroup .cab-btn-go{color:#08110c;border:0}
/* Панель разовой проверки внутри админки — это блок ГЛАВНОЙ, целиком со своим
   видом (7.30): у неё поле и две кнопки такие же, как на главной. */
.agroup .chk-form input[type=text]{font:15px var(--sans);padding:11px 14px;border-radius:11px;border-width:1.5px;background:var(--bg2)}
.agroup .chk-form .chk-dir{font:650 15px var(--sans);color:#08110c;border:0;border-radius:11px;
  padding:9px 20px;background:linear-gradient(180deg,#48e6a0,var(--ok))}
.agroup .chk-form .chk-dir:hover{border:0;filter:brightness(1.07)}
.agroup .chk-form .chk-dir .chk-dir-l1{font-weight:500;font-size:13px;opacity:.85}
.agroup .chk-form .chk-dir .chk-dir-l2{font-weight:700;font-size:15px}

/* Таблицы админки — одна разлиновка: шапка тем же капсом, что подписи, линии
   темы (var(--line)), а не белым по прозрачному, и один шаг отступов. */
.ag-tbl th,.mtx th,.adm-br-tbl th{font:600 11px/1.2 var(--sans);letter-spacing:.04em;
  text-transform:uppercase;color:var(--muted);opacity:1;padding:6px 12px 6px 0}
.ag-tbl td,.adm-br-tbl td{border-top:1px solid var(--line);padding:8px 12px 8px 0}
.mtx th,.mtx td{padding:6px 10px}
.mtx td{border-top:1px solid var(--line)}
.mtx-sum td{border-top:1px solid var(--line2)}
.ag-tbl tr:hover>td{background:rgba(255,255,255,.02)}
@media(max-width:1100px){.ag-tbl tr:hover>td{background:none}}

/* Переключатель темы в шапке (☾) не имел стилей ВООБЩЕ — серая кнопка движка с
   белой рамкой, на каждой странице сайта, рядом с аккуратной «Кабинет». Замер
   нашёл её там же, где остальных отставших. Теперь это та же «пилюля», что и
   ссылка кабинета, и подсветка у обеих — зелёная, как у остальной навигации. */
.theme-btn{font:500 13px var(--mono);line-height:1.2;padding:6px 12px;border-radius:8px;cursor:pointer;
  border:1px solid var(--line);background:var(--panel);color:inherit}
.theme-btn:hover,.head-auth:hover{border-color:rgba(49,217,138,.45);background:var(--ok-dim);color:inherit}

/* Остатки собственных размеров в админке: шаблоны сообщений и списки исключений
   моноширинные по делу (в них подставляемые метки и пути) — гарнитуру им
   оставляем, кегль берём общий; списки конструктора тарифов приводим к шкале. */
.agroup textarea[name^="tg_tpl"],.agroup textarea[name^="files_excl"]{font-family:var(--mono);font-size:12.5px}
.agroup .plan-edit input[type=text],.agroup .plan-edit select,.agroup .plan-edit input[type=number]{
  font-size:12.5px;padding:5px 9px;border-radius:8px}

/* Кегли админки жили в разметке: 46 инлайновых font-size на 22 панели («так
   быстрее» — и так они переставали слушаться темы и правились в двадцати
   местах). Теперь их даёт класс: строка-состояние 13, чип 11, таблица 13,
   моноширинное поле и вывод — 12,5. Разметка занимается разметкой. */
.agroup .flash,.agroup p.num,.agroup .diag-block p{font-size:13px}
.agroup .chip{font-size:11px}
.ag-tbl{font-size:13px}
.adm-mono{width:100%;font-family:var(--mono);font-size:12.5px}
.adm-pre{white-space:pre-wrap;font-family:var(--mono);font-size:12.5px;margin:6px 0 0;max-height:260px;overflow:auto}
/* Выбор файла (гео-база) — единственный элемент формы, которому браузер рисует
   собственную кнопку: приводим к общей гарнитуре и кеглю. */
.agroup input[type=file]{font:12.5px var(--sans);color:var(--muted)}
.agroup input[type=file]::file-selector-button{font:600 12.5px var(--sans);color:var(--ink);
  background:var(--panel2);border:1px solid var(--line2);border-radius:8px;padding:5px 10px;margin-right:10px;cursor:pointer}
.agroup input[type=file]::file-selector-button:hover{border-color:rgba(49,217,138,.45)}
/* Подписи полей в админке — того же кегля, что сами поля: плотная страница, где
   подпись в 16 px рядом с полем в 12,5 читается как заголовок, а не как подпись
   («Проверка из России» у поля зон выглядела крупнее панели). */
.agroup label{font-size:12.5px;line-height:1.35}
.agroup .active-tgl,.agroup .zone-box{font-size:12px}
.agroup .chk-form label{font-size:13px}
/* Образцы цвета в палитре — свой род элемента (как галочка): рамка и радиус
   общие, отступов у образца быть не должно. */
.adm-color{width:54px;height:28px;padding:0;border:1px solid var(--line2);border-radius:8px;
  background:var(--bg2);cursor:pointer}
/* Шапка панели — флекс в одну строку (7.30). У «Браузерных проб» в ней ещё и
   пояснение с чипами, и на 390 px строка не помещалась: страница уезжала вбок
   на 5 px. Разрешаем перенос — шеврон при этом остаётся на первой строке.
   Найдено замером ширины (test_v735), а не глазом. */
@media (max-width:760px){
  details.apanel>summary{flex-wrap:wrap}
  details.apanel>summary h2{flex:1 1 auto;min-width:0}
  details.apanel>summary>.ag-sub{flex:1 1 100%;order:4}
  details.apanel>summary::after{margin-left:auto;order:2}
  details.apanel>summary>.chip{order:3}
}

/* ══════════════════════════════════════════════════════════════════════════
   v7.38 — ВИТРИНА КЛИЕНТА ГОВОРИТ ЯЗЫКОМ ПРОЕКТА
   Замечание владельца: страница состояния сервисов «имеет отличный дизайн» —
   то есть ОТЛИЧАЮЩИЙСЯ. Так и было: у неё своя оболочка (sp_layout — без шапки
   сайта и карты, это решение 7.15 и оно остаётся), а вместе с оболочкой
   завелась и своя шкала — заголовок 28, подпись 15.5, «Инциденты» 18 при
   проектных 14, карточка на фоне --panel вместо --panel2, своя кнопка подписки.
   Здесь витрина берёт ту же лестницу, что весь сайт: заголовок страницы,
   подпись второго уровня капсом, карточка из общей семьи, пилюли и кнопки.
   Узкая колонка (820 px) — не расхождение, а решение: страница клиента для его
   клиентов, читается с телефона.
   ══════════════════════════════════════════════════════════════════════════ */
.sp-body main{max-width:820px;margin:0 auto;padding:26px var(--gutter) 44px}
/* Заголовок и вводные строки — по левому краю содержимого карточек (16 px),
   как h1 сайта стоит вровень с текстом внутри панелей (решение 7.05). */
.sp-head h1,.sp-stub .sp-title{font-size:clamp(21px,2.3vw,30px);line-height:1.2;letter-spacing:-.4px;margin:0 0 10px}
.sp-head h1{padding-left:16px}
.sp-note,.sp-period,.sp-compl,.sp-facts{padding-left:16px}
.sp-note{font-size:14px;margin:0 0 14px}
.sp-compl,.sp-facts{font-size:13px;margin:0 0 8px}
@media (max-width:700px){.sp-head h1,.sp-note,.sp-period,.sp-compl,.sp-facts{padding-left:12px}}

/* Баннер состояния — панель, а не отдельный жанр: рамка 1 px и радиус 12, как
   у карточек ресурсов под ним; крупная строка — 15, не 18. */
.sp-banner{padding:14px 16px;border-radius:12px;border-width:1px}
.sp-banner b{font-size:15px}
.sp-banner span:not(.dot):not(.sp-upd){font-size:13px}
.sp-isr{font-size:13px;border-radius:12px;padding:10px 14px}

/* Карточка ресурса — из общей семьи (радиус 12, отступ 14/16, фон панели). */
.sp-comp{background:var(--panel2)}
.sp-comp-name{font-size:15px}
.sp-comp-state{font-size:13px}
.sp-comp-up{font-size:15px}
.sp-comp-ms,.sp-comp-br,.sp-comp-bad{font-size:12.5px}

/* «Инциденты за …» — заголовок раздела (14 капсом, как везде), строки — 13. */
.sp-incs h2{font-size:14px;margin:0 0 10px}
.sp-inc li,.sp-none{font-size:13px}
.sp-inc li{padding:8px 0}

/* Блок подписки: «Следить за состоянием в Telegram» — подпись второго уровня,
   кнопки ресурсов — те же пилюли, что переключатель периода над ними. */
.sp-sub{padding:14px 16px;border-radius:12px;margin:22px 0 0}
.sp-sub b{display:block;margin-bottom:10px;font:500 12.5px/1.35 var(--display);
  letter-spacing:.6px;text-transform:uppercase;color:var(--muted)}
.sp-sub-btn{padding:6px 13px;border-radius:999px;font:500 13px/1.2 var(--sans)}
.sp-sub-cap{font-size:12.5px}

/* Заглушка и форма пароля — та же кнопка и то же поле, что в формах сайта. */
.sp-stub-msg{font-size:14px;color:var(--muted);margin:0 auto 18px}
.sp-btn{font:600 13.5px var(--sans);padding:9px 18px;border-radius:10px}
.sp-gate-form input[type=password]{font:15px var(--sans);padding:11px 14px;border-radius:11px;
  border:1.5px solid var(--line2);background:var(--bg2)}
.sp-gate-form input[type=password]:focus{border-color:var(--ok);outline:none}
.sp-foot{font-size:13px;margin-top:28px}
/* Инциденты — тоже карточка: на сайте список чего-либо всегда живёт в панели,
   а здесь строки шли по голому фону, начинаясь левее всего остального. */
.sp-incs{padding:14px 16px;border:1px solid var(--line);border-radius:12px;background:var(--panel2);margin:18px 0 0}
.sp-incs h2{margin:0 0 8px}
.sp-inc li:first-child{border-top:0;padding-top:2px}
.sp-inc li:last-child{border-bottom:0;padding-bottom:2px}

/* ── v7.40: СВОИ ТЕКСТЫ СООБЩЕНИЙ ─────────────────────────────────────────
   Правило 7.35 красит зелёным ЛЮБУЮ кнопку .auth-form — включая «Вернуть
   заводские», которая по смыслу вторая. Возвращаем ей призрачный вид тем же
   способом, каким он задан в кабинете, и не трогаем общее правило. */
.auth-form button.cab-btn-ghost{background:transparent;border:1px solid rgba(255,255,255,.18);color:var(--ink);box-shadow:none}
.auth-form button.cab-btn-ghost:hover{background:rgba(255,255,255,.08)}
.cab-tpl textarea{font-size:13px;line-height:1.45;min-height:0}
.cab-tpl textarea[disabled]{opacity:.6}

/* ── v7.41: SMS И ЗВОНОК В КАБИНЕТЕ ───────────────────────────────────────
   Подпись «на какие события» вне <label> не попадала под правило подсказки и
   вырастала до кегля обычного текста — рядом с такой же подсказкой выше это
   читалось как два разных уровня там, где уровень один. */
.cab-sms-ev{display:grid;gap:4px;margin:2px 0 6px}
.cab-sms-ev>.auth-hint{font-size:12.5px;color:var(--muted)}
.cab-sms-ev .auth-accept{margin:0}

/* ── v7.42: СЛУЖЕБНЫЕ ТАБЛИЦЫ АДМИНКИ ────────────────────────────────────
   Узкие колонки (дата, размер, «скачать») в таблице во всю ширину ужимались
   до одной буквы в строку — из-за длинного соседа. Запрещаем перенос везде,
   кроме последней содержательной колонки, и отдаём ей остаток ширины. */
.adm-nowrap td,.adm-nowrap th{white-space:nowrap}
.adm-nowrap .adm-wide{white-space:normal;width:99%}
.adm-nowrap.ag-tbl{table-layout:auto}
