/* ============================================================
   ЛЕКАЛО — дизайн-система
   Тёплая бумага + чернила + ржавчина. Не тех-синий, не глянец.
   ============================================================ */

/* Golos Text — официальный шрифт Госуслуг / mos.ru. Вариативный (веса 400–700
   в одном файле), самохостинг из site/fonts/ — без внешней зависимости от Google
   (не блокирует рендер, не течёт к третьим лицам). 4 субсета Юникода; ₽ (U+20BD)
   попадает в latin-ext. */
@font-face {
  font-family: "Golos Text"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("../fonts/golos-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Golos Text"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("../fonts/golos-cyrillic-ext.woff2") format("woff2");
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Golos Text"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("../fonts/golos-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Golos Text"; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url("../fonts/golos-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* поверхности */
  --paper: #f5f0e5;
  --paper-alt: #ece4d3;
  --paper-deep: #e1d7c0;
  --white: #fffdf9;

  /* текст */
  --ink: #1f1b15;
  --ink-soft: #57503f;
  --ink-faint: #857b69;

  /* акценты */
  --rust: #b3401f;
  --rust-dark: #8f3018;
  --rust-tint: #f3e1d7;
  --brass: #a97c25;
  --brass-tint: #f2e6c8;
  --sage: #4c6b4f;
  --sage-tint: #e3ecdf;

  /* статусы вердикта */
  --ok: #3f6a45;
  --ok-bg: #e2ecdf;
  --gap: #a9762e;
  --gap-bg: #f4e8ce;
  --bad: #96362a;
  --bad-bg: #f1ddd6;

  --line: #dcceb1;
  --line-soft: #e8dfca;

  /* Тени двухслойные и тёплые (не серые): близкий контактный слой + мягкий
     дальний. На кремовой бумаге нейтрально-серая тень выглядит грязной. */
  --shadow-xs: 0 1px 1px rgba(58, 38, 14, 0.05);
  --shadow-sm: 0 1px 2px rgba(58, 38, 14, 0.06), 0 2px 6px rgba(58, 38, 14, 0.05);
  --shadow-md: 0 2px 4px rgba(58, 38, 14, 0.05), 0 8px 22px rgba(58, 38, 14, 0.09);
  --shadow-lg: 0 4px 8px rgba(58, 38, 14, 0.06), 0 22px 50px rgba(58, 38, 14, 0.15);
  --shadow-rust: 0 2px 5px rgba(143, 48, 24, 0.18), 0 10px 26px rgba(143, 48, 24, 0.20);

  /* фокус-кольцо одним токеном — раньше писалось руками в 4 местах */
  --ring: 0 0 0 3px rgba(179, 64, 31, 0.22);

  --radius-xs: 6px;
  --radius-sm: 9px;
  --radius-md: 13px;
  --radius-lg: 18px;
  --radius-xl: 26px;

  /* Движение. Один ease на всё, три длительности — иначе анимации «разъезжаются». */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 130ms;
  --dur: 240ms;
  --dur-slow: 620ms;

  /* Зерно бумаги: feTurbulence в data-URI. Одна фоновая прослойка вместо
     прежней «сетки в горошек» — та читалась как декор, а не как материал. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.055'/%3E%3C/svg%3E");
  --grain-size: 180px 180px;

  --font-display: "Golos Text", -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Golos Text", -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;

  --container: 1180px;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Тёмная тема — не «чёрная», а густые чернила с той же тёплой осью.
       Поверхности идут вверх по светлоте (paper → white), чтобы карточка
       на фоне читалась без опоры на границу. */
    --paper: #17130d;
    --paper-alt: #1f1a12;
    --paper-deep: #2b2418;
    --white: #231d15;
    --ink: #f4ecdb;
    --ink-soft: #cec3ab;
    --ink-faint: #978b70;
    --rust: #e8794a;
    --rust-dark: #f5936a;
    --rust-tint: #3b2419;
    --brass: #d9ae4f;
    --brass-tint: #342a1a;
    --sage: #94b594;
    --sage-tint: #212b20;
    --ok: #94b594;
    --ok-bg: #212b20;
    --gap: #d9ae4f;
    --gap-bg: #342a19;
    --bad: #e88b74;
    --bad-bg: #37221c;
    --line: #40361f;
    --line-soft: #2e2718;
    --shadow-xs: 0 1px 1px rgba(0, 0, 0, 0.4);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 6px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.4), 0 8px 22px rgba(0, 0, 0, 0.42);
    --shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.45), 0 22px 50px rgba(0, 0, 0, 0.6);
    --shadow-rust: 0 2px 5px rgba(0, 0, 0, 0.4), 0 10px 26px rgba(232, 121, 74, 0.22);
    --ring: 0 0 0 3px rgba(232, 121, 74, 0.28);
    /* на тёмном зерно должно светлеть, а не темнить */
    --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.35 0.35 0.35 0 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
  }
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 92px; }

body {
  margin: 0;
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Зерно `fixed`: при скролле оно стоит на месте, поэтому читается как фактура
     самого листа, а не как ползущий узор поверх контента. */
  background-image: var(--grain);
  background-size: var(--grain-size);
  background-attachment: fixed;
}

img, svg { display: block; max-width: 100%; }

a { color: inherit; }

::selection { background: var(--rust); color: #fff; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.15;
  margin: 0 0 0.5em;
  /* Оптический трекинг: чем крупнее кегль, тем плотнее — иначе крупные
     заголовки выглядят разболтанными, а мелкие слипаются. */
  letter-spacing: -0.022em;
  text-wrap: balance;
}
h3 { letter-spacing: -0.014em; }
h4, h5 { letter-spacing: -0.006em; }

p { margin: 0 0 1em; color: var(--ink-soft); text-wrap: pretty; }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 28px;
}

:focus-visible {
  outline: 2px solid var(--rust);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Полосы прокрутки в тон бумаге — дефолтные системные рвут тёплую гамму. */
* { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); background-clip: content-box; }

/* ---------- topbar / nav ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
/* Шапка «отрывается» от страницы только после прокрутки: в самом верху линия и
   тень лишние, они режут геро-блок пополам. Порог ловим без JS — sentinel-элемент
   не нужен, хватает animation-timeline там, где он есть. */
@supports (animation-timeline: scroll()) {
  .site-header {
    animation: header-lift linear both;
    animation-timeline: scroll();
    animation-range: 0 90px;
  }
  @keyframes header-lift {
    from { border-bottom-color: transparent; box-shadow: none; }
    to { border-bottom-color: var(--line-soft); box-shadow: var(--shadow-sm); }
  }
}
@supports not (animation-timeline: scroll()) {
  .site-header { border-bottom-color: var(--line-soft); }
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 76px;
  gap: 24px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  color: var(--ink);
  flex-shrink: 0;
}
.brand__mark {
  width: 34px; height: 34px;
  transition: transform var(--dur) var(--ease-out);
}
.brand:hover .brand__mark { transform: rotate(-8deg) scale(1.06); }
.brand__word {
  font-family: var(--font-display);
  font-size: 1.36rem;
  font-weight: 700;
  letter-spacing: -0.025em;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: 30px;
  font-size: 0.95rem;
}
.main-nav a {
  position: relative;
  text-decoration: none;
  color: var(--ink-soft);
  padding: 6px 0;
  transition: color var(--dur-fast) var(--ease);
}
/* Подчёркивание выезжает из центра, а не мигает целиком — раньше это был
   border-bottom, который появлялся скачком. */
.main-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1.5px;
  background: var(--rust);
  transform: scaleX(0);
  transition: transform var(--dur) var(--ease-out);
}
.main-nav a:hover { color: var(--ink); }
.main-nav a:hover::after { transform: scaleX(1); }

.header-actions { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }

/* ---------- buttons ---------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 22px;
  border-radius: 999px;
  font-size: 0.94rem;
  font-weight: 600;
  font-family: var(--font-body);
  letter-spacing: -0.005em;
  cursor: pointer;
  border: 1px solid transparent;
  text-decoration: none;
  white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur) var(--ease),
              background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(1px); transition-duration: 60ms; }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }

.btn-primary {
  /* Мягкий вертикальный градиент + внутренний блик сверху: плоская заливка на
     тёплой бумаге выглядит наклейкой, здесь кнопка получает объём. */
  background-image: linear-gradient(180deg,
    color-mix(in srgb, var(--rust) 92%, #fff) 0%,
    var(--rust) 55%,
    color-mix(in srgb, var(--rust) 88%, var(--rust-dark)) 100%);
  background-color: var(--rust);
  color: var(--white);
  box-shadow: var(--shadow-sm), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.btn-primary:hover {
  background-color: var(--rust-dark);
  box-shadow: var(--shadow-rust), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
/* Блик пробегает по кнопке при наведении. Живость без суеты: движется свет,
   а не сама кнопка. overflow скрывает блик за скруглением. */
.btn-primary { overflow: hidden; isolation: isolate; }
.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 35%,
              rgba(255, 255, 255, 0.32) 50%, transparent 65%);
  transform: translateX(-120%);
  transition: transform 620ms var(--ease-out);
  pointer-events: none;
  z-index: -1;
}
.btn-primary:hover::after { transform: translateX(120%); }
.btn-primary:focus-visible { box-shadow: var(--ring), var(--shadow-rust); }

