/* Дозор 404 — стили. Шапка/тема/футер — паттерн от FC.
 * Контент-сетка карточек и детальная страница — наши. */

:root {
  --bg-page: #0a0a0b;
  --bg-card: #131314;
  --bg-elev: #18181c;
  --bg-input: #1a1a1e;
  --text-primary: #e6e6e6;
  --text-bright: #fff;
  --text-secondary: #a0a0a8;
  --text-faint: #71717a;
  --text-hover: #fff;
  --border-line: rgba(255,255,255,0.10);
  --border-card: rgba(255,255,255,0.08);
  --accent: #C50F35;
  --accent-from: #C50F35;
  --accent-to: #690B1F;
  --st-ok-bg: rgba(56,176,77,0.16);
  --st-ok-fg: #4ade80;
  --st-partial-bg: rgba(245,158,11,0.18);
  --st-partial-fg: #fbbf24;
  --st-fail-bg: rgba(197,15,53,0.20);
  --st-fail-fg: #f87171;
  --st-none-bg: rgba(127,127,127,0.16);
  --st-none-fg: #a0a0a8;
}
html[data-theme="light"] {
  --bg-page: #fafafa;
  --bg-card: #ffffff;
  --bg-elev: #f4f4f6;
  --bg-input: #f0f0f3;
  --text-primary: #18181b;
  --text-bright: #0a0a0b;
  --text-secondary: #525258;
  --text-faint: #71717a;
  --text-hover: #18181b;
  --border-line: rgba(0,0,0,0.10);
  --border-card: rgba(0,0,0,0.08);
}

* { box-sizing: border-box; }
html, body { margin:0; padding:0; }
body {
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  min-height: 100vh;
  -webkit-tap-highlight-color: transparent;
}
a { color: inherit; text-decoration: none; }
a:hover { color: var(--text-hover); }

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 20px; }

/* ── Header ── */
.sticky-hdr { position: sticky; top: 0; z-index: 20; backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); background: color-mix(in srgb, var(--bg-page) 75%, transparent); border-bottom: 1px solid var(--border-line); }
.hdr-row { display:flex; align-items:center; justify-content:space-between; padding: 14px 20px; }
.brand { display: inline-flex; align-items: flex-end; gap: 10px; color: var(--text-bright); }
.brand > img:first-child { border-radius: 5px; display: block; width: 28px; height: 28px; flex-shrink: 0; }
/* Wordmark прижат по нижней грани favicon (`align-items: flex-end` выше);
 * высота ~22px = ~80% от favicon — крупно, но не перекрывает иконку. */
.brand-wordmark { display: block; height: 22px; width: auto; margin-bottom: -1px; }
html[data-theme="light"] .brand-wordmark { filter: invert(1); }
.hdr-actions { display:flex; align-items:center; gap:6px; }
.icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 7px; border: none; background: transparent; color: var(--text-secondary); border-radius: 8px; cursor: pointer; transition: background .12s ease, color .12s ease; }
.icon-btn:hover { background: var(--bg-elev); color: var(--text-bright); }
.icon-btn svg { width: 100%; height: 100%; }
.theme-ico-sun { display: none; }
html[data-theme="light"] .theme-ico-moon { display: none; }
html[data-theme="light"] .theme-ico-sun  { display: block; }

/* ── Hero ── */
.hero { padding: 40px 0 16px; text-align: left; }
.hero h1 { font-size: clamp(28px, 4vw, 40px); margin: 0 0 12px; font-weight: 700; letter-spacing: -0.02em; color: var(--text-bright); }
.hero .lead { font-size: clamp(15px, 1.6vw, 17px); margin: 0; max-width: 720px; color: var(--text-secondary); line-height: 1.55; }

/* ── Toolbar: search + categories + meta/sort ── */
.toolbar { margin: 28px 0 16px; }
#search { width: 100%; padding: 13px 16px; font-size: 15px; background: var(--bg-input); color: var(--text-bright); border: 1px solid var(--border-line); border-radius: 10px; outline: none; transition: border-color .12s ease; }
#search:focus { border-color: var(--accent); }
#search::placeholder { color: var(--text-faint); }