.btn-ghost {
  background: color-mix(in srgb, var(--white) 60%, transparent);
  color: var(--ink);
  border-color: var(--line);
}
.btn-ghost:hover { border-color: var(--rust); color: var(--rust); background: var(--white); box-shadow: var(--shadow-sm); }

.btn-quiet {
  background: transparent;
  color: var(--ink-soft);
  padding: 11px 6px;
}
.btn-quiet:hover { color: var(--rust); }

.btn-sm { padding: 7px 15px; font-size: 0.84rem; }
.btn-block { width: 100%; }

/* ---------- hero ---------- */

.hero {
  position: relative;
  padding: 84px 0 76px;
  overflow: hidden;
}
/* Тёплое свечение за геро-блоком: даёт глубину и уводит взгляд к карточке-вердикту.
   Держим его на самой секции, а не на body — на страницах приложения оно не нужно. */
.hero::before {
  content: "";
  position: absolute;
  top: -30%; right: -10%;
  width: 70vw; height: 120%;
  background:
    radial-gradient(45% 50% at 60% 45%, color-mix(in srgb, var(--rust) 22%, transparent) 0%, transparent 70%),
    radial-gradient(40% 45% at 85% 70%, color-mix(in srgb, var(--brass) 20%, transparent) 0%, transparent 72%);
  filter: blur(30px);
  pointer-events: none;
  z-index: 0;
}
.hero > .container {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 56px;
  align-items: center;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--rust);
  background: color-mix(in srgb, var(--rust-tint) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--rust) 22%, transparent);
  padding: 6px 14px;
  border-radius: 999px;
  margin-bottom: 22px;
}
.eyebrow::before {
  content: "";
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--rust);
  flex-shrink: 0;
}
/* Пульс — только у геро-надзаголовка: он значит «лента живая». Если пульсировать
   во всех секциях, страница начинает мигать в четырёх местах разом. */
.hero .eyebrow::before {
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--rust) 55%, transparent);
  animation: eyebrow-pulse 2.6s var(--ease) infinite;
}
@keyframes eyebrow-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--rust) 50%, transparent); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

.hero h1 {
  font-size: clamp(2.3rem, 4.6vw, 3.7rem);
  color: var(--ink);
  max-width: 16ch;
  letter-spacing: -0.032em;
  margin-bottom: 0.42em;
}
/* Подчёркивание акцента — от руки, лекальной кривой, а не прямой линией:
   проект называется «Лекало», это его подпись. */
.hero h1 em {
  font-style: normal;
  color: var(--rust);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 12' preserveAspectRatio='none'%3E%3Cpath d='M2 8.5 C40 2.5 78 2 108 5 C138 8 170 9.5 198 4' fill='none' stroke='%23b3401f' stroke-width='3.2' stroke-linecap='round' opacity='0.42'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 0.28em;
  padding-bottom: 0.1em;
}

.hero-lede {
  font-size: 1.14rem;
  line-height: 1.62;
  max-width: 46ch;
  margin-bottom: 30px;
}

.hero-actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 38px;}

.hero-note { font-size: 0.86rem; color: var(--ink-faint); }

.hero-stats {
  display: flex;
  gap: 14px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}
.hero-stat {
  flex: 1;
  min-width: 0;
  padding-left: 14px;
  border-left: 2px solid var(--rust);
}
.hero-stat:first-child { padding-left: 0; border-left: none; }
.hero-stat b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.3rem;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-bottom: 2px;
}
.hero-stat span { font-size: 0.82rem; color: var(--ink-faint); line-height: 1.45; display: block; }

/* hero visual: mock verdict card */
.hero-visual { position: relative; perspective: 1200px; }
.mock-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: 28px;
  position: relative;
  transform: rotate(-1.4deg);
  transition: transform var(--dur-slow) var(--ease-out), box-shadow var(--dur-slow) var(--ease-out);
}
/* Ленивое «дыхание» карточки в покое: очень малая амплитуда и длинный цикл —
   страница выглядит живой, но движение не ловит на себя взгляд и не мешает
   читать заголовок рядом. При наведении покачивание останавливается. */
@media (prefers-reduced-motion: no-preference) {
  .mock-card { animation: mock-float 7s ease-in-out 1.2s infinite; }
}
@keyframes mock-float {
  0%, 100% { transform: rotate(-1.4deg) translateY(0); }
  50%      { transform: rotate(-1deg) translateY(-7px); }
}
.hero-visual:hover .mock-card {
  /* Именно `animation: none`, а не `paused`: у работающей анимации transform
     приоритетнее обычного объявления, и на паузе карточка застыла бы в кадре
     покачивания, проигнорировав hover-состояние. Снимаем анимацию — и
     transition доводит трансформ до наведённого положения плавно. */
  animation: none;
  transform: rotate(-0.4deg) translateY(-8px);
  box-shadow: var(--shadow-lg), 0 34px 70px rgba(58, 38, 14, 0.12);
}
/* Двойная «стопка» бумаги под карточкой — второй лист чуть выглядывает.
   Раньше был один призрак; второй слой делает стопку читаемой. */
.mock-card::before,
.mock-card::after {
  content: "";
  position: absolute;
  inset: 14px -14px auto auto;
  width: 94%;
  height: 94%;
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  z-index: -1;
  transform: rotate(3deg);
  background: var(--paper-alt);
}
.mock-card::after {
  inset: 26px -26px auto auto;
  width: 90%; height: 90%;
  transform: rotate(6deg);
  background: var(--paper-deep);
  opacity: 0.6;
}
.mock-card__top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16px; }
.mock-card__score {
  font-family: var(--font-mono);
  font-size: 2.1rem;
  font-weight: 600;
  color: var(--ok);
  line-height: 1;
}
.mock-card__score span { font-size: 0.95rem; color: var(--ink-faint); font-family: var(--font-body); }
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 700;
  padding: 4px 11px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  /* Полупрозрачная граница в цвет текста: на белой карточке и на кремовой
     бумаге бейдж одинаково держит форму, без второго набора токенов. */
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
  white-space: nowrap;
}
.badge-ok { background: var(--ok-bg); color: var(--ok); }
.badge-gap { background: var(--gap-bg); color: var(--gap); }
.badge-bad { background: var(--bad-bg); color: var(--bad); }
.badge-unknown { background: var(--paper-deep); color: var(--ink-faint); }
.badge-source { background: var(--paper-deep); color: var(--ink-soft); }

.mock-card h4 { font-size: 1.02rem; margin-bottom: 4px; }
.mock-card .meta { font-size: 0.83rem; color: var(--ink-faint); margin-bottom: 16px; }

.check-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 0;
  border-top: 1px dashed var(--line);
  font-size: 0.87rem;
}
.check-row:first-of-type { border-top: none; }
.check-status { font-weight: 600; flex-shrink: 0; }
.check-status.ok { color: var(--ok); }
.check-status.gap { color: var(--gap); }

/* ---------- section shell ---------- */

section { padding: 92px 0; position: relative; }
.section-head { max-width: 660px; margin: 0 0 48px; }
.section-head .eyebrow { margin-bottom: 18px; }
.section-head h2 { font-size: clamp(1.8rem, 3.2vw, 2.5rem); }
.section-head p { font-size: 1.05rem; line-height: 1.62; }
.section-alt {
  background: var(--paper-alt);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
}
/* Тонкая световая линия по верхней кромке alt-секции: стык двух почти одинаковых
   кремовых плоскостей иначе читается как случайный шов. */
.section-alt::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--rust) 30%, transparent), transparent);
}

/* ---------- compare ---------- */

.compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  align-items: start;
}
.compare-col {
  position: relative;
  border-radius: var(--radius-xl);
  padding: 32px;
  border: 1px solid var(--line);
  overflow: hidden;
}
.compare-col.is-old { background: color-mix(in srgb, var(--paper) 60%, transparent); opacity: 0.82; }
.compare-col.is-new { background: var(--white); box-shadow: var(--shadow-md); border-color: color-mix(in srgb, var(--rust) 40%, var(--line)); }
/* Ржавая кромка сверху вместо обводки по всему периметру — рамка целиком
   спорила с карточками-тарифами ниже и делала блок «обведённым дважды». */
.compare-col.is-new::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--rust), var(--brass));
}
.compare-col h3 { font-size: 1.12rem; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.compare-col ul { margin: 20px 0 0; padding: 0; list-style: none; }
.compare-col li {
  display: flex; gap: 12px; padding: 11px 0;
  border-top: 1px solid var(--line-soft);
  font-size: 0.94rem; color: var(--ink-soft); line-height: 1.5;
}
.compare-col li:first-child { border-top: none; }
/* Маркеры-жетоны вместо голых символов: одинаковая ширина держит текст в колонку. */
.compare-col li::before {
  flex-shrink: 0;
  width: 20px; height: 20px;
  margin-top: 2px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.78rem; font-weight: 700; line-height: 1;
}
.compare-col.is-old li::before { content: "×"; color: var(--ink-faint); background: var(--paper-deep); }
.compare-col.is-new li::before { content: "✓"; color: var(--rust); background: var(--rust-tint); }
.pill-tag {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  background: var(--paper-deep);
  padding: 3px 8px;
  border-radius: 5px;
  color: var(--ink-soft);
}
.compare-col.is-new .pill-tag { background: var(--rust-tint); color: var(--rust); }

/* ---------- steps ---------- */

/* ---------- чернильная секция ----------
   Отдельный характер для «Как это работает»: тёмная полоса во всю ширину
   разбивает кремовую ленту и делает блок самостоятельной главой, а не
   продолжением лендинга. От финального призыва отличается тем, что тот —
   вставная скруглённая плашка, а этот идёт от края до края. */
.section-ink {
  background:
    radial-gradient(60% 90% at 15% 0%, color-mix(in srgb, var(--rust) 30%, transparent) 0%, transparent 60%),
    linear-gradient(165deg, #2c261d 0%, #1a1610 100%);
  color: var(--paper);
  border-top: none;
  border-bottom: none;
  isolation: isolate;
}
.section-ink::after {
  content: "";
  position: absolute; inset: 0;
  background-image: var(--grain);
  background-size: var(--grain-size);
  mix-blend-mode: screen;
  opacity: 0.5;
  pointer-events: none;
  z-index: -1;
}
.section-ink h2 { color: #fdf8ee; }
.section-ink .section-head p { color: rgba(246, 241, 230, 0.7); }
.section-ink .eyebrow {
  color: #f0a883;
  background: rgba(232, 121, 74, 0.12);
  border-color: rgba(232, 121, 74, 0.32);
}
.section-ink .eyebrow::before { background: #f0a883; }

/* ---------- steps как маршрут ---------- */

.steps {
  position: relative;
  display: grid;
  /* minmax(0, 1fr), а не 1fr: у трека 1fr неявный min-width:auto, поэтому он
     не сжимается ниже min-content содержимого и сетка вылезает за контейнер. */
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0;
}
/* Линия маршрута проходит через центры узлов. Гасим её на краях градиентом,
   чтобы она не упиралась в поля контейнера обрубленным концом. */
.steps::before {
  content: "";
  position: absolute;
  top: 23px; left: 8%; right: 8%;
  height: 2px;
  background: linear-gradient(90deg,
    transparent, rgba(232, 121, 74, 0.55) 12%, rgba(232, 121, 74, 0.55) 88%, transparent);
}
.step {
  position: relative;
  padding: 0 14px;
  text-align: center;
}
/* Узел маршрута: номер внутри кружка прямо на линии. */
.step__num {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  margin: 0 auto 16px;
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0;
  color: #f6efe2;
  background: #221c14;
  border: 2px solid rgba(232, 121, 74, 0.5);
  -webkit-text-stroke: 0;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.step:hover .step__num {
  background: var(--rust);
  border-color: var(--rust);
  color: #fff;
  box-shadow: 0 0 0 6px rgba(232, 121, 74, 0.16);
}
.step h4 {
  font-size: 0.98rem;
  margin-bottom: 7px;
  color: #fdf8ee;
  transition: color var(--dur) var(--ease);
}
.step p {
  font-size: 0.86rem;
  margin: 0;
  line-height: 1.55;
  color: rgba(246, 241, 230, 0.62);
  transition: color var(--dur) var(--ease);
}
.step:hover p { color: rgba(246, 241, 230, 0.85); }

/* ---------- sources ---------- */

.sources-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.source-chip {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 11px 20px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--ink-soft);
  box-shadow: var(--shadow-xs);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.source-chip:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: color-mix(in srgb, var(--rust) 45%, var(--line));
  color: var(--ink);
}
.source-chip .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--rust); flex-shrink: 0;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--rust) 16%, transparent);
}

/* ---------- pricing ---------- */

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
  align-items: stretch;
}
.price-card {
  position: relative;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  padding: 34px 30px;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-xs);
  /* Своя длительность: подъём карточки — жест крупный, на общих 240мс он
     выходит дёрганым. 420мс на ease-out читается как «лист поднимают», а не
     «блок прыгнул». Отдельные свойства, а не `all`, — иначе браузер
     анимирует и то, что меняться не должно. */
  /* БЕЗ scale() и БЕЗ will-change — иначе текст на карточке мылит:
     1) scale() браузер применяет к уже растрированному слою, а не
        перерисовывает — буквы получаются растянутой картинкой;
     2) will-change: transform навсегда выносит карточку в отдельный слой,
        а на Windows это отключает субпиксельное сглаживание (ClearType),
        и текст выглядит мягче соседнего даже без наведения.
     Выход вперёд даём подъёмом и тенью: translateY на целое число пикселей
     ничего не пересэмплирует, текст остаётся идеально резким. */
  --lift: 0px;
  transform: translateY(var(--lift));
  transition: transform 420ms var(--ease-out), box-shadow 420ms var(--ease-out),
              border-color var(--dur) var(--ease), opacity 420ms var(--ease-out);
}
.price-card:hover {
  --lift: -12px;
  box-shadow: var(--shadow-lg), 0 30px 60px rgba(58, 38, 14, 0.10);
  border-color: color-mix(in srgb, var(--rust) 55%, var(--line));
  z-index: 2;
}
/* Соседи отступают, когда наводишь на любую карточку: выбранная выходит
   вперёд не только своим подъёмом, но и контрастом с остальными. Именно это
   даёт ощущение живой сетки, а не трёх независимых блоков.
   Приглушение — только прозрачностью: она не пересэмплирует пиксели, в отличие
   от уменьшающего scale, которым это делалось раньше. */
.pricing-grid:hover .price-card:not(:hover) { opacity: 0.62; }
.price-card.is-featured {
  border-color: color-mix(in srgb, var(--rust) 50%, var(--line));
  box-shadow: var(--shadow-lg);
  --lift: -10px;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--rust-tint) 55%, transparent) 0%, transparent 240px),
    var(--white);
}
.price-card.is-featured:hover { --lift: -20px; }

/* Внутренности реагируют вместе с карточкой — иначе поднимается «коробка»,
   а содержимое остаётся мёртвым. */
.price-card__price,
.price-card .btn,
.price-badge {
  transition: transform 420ms var(--ease-out), box-shadow 420ms var(--ease-out),
              color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.price-card:hover .price-card__price { transform: translateY(-2px); }
.price-card:hover .price-badge { transform: translateY(-3px); }
.price-card:hover .btn-ghost { border-color: var(--rust); color: var(--rust); background: var(--white); }
.price-card:hover .btn-primary { box-shadow: var(--shadow-rust), inset 0 1px 0 rgba(255, 255, 255, 0.2); }

/* Галочки проявляются очередью — короткая волна сверху вниз, читается как
   «список ожил». Задержки заданы только на hover, поэтому обратный ход
   происходит разом, без «раскручивания» волны назад. */
.price-card li::before { transition: box-shadow 260ms var(--ease-out), background-color 260ms var(--ease), color 260ms var(--ease); }
.price-card:hover li::before {
  background: color-mix(in srgb, var(--rust) 22%, var(--rust-tint));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--rust) 12%, transparent);
}
.price-card:hover li:nth-child(1)::before { transition-delay: 0ms; }
.price-card:hover li:nth-child(2)::before { transition-delay: 45ms; }
.price-card:hover li:nth-child(3)::before { transition-delay: 90ms; }
.price-card:hover li:nth-child(4)::before { transition-delay: 135ms; }
.price-card:hover li:nth-child(5)::before { transition-delay: 180ms; }
.price-card.is-featured::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; height: 3px;
  border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  background: linear-gradient(90deg, var(--rust), var(--brass));
}
/* бейдж «выбор большинства» — якорь взгляда в сетке из трёх равных карточек */
.price-badge {
  position: absolute;
  top: -12px; right: 24px;
  background: var(--rust);
  color: var(--white);
  font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 5px 13px;
  border-radius: 999px;
  box-shadow: var(--shadow-rust);
  white-space: nowrap;
}
.price-card__plan { font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-faint); font-weight: 700; }
.price-card__price {
  font-family: var(--font-display); font-size: 2.45rem; font-weight: 700;
  letter-spacing: -0.03em; margin: 10px 0 2px;
  font-variant-numeric: tabular-nums;
}
.price-card__price span { font-size: 1rem; font-family: var(--font-body); color: var(--ink-faint); font-weight: 400; letter-spacing: 0; }
.price-card__note { font-size: 0.85rem; color: var(--ink-faint); margin-bottom: 24px; line-height: 1.5; }
.price-card ul { list-style: none; padding: 0; margin: 0 0 28px; flex-grow: 1; }
.price-card li {
  display: flex; gap: 11px; padding: 10px 0;
  font-size: 0.9rem; color: var(--ink-soft); line-height: 1.5;
  border-top: 1px solid var(--line-soft);
}
.price-card li:first-child { border-top: none; }
.price-card li::before {
  content: "✓";
  flex-shrink: 0;
  width: 18px; height: 18px; margin-top: 2px;
  border-radius: 50%;
  background: var(--rust-tint); color: var(--rust);
  font-size: 0.72rem; font-weight: 700; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}

/* ---------- final cta ---------- */

/* Финальный призыв — чернильная плашка, а не просто текст по центру бумаги.
   Инверсия тона в конце страницы даёт остановку и делает кнопку неизбежной. */