.cat-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 0; }
.cat-chip { padding: 7px 12px; font-size: 13px; font-weight: 500; background: var(--bg-elev); color: var(--text-secondary); border: 1px solid transparent; border-radius: 8px; cursor: pointer; transition: background .12s ease, color .12s ease, border-color .12s ease; white-space: nowrap; }
.cat-chip:hover { color: var(--text-bright); }
.cat-chip.active { background: linear-gradient(135deg, var(--accent-from), var(--accent-to)); color: #fff; box-shadow: 0 4px 12px -4px rgba(197,15,53,.6); }

/* sr-only: для текста, который виден краулерам и скринридерам, но скрыт
 * визуально. Применяется к H1, который дублирует SVG-логотип в шапке. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

.meta-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; font-size: 13px; color: var(--text-secondary); flex-wrap: wrap; }
.meta-stat { font-weight: 500; }
.sort-toggle { display: inline-flex; background: var(--bg-elev); border-radius: 8px; padding: 2px; }
.sort-btn { padding: 6px 12px; font-size: 12.5px; font-weight: 600; background: transparent; color: var(--text-secondary); border: none; border-radius: 6px; cursor: pointer; transition: background .12s ease, color .12s ease; }
.sort-btn:hover { color: var(--text-bright); }
.sort-btn.sort-active { background: var(--bg-page); color: var(--text-bright); box-shadow: 0 1px 3px rgba(0,0,0,.2); }
html[data-theme="light"] .sort-btn.sort-active { background: #fff; }

/* ── Grid + cards ── */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; margin-top: 20px; }
.grid-empty { padding: 40px 0; text-align: center; color: var(--text-faint); }
.card { display: flex; flex-direction: column; gap: 10px; padding: 14px; background: var(--bg-card); border: 1px solid var(--border-card); border-radius: 10px; cursor: pointer; transition: transform .12s ease, border-color .12s ease, background .12s ease; text-align: left; color: inherit; }
.card:hover { transform: translateY(-2px); border-color: var(--accent); background: var(--bg-elev); }
.card-row { display: flex; align-items: center; gap: 12px; }
.card-ico { width: 36px; height: 36px; border-radius: 8px; flex-shrink: 0; background: var(--bg-elev); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.card-ico img { width: 100%; height: 100%; object-fit: contain; }
.card-body { flex: 1; min-width: 0; }
.card-title { font-size: 14px; font-weight: 600; color: var(--text-bright); margin: 0 0 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-meta { font-size: 12px; color: var(--text-faint); display: flex; gap: 8px; align-items: center; }
.card-pct { font-weight: 600; }
.card-chart { color: var(--text-faint); }
.mini-chart { display: block; width: 100%; height: 18px; }

/* Status badges (used in both card and detail header). */
.st { display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.st::before { content:""; width:6px; height:6px; border-radius:50%; }
.st-ok { background: var(--st-ok-bg); color: var(--st-ok-fg); }
.st-ok::before { background: var(--st-ok-fg); }
.st-partial { background: var(--st-partial-bg); color: var(--st-partial-fg); }
.st-partial::before { background: var(--st-partial-fg); }
.st-fail { background: var(--st-fail-bg); color: var(--st-fail-fg); }
.st-fail::before { background: var(--st-fail-fg); }
.st-none { background: var(--st-none-bg); color: var(--st-none-fg); }
.st-none::before { background: var(--st-none-fg); }

/* ── Detail page ── */
.detail-head { display: flex; align-items: center; gap: 16px; padding: 24px 0 16px; flex-wrap: wrap; }
.detail-back { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; background: var(--bg-elev); color: var(--text-bright); border: 1px solid var(--border-line); border-radius: 8px; font-size: 13px; font-weight: 600; cursor: pointer; }
.detail-back:hover { background: var(--bg-card); }
.detail-ico { width: 48px; height: 48px; border-radius: 10px; background: var(--bg-elev); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.detail-ico img { width: 100%; height: 100%; object-fit: contain; }
.detail-title { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.detail-name { font-size: 22px; font-weight: 700; color: var(--text-bright); margin: 0; }
.detail-cat { font-size: 13px; color: var(--text-secondary); }

.detail-section { margin: 24px 0; padding: 20px; background: var(--bg-card); border: 1px solid var(--border-card); border-radius: 12px; }
.detail-section h3 { font-size: 14px; font-weight: 700; color: var(--text-bright); margin: 0 0 12px; text-transform: uppercase; letter-spacing: 0.06em; }
.detail-pct-big { font-size: 36px; font-weight: 700; color: var(--text-bright); margin: 4px 0 4px; line-height: 1; }
.detail-pct-label { font-size: 12px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.06em; }

.chart-wrap { position: relative; margin-top: 16px; }
.chart-wrap svg { display: block; width: 100%; height: auto; max-height: 240px; }
.chart-axis { font-size: 10px; fill: var(--text-faint); }
.chart-bar { fill: var(--accent); opacity: 0.85; }
.chart-grid { stroke: var(--border-line); stroke-dasharray: 2 4; }

.kv-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; }
.kv { display: flex; flex-direction: column; gap: 4px; padding: 12px 14px; background: var(--bg-elev); border-radius: 8px; }
.kv-k { font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; }
.kv-v { font-size: 16px; font-weight: 600; color: var(--text-bright); }
.kv-v small { font-size: 11px; font-weight: 500; color: var(--text-secondary); margin-left: 4px; }

.detail-foot { font-size: 13px; color: var(--text-secondary); padding: 16px 0; border-top: 1px solid var(--border-line); }
.detail-foot a { color: var(--accent); }
.detail-foot a:hover { text-decoration: underline; }
.detail-foot p { margin: 4px 0; }

/* ── Spoiler / Показать ещё ── */
/* `display:flex` иначе перебивает HTML-атрибут `hidden` (его дефолтный
 * `display:none` имеет более низкую специфичность чем класс) — поэтому
 * явно прячем через атрибут-селектор, чтобы more.hidden=true реально
 * скрывал блок когда все карточки уже показаны. */
.grid-more { margin: 20px 0 0; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.grid-more[hidden] { display: none; }
.grid-empty[hidden] { display: none; }
.show-more { display: inline-flex; align-items: center; gap: 8px; padding: 11px 22px; background: linear-gradient(135deg, var(--accent-from), var(--accent-to)); color: #fff; border: none; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer; box-shadow: 0 6px 16px -4px rgba(197,15,53,.45); transition: transform .12s ease, box-shadow .12s ease, filter .12s ease; }
.show-more:hover { filter: brightness(1.08); transform: translateY(-1px); box-shadow: 0 8px 20px -4px rgba(197,15,53,.55); }
.show-more strong { font-weight: 700; }
.show-more-arrow { font-size: 12px; opacity: .85; }
.show-more-meta { font-size: 12px; color: var(--text-faint); }

/* ── Other services block (cross-promo) ── */
.other-section { margin: 56px 0 32px; }
.other-section h2 { font-size: clamp(22px, 3vw, 28px); margin: 0 0 20px; font-weight: 600; letter-spacing: -0.01em; color: var(--text-bright); }
.other-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
.other-card { display: flex; flex-direction: column; gap: 10px; padding: 22px; background: var(--bg-card); border: 1px solid var(--border-card); border-radius: 12px; color: inherit; text-decoration: none; transition: transform .15s ease, border-color .15s ease, background .15s ease; }
.other-card:hover { transform: translateY(-2px); border-color: var(--accent); background: var(--bg-elev); }
.other-card__badge { align-self: flex-start; font-size: 11px; font-weight: 600; padding: 4px 10px; border-radius: 4px; background: rgba(197,15,53,0.15); color: var(--accent); text-transform: uppercase; letter-spacing: 0.06em; }
.other-card h3 { font-size: 20px; margin: 0; font-weight: 600; letter-spacing: -0.01em; color: var(--text-bright); }
.other-card p { font-size: 14px; line-height: 1.5; margin: 0; color: var(--text-secondary); flex: 1; }
.other-card__cta { font-size: 14px; font-weight: 500; color: var(--accent); margin-top: 4px; }

/* ── Footer (centered) ── */
.footer { margin-top: 56px; padding: 28px 0 36px; border-top: 1px solid var(--border-line); color: var(--text-secondary); font-size: 13px; text-align: center; }
.footer p { margin: 4px 0; }
.footer a { color: var(--text-hover); font-weight: 600; }
.footer a:hover { color: var(--accent); }

/* ── Telegram Mini App safe-area ── */
body.tg-fs { padding-top: var(--tg-safe-area-inset-top, env(safe-area-inset-top, 0)); padding-bottom: var(--tg-safe-area-inset-bottom, env(safe-area-inset-bottom, 0)); }

/* ── Preloader (1:1 from FC status-node, swapped fist → dino) ──────────
 * Red gradient rect reveals from bottom (clip-path), dino jumps in from
 * below, Дозор 404 wordmark slides in from the right. Hidden by adding
 * `.done` class on body once app.js finishes init. */
#preloader{position:fixed;inset:0;z-index:99999;background:#0a0a0b;display:flex;align-items:center;justify-content:center;opacity:1;transition:opacity .6s cubic-bezier(.4,0,.2,1)}
#preloader::before{content:'';position:absolute;inset:0;background:url('/static/backround-main.svg') center/cover no-repeat;opacity:1;pointer-events:none;animation:plBgDim 1.8s cubic-bezier(.4,0,.2,1) .2s forwards}
#preloader.done{opacity:0;pointer-events:none}
.pl-wrap{display:flex;align-items:stretch;gap:28px;position:relative;z-index:1}
.pl-icon{position:relative;width:160px;height:160px;flex-shrink:0;overflow:hidden}
.pl-rect{position:relative;width:160px;height:160px;clip-path:inset(100% 0 0 0);animation:plRevealRect .9s cubic-bezier(.22,1,.36,1) .15s forwards;border-radius:12px;overflow:hidden}
.pl-rect svg{width:100%;height:100%;display:block}
.pl-rect::after{content:'';position:absolute;inset:0;border-radius:12px;background:linear-gradient(135deg,rgba(255,255,255,.08) 0%,rgba(255,255,255,.03) 40%,transparent 55%);box-shadow:inset 0 0 0 1px rgba(255,255,255,.06),inset 0 1px 1px rgba(255,255,255,.07);pointer-events:none}
/* Static "stage" layers inside the red square. Both SVGs are 512×512 with
 * the same canvas as the rect, so a full-cover absolute position lines
 * them up to the rect's edges with no scale juggling.
 * Grass: stays in place, just fades in once the rect is fully open.
 * Dino:  starts off-canvas left, slides right into the scene. */
.pl-grass,.pl-dino{position:absolute;inset:0;width:100%;height:100%;display:block;object-fit:contain;image-rendering:pixelated;-webkit-mask-image:linear-gradient(#000,#000);pointer-events:none}
.pl-grass{opacity:0;animation:plGrassIn .5s cubic-bezier(.22,1,.36,1) .85s forwards}
/* Парабола + микро-отскоки. Linear timing — кривую рисуют сами keyframes,
 * percent-based translateY (% от высоты пл-rect) даёт корректную дугу и
 * на мобилке, и на десктопе без отдельных breakpoints. После приземления
 * два маленьких отскока (~1.5%, потом ~0.6%) — пиксель-арт «дзынь-дзынь». */
.pl-dino{opacity:0;transform-origin:bottom center;transform:translate(-120%,0) scale(.8);animation:plDinoJump .6s linear 1.05s forwards}
@keyframes plGrassIn{to{opacity:1}}
/* Жёсткий 8-битный прыжок: scale 0.8→1.0 (как будто выпрыгивает из-за
 * кадра «издалека»), параболическая дуга, squash на приземлении и два
 * микро-отскока. Linear timing для механического pixel-art feel'а. */
@keyframes plDinoJump{
  0%   {opacity:0;transform:translate(-120%,0) scale(.8)}
  6%   {opacity:1;transform:translate(-105%,-2%) scale(.82)}
  /* Восходящая ветвь параболы (X быстро, Y растёт, scale тоже растёт) */
  20%  {transform:translate(-82%,-12%) scale(.87)}
  35%  {transform:translate(-55%,-20%) scale(.92)}
  /* Пик дуги */
  45%  {transform:translate(-38%,-22%) scale(.95)}
  /* Нисходящая ветвь — Y падает быстрее (гравитация), scale добирает */
  60%  {transform:translate(-18%,-14%) scale(.98)}
  73%  {transform:translate(-5%,-3%) scale(1)}
  /* Приземление с лёгким сжатием (squash) */
  80%  {transform:translate(0,1%) scale(1)}
  /* Отскок 1 (~1.5% вверх) */
  86%  {transform:translate(0,-1.5%) scale(1)}
  90%  {transform:translate(0,0.5%) scale(1)}
  /* Отскок 2 (мельче — ~0.6%) */
  94%  {transform:translate(0,-0.6%) scale(1)}
  98%  {transform:translate(0,0.2%) scale(1)}
  100% {opacity:1;transform:translate(0,0) scale(1)}
}
.pl-text{display:flex;flex-direction:column;justify-content:space-between;padding:6px 0}
.pl-title{height:115px;opacity:0;transform:translateX(60px);animation:plSlideText .85s cubic-bezier(.22,1,.36,1) .75s forwards}
.pl-title svg,.pl-title img{height:100%;width:auto;display:block}
.pl-sub{height:16px;align-self:flex-end;opacity:0;transform:translateX(40px);animation:plSlideText .85s cubic-bezier(.22,1,.36,1) 1.05s forwards}
.pl-sub svg{height:100%;width:auto;display:block}
@keyframes plRevealRect{to{clip-path:inset(0 0 0 0)}}
@keyframes plFistUp{to{opacity:1;transform:translate(-50%,0%)}}
@keyframes plSlideText{to{opacity:1;transform:translateX(0)}}
@keyframes plBgDim{to{opacity:.4}}
@media (max-width:540px){
  .pl-wrap{gap:16px}
  .pl-icon{width:96px;height:96px}
  .pl-rect{width:96px;height:96px}
  .pl-fist{height:80%;transform:translate(-50%,24px)}
  .pl-text{padding:4px 0}
  .pl-title{height:68px}
  .pl-sub{height:10px}
}

/* ── Mobile ── */
@media (max-width: 540px) {
  .wrap { padding: 0 14px; }
  .hero { padding: 28px 0 12px; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; }
  .card { padding: 12px; gap: 10px; }
  .card-ico { width: 32px; height: 32px; }
  .detail-section { padding: 16px; }
  .detail-pct-big { font-size: 30px; }
}