.final-cta { padding: 40px 0 96px; }
.final-cta > .container {
  position: relative;
  text-align: center;
  padding: 76px 40px;
  border-radius: var(--radius-xl);
  background:
    radial-gradient(70% 120% at 50% 0%, color-mix(in srgb, var(--rust) 40%, transparent) 0%, transparent 62%),
    linear-gradient(180deg, #2b251c 0%, #1d1811 100%);
  color: var(--paper);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  isolation: isolate;
}
/* то же зерно, что и на бумаге — плашка должна быть из того же материала */
.final-cta > .container::before {
  content: "";
  position: absolute; inset: 0;
  background-image: var(--grain);
  background-size: var(--grain-size);
  opacity: 0.55;
  mix-blend-mode: screen;
  pointer-events: none;
  z-index: -1;
}
.final-cta h2 {
  font-size: clamp(1.9rem, 3.6vw, 2.7rem);
  max-width: 20ch;
  margin: 0 auto 16px;
  color: #fdf8ee;
}
.final-cta p {
  max-width: 46ch;
  margin: 0 auto 32px;
  font-size: 1.05rem;
  color: rgba(246, 241, 230, 0.72);
}
.final-cta .btn-primary { box-shadow: var(--shadow-rust), inset 0 1px 0 rgba(255, 255, 255, 0.22); }

/* ---------- footer ---------- */

.site-footer {
  border-top: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--paper-alt) 55%, transparent);
  padding: 54px 0 36px;
}
.footer-grid { display: flex; justify-content: space-between; align-items: flex-start; gap: 40px; flex-wrap: wrap; }
.footer-brand p { font-size: 0.88rem; max-width: 32ch; margin-top: 12px; line-height: 1.55; }
.footer-links { display: flex; gap: 56px; }
.footer-col h5 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--ink-faint); margin-bottom: 14px; }
.footer-col a {
  display: block; font-size: 0.9rem; color: var(--ink-soft);
  text-decoration: none; margin-bottom: 10px;
  transition: color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.footer-col a:hover { color: var(--rust); transform: translateX(3px); }
.footer-bottom { margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--line-soft); display: flex; justify-content: space-between; font-size: 0.8rem; color: var(--ink-faint); flex-wrap: wrap; gap: 10px;}

/* ================= AUTH / ONBOARDING PAGES ================= */

.auth-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.auth-side {
  background: var(--ink);
  color: var(--paper);
  padding: 54px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;
  overflow: hidden;
}
@media (prefers-color-scheme: dark) { .auth-side { background: var(--paper-deep); } }
.auth-side .brand { color: var(--paper); }
.auth-side__quote { max-width: 34ch; }
.auth-side__quote h3 { font-size: 1.5rem; color: var(--paper); line-height: 1.3; }
.auth-side__quote p { color: rgba(246,241,230,0.68); }
/* Знак-лекало как водяной знак: сильнее уходит за край и заметно тише по
   плотности — на новой чернильной панели прежние 0.14 читались серым пятном,
   а не фирменным элементом. */
.auth-side__curve {
  position: absolute;
  right: -130px; bottom: -120px;
  width: 460px;
  opacity: 0.07;
  transform: rotate(-12deg);
}

.auth-main {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
}
.auth-box { width: 100%; max-width: 420px; }
.auth-box h1 { font-size: 1.9rem; margin-bottom: 8px; }
.auth-box > p.lede { margin-bottom: 30px; }

.field { margin-bottom: 18px; }
.field label { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 7px; color: var(--ink); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--ink);
  font-size: 0.95rem;
  font-family: var(--font-body);
}
.field textarea { resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--rust); box-shadow: var(--ring); }
.field-hint { font-size: 0.78rem; color: var(--ink-faint); margin-top: 6px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

.auth-switch { margin-top: 24px; font-size: 0.9rem; color: var(--ink-soft); text-align: center; }
.auth-switch a { color: var(--rust); font-weight: 600; text-decoration: none; }

.form-error {
  background: var(--bad-bg);
  color: var(--bad);
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  font-size: 0.86rem;
  margin-bottom: 18px;
  display: none;
}
.form-error.is-visible { display: block; }

/* ================= APP SHELL ================= */

.app-shell { display: grid; grid-template-columns: 260px 1fr; min-height: 100vh; }

.app-sidebar {
  background: var(--paper-alt);
  border-right: 1px solid var(--line);
  padding: 22px 20px;
  display: flex;
  flex-direction: column;
  gap: 26px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  /* Внутренняя тень у правого края: сайдбар уходит «под» ленту, а не лежит
     с ней в одной плоскости — иначе граница читается просто как линия. */
  box-shadow: inset -12px 0 18px -14px rgba(58, 38, 14, 0.16);
}
.app-sidebar .brand { margin-bottom: 4px; }

.sidebar-block h5 {
  font-size: 0.71rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  margin: 0 0 12px;
  font-weight: 700;
}

.product-switch {
  border: 1px solid var(--line);
  background: var(--white);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  cursor: pointer;
}
.product-switch__label { font-size: 0.72rem; color: var(--ink-faint); }
.product-switch select { border: none; background: transparent; padding: 4px 0 0; font-weight: 700; font-size: 0.95rem; width: 100%; }
.product-switch select:focus { outline: none; }

.filter-group { margin-bottom: 18px; }
.filter-group label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 6px; }
.filter-group input[type="text"],
.filter-group input[type="number"],
.filter-group select {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
  font-size: 0.87rem;
  font-family: var(--font-body);
  color: var(--ink);
}
.filter-range { display: flex; align-items: center; gap: 8px; }
.filter-range input { width: 100%; }

.checklist { display: flex; flex-direction: column; gap: 8px; }
.checklist label { display: flex; align-items: center; gap: 9px; font-size: 0.87rem; font-weight: 500; color: var(--ink-soft); cursor: pointer; }
.checklist input { width: 15px; height: 15px; accent-color: var(--rust); }

.radio-pair { display: flex; gap: 8px; }
.radio-pair label {
  flex: 1;
  text-align: center;
  font-size: 0.82rem;
  font-weight: 600;
  padding: 8px 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--ink-soft);
  background: var(--white);
}
.radio-pair input { display: none; }
.radio-pair input:checked + span { color: var(--rust); }
.radio-pair label:has(input:checked) { border-color: var(--rust); background: var(--rust-tint); }

.sidebar-foot { margin-top: auto; }
.plan-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  font-size: 0.83rem;
}
.plan-card b { display: block; font-size: 0.92rem; margin-bottom: 2px; }
.plan-card a { color: var(--rust); font-weight: 600; text-decoration: none; font-size: 0.8rem; }

/* main app content */
.app-main { display: flex; flex-direction: column; min-height: 100vh; }

.app-topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 30px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--paper) 85%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  position: sticky;
  top: 0;
  z-index: 10;
}
.search-box {
  flex-grow: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 9px 16px;
  max-width: 420px;
  box-shadow: var(--shadow-xs);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
/* Поиск — главный инструмент экрана: при фокусе он должен явно «включаться».
   Раньше рамка не реагировала вообще, потому что input внутри снимает outline. */
.search-box:focus-within { border-color: var(--rust); box-shadow: var(--ring); }
.search-box:focus-within svg { opacity: 1; color: var(--rust); }
.search-box input { border: none; background: transparent; outline: none; flex: 1; min-width: 0; width: 100%; font-size: 0.9rem; color: var(--ink); }
.search-box input::placeholder { color: var(--ink-faint); }
.search-box svg { flex-shrink: 0; opacity: 0.5; transition: opacity var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease); }

.sort-select {
  border: 1px solid var(--line);
  background: var(--white);
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 0.86rem;
  color: var(--ink-soft);
}

.user-menu { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.user-avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--rust); color: var(--white);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.85rem; font-family: var(--font-display);
  flex-shrink: 0;
}
.user-name { font-size: 0.86rem; font-weight: 600; line-height: 1.2; }
.user-company { font-size: 0.76rem; color: var(--ink-faint); }

.feed-wrap { padding: 26px 30px 60px; max-width: 980px; }

.feed-header { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 18px; flex-wrap: wrap; gap: 10px;}
.feed-header h2 { font-size: 1.3rem; margin: 0; }
.feed-count { font-size: 0.86rem; color: var(--ink-faint); }

.tender-card {
  position: relative;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  margin-bottom: 14px;
  overflow: hidden;
  box-shadow: var(--shadow-xs);
  transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
/* Ржавая кромка слева выезжает при наведении и остаётся у раскрытой карточки —
   в длинной ленте это единственный якорь «где я сейчас». */
.tender-card::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--rust);
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform var(--dur) var(--ease-out);
}
.tender-card:hover { box-shadow: var(--shadow-md); border-color: color-mix(in srgb, var(--rust) 30%, var(--line)); transform: translateY(-2px); }
.tender-card:hover::before,
.tender-card.is-open::before { transform: scaleY(1); }
.tender-card.is-open { box-shadow: var(--shadow-md); border-color: color-mix(in srgb, var(--rust) 40%, var(--line)); }

/* Карточка отвечает на наведение целиком, а не только рамкой: шеврон
   подаётся вниз и темнеет, бейджи чуть подаются вперёд, звезда проявляется.
   Без scale() — он мылит текст (см. историю с тарифами). */
.tender-card__main .badge { transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.tender-card:hover .tender-chevron { color: var(--rust); transform: translateY(2px); }
.tender-card.is-open:hover .tender-chevron { transform: rotate(180deg) translateY(2px); }
.tender-card:hover .save-btn { color: var(--ink-faint); }
.tender-card:hover .save-btn.is-saved { color: var(--brass); }

/* Появление ленты очередью. Задержка растёт только у первых восьми карточек:
   дальше пользователь всё равно доскроллит позже, а длинный каскад на
   странице в 50 позиций читался бы как тормоза. */
@media (prefers-reduced-motion: no-preference) {
  .tender-card { animation: card-in 340ms var(--ease-out) backwards; }
  .tender-card:nth-child(1) { animation-delay: 0ms; }
  .tender-card:nth-child(2) { animation-delay: 40ms; }
  .tender-card:nth-child(3) { animation-delay: 80ms; }
  .tender-card:nth-child(4) { animation-delay: 120ms; }
  .tender-card:nth-child(5) { animation-delay: 160ms; }
  .tender-card:nth-child(6) { animation-delay: 200ms; }
  .tender-card:nth-child(7) { animation-delay: 240ms; }
  .tender-card:nth-child(n+8) { animation-delay: 280ms; }
}
@keyframes card-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* Горящий срок: чем меньше дней, тем заметнее. Класс вешает разметка ленты,
   здесь только подача — тихое тление, а не мигающая тревога. */
.deadline.is-urgent b { color: var(--rust); }
.deadline.is-urgent::before {
  content: "";
  display: inline-block;
  width: 6px; height: 6px; margin-right: 6px;
  border-radius: 50%;
  background: var(--rust);
  vertical-align: 1px;
}
@media (prefers-reduced-motion: no-preference) {
  .deadline.is-urgent::before { animation: ember 2.4s var(--ease) infinite; }
}
@keyframes ember {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 color-mix(in srgb, var(--rust) 45%, transparent); }
  70%      { opacity: 0.65; box-shadow: 0 0 0 6px transparent; }
}

/* просмотренные — тусклее, чтобы не путаться в ленте; при наведении/раскрытии видно как обычно */
.tender-card.is-viewed { opacity: 0.6; }
.tender-card.is-viewed:hover,
.tender-card.is-viewed.is-open { opacity: 1; }

.tender-card__main { display: flex; gap: 20px; padding: 20px 22px; cursor: pointer; }
.tender-score { flex-shrink: 0; width: 78px; text-align: center; }
.tender-score__num { font-family: var(--font-mono); font-size: 1.7rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.tender-score__num.ok { color: var(--ok); }
.tender-score__num.gap { color: var(--gap); }
.tender-score__num.bad { color: var(--bad); }
.tender-score__pct { font-size: 0.9rem; color: var(--ink-faint); }
/* ТЗ закупки не разобрано — честный прочерк вместо выдуманного процента.
   Причина висит в title и разворачивается в детали карточки. */
.tender-score__num--none { color: var(--ink-faint); cursor: help; }
/* второй строкой — совпадение по требованиям разобранного ТЗ; отдельно от
   предмета намеренно: смешать их в одно число значило бы выдать совпадение
   шаблонных формулировок за совпадение товара */
.tender-score__req { display: block; margin-top: 5px; font-family: var(--font-mono); font-size: 0.72rem;
  color: var(--ink-soft); cursor: help; }
.tender-score__req--none { color: var(--ink-faint); }

/* разбор сверки в детали карточки */
.match-row { display: flex; gap: 10px; padding: 7px 0; font-size: 0.86rem; align-items: baseline; }
.match-row__k { flex: 0 0 200px; color: var(--ink-faint); }
.match-row__v { flex: 1; min-width: 0; }
.match-row__v.muted { color: var(--ink-faint); }
.term-chip { display: inline-block; margin: 0 5px 5px 0; padding: 2px 8px; border-radius: 6px;
  font-family: var(--font-mono); font-size: 0.78rem; background: var(--paper-alt); border: 1px solid var(--line); }
/* Значок внутри фишки, а не только цвет: в строке позиции лота совпавшие и
   недостающие слова идут подряд, и одним цветом они читаются как один список —
   проверено на стенде. Плюс это не полагается на различение цвета. */
.term-chip.is-ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
.term-chip.is-ok::before { content: "✓ "; opacity: 0.75; }
.term-chip.is-gap { color: var(--gap); border-color: color-mix(in srgb, var(--gap) 35%, transparent); }
.term-chip.is-gap::before { content: "✗ "; opacity: 0.75; }
.term-more { font-size: 0.78rem; color: var(--ink-faint); }
@media (max-width: 760px) { .match-row { display: block; } .match-row__k { margin-bottom: 4px; } }

/* разбор совпадения: предмет / позиции лота / требования — отдельными блоками,
   каждый со своим объяснением, откуда взялось число */
.match-sub { padding: 12px 0; border-top: 1px dashed var(--line); }
.match-sub:first-of-type { border-top: none; padding-top: 4px; }
.match-sub__title { font-weight: 600; font-size: 0.92rem; margin-bottom: 6px; }
.match-why { margin-top: 8px; font-size: 0.8rem; line-height: 1.5; color: var(--ink-faint);
  border-left: 2px solid var(--line); padding-left: 10px; }

.lot-match { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.lot-match__row { display: flex; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line-soft, var(--line)); align-items: baseline; }
.lot-match__row:last-child { border-bottom: none; }
.lot-match__row.is-none { opacity: 0.55; }
.lot-match__score { flex: 0 0 46px; text-align: right; font-family: var(--font-mono);
  font-weight: 700; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.lot-match__pct { font-size: 0.7em; color: var(--ink-faint); }
.lot-match__body { flex: 1; min-width: 0; }
.lot-match__name { display: block; font-size: 0.88rem; margin-bottom: 4px; }
.lot-match__terms { display: block; }

.tender-body { flex-grow: 1; min-width: 0; }
.tender-body__top { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; flex-wrap: wrap; }
.tender-title {
  font-family: var(--font-display);
  font-size: 1.08rem;
  line-height: 1.35;
  letter-spacing: -0.014em;
  margin: 0 0 7px;
  transition: color var(--dur-fast) var(--ease);
}
.tender-card:hover .tender-title { color: var(--rust); }
.tender-meta { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 0.83rem; color: var(--ink-faint); }
.tender-meta b { color: var(--ink-soft); font-weight: 600; font-variant-numeric: tabular-nums; }
.lot-note { font-size: 0.78rem; color: var(--brass); background: var(--brass-tint); padding: 2px 9px; border-radius: 999px; display: inline-flex; align-items: center; }

/* Шеврон крутится ровно столько же, сколько разворачивается панель — иначе
   стрелка уже перевернулась, а карточка ещё едет, и жест распадается надвое. */
.tender-chevron {
  align-self: center;
  color: var(--ink-faint);
  transition: transform 280ms var(--ease), color var(--dur-fast) var(--ease);
  flex-shrink: 0;
}
.tender-card.is-open .tender-chevron { transition: transform 400ms var(--ease-out), color var(--dur-fast) var(--ease); }
.tender-card.is-open .tender-chevron { transform: rotate(180deg); }

/* Ранняя версия блока раскрытия (отступ слева под колонку % совпадения).
   Отступы и рамка переехали на .tender-detail__inner — здесь их держать
   нельзя: контейнер теперь свёрнутый грид, и любой его паддинг оставлял бы
   щель под закрытой карточкой. Актуальные правила — ниже по файлу. */
.tender-detail .check-row { font-size: 0.9rem; }
.tender-detail .check-status.bad { color: var(--bad); }
.explanation {
  margin-top: 14px;
  padding: 13px 16px;
  background: var(--paper-alt);
  border-radius: var(--radius-md);
  font-size: 0.88rem;
  color: var(--ink-soft);
}
.tender-actions { display: flex; gap: 10px; margin-top: 16px; }

.section-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 0;
  cursor: pointer;
  color: var(--ink-faint);
  font-size: 0.88rem;
  font-weight: 600;
  border-top: 1px solid var(--line);
  margin-top: 8px;
}
.section-toggle svg { transition: transform 0.15s ease; }
.section-toggle.is-open svg { transform: rotate(180deg); }
#disqualified-list { display: none; }
#disqualified-list.is-open { display: block; }
#disqualified-list .tender-card { opacity: 0.72; }

.plan-expired-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 16px; padding: 12px 16px;
  background: var(--rust-tint); border: 1px solid var(--rust);
  border-radius: var(--radius-lg); color: var(--ink);
  font-size: 0.92rem;
}
.plan-expired-banner a { color: var(--rust); font-weight: 600; }
.plan-expired-banner[hidden] { display: none; }

.empty-state {
  text-align: center;
  padding: 70px 30px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--white);
}
.empty-state h3 { font-size: 1.2rem; }
.empty-state p { max-width: 40ch; margin: 0 auto 22px; }

/* onboarding modal */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(33, 29, 23, 0.5);
  display: none; align-items: center; justify-content: center; z-index: 100; padding: 20px;
}
.modal-backdrop.is-open { display: flex; }
.modal-box {
  background: var(--white); border-radius: var(--radius-lg);
  padding: 34px; max-width: 560px; width: 100%;
  max-height: 88vh; overflow-y: auto;
  box-shadow: var(--shadow-lg);
}
.modal-box h2 { font-size: 1.4rem; }
.attr-row { display: grid; grid-template-columns: 1fr 1fr auto; gap: 10px; margin-bottom: 10px; align-items: center; }
.attr-remove { background: none; border: none; color: var(--ink-faint); cursor: pointer; font-size: 1.1rem; padding: 4px; }
.attr-remove:hover { color: var(--bad); }
.add-attr-btn { font-size: 0.85rem; color: var(--rust); background: none; border: none; cursor: pointer; font-weight: 600; padding: 6px 0; }

/* toast */
.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(20px);
  background: var(--ink); color: var(--paper);
  padding: 13px 22px; border-radius: 999px; font-size: 0.88rem;
  box-shadow: var(--shadow-lg); opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease; z-index: 200;
}
.toast.is-visible { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ================= ПОИСК ТОРГОВ: сайдбар, фильтры, лента ================= */

/* строка поиска в топбаре */
.search-box { max-width: 620px; }
.search-save {
  flex-shrink: 0;
  border: none;
  background: var(--rust-tint);
  color: var(--rust);
  font-weight: 600;
  font-size: 0.78rem;
  padding: 5px 12px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
}
.search-save:hover { background: var(--rust); color: var(--white); }

/* кнопка «новый поиск» в сайдбаре — растянуть */
.app-sidebar .btn-block { justify-content: center; }

/* сохранённые поиски */
.saved-searches { display: flex; flex-direction: column; gap: 2px; }
.saved-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
}
.saved-search:hover { background: var(--paper); color: var(--ink); }
.saved-search.is-active { background: var(--white); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-sm); }
.saved-search__name { flex-grow: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.saved-search__count {
  flex-shrink: 0;
  background: var(--rust);
  color: var(--white);
  font-size: 0.72rem;
  font-weight: 700;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.saved-search__edit {
  flex-shrink: 0;
  border: none;
  background: none;
  color: var(--ink-faint);
  cursor: pointer;
  padding: 2px;
  /* всегда чуть виден (не только по наведению) — иначе на тач-устройствах
     карандаш недоступен, а изменить/удалить поиск можно только через него */
  opacity: 0.45;
  display: flex;
}
.saved-search:hover .saved-search__edit { opacity: 1; }
.saved-search__edit:hover { color: var(--rust); }
.saved-empty { font-size: 0.82rem; color: var(--ink-faint); line-height: 1.5; padding: 4px 2px; }

/* панель фильтров */
.filter-bar {
  display: flex;
  align-items: flex-end;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 30px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.filter-chip { display: flex; flex-direction: column; gap: 5px; }
.filter-chip label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-faint); font-weight: 700; }
.filter-chip select,
.filter-chip input {
  border: 1px solid var(--line);
  background: var(--white);
  border-radius: var(--radius-sm);
  padding: 7px 10px;
  font-size: 0.85rem;
  font-family: var(--font-body);
  color: var(--ink);
}
.chip-range { display: flex; align-items: center; gap: 6px; }
.chip-range input { width: 92px; }
.chip-range span { color: var(--ink-faint); }
.filter-reset {
  border: none;
  background: none;
  color: var(--ink-faint);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  padding: 8px 0;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.filter-reset:hover { color: var(--rust); }

/* надстройка сверки по ТЗ */
.match-bar {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding: 12px 30px;
  background: var(--paper-alt);
  border-bottom: 1px solid var(--line-soft);
}
.match-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.match-bar.is-on { background: var(--rust-tint); border-bottom-color: var(--rust); }
.match-toggle { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-weight: 600; font-size: 0.9rem; }
.match-toggle input { display: none; }
.match-toggle__track {
  width: 40px; height: 22px; border-radius: 999px;
  background: var(--line); position: relative; transition: background 0.15s ease; flex-shrink: 0;
}
.match-toggle__thumb {
  position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--white); box-shadow: var(--shadow-sm); transition: transform 0.15s ease;
}
.match-toggle input:checked + .match-toggle__track { background: var(--rust); }
.match-toggle input:checked + .match-toggle__track .match-toggle__thumb { transform: translateX(18px); }
.match-bar select {
  border: 1px solid var(--line);
  background: var(--white);
  border-radius: var(--radius-sm);
  padding: 7px 10px;
  font-size: 0.85rem;
  color: var(--ink);
  max-width: 320px;
}
.match-bar select:disabled { opacity: 0.5; }
.match-hint { font-size: 0.82rem; color: var(--ink-soft); }
/* бейдж «сверка по товару» на карточке ленты */
.badge-prod-load { background: var(--line); color: var(--ink-soft); }
.badge-prod { cursor: help; }

/* badges: закон / этап / новизна */
.badge-law { background: var(--sage-tint); color: var(--sage); }
.badge-law.is-223 { background: var(--brass-tint); color: var(--brass); }
.badge-stage.stage-active { background: var(--ok-bg); color: var(--ok); }
.badge-stage.stage-committee { background: var(--gap-bg); color: var(--gap); }
.badge-stage.stage-done { background: var(--paper-deep); color: var(--ink-faint); }
/* неконкурентная (223 «Иной способ»/ед. поставщик) — пунктир = «не открытые торги» */
.badge-stage.stage-noncomp { background: transparent; color: var(--ink-soft); border: 1px dashed var(--line); }
.badge-fresh { background: var(--rust-tint); color: var(--rust); }

/* карточка закупки: доп. мета и раскрытие */
.tender-score__cap { display: block; font-size: 0.64rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.04em; margin-top: 4px; }
.tender-card:not(.has-match) .tender-card__main { padding-left: 22px; }
.tender-meta--strong { margin-top: 8px; font-size: 0.9rem; }
.tender-meta--strong b { color: var(--ink); }
.deadline { color: var(--ink-soft); }
.deadline b { color: var(--rust); font-weight: 700; }
.deadline.muted { color: var(--ink-faint); }
.tender-title mark { background: var(--brass-tint); color: var(--ink); border-radius: 3px; padding: 0 2px; }

/* Плавное разворачивание карточки.
   `display: none/block` анимировать нельзя, а height:auto недостижим для
   transition. Приём с grid: контейнер анимирует grid-template-rows 0fr→1fr,
   внутренняя обёртка гасит переполнение. Высота считается браузером сама,
   поэтому не нужен ни JS-замер, ни max-height «на глазок». */
.tender-detail {
  display: grid;
  grid-template-rows: 0fr;
  /* Закрытие чуть быстрее открытия: убрать с глаз уже прочитанное хочется
     сразу, а разворачивание должно успеть прочитаться как движение. */
  transition: grid-template-rows 280ms var(--ease);
}
.tender-card.is-open .tender-detail { transition: grid-template-rows 400ms var(--ease-out); }
.tender-detail__inner {
  min-height: 0;
  overflow: hidden;
  border-top: 1px dashed transparent;
  /* Вертикальные паддинги живут ТОЛЬКО в раскрытом состоянии и анимируются
     вместе с высотой. Держать их постоянно нельзя: при box-sizing: border-box
     padding входит в границы блока и не схлопывается вслед за нулевой строкой
     грида — под каждой закрытой карточкой торчала полоса в 40px с началом
     содержимого. Горизонтальные на высоту не влияют, они постоянны. */
  padding: 0 22px;
  /* Содержимое проявляется вдогонку высоте, а не появляется сразу целиком:
     без этого коробка ещё растёт, а текст уже стоит на полной яркости —
     и раскрытие читается как рывок, хотя высота анимируется. */
  opacity: 0;
  transition: padding 280ms var(--ease), border-color 280ms var(--ease),
              opacity 120ms var(--ease);
}
.tender-card.is-open .tender-detail { grid-template-rows: 1fr; }
.tender-card.is-open .tender-detail__inner {
  padding: 18px 22px 22px;
  border-top-color: var(--line);
  opacity: 1;
  /* Задержка = примерно четверть хода высоты: содержимое догоняет открывшуюся
     часть панели, а не опережает её. */
  transition: padding 400ms var(--ease-out), border-color 400ms var(--ease-out),
              opacity 260ms var(--ease-out) 100ms;
}
.detail-block { margin-bottom: 20px; }
.detail-block__title {
  font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-faint); font-weight: 700; margin-bottom: 10px;
  display: flex; align-items: center; gap: 10px;
}
.detail-match { background: var(--paper-alt); border-radius: var(--radius-md); padding: 16px 18px; }
.detail-match .check-row { font-size: 0.9rem; }
.detail-match .check-status.bad { color: var(--bad); }
.check-note { color: var(--ink-faint); }

.lot-line {
  display: grid;
  /* Фикс. ширина колонок «Количество»/«Цена за ед.»: каждая строка лота — отдельный
     grid, при auto-колонках ширина считается по своему контенту и заголовок с числом
     не совпадают. Фиксированные треки → все строки делят одну сетку, числа ровно под
     заголовком (оба выровнены вправо). */
  grid-template-columns: 20px minmax(0, 1fr) 150px 140px;
  gap: 12px;
  align-items: baseline;
  padding: 8px 0;
  border-top: 1px solid var(--line-soft);
  font-size: 0.9rem;
}
.lot-line:first-of-type { border-top: none; }
.lot-line__idx { color: var(--ink-faint); }
.lot-line__name { min-width: 0; overflow-wrap: anywhere; }
.lot-line__qty { color: var(--ink-soft); font-size: 0.84rem; white-space: nowrap; text-align: right; }
.lot-line__price { font-weight: 600; white-space: nowrap; text-align: right; }
/* строка-заголовок колонок лота (Позиция · Количество товара · Цена за единицу) */
.lot-head { border-top: none; padding-bottom: 4px; }
.lot-head .lot-line__name,
.lot-head .lot-line__qty,
.lot-head .lot-line__price {
  color: var(--ink-faint); font-size: 0.7rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em;
}

/* спецификация из таблицы КТРУ: позиция + требования к её характеристикам.
   Позиция — карточка, а не строка таблицы: у неё переменное число требований,
   и в общей сетке они разъезжались бы с соседними позициями. */
.spec-list { display: flex; flex-direction: column; gap: 10px; }
.spec-item {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  background: var(--paper-alt);
}
.spec-item__head {
  display: grid; grid-template-columns: 24px minmax(0, 1fr) auto;
  gap: 10px; align-items: baseline; font-size: 0.9rem;
}
.spec-item__idx { color: var(--ink-faint); }
.spec-item__name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.spec-item__qty { color: var(--ink-soft); font-size: 0.84rem; white-space: nowrap; }
.spec-item__code {
  margin: 2px 0 0 34px; font-size: 0.74rem; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.spec-chars { margin: 8px 0 0 34px; display: flex; flex-direction: column; }
.spec-char {
  /* Обе колонки — доли, а не auto: длинное текстовое требование при auto
     съедало почти всю ширину, и название характеристики схлопывалось в столбик
     по одной букве. Проверено на «Назначении» лестничного подъёмника. */
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 12px; align-items: baseline;
  padding: 5px 0; border-top: 1px dashed var(--line-soft); font-size: 0.84rem;
}
.spec-char:first-child { border-top: none; }
.spec-char__k { color: var(--ink-soft); min-width: 0; overflow-wrap: anywhere; }
.spec-char__v { font-weight: 600; text-align: right; overflow-wrap: anywhere; }
/* Жёсткое требование — то, значение которого участник менять не вправе: его
   нарушение дисквалифицирует заявку целиком, поэтому отмечаем ржавчиной. */
.spec-char.is-hard .spec-char__v { color: var(--rust); }
.spec-chars__none, .spec-chars__more {
  margin-top: 6px; font-size: 0.78rem; color: var(--ink-faint);
}
.spec-chars__none { margin-left: 34px; }

.facts-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 28px; }
.fact { display: flex; justify-content: space-between; gap: 12px; padding: 7px 0; border-bottom: 1px dashed var(--line-soft); font-size: 0.88rem; }
.fact__k { color: var(--ink-faint); }
.fact__v { font-weight: 600; text-align: right; }

/* аналитика: ценовой ориентир + история заказчика */
.detail-analytics { background: var(--paper-alt); border-radius: var(--radius-md); padding: 16px 18px; }
.analytics-row { display: flex; flex-direction: column; gap: 2px; padding: 8px 0; border-top: 1px dashed var(--line-soft); font-size: 0.88rem; }
.analytics-row:first-of-type { border-top: none; }
.analytics-row__k { color: var(--ink-faint); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; }
.analytics-row__v { font-weight: 500; line-height: 1.5; }
.analytics-diff { font-weight: 700; }
.analytics-diff.is-high { color: var(--bad); }
.analytics-diff.is-low { color: var(--ok); }
.analytics-note { margin-top: 10px; font-size: 0.76rem; color: var(--ink-faint); line-height: 1.4; }

/* документы закупки */
.doc-list { display: flex; flex-direction: column; gap: 6px; }
.doc-link {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--white);
  text-decoration: none;
  color: var(--ink);
  font-size: 0.88rem;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
.doc-link:hover { border-color: var(--rust); background: var(--rust-tint); }
.doc-ic { flex-shrink: 0; }
.doc-name { flex-grow: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-dl { flex-shrink: 0; font-size: 0.78rem; font-weight: 600; color: var(--rust); }

/* постраничная навигация + размер страницы */
.feed-pagebar { display: flex; align-items: center; gap: 16px; margin: 22px 0 8px; flex-wrap: wrap; }
.page-size { display: flex; align-items: center; gap: 8px; font-size: 0.84rem; color: var(--ink-faint); flex-shrink: 0; }
.page-size select {
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--white); color: var(--ink); font-family: var(--font-body);
  font-size: 0.85rem; font-weight: 600; padding: 6px 10px;
}
.pagination { display: flex; justify-content: center; align-items: center; gap: 6px; flex: 1; flex-wrap: wrap; margin: 0; }
.page-btn {
  min-width: 34px; height: 34px; padding: 0 8px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--white); color: var(--ink-soft);
  font-size: 0.86rem; font-weight: 600; cursor: pointer;
  transition: border-color 0.12s ease, background-color 0.12s ease, color 0.12s ease;
}
.page-btn:hover:not(:disabled) { border-color: var(--rust); color: var(--rust); }
.page-btn.is-current { background: var(--rust); border-color: var(--rust); color: var(--white); cursor: default; }
.page-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.page-arrow { font-size: 1rem; }
.page-ellipsis { color: var(--ink-faint); padding: 0 2px; }

/* ★ сохранить конкурс */
.save-btn {
  margin-left: auto; flex-shrink: 0;
  border: none; background: none; cursor: pointer;
  font-size: 1.15rem; line-height: 1; color: var(--line);
  padding: 2px 4px; transition: color 0.12s ease, transform 0.1s ease;
}
.save-btn:hover { color: var(--brass); transform: scale(1.15); }
.save-btn.is-saved { color: var(--brass); }

/* ---------- доска закупок (статусы воронки + ответственный) ---------- */

/* контролы в правой части шапки карточки */
.board-head-controls {
  margin-left: auto; flex-shrink: 0;
  display: inline-flex; align-items: center; gap: 8px;
}
.assignee-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 0.74rem; color: var(--ink-soft);
  background: var(--paper-alt); border: 1px solid var(--line-soft);
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
/* компактный селект статуса в шапке; на доске подсвечен ржавчиной */
.board-select {
  font: inherit; font-size: 0.78rem; font-weight: 600;
  color: var(--ink-soft); background: var(--paper);
  border: 1px solid var(--line); border-radius: 7px;
  padding: 3px 8px; cursor: pointer; max-width: 190px;
}
.board-select:hover { border-color: var(--ink-faint); }
.board-select.is-on { color: var(--rust); border-color: var(--rust); background: var(--rust-tint); }

/* sub-навигация статусов в сайдбаре */
.board-nav { display: flex; flex-direction: column; gap: 1px; margin: 2px 0 0 6px; }
.board-nav__item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 6px 10px; border-radius: 7px; cursor: pointer;
  font-size: 0.82rem; color: var(--ink-soft);
  border-left: 2px solid var(--line-soft);
  /* Это <a href="#">, и без сброса они рисовались подчёркнутыми — в сайдбаре
     выглядело как неоформленные ссылки. У соседнего .saved-search сброс был. */
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
              border-left-color var(--dur-fast) var(--ease);
}
.board-nav__item:hover { background: var(--paper-alt); color: var(--ink); }
.board-nav__item.is-active { background: var(--rust-tint); color: var(--rust); border-left-color: var(--rust); font-weight: 600; }
.board-nav__count {
  flex-shrink: 0; min-width: 18px; height: 18px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--paper-deep); color: var(--ink-soft);
  font-size: 0.7rem; font-weight: 700; border-radius: 999px;
}
.board-nav__item.is-active .board-nav__count { background: var(--rust); color: var(--white); }

/* блок «Работа с закупкой» в детали */
.detail-board .board-row {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px;
}
.board-field { display: flex; flex-direction: column; gap: 4px; font-size: 0.8rem; color: var(--ink-faint); }
.board-field select {
  font: inherit; font-size: 0.86rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); border-radius: 8px;
  padding: 7px 10px; min-width: 190px; cursor: pointer;
}
.board-field select:hover { border-color: var(--ink-faint); }
.board-remove { color: var(--bad); border-color: var(--line); }
.board-remove:hover { border-color: var(--bad); background: var(--rust-tint); }
.board-hint { margin-top: 8px; font-size: 0.8rem; color: var(--ink-faint); }

@media (max-width: 640px) {
  .board-field select, .board-select { min-width: 0; width: 100%; max-width: none; }
  .detail-board .board-row { flex-direction: column; align-items: stretch; }
}

/* модалка сверки ТЗ */
#tz-modal .modal-box { max-width: 720px; }
.tz-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 8px; }
.tz-col { display: flex; flex-direction: column; gap: 8px; }
.tz-col > label { font-size: 0.82rem; font-weight: 600; }
.tz-col input[type=file] { font-size: 0.8rem; }
.tz-col textarea {
  min-height: 120px; resize: vertical;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 10px; font-family: var(--font-body); font-size: 0.85rem;
  background: var(--white); color: var(--ink);
}
.tz-col textarea:focus { outline: none; border-color: var(--rust); box-shadow: var(--ring); }
.tz-verdict { display: flex; align-items: center; gap: 18px; padding: 14px 16px; background: var(--paper-alt); border-radius: var(--radius-md); margin-top: 14px; }
.tz-score { font-family: var(--font-mono); font-size: 2.2rem; font-weight: 700; line-height: 1; flex-shrink: 0; }
.tz-score span { font-size: 0.9rem; color: var(--ink-faint); }
.tz-score.ok { color: var(--ok); } .tz-score.gap { color: var(--gap); } .tz-score.bad { color: var(--bad); }
.tz-hint { font-size: 0.85rem; color: var(--ink-faint); padding: 8px 0; }
.tz-err { color: var(--bad); font-weight: 600; }
@media (max-width: 640px) { .tz-cols { grid-template-columns: 1fr; } }

/* ---------- личный кабинет ---------- */

.cabinet-wrap { padding: 26px 30px 60px; max-width: 780px; display: flex; flex-direction: column; gap: 20px; }
.cabinet-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 22px 24px;
}
.cabinet-card h3 { margin: 0 0 16px; font-size: 1.05rem; display: flex; align-items: center; gap: 10px; }
.cabinet-num { font-size: 0.8rem; font-weight: 600; color: var(--ink-faint); background: var(--paper-alt); padding: 2px 10px; border-radius: 999px; }
.cabinet-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 0; }
.cabinet-sub {
  margin-top: 16px; padding-top: 16px; border-top: 1px dashed var(--line);
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.cabinet-sub__label { font-size: 0.8rem; color: var(--ink-faint); }
.cabinet-sub__hint { font-size: 0.82rem; color: var(--ink-faint); }
.cabinet-empty { color: var(--ink-faint); font-size: 0.88rem; padding: 6px 0; }

.employee-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 6px; }
.employee-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--paper-alt);
}

.tz-history-list { display: flex; flex-direction: column; gap: 8px; }
.tz-history-row { display: flex; align-items: center; gap: 14px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.tz-history-score { font-family: var(--font-mono); font-weight: 700; font-size: 1.1rem; flex-shrink: 0; width: 54px; text-align: center; }
.tz-history-score.ok { color: var(--ok); } .tz-history-score.gap { color: var(--gap); } .tz-history-score.bad { color: var(--bad); }

@media (max-width: 640px) { .cabinet-grid { grid-template-columns: 1fr; } }

/* ---------- responsive ---------- */

@media (max-width: 1024px) {
  /* грид живёт на .container, а не на секции — иначе правило не срабатывает */
  .hero > .container { grid-template-columns: 1fr; gap: 40px; }
  .hero-visual { max-width: 460px; }
  .hero::before { width: 100%; right: -30%; opacity: 0.7; }
  .compare { grid-template-columns: 1fr; }
  /* Маршрут разворачивается вертикально: горизонтальная линия через две
     колонки соединяла бы шаги в неверном порядке (1-2, потом 3-4 ниже). */
  .steps { grid-template-columns: minmax(0, 1fr); gap: 26px; max-width: 520px; }
  .steps::before {
    top: 10px; bottom: 10px; left: 22px; right: auto;
    width: 2px; height: auto;
    background: linear-gradient(180deg,
      transparent, rgba(232,121,74,0.55) 8%, rgba(232,121,74,0.55) 92%, transparent);
  }
  .step {
    display: grid;
    grid-template-columns: 46px minmax(0, 1fr);
    column-gap: 18px;
    text-align: left;
    padding: 0;
  }
  .step__num { margin: 0; grid-row: 1 / span 2; }
  .step h4, .step p { min-width: 0; overflow-wrap: anywhere; }
  .step h4 { align-self: center; margin-bottom: 4px; }
  .step p { grid-column: 2; }
  .pricing-grid { grid-template-columns: 1fr; max-width: 420px; margin: 0 auto; }
  .price-card.is-featured { transform: none; }
  .app-shell { grid-template-columns: 1fr; }
  .app-sidebar { display: none; }
  .main-nav { display: none; }
  .filter-bar { padding: 12px 18px; gap: 12px; }
  .match-bar { padding: 10px 18px; }
}

@media (max-width: 640px) {
  .price-card:hover, .price-card.is-featured:hover { transform: none; }
  .final-cta > .container { padding: 52px 24px; }
  .hero-stats { flex-direction: column; gap: 16px; }
  .hero-stat { padding-left: 0; border-left: none; padding-top: 14px; border-top: 2px solid var(--rust); }
  .hero-stat:first-child { padding-top: 0; border-top: none; }
  .footer-grid { flex-direction: column; }
  .tender-card__main { flex-direction: column; }
  .tender-score { display: flex; align-items: center; gap: 8px; width: auto; text-align: left; }
  .tender-score__cap { margin-top: 0; }
  .facts-grid { grid-template-columns: 1fr; }
  .lot-line { grid-template-columns: 16px 1fr; }
  .lot-line__qty, .lot-line__price { grid-column: 2; text-align: left; }
  .lot-head { display: none; }  /* на узком экране колонки стопкой — шапка не нужна */
  /* Спецификация: отступ под номером позиции съедает половину узкого экрана,
     а значение требования уходит в перенос — выпрямляем в один столбец. */
  .spec-item__head { grid-template-columns: 22px 1fr; }
  .spec-item__qty { grid-column: 2; }
  .spec-item__code, .spec-chars, .spec-chars__none { margin-left: 0; }
  .spec-char { grid-template-columns: 1fr; gap: 2px; }
  .spec-char__v { text-align: left; }
  .field-row { grid-template-columns: 1fr; }
  .auth-shell { grid-template-columns: 1fr; }
  .auth-side { display: none; }
}

/* ============================================================
   ПОЛИРОВКА: состояния форм, движение, доступность
   Держим одним блоком в конце — это сквозные правила поверх
   компонентов выше, а не отдельный компонент.
   ============================================================ */

/* ---------- единое фокус-состояние для всех полей ----------
   Раньше рамка-при-фокусе была прописана только у .field и .tz-col textarea,
   а фильтры, селекты доски и поиск оставались без обратной связи. */
.filter-group input, .filter-group select,
.filter-chip input, .filter-chip select,
.board-field select, .board-select,
.match-bar select, .sort-select, .page-size select,
.product-switch select {
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.filter-group input:focus, .filter-group select:focus,
.filter-chip input:focus, .filter-chip select:focus,
.board-field select:focus, .board-select:focus,
.match-bar select:focus, .sort-select:focus, .page-size select:focus {
  outline: none;
  border-color: var(--rust);
  box-shadow: var(--ring);
}
/* .product-switch — рамка на обёртке, селект внутри без своей границы */
.product-switch:focus-within { border-color: var(--rust); box-shadow: var(--ring); }

/* ---------- карточки и панели приложения ---------- */
.filter-bar { background: color-mix(in srgb, var(--paper) 70%, transparent); }
.filter-chip label { transition: color var(--dur-fast) var(--ease); }
.filter-chip:focus-within label { color: var(--rust); }

.doc-link { box-shadow: var(--shadow-xs); }
.doc-link:hover { box-shadow: var(--shadow-sm); transform: translateX(2px); }

.empty-state { box-shadow: var(--shadow-xs); }

.cabinet-card { box-shadow: var(--shadow-xs); transition: box-shadow var(--dur) var(--ease); }
.cabinet-card:hover { box-shadow: var(--shadow-sm); }

.modal-backdrop { backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
.modal-box { border: 1px solid var(--line); }

/* ---------- боковина страниц входа ----------
   Чернильная панель из того же материала, что и финальный призыв на лендинге. */
.auth-side {
  background:
    radial-gradient(60% 80% at 15% 10%, color-mix(in srgb, var(--rust) 34%, transparent) 0%, transparent 60%),
    linear-gradient(160deg, #2b251c 0%, #1a1610 100%);
}
/* Зерно уводим под контент через isolation + z-index:-1, а НЕ через
   `.auth-side > * { position: relative }`: то правило имело ту же
   специфичность, что и .auth-side__curve, стояло ниже по файлу и сбивало
   знаку `position: absolute` — он вываливался в поток серым пятном. */
.auth-side { isolation: isolate; }
.auth-side::after {
  content: "";
  position: absolute; inset: 0;
  background-image: var(--grain);
  background-size: var(--grain-size);
  mix-blend-mode: screen;
  opacity: 0.55;
  pointer-events: none;
  z-index: -1;
}
.auth-side__quote h3 { color: #fdf8ee; }

/* ---------- появление контента ----------
   Анимация привязана ко ВРЕМЕНИ, а не к прокрутке. Пробовали
   `animation-timeline: view()` — и получили воспроизводимый провал: при переходе
   по якорю из шапки (#how, #sources, #pricing) секция оказывается в кадре, но
   прогресс таймлайна в диапазон не попадает, и экран остаётся пустым. Временная
   анимация с fill:both всегда доигрывает до конца, спрятать контент не может. */
@media (prefers-reduced-motion: no-preference) {
  .hero-copy > *, .hero-visual,
  .section-head, .compare-col, .step, .price-card, .final-cta > .container {
    /* fill: BACKWARDS, не both. При `both` конечный кадр `transform: none`
       остаётся приклеенным навсегда и перебивает обычный каскад — пропали бы и
       подъём избранного тарифа, и все hover-состояния. `backwards` держит
       только стартовый кадр до запуска, а после — управление возвращается CSS. */
    animation: reveal-up var(--dur-slow) var(--ease-out) backwards;
  }
  .hero-copy > .eyebrow      { animation-delay: 40ms; }
  .hero-copy > h1            { animation-delay: 90ms; }
  .hero-copy > .hero-lede    { animation-delay: 150ms; }
  .hero-copy > .hero-actions { animation-delay: 210ms; }
  .hero-copy > .hero-stats   { animation-delay: 270ms; }
  .hero-visual               { animation-delay: 180ms; }

  /* Лесенка внутри групп: одновременный подъём трёх одинаковых карточек
     читается как рывок всей строки. */
  .compare-col:nth-child(2) { animation-delay: 90ms; }
  .step:nth-child(2) { animation-delay: 60ms; }
  .step:nth-child(3) { animation-delay: 120ms; }
  .step:nth-child(4) { animation-delay: 180ms; }
  .step:nth-child(5) { animation-delay: 240ms; }
  .price-card:nth-child(2) { animation-delay: 80ms; }
  .price-card:nth-child(3) { animation-delay: 160ms; }
}
@keyframes reveal-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- общий выключатель движения ----------
   Ставим последним, чтобы перекрыть все анимации выше. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .btn:hover, .price-card:hover, .step:hover,
  .source-chip:hover, .tender-card:hover, .hero-visual:hover .mock-card { transform: none; }
}
