/* ============================================================
   Kaufman Lab — основа обеих таблиц стилей: шрифты и примитивы.
   Сборка (build.py) ставит этот файл первым в site.css и proekt.css,
   отдельно на сайт он не попадает. Единственное место, где живут
   палитра, шрифтовые семейства, шкала размеров и отступы.
   Семантические цвета (--color-*) у страниц и статей свои — в их файлах.
   ============================================================ */

/* --- 0. Шрифты: свои, не Google. Кириллица и латиница отдельными файлами,
   браузер качает только нужный поднабор. font-display:swap — текст виден сразу. */
@font-face{font-family:Onest;font-style:normal;font-weight:700;font-display:swap;
  src:url("/assets/fonts/onest-cyrillic-700-normal.woff2") format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:Onest;font-style:normal;font-weight:700;font-display:swap;
  src:url("/assets/fonts/onest-latin-700-normal.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:Onest;font-style:normal;font-weight:800;font-display:swap;
  src:url("/assets/fonts/onest-cyrillic-800-normal.woff2") format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:Onest;font-style:normal;font-weight:800;font-display:swap;
  src:url("/assets/fonts/onest-latin-800-normal.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:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;
  src:url("/assets/fonts/ibm-plex-mono-cyrillic-400-normal.woff2") format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;
  src:url("/assets/fonts/ibm-plex-mono-latin-400-normal.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:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;
  src:url("/assets/fonts/ibm-plex-mono-cyrillic-500-normal.woff2") format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;
  src:url("/assets/fonts/ibm-plex-mono-latin-500-normal.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}

/* --- Примитивы --------------------------------------------- */
:root{
  --paper-100:#F8F7F5; --paper-200:#EDEBE8; --paper-300:#E3E0DC; --paper-400:#D4D0CB;
  --ink-900:#17161A;   --ink-400:#676370;   --ink-200:#A9A5AC;
  --magenta-500:#C40064; --magenta-100:#FBE3EF;
  --green-500:#1C6E4E;

  --f-display:Onest,system-ui,-apple-system,"Segoe UI",sans-serif;
  --f-body:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
  --f-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  --step--1:.78rem;
  --step-0:1rem;
  --step-1:1.12rem;
  --step-2:clamp(1.25rem,3.2vw,1.6rem);
  --step-3:clamp(1.7rem,4.5vw,2.4rem);
  --step-4:clamp(2.1rem,6vw,3.4rem);

  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px;
  --sp-6:28px; --sp-7:40px; --sp-8:56px;

  --measure:64ch; --page:1140px;
}

/* --- Общие компоненты шапки и подвала — одинаковы у сайта и статей ---
   С 29.09.2026: правила, стоявшие копиями в site.css и proekt.css. Порядок —
   как был в site.css, не переставлять. Токены --color-* сюда не переносить:
   у сайта и статей они свои (решение 0005). */

/* База */
*{box-sizing:border-box}
body{
  margin:0; color:var(--color-text);
  /* фон: цвет + сетка еле заметных точек (глубина, как в Claude Code) */
  background-color:var(--color-bg);
  background-image:radial-gradient(color-mix(in srgb, var(--color-text) 7%, transparent) 1px, transparent 1.5px);
  background-size:22px 22px;
  font-family:var(--f-body); font-size:1rem; line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit; text-decoration:none}
.page{max-width:var(--page); margin:0 auto; padding:0 var(--sp-5)}
.muted{color:var(--color-text-muted)}
.mono{font-family:var(--f-mono)}
strong{font-weight:600}
.link{border-bottom:1px solid var(--color-accent)}
.label{
  font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--color-text-muted);
}

/* Шапка */
.top{
  display:flex; align-items:center; gap:var(--sp-5); flex-wrap:wrap;
  padding:var(--sp-6) 0 var(--sp-5);
}
.nav{display:flex; gap:var(--sp-5); margin-left:auto; flex-wrap:wrap}
.nav a:hover,.nav a[aria-current]{color:var(--color-text); border-bottom-color:var(--color-accent)}

/* Подвал: политика — отдельный нижний ряд */
.foot-doc a:hover{color:var(--color-accent)}
/* на телефоне меню подвала ложится в несколько строк, и политика читалась
   его пунктом — её отделяет тонкая линейка */
@media (max-width:760px){.foot-doc{padding-top:var(--sp-3); border-top:1px solid var(--color-line)}}

/* Уведомление о cookie (COOKIE_JS в build.py) */
.cookie{position:fixed; left:var(--sp-5); bottom:var(--sp-5); z-index:10; max-width:460px;
  display:flex; align-items:center; gap:var(--sp-5); padding:var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-5);
  background:var(--color-surface); border:1px solid var(--color-line);
  opacity:0; transform:translateY(8px); transition:opacity .3s, transform .3s; pointer-events:none}
.cookie.on{opacity:1; transform:none; pointer-events:auto}
.cookie p{margin:0; font-family:var(--f-body); font-size:0.85rem; line-height:1.5; color:var(--color-text-muted)}
.cookie p a{color:var(--color-text)}
.cookie button{flex:0 0 auto; padding:10px var(--sp-4); background:none; cursor:pointer;
  border:1px solid var(--color-text); color:var(--color-text);
  font-family:var(--f-mono); font-size:0.725rem; letter-spacing:.16em; text-transform:uppercase}
.cookie button:hover{border-color:var(--color-accent); color:var(--color-accent)}
@media (max-width:560px){
  .cookie{left:var(--sp-3); right:var(--sp-3); bottom:calc(var(--sp-3) + env(safe-area-inset-bottom)); max-width:none}
}
@media (prefers-reduced-motion:reduce){.cookie{transition:none; transform:none}}

/* Секции и таблицы */
.sec-head{display:flex; flex-direction:column; gap:var(--sp-2)}
tbody tr:last-child td{border-bottom:none}
.yes{color:var(--color-yes); font-weight:600}

/* Наверх, марка, кнопка темы */
.totop .ar{color:var(--color-accent)}
.totop:hover .wd{color:var(--color-accent)}
.mark em{font-style:normal; color:var(--color-accent)}
.mark:hover{color:var(--color-accent)}
/* половина круга рисуется стилем: глифа ◐ нет в системных шрифтах, вместо него был квадрат */
/* Круг темы: 13 px — это сам круг, рамка снаружи. Без content-box рамка
   съедала бы 3 px внутрь, а без flex:0 0 auto круг сплющивался бы в овал,
   потому что как элемент флекса он имеет право сжиматься. */
.theme-btn::before{content:''; flex:0 0 auto; box-sizing:content-box;
  width:13px; height:13px; border-radius:50%;
  border:1.5px solid currentColor;
  background:linear-gradient(90deg, currentColor 50%, transparent 50%)}
.theme-btn:hover{color:var(--color-accent)}

/* Общие с proekt.css правила — в конце osnova.css (29.09.2026). Остальные повторы
   намеренные: порядок правил в файле решает спор одинаковой силы, а th, .mt3, .mt6
   и @media (max-width:620px) перебивают ранние правила. Перенос всего подряд
   20.09.2026 сломал отступ (.mt6: 16px вместо 28). Переносить — со сверкой tests/vid.py. */
/* ============================================================
   Kaufman Lab — стиль страниц сайта: главная, разделы, теги, панель.
   Язык: узкая колонка, тонкие линейки, таблицы, точечный акцент.
   Числа живут здесь, в разметке их быть не должно.

   Статьи этот файл НЕ грузят: у них свой proekt.css, и компоненты статьи
   описаны там. Здесь их копия лежала до 08.09.2026 — не применялась ни
   к чему и успела разойтись значениями (.article 720px против 820, .lede
   1.1rem/58ch против 1rem/62ch), то есть врала тому, кто правил её как
   эталон. Копия снята. Общее у двух файлов — шрифты, примитивы и одинаковые
   правила базы, шапки и подвала — лежит в osnova.css, сборка ставит его первым в оба.
   ============================================================ */

/* --- 1. Примитивы: в osnova.css, сборка ставит его первым --- */
:root{--wide:1140px;}

/* --- 2. Семантика ---------------------------------------- */
:root{
  --color-bg:var(--paper-200);
  --color-surface:var(--paper-100);
  --color-sunk:var(--paper-300);
  --color-text:var(--ink-900);
  --color-text-muted:var(--ink-400);
  --color-line:var(--paper-400);
  --color-poisk:#5189C6;      /* ряд «Яндекс» */
  --color-goo:#2F8F66;        /* ряд «Google» на панели видимости */
  --color-accent:var(--magenta-500);
  --color-seti:#6A4BD8;       /* нейросети на панели: розовый отдан просмотрам */
  --color-accent-bg:var(--magenta-100);
  --color-yes:var(--green-500);
  --color-no:#676370;
  /* чернила поверх акцентной плашки: в светлой теме акцент тёмный, в тёмной светлый */
  --chip-ink:#fff;
  --shot-bg:#1A181D; --shot-line:#34303A; --shot-ink:#8E8896;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --color-bg:#131215; --color-surface:#1B191E; --color-sunk:#0E0D10;
    --color-text:#F2F0EE; --color-text-muted:#9C97A2; --color-line:#302D36;
    --color-accent:#FF4D9E; --color-accent-bg:#3A0F26; --color-seti:#9B85F0;
    --color-yes:#5FD3A0; --color-no:#8E8896; --chip-ink:#131215;
    --shot-bg:#0B0A0D; --shot-line:#2A2730; --shot-ink:#6D6875;
  }
}
:root[data-theme="dark"]{
  --color-bg:#131215; --color-surface:#1B191E; --color-sunk:#0E0D10;
  --color-text:#F2F0EE; --color-text-muted:#9C97A2; --color-line:#302D36;
  --color-accent:#FF4D9E; --color-accent-bg:#3A0F26; --color-seti:#9B85F0;
  --color-yes:#5FD3A0; --color-no:#8E8896; --chip-ink:#131215;
  --shot-bg:#0B0A0D; --shot-line:#2A2730; --shot-ink:#6D6875;
}

/* --- 3. База --------------------------------------------- */
/* Плавная прокрутка — только тем, кто не просил убрать движение: «наверх»
   с конца главной везёт через 5–10 тысяч пикселей, и общий выключатель ниже
   её не гасит — он трогает animation и transition, а это отдельное свойство. */
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
h1,h2,h3{font-family:var(--f-display); margin:0; text-wrap:balance; letter-spacing:-.02em; line-height:1.12}
h1{font-weight:800; font-size:var(--step-3); letter-spacing:-.03em; line-height:1.02}
h2{font-weight:800; font-size:var(--step-2)}
h3{font-weight:700; font-size:var(--step-0)}
p{margin:0}
a:focus-visible,button:focus-visible{outline:2px solid var(--color-accent); outline-offset:3px}
svg{max-width:100%; display:block}

.prose{display:flex; flex-direction:column; gap:var(--sp-4); max-width:var(--measure)}
.nums{font-family:var(--f-mono); font-variant-numeric:tabular-nums}

.eyebrow{
  font-family:var(--f-mono); font-size:0.725rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--color-accent);
}

/* --- 4. Шапка и подвал ----------------------------------- */
.nav a{
  font-family:var(--f-mono); font-size:0.725rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--color-text-muted);
  padding-bottom:2px; border-bottom:1px solid transparent;
}
.nav a.cta, .foot-meta a.cta{color:var(--color-accent)}

.foot{
  border-top:1px solid var(--color-line); margin-top:var(--sp-6);
  padding:var(--sp-4) 0 var(--sp-7);
  display:flex; flex-wrap:wrap; gap:var(--sp-5); align-items:baseline;
  color:var(--color-text-muted); font-size:0.85rem;
}
.foot-brand{font-family:var(--f-mono); font-size:0.788rem; color:var(--color-text-muted)}
.foot-meta{margin-left:auto; font-family:var(--f-mono); font-size:0.788rem; display:flex; gap:var(--sp-5); flex-wrap:wrap}
.foot-meta a{color:var(--color-text-muted)}
.foot-meta a:hover{color:var(--color-accent)}
/* политика — отдельный нижний ряд подвала */
.foot-doc{flex-basis:100%; font-family:var(--f-mono); font-size:0.788rem}
.foot-doc a{display:inline-block; padding:4px 0; color:var(--color-text-muted)}
/* Линейка над политикой на телефоне и уведомление о cookie — в конце osnova.css:
   у сайта и статей они одинаковы. */

/* --- 6. Секции ------------------------------------------- */
.sec{display:flex; flex-direction:column; gap:var(--sp-5); padding:var(--sp-7) 0; border-top:1px solid var(--color-line)}

/* --- 7. Капсула, фактбокс, вердикт ----------------------- */


/* --- 8. Список проектов ------------------------------------ */
/* --- 9. Таблицы ------------------------------------------ */
.tw{overflow-x:auto; min-width:0; max-width:100%; border:1px solid var(--color-line); background:var(--color-surface)}
table{border-collapse:collapse; width:100%; min-width:520px}
th,td{text-align:left; padding:11px 15px; border-bottom:1px solid var(--color-line); font-size:0.925rem; vertical-align:top}
th{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.13em; text-transform:uppercase; color:var(--color-text-muted); font-weight:500}
td.n,th.n{font-family:var(--f-mono); font-variant-numeric:tabular-nums; text-align:right}
td.c,th.c{text-align:center; font-family:var(--f-mono)}
tr.total td{border-top:2px solid var(--color-text); font-weight:600}
.no{color:var(--color-no)}

/* --- 10. Схемы, скриншоты, код --------------------------- */
figure{margin:0; display:flex; flex-direction:column; gap:var(--sp-3)}
figcaption{font-size:0.85rem; color:var(--color-text-muted); max-width:var(--measure)}
.shot{background:var(--shot-bg); border:1px solid var(--color-line); padding:var(--sp-4); overflow-x:auto}
pre{
  background:var(--color-sunk); border:1px solid var(--color-line);
  padding:var(--sp-4); overflow-x:auto; font-family:var(--f-mono);
  font-size:0.85rem; line-height:1.55; margin:0;
}
code{font-family:var(--f-mono); font-size:.9em}

details.faq{border-bottom:1px solid var(--color-line); padding:var(--sp-4) 0}
/* text-wrap:balance — как у заголовков. Без него вопрос рвался по дефису:
   «сотрудника AI-» / «агентом?». Браузер сам переразбивает строки по
   пробелу и заодно не оставляет коротких хвостов у длинных вопросов. */
details.faq summary{cursor:pointer; font-family:var(--f-display); font-weight:700; font-size:1rem;
  list-style:none; display:flex; gap:var(--sp-3); text-wrap:balance}
details.faq summary::-webkit-details-marker{display:none}
details.faq summary::before{content:"+"; color:var(--color-accent); font-family:var(--f-mono)}
details.faq[open] summary::before{content:"−"}
details.faq p{margin-top:var(--sp-3); max-width:var(--measure); color:var(--color-text-muted); font-size:0.925rem}
/* Ответ раскрывается плавно, а не скачком: высота растёт за 0,25 с,
   сворачивается быстрее, за 0,18 с — уход короче появления. Текст ответа
   всегда в разметке и индексируется. Где нет ::details-content или
   interpolate-size, раскрытие мгновенное, как было. */
@supports (interpolate-size:allow-keywords) and selector(::details-content){
@media (prefers-reduced-motion:no-preference){
  details.faq{interpolate-size:allow-keywords}
  details.faq::details-content{block-size:0; overflow:hidden;
    transition:block-size .18s ease-in, content-visibility .18s allow-discrete}
  details.faq[open]::details-content{block-size:auto;
    transition:block-size .25s cubic-bezier(.16,1,.3,1), content-visibility .25s allow-discrete}
}
}


@media (prefers-reduced-motion:reduce){*{animation:none!important; transition:none!important}}

/* --- 13. Первый экран ------------------------------------ */
.wide{max-width:var(--wide); margin:0 auto; padding:0 var(--sp-5)}
.hero{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--sp-7); align-items:center; padding:var(--sp-7) 0 var(--sp-8);
}
@media (max-width:900px){.hero{grid-template-columns:1fr; gap:var(--sp-6); padding-bottom:var(--sp-7)}}
.hero-name{
  font-family:var(--f-display); font-weight:800;
  font-size:clamp(2.7rem,6.4vw,5.1rem); line-height:.9; letter-spacing:-.045em; margin:0;
}
.hero-name em{font-style:normal; color:var(--color-accent)}

.hero-links{display:flex; align-items:baseline; gap:var(--sp-4); margin-top:var(--sp-6); font-family:var(--f-mono); font-size:0.788rem}
.hero-links a{color:var(--color-text-muted)}
.hero-links .sep{color:var(--color-text-muted); opacity:.5}
.hero-links a:hover{color:var(--color-accent)}

/* --- 16. Выравнивание и мелкие правки -------------------- */
.sec-head h2{max-width:24ch}

.tw{max-width:min(1000px, 100%)}

figure{max-width:1000px}
pre{max-width:1000px}

/* --- 17. Контраст цены и объём --------------------------- */


/* --- 19. Блок видимости в первом экране ------------------ */
.viz{border:1px solid var(--color-line); background:var(--color-surface); padding:var(--sp-5); display:flex; flex-direction:column; gap:var(--sp-4)}
.viz-chart{background:var(--color-bg); border:1px solid var(--color-line); padding:var(--sp-3)}
.viz-rows{display:flex; flex-direction:column; gap:7px}
.vrow{display:grid; grid-template-columns:92px 1fr 52px; gap:var(--sp-3); align-items:center; font-family:var(--f-mono); font-size:0.725rem; color:var(--color-text-muted)}
.vbar{height:7px; background:var(--color-sunk); position:relative}
/* Английская главная (решение 0014): справа на первом экране реестр в долларах —
   те же полосы, но подпись слева шире: там название системы, а не «Яндекс». */
.vrow.shir{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) 64px}
.vrow.shir a{color:var(--color-text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  display:block; padding-block:4px}   /* палец попадает: строка ссылки не ниже 24 px */
.vrow.shir a:hover{color:var(--color-accent)}
.vrow.shir .vbar i{background:var(--color-accent)}
@media (max-width:560px){   /* телефон: название целиком, полоса и цена строкой ниже */
  .vrow.shir{grid-template-columns:minmax(0,1fr) 64px; row-gap:2px}
  .vrow.shir a{grid-column:1/-1; white-space:normal}}
/* плашка согласия на английском сайте: две кнопки рядом, «Accept» последней */
.cookie .knopki{display:flex; gap:var(--sp-2); flex:0 0 auto}
.cookie:has(.knopki){flex-wrap:wrap; max-width:520px}
.cookie:has(.knopki) p{flex:1 1 260px}
@media (max-width:560px){.cookie .knopki{flex:1 1 100%} .cookie .knopki button{flex:1}}
.vrow-itog{font-size:0.85rem; color:var(--color-text-muted); border-top:1px solid var(--color-line); padding-top:var(--sp-3)}
.vbar i{position:absolute; inset:0 auto 0 0; background:var(--color-seti); display:block}
.vbar.ya i{background:var(--color-poisk)}
.vbar.ist i{background:var(--color-poisk)}
.vbar.go i{background:var(--color-goo)}

/* Верх панели: сумма показов и доля упоминаний двумя числами */
.viz-dva{display:flex; gap:26px; align-items:center; padding-bottom:4px; flex-wrap:wrap}
/* Подпись стоит СПРАВА от числа, а не под ним: так верхняя строка экономит
   высоту, и её остаётся больше для таблицы под графиком. */
.viz-dva .p{display:flex; gap:9px; align-items:center}
.viz-dva b{font-family:var(--f-display); font-weight:800; font-size:1.9rem; line-height:1;
  font-variant-numeric:tabular-nums; color:var(--color-text); white-space:nowrap}
.viz-dva b.hot{color:var(--color-seti)}
.viz-dva span{font-family:var(--f-mono); font-size:.67rem; color:var(--color-text-muted); line-height:1.35}

/* Поиск таблицей: подписи метрик слева один раз, системы колонками */
.ptab{display:grid; gap:7px 14px; align-items:center;
  font-family:var(--f-mono); font-size:.715rem; color:var(--color-text-muted)}
.ptab.k1{grid-template-columns:auto 1fr}
.ptab.k2{grid-template-columns:auto 1fr 1fr}
.ptab.k3{grid-template-columns:auto 1fr 1fr 1fr}
.ptab .hd{font-size:.64rem; letter-spacing:.09em; text-transform:uppercase; text-align:left}
.ptab .cell{display:grid; grid-template-columns:1fr auto; gap:8px; align-items:center}
.ptab .bar{height:7px; background:var(--color-sunk); position:relative}
.ptab .bar i{position:absolute; inset:0 auto 0 0; display:block}
.ptab .bar.ya i{background:var(--color-poisk)}
.ptab .bar.go i{background:var(--color-goo)}
.ptab .v{color:var(--color-text); font-variant-numeric:tabular-nums; text-align:left; min-width:0}
.otkuda{display:flex; flex-direction:column; gap:7px; margin-top:2px}
.otkuda .imena{display:flex; flex-wrap:wrap; gap:0 9px; font-family:var(--f-mono);
  font-size:.66rem; color:var(--color-text-muted); line-height:1.5}
.otkuda .imena > span{white-space:nowrap}
.otkuda .imena b{color:var(--color-text); font-weight:400; font-variant-numeric:tabular-nums}
.otkuda .imena i{font-style:normal; color:var(--color-text-muted); opacity:.55; margin-left:9px}
.otkuda .polosa{display:flex; height:13px; overflow:hidden}
.otkuda .polosa i{display:block; height:100%}
.otkuda .kv2{display:inline-block; width:8px; height:8px; margin-right:5px; vertical-align:baseline}
/* Каждый источник своим цветом, поиск — синим, как Яндекс на графике;
   между долями тонкий зазор. Решение владельца 28.09.2026 — до этого был
   один тон от тёмного к светлому, и доли сливались. */
.t1{background:#6A4BD8} .t2{background:#E07A5F} .t3{background:#8E8896}
.t4{background:#5189C6} .t5{background:#D9A441} .t6{background:#C9C2CF}
.otkuda .label{margin-bottom:2px}
.otkuda .imena{gap:4px 14px}
.otkuda .polosa{gap:2px}
.otkuda .polosa i{min-width:3px}

/* Телефон: график там крупнее кеглем (раздел 33), и подписи у концов линий
   не помещаются — они уходят строкой под график, заголовок графика прячется. */
.legenda-mob{display:none}
@media (max-width:760px){
  .viz-chart .podpisi, .viz-chart .zagolovok{display:none}
  .legenda-mob{display:flex; flex-wrap:wrap; gap:4px 14px; margin:var(--sp-2) 0 0;
    font-family:var(--f-mono); font-size:.72rem}
  .legenda-mob b{display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:6px}
  .legenda-mob .v{color:var(--color-accent)} .legenda-mob .v b{background:var(--color-accent)}
  .legenda-mob .y{color:var(--color-poisk)}  .legenda-mob .y b{background:var(--color-poisk)}
  .legenda-mob .g{color:var(--color-goo)}    .legenda-mob .g b{background:var(--color-goo)}
}
.stolbik{display:none}
@media (max-width:600px){ .ptab{display:none} .stolbik{display:block} }
/* Узкие телефоны: два числа рядом не помещаются, дата уходит под них */
@media (max-width:380px){
  .viz-dva{gap:16px}
  .viz-dva b{font-size:1.6rem}
  .viz-dva .p{flex-direction:column; gap:2px; align-items:flex-start}
}
.kv{display:inline-block; width:9px; height:9px; margin-right:7px}
.kv-ya{background:var(--color-poisk)}
.kv-go{background:var(--color-goo)}
.viz-dva b.pro{color:var(--color-accent)}   /* просмотры: тот же розовый, что область на графике */
.vrow .val{text-align:right; color:var(--color-text); font-variant-numeric:tabular-nums}
.viz-split{border-top:1px solid var(--color-line); padding-top:var(--sp-3); display:flex; flex-direction:column; gap:7px}

/* --- 20. Статейный формат кейса -------------------------- */
.factline{
  display:flex; flex-wrap:wrap; gap:var(--sp-5); padding:var(--sp-4) 0;
  border-top:1px solid var(--color-line); border-bottom:1px solid var(--color-line);
  font-family:var(--f-mono); font-size:0.788rem; color:var(--color-text-muted);
}
/* Последней в секции нижняя линейка не нужна: секция рисует свою, и между
   ними оставался пустой отступ — на телефоне это читалось как забытая
   пустая строка, а не как граница блока. */
.sec > .factline:last-child{border-bottom:none}
.factline b{font-family:var(--f-display); font-weight:700; font-size:0.925rem; color:var(--color-text); margin-left:6px}
.factline .ok{color:var(--color-accent)}
details.code{border:1px solid var(--color-line); background:var(--color-surface); padding:var(--sp-4) var(--sp-5)}
details.code summary{cursor:pointer; font-family:var(--f-mono); font-size:0.85rem; color:var(--color-accent); list-style:none}
details.code summary::-webkit-details-marker{display:none}
details.code pre{margin-top:var(--sp-4); background:var(--color-bg)}

/* --- 23. Реестр (страница /all/) ------------------------- */
.reg{width:100%; border-collapse:collapse; background:var(--color-surface); border:1px solid var(--color-line)}
.reg th{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.13em; text-transform:uppercase;
        color:var(--color-text-muted); font-weight:500; text-align:left; padding:12px 16px; border-bottom:1px solid var(--color-line)}
.reg th.n{text-align:right}
.reg td{padding:0; border-bottom:1px solid var(--color-line); vertical-align:top}
.reg tr:last-child td{border-bottom:none}
.reg a.cell{display:block; padding:16px; color:inherit}
/* Номер проекта: порядок его появления в лаборатории, не место в списке.
   Даёт глазу опору — без него на телефоне карточки сливаются в одну ленту. */
.reg .nomer{display:block; font-family:var(--f-mono); font-size:0.663rem;
  letter-spacing:.14em; color:var(--color-accent); margin-bottom:6px}
/* строкой, а не flex (08.10.2026): в flex длинное название занимало всю ширину,
   и стрелка с плашкой «новое» отрывались к правому краю */
.reg .name{font-family:var(--f-display); font-weight:700; font-size:1rem; line-height:1.25; display:block}
.reg .name .arrow{display:inline-block; margin-left:8px}

/* Две цены, ради которых человек и открыл реестр. По рынку — жирным чёрным,
   себестоимость — тем же начертанием, но акцентом. Подписи и пояснения под
   ними остаются служебными: выделяется только само число. */
.reg .m[data-k="По рынку"], .reg .m[data-k="Market price"]{font-weight:700}
.reg .m[data-k="Себестоимость"], .reg .m[data-k="Cost"]{color:var(--color-accent)}
.reg .razovo{display:block; margin-top:var(--sp-3)}
.reg .m[data-k="По рынку"]::before, .reg .m[data-k="Market price"]::before,
.reg .m[data-k="По рынку"] .kto, .reg .m[data-k="Market price"] .kto{font-weight:400}
.reg .m[data-k="Себестоимость"]::before, .reg .m[data-k="Cost"]::before,
.reg .m[data-k="Себестоимость"] .kto, .reg .m[data-k="Cost"] .kto{color:var(--color-text-muted)}
.reg .name .arrow{color:var(--color-accent); opacity:0; transform:translateX(-4px); transition:opacity .14s ease, transform .14s ease; font-family:var(--f-mono)}
.reg .desc{font-size:0.85rem; color:var(--color-text-muted); margin-top:5px; max-width:62ch}
.reg .m{font-family:var(--f-mono); font-variant-numeric:tabular-nums; font-size:0.85rem; text-align:right; white-space:nowrap; padding:16px}
/* Цифры выравниваются по названию проекта, а не по верху ячейки: над названием
   стоит номер отдельной строкой, и без этого отступа цифра висела на его уровне,
   в сорока пикселях над строкой, к которой относится. На телефоне таблица
   разворачивается в карточку и отступ не нужен. */
@media (min-width:761px){ .reg td.m{padding-top:40px} }
.reg .m.txt{text-align:left; white-space:normal; overflow-wrap:anywhere; line-height:1.35}
.reg .size{display:block; margin-top:6px; font-family:var(--f-mono); font-size:0.725rem; color:var(--color-text-muted)}
.reg .size i{font-style:normal}
.v-ok{color:var(--color-yes)}  .v-no{color:var(--color-accent)}
.reg tbody tr{transition:background .12s ease; cursor:pointer}
/* Строка подсвечивается целиком, показывает стрелку и курсор-руку — то есть
   обещает переход. Раньше переход был только в первой ячейке: клик по цене
   или дате подсвечивал строку и ничего не делал. Теперь невидимый слой
   ссылки растянут на всю строку. Других ссылок в строках реестра нет,
   перекрывать нечего. */
.reg tbody tr{position:relative}
.reg a.cell::after{content:""; position:absolute; inset:0}
.reg tbody tr:hover{background:var(--color-accent-bg)}
.reg tbody tr:hover .name .arrow{opacity:1; transform:translateX(0)}
.reg tbody tr:hover td:first-child{box-shadow:inset 3px 0 0 var(--color-accent)}
.reg tr.total td{border-top:2px solid var(--color-text); font-weight:600; padding:14px 16px; font-family:var(--f-mono); font-size:0.85rem; cursor:default}
.reg tr.total td.acc{color:var(--color-accent); font-weight:700}
.reg tr.podpis td{padding:10px 16px 4px; border-bottom:none; font-family:var(--f-mono);
  font-size:0.663rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--color-text-muted); cursor:default; text-align:right}
.reg tr.podpis td:first-child{text-align:left}
.reg tr.podpis:hover{background:transparent}
.reg tr.total:hover{background:transparent}
/* На телефоне таблица разворачивается в карточку: шапка скрывается, и каждая
   ячейка сама называет себя подписью из data-k. Без этого от проекта остаётся
   столбик голых цифр, по которому не понять, где объём, а где цена по рынку. */
@media (max-width:760px){
  .reg thead{display:none}
  .reg tr{display:block; border-bottom:1px solid var(--color-line)}
  .reg td{display:block; border:none}
  .reg a.cell{padding:16px 16px 12px}
  .reg .m{display:flex; flex-wrap:wrap; gap:0 var(--sp-4); align-items:baseline;
    justify-content:space-between; padding:7px 16px; font-size:0.85rem; text-align:right;
    border-top:1px solid var(--color-line)}
  .reg .m::before{content:attr(data-k); flex:0 0 auto; font-size:0.663rem; letter-spacing:.13em;
    text-transform:uppercase; color:var(--color-text-muted); text-align:left}
  .reg .m.txt{text-align:right}
  .reg .m .kto{flex-basis:100%; text-align:right; margin-top:2px}
  .reg .m .razovo{flex-basis:100%; text-align:right}
  .reg .m.skryt, .reg tr.total .m.skryt{display:none}

}

/* --- 24. Первый экран: компактнее и понятнее ------------- */
.hero{padding:var(--sp-6) 0 var(--sp-7); gap:var(--sp-6)}
.hero-name{font-size:clamp(2.5rem,5.4vw,4.4rem); line-height:.92}
.hero-rule{margin-top:var(--sp-4); font-size:1.06rem; max-width:30ch}



.hero-links{margin-top:var(--sp-4)}
.viz{padding:var(--sp-4); gap:var(--sp-3)}
/* Шапка панели в одну строку: слева название, справа просмотры за неделю.
   С 28.09.2026 отдельной строки под число нет — её высота отдана графику. */
.viz-head{display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:var(--sp-2) var(--sp-4);
  border-bottom:1px solid var(--color-line); padding-bottom:var(--sp-3)}
.viz-head .viz-dva{padding-bottom:0}
.viz-head .viz-dva b{font-size:var(--step-1)}
.viz-head > b{font-family:var(--f-display); font-weight:800; font-size:var(--step-1);
  letter-spacing:-.02em; line-height:1.2; color:var(--color-text)}
.viz-chart{padding:var(--sp-3) var(--sp-3) var(--sp-2)}
.viz-rows{gap:5px}
.vrow{font-size:0.725rem}

/* --- 26. Акценты в таблице ------------------------------- */
.badge{
  font-family:var(--f-mono); font-size:0.613rem; letter-spacing:.12em; text-transform:uppercase;
  padding:2px 7px; margin-left:8px; vertical-align:middle; white-space:nowrap;
}
.badge.new{background:var(--color-accent); color:var(--chip-ink)}

/* --- 27. FAQ на главной ---------------------------------- */
.faq-list{border-top:1px solid var(--color-line); max-width:820px}

/* --- 27б. Таблица замера на телефоне ------------------------
   24 вопроса × 5 систем — форма для монитора. На 390 px каждый вопрос
   ломался на шесть строк, две системы уезжали за экран, а страница
   вытягивалась на девять экранов подряд из одних прочерков.
   Разворачиваем в карточку: вопрос строкой, под ним пять меток в ряд. */
@media (max-width:760px){
  .zamer table{min-width:0}
  .zamer thead{display:none}
  .zamer tr{display:block; padding:var(--sp-4) var(--sp-5);
    border-bottom:1px solid var(--color-line)}
  .zamer tr:last-child{border-bottom:none}
  .zamer td{display:block; border:none; padding:0}
  .zamer td:first-child{font-size:0.925rem; line-height:1.45; margin-bottom:var(--sp-3)}
  .zamer td.c{display:none}
  .zamer td.svod-mob{display:block; font-family:var(--f-mono); font-size:0.663rem;
    letter-spacing:.06em; color:var(--color-text-muted)}
}
/* На мониторе матрица читается по столбцам, и сводная строка там лишняя */
.svod-mob{display:none}

/* --- 27б. История замеров на телефоне ---------------------- */
/* Шесть колонок в 333 px не помещаются: «кого называют вместо нас» и
   «методология» уезжали за край — и это они растягивали строки до 90 px,
   так что видимая часть выглядела полупустой, будто вёрстка сломалась.
   Строка становится карточкой: короткие цифры в ряд с подписью, длинные
   тексты — подпись сверху, значение под ней. */
@media (max-width:760px){
  .istoriya{min-width:0}
  .istoriya thead{display:none}
  .istoriya tr{display:block; padding:var(--sp-4) var(--sp-5);
    border-bottom:1px solid var(--color-line)}
  .istoriya tr:last-child{border-bottom:none}
  .istoriya td{display:flex; justify-content:space-between; align-items:baseline;
    gap:0 var(--sp-4); border:none; padding:3px 0; text-align:right}
  .istoriya td::before{content:attr(data-k); flex:0 0 auto; font-family:var(--f-mono);
    font-size:0.663rem; letter-spacing:.13em; text-transform:uppercase;
    color:var(--color-text-muted); text-align:left}
  .istoriya td.dlinno{display:block; text-align:left; padding-top:var(--sp-3)}
  .istoriya td.dlinno::before{display:block; margin-bottom:3px}
}

/* --- 27в. Таблица «кого называют вместо нас» на панели ------ */
/* min-width:0 гасит общее table{min-width:520px}: таблица «домен → число»
   узкая и на телефоне помещается целиком. С общей границей она упиралась
   в 520 px внутри 333 и уезжала вбок без всякой нужды. */
.vmesto{width:100%; max-width:520px; min-width:0; border-collapse:collapse;
  background:var(--color-surface); border:1px solid var(--color-line)}
.vmesto th{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--color-text-muted); font-weight:400;
  text-align:left; padding:10px 16px; border-bottom:1px solid var(--color-line)}
.vmesto th.n{text-align:right}
.vmesto td{padding:9px 16px; font-family:var(--f-mono); font-size:0.85rem;
  border-bottom:1px solid var(--color-line)}
.vmesto td.m{text-align:right; font-variant-numeric:tabular-nums; color:var(--color-text-muted)}
.vmesto tr:last-child td{border-bottom:none}

/* --- 28. Наверх ------------------------------------------ */
.totop{
  display:inline-block; margin-top:var(--sp-5); font-family:var(--f-mono); font-size:0.788rem;
  color:var(--color-text-muted); border-bottom:0;
}

.viz-split{padding-top:var(--sp-2)}

/* --- 30. Мобильная: итоговая строка теми же подписями, что и карточки --- */
@media (max-width:760px){
  /* Повтор шапки перед итогом на телефоне не нужен: итоговая строка теперь
     называет свои цифры сама, а без значений рядом эти подписи висят столбиком. */
  .reg tr.podpis{display:block; padding:14px 16px 0}
  .reg tr.podpis td{display:none; padding:0; border:none}
  .reg tr.podpis td:first-child{display:block; font-family:var(--f-mono); font-size:0.663rem;
    letter-spacing:.13em; text-transform:uppercase; color:var(--color-text-muted)}
  .reg tr.total{display:block; padding:8px 16px 14px; border-top:2px solid var(--color-text)}
  .reg tr.total td{display:block; padding:0; border:none}
  .reg tr.total td:empty{display:none}
  .reg tr.total > td:first-child{font-family:var(--f-mono); font-size:0.663rem;
    letter-spacing:.13em; text-transform:uppercase; color:var(--color-text-muted); margin-bottom:var(--sp-2)}
  .reg tr.total .m{display:flex; justify-content:space-between; align-items:baseline;
    gap:var(--sp-4); padding:4px 0; border:none; text-align:right}
  
  
  
}

/* --- 31. Логотип как меню, AI акцентом -------------------- */
/* Одно определение на файл. Раньше .mark стоял в трёх местах, и из первого
   жил ровно один line-height — остальное перебивалось. Кто убирал первое
   правило как «почти мёртвое», ронял высоту шапки: ровно эта поломка
   вылезла 08.09.2026 в proekt.css, где line-height не был задан вовсе. */
.mark{font-family:var(--f-mono); font-weight:500; font-size:0.725rem; letter-spacing:.16em; text-transform:uppercase; color:var(--color-text); line-height:1; padding:7px 0}

/* --- 32. Первый экран занимает экран целиком -------------- */
.hero{min-height:calc(100svh - 108px); align-content:center; padding:var(--sp-6) 0 var(--sp-7)}
@media (max-width:900px){.hero{min-height:0}}
.hero-name{font-size:clamp(2.7rem,6.2vw,5.2rem)}
.hero-rule{font-size:1.18rem; max-width:28ch}


.viz{padding:var(--sp-5)}

/* --- 35. Первый экран ровно по высоте окна ---------------- */
#top{min-height:100svh; display:flex; flex-direction:column}
#top .hero{flex:1 0 auto; min-height:0; align-content:center}
@media (max-width:900px){#top{min-height:0}#top .hero{flex:0 0 auto}}

/* --- 51. Телефон: первый экран во всю высоту, ссылки прижаты к низу ------
   svh — высота окна при развёрнутой строке браузера. С ней нижняя строка
   никогда не уезжает под адресную строку, в отличие от vh и dvh.
   190px — шапка с меню в две строки плюс верхний отступ хиро. */
@media (max-width:760px){
  #top{min-height:100svh; display:flex; flex-direction:column}
  /* Свой отступ сверху убран: он складывался с auto-отступом, и воздух над
     заголовком выходил на 28 px больше, чем над ссылками. */
  #top > .hero{display:flex; flex-direction:column; gap:var(--sp-8); flex:1 1 auto;
    padding-top:0}
  #top > .hero > div:first-child{display:flex; flex-direction:column;
    min-height:calc(100svh - 190px)}
  /* Два auto-отступа делят свободное место поровну: часть встаёт над
     заголовком, часть над ссылками. Один auto собрал бы всё в одну дыру. */
  #top .hero-name{margin-top:auto}
  #top .hero-links{margin-top:auto; padding-bottom:var(--sp-5)}

  /* воздух между блоками: на телефоне ритм крупнее, чем на десктопе */
  .sec{padding:var(--sp-8) 0; gap:var(--sp-6)}
  .hero-rule{margin-top:var(--sp-5)}
  .numstrip .inner{gap:1px}
  .numstrip .tile{padding:var(--sp-5) var(--sp-4)}
}
/* Блоки первого экрана — во всю ширину колонки: с выравниванием по центру на
   iPad mini они сжимались до 464 px посреди экрана (08.10.2026). */
@media (max-width:760px){#top > .hero{align-items:stretch}}
/* Высота «во весь экран» — только телефонам. На iPad mini (744×1133) она давала
   первому блоку 943 px и пустоту в 250 px перед ссылками (08.10.2026). */
@media (min-width:601px) and (max-width:760px){
  #top{min-height:0}
  #top > .hero{padding-top:var(--sp-6)}
  #top > .hero > div:first-child{min-height:0}
  #top .hero-links{margin-top:var(--sp-6)}
}
/* Первый экран «ровно по высоте окна» — для горизонтальных экранов. На iPad Pro
   вертикально (1024×1366) он растягивался до 1366 px с пустотами сверху и снизу. */
@media (min-width:901px) and (orientation:portrait){
  #top{min-height:0}
  #top .hero, .hero{min-height:0}
}

/* --- 36. Блок «Проверить самому» -------------------------- */
.verify-rows{display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:1px; background:var(--color-line); border:1px solid var(--color-line)}
.verify-rows a{background:var(--color-bg); padding:var(--sp-4); display:flex; flex-direction:column; gap:var(--sp-1)}
.verify-rows a span{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.14em; text-transform:uppercase; color:var(--color-text-muted)}
.verify-rows a b{font-weight:600; font-size:0.925rem}
.verify-rows a:hover b{color:var(--color-accent)}
.verify-note{font-size:0.85rem; color:var(--color-text-muted); max-width:64ch}

/* --- 37. Журнал правок ------------------------------------ */
.log{display:flex; flex-direction:column; border-top:1px solid var(--color-line); max-width:820px}
.log-row{display:grid; grid-template-columns:110px 1fr; gap:var(--sp-5); padding:var(--sp-4) 0; border-bottom:1px solid var(--color-line)}
.log-row .d{font-family:var(--f-mono); font-size:0.788rem; color:var(--color-text-muted); font-variant-numeric:tabular-nums}
.log-row .t{font-size:0.925rem; max-width:60ch}
.log-row .t .where{font-family:var(--f-mono); font-size:0.725rem; color:var(--color-accent); margin-right:8px}
@media (max-width:600px){.log-row{grid-template-columns:1fr; gap:var(--sp-1)}}

/* --- 38. Страница 404 ------------------------------------- */
.nf{display:flex; flex-direction:column; gap:var(--sp-5); padding:var(--sp-8) 0; min-height:52svh; justify-content:center; align-items:flex-start}
.nf .code{font-family:var(--f-display); font-weight:800; font-size:clamp(4rem,14vw,8rem); line-height:1; color:var(--color-accent); font-variant-numeric:tabular-nums}
.nf p{max-width:44ch}

.reg span.cell{display:block; padding:16px}

/* без переноса квадратика (08.10.2026): на телефоне он оставался на строке один,
   а текст уходил под него */
.press-media{font-family:var(--f-mono); font-size:0.725rem; letter-spacing:.12em; text-transform:uppercase; color:var(--color-text-muted); display:flex; align-items:flex-start; gap:10px}
.press-media .sq{margin-top:.35em}
.press-media em{font-style:normal; color:var(--color-text)}
.press-media .sq{width:8px; height:8px; background:var(--color-accent); display:inline-block; flex:0 0 auto}

/* --- 40. Реестр: стабильные колонки и стыки тел таблицы ---- */
@media (min-width:761px){
  .reg{table-layout:fixed}
  .reg col.c-name{width:43%} .reg col.c-vol{width:12%} .reg col.c-cost{width:16%} .reg col.c-mkt{width:18%} .reg col.c-date{width:11%}
}
/* iPad вертикально (08.10.2026): дата «Sep 29, 2026» и «29.09.2026» не влезала в 11 %
   и вылезала за рамку таблицы — колонке даты место за счёт названия, отступы уже */
@media (min-width:761px) and (max-width:1100px){
  .reg col.c-name{width:37%} .reg col.c-vol{width:13%} .reg col.c-date{width:16%}
  .reg td.m{padding-left:8px; padding-right:12px}
}
.reg tbody:not(:last-child) tr:last-child td{border-bottom:1px solid var(--color-line)}

/* --- 42. Переключатель темы -------------------------------- */
.theme-btn{background:none; border:none; cursor:pointer; color:var(--color-text-muted); padding:0 2px;
  display:inline-flex; align-items:center; justify-content:center}
/* Круг темы и цвет при наведении — в конце osnova.css, общие со статьями. */

/* --- 43. Второй экран: автор + карта ----------------------- */
.about2{display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,1fr); gap:var(--sp-7); align-items:center}
/* minmax(0,1fr), а не 1fr: у элемента грида min-width:auto, и колонка
   растягивается под самое широкое содержимое. С картой на 700 px это
   распирало страницу вместо того, чтобы включить прокрутку внутри карты. */
@media (max-width:900px){.about2{grid-template-columns:minmax(0,1fr)}}

/* --- 44. Цифровая полоса между экранами: плитки ------------ */
.numstrip .inner{max-width:var(--wide); margin:0 auto; display:grid; grid-template-columns:repeat(5,1fr); gap:1px;
  border-top:1px solid var(--color-line); border-bottom:1px solid var(--color-line)}
.numstrip .tile{background:var(--color-surface); padding:var(--sp-4) var(--sp-5); display:flex; flex-direction:column; gap:3px}
.numstrip .tile b{font-family:var(--f-display); font-weight:800; font-size:1.4rem; line-height:1.1; color:var(--color-text); font-variant-numeric:tabular-nums}
.numstrip .tile.akcent b{color:var(--color-accent)}
.numstrip .tile > span{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.11em; text-transform:uppercase; color:var(--color-text-muted)}
@media (max-width:900px){.numstrip .inner{grid-template-columns:repeat(2,1fr)}
  /* нечётная последняя плитка — на всю ширину, без пустой клетки рядом (08.10.2026) */
  .numstrip .tile:last-child:nth-child(odd){grid-column:1 / -1}}
@media (max-width:420px){.numstrip .inner{grid-template-columns:1fr}}

/* --- 44б. Первый экран с 28.09.2026: модели, системы, живой график ---
   Цена ушла из первого экрана в полосу цифр под ним: она не менялась
   неделями, и сайт казался застывшим. Слева — чем работаем и что уже
   работает, справа — видимость, которая обновляется каждое утро. */
.hero-rule.hero-offer{font-family:var(--f-display); font-weight:700; font-size:clamp(1.25rem,1.7vw,1.5rem);
  line-height:1.25; letter-spacing:-.015em; color:var(--color-text); max-width:none}
.hero-offer strong{font-weight:inherit; color:var(--color-accent)}
/* Модели плашками: у каждой маджентовая точка «в работе». Уголок как у панелей. */
.modeli-chipy{margin-top:var(--sp-4); display:flex; flex-wrap:wrap; gap:8px}
.modeli-chipy span{display:inline-flex; align-items:center; gap:8px; padding:5px 11px 5px 10px;
  border:1px solid var(--color-line); border-radius:var(--ugol); background:var(--color-surface);
  font-family:var(--f-mono); font-size:.74rem; letter-spacing:.02em; color:var(--color-text); white-space:nowrap}
.modeli-chipy span::before{content:""; width:6px; height:6px; border-radius:50%; background:var(--color-accent)}
/* Что уже работает: серым и с тонкой иконкой, чтобы не спорить с заголовком */
.rabotaet{margin-top:var(--sp-6); display:grid; grid-template-columns:1fr 1fr; gap:2px var(--sp-5); max-width:34rem}
.rabotaet .label{grid-column:1/-1; margin-bottom:var(--sp-2)}
.rabotaet a{display:flex; align-items:center; gap:10px; padding:6px 0; text-decoration:none;
  font-size:.9rem; line-height:1.35; color:var(--color-text-muted); transition:color .15s}
.rabotaet svg{flex:none; opacity:.75; transition:color .15s, opacity .15s}
.rabotaet a:hover{color:var(--color-text)}
.rabotaet a:hover svg{color:var(--color-accent); opacity:1}
@media (max-width:560px){.rabotaet{grid-template-columns:1fr}}
/* Ссылки: Telegram первым и акцентом; на телефоне — своей строкой */
.hero-links{flex-wrap:wrap; row-gap:var(--sp-2)}
.hero-links a{white-space:nowrap}
.hero-links a.tg{color:var(--color-accent)}
.hero-links a.tg:hover{color:var(--color-text)}
@media (max-width:560px){
  .hero-links a.tg{flex-basis:100%}
  .hero-links a.tg + .sep{display:none}
}

/* --- 44в. Главный момент первого экрана: линии прочерчиваются ---
   С начала замеров до сегодня; когда линия «все просмотры» доходит до конца,
   число в шапке панели загорается маджентой, у концов линий появляются
   подписи и от последней точки расходится одно кольцо. Без движения —
   «уменьшить движение», печать, высокая контрастность — всё стоит на месте. */
.volna{opacity:0}
@media screen and (prefers-reduced-motion:no-preference) and (forced-colors:none){
  .viz-chart .put{stroke-dasharray:1; animation:prochert 1.5s cubic-bezier(.45,0,.2,1) .35s both}
  .viz-chart .put-ya{animation-delay:.45s}
  .viz-chart .put-go{animation-delay:.5s}
  .viz-chart .put-obl{animation:proyavka .7s ease-out 1.5s both}
  .viz-chart .apdeyt path{transform-box:fill-box; transform-origin:50% 100%;
    animation:rost .45s cubic-bezier(.16,1,.3,1) both}
  .viz-chart .apdeyt .a0{animation-delay:1.35s} .viz-chart .apdeyt .a1{animation-delay:1.45s}
  .viz-chart .apdeyt .a2{animation-delay:1.5s}  .viz-chart .apdeyt .a3{animation-delay:1.6s}
  .viz-chart .apdeyt-podp{animation:proyavka .4s ease-out 1.45s both}
  .viz-chart .tochki-kon{animation:proyavka .15s ease-out 1.85s both}
  .viz-chart .podpisi{animation:proyavka .4s ease-out 1.9s both}
  .viz-chart .volna{transform-box:fill-box; transform-origin:center;
    animation:volna 1s cubic-bezier(.16,1,.3,1) 1.9s forwards}
  .viz-head b.pro{animation:zagoraetsya .35s ease-out 1.85s both}
}
@keyframes prochert{from{stroke-dashoffset:1}}
@keyframes proyavka{from{opacity:0}}
@keyframes rost{from{transform:scaleY(0)}}
@keyframes volna{from{opacity:.6; transform:scale(1)} to{opacity:0; transform:scale(3.5)}}
@keyframes zagoraetsya{from{color:var(--color-text)}}

/* строка под ценой в реестре: что это за цена и откуда */
.reg .kto{display:block; margin-top:4px; font-family:var(--f-mono); font-size:0.663rem;
  line-height:1.35; letter-spacing:.02em; color:var(--color-text-muted);
  white-space:normal; text-align:right}

/* --- 45. Тэглайн хиро: подстрочный, лёгкий ------------------ */
.hero-rule{font-family:var(--f-body); font-weight:400; font-size:1rem; line-height:1.6; letter-spacing:0; color:var(--color-text-muted); max-width:42ch}

/* --- 46. Ревизия 24.08: шапка, полоса, реестр --------------- */

/* 19 · тап-таргеты: пункты меню до 24px, кегль не трогаем */
.nav a{padding-top:5px; padding-bottom:5px; border-bottom-width:1px}
.nav a:hover,.nav a[aria-current]{border-bottom-color:var(--color-accent)}

/* 15 · мобильная шапка в две строки: кнопка темы уходит на строку логотипа */
@media (max-width:620px){
  .top{position:relative; padding-right:34px}
  .theme-btn{position:absolute; top:var(--sp-6); right:0; padding:6px 4px}
  .nav{gap:var(--sp-2) var(--sp-4)}
}

/* 17 · у полосы цифр больше нет собственного фона — по краям видно страницу */
.numstrip{background:transparent}
.numstrip .inner{background:var(--color-line)}

/* 16 · на мобильном реестр раскладывается карточками, ширина таблицы не нужна */
@media (max-width:760px){
  .reg{min-width:0}
}

/* --- 47. Тап-таргеты: всё, что не ссылка внутри строки текста, — от 24px --- */
.theme-btn{min-width:24px; display:inline-flex; align-items:center; justify-content:center}
.foot-meta a{padding:4px 0; display:inline-block}
.sec > p > a.link:only-child{padding:2px 0; display:inline-block}

/* --- 48. Тап-таргеты: одиночные ссылки-строки ---------------- */
.hero-links a{padding:4px 0}
.viz a.link, .totop, .article + p a.link{padding:3px 0; display:inline-block}
.page > p > a.link{padding:3px 0; display:inline-block}

/* --- 50. Утилиты вместо инлайновых стилей ---------------------
   Инлайновый style="" запрещён строгой политикой CSP: чтобы браузер
   мог отличить нашу разметку от подсунутой, стили живут только в файлах. */
.svg-fluid{width:100%; height:auto}

/* --- 33. Схемы на телефоне -------------------------------- */
/* Текст в SVG масштабируется вместе с картинкой: на 390 px подписи падали
   до 5,2–5,9 px при читаемом минимуме 12. Лечится по-разному, потому что
   схемы разные. */
@media (max-width:760px){
  /* График: в нём важна форма, он должен быть виден целиком. Поэтому не
     прокрутка, а крупнее шрифт и вдвое меньше дат — восемь при таком кегле
     сходятся вплотную. 15 — это единицы viewBox, на экране выходит ~10 px. */
  .viz-chart .svg-fluid text{font-size:15px; letter-spacing:0}

  /* Карта целиком в ширину экрана (08.10.2026). Прежде держали 700px и листали
     вбок — на телефоне были видны 2 столбца из 5. Подписи строк стоят над линиями,
     а не на них, и кегль 18 единиц viewBox (~9,5 px на экране) узлов не задевает:
     в строке «ИНФРАСТРУКТУРА» единственный узел далеко справа. */
  .karta text{font-size:18px; letter-spacing:1px}
}
.sec-first{border-top:none}
.mera{max-width:var(--measure)}
.mt0{margin-top:0}
.mt3{margin-top:var(--sp-3)}
.mt5{margin-top:var(--sp-5)}
.mt6{margin-top:var(--sp-6)}

.mb5{margin-bottom:var(--sp-5)}
.my6{margin:var(--sp-6) 0}
.fs76{font-size:0.788rem}
.fs88{font-size:0.85rem}
.fs90{font-size:0.925rem}
.fs94{font-size:0.925rem}

/* --- 12. Исследования: витрина на главной, список раздела ------------------
   Плитки собирает build.py из src/research/*.json через articles/research.py.
   Синий второго ряда — цвет ряда «Яндекс» на панели (--color-poisk). */
/* ── «04 · Статьи» на главной (29.09.2026): свежая статья крупно слева, лента
   справа. Сетка с волосяными линиями, как у витрины исследований. Строка без
   адреса — div без наведения: статьи готовятся, ссылок пока нет. */
.stati{display:grid; grid-template-columns:minmax(0,1.35fr) minmax(0,1fr); gap:1px; background:var(--color-line); border:1px solid var(--color-line); border-radius:var(--ugol); overflow:hidden}
.stati .glavn{background:var(--color-surface); padding:var(--sp-7) var(--sp-6); display:flex; flex-direction:column; justify-content:center; gap:var(--sp-4)}
.stati .glavn h3{font-size:var(--step-3); line-height:1.1; max-width:18ch}
.stati .glavn .lid{font-size:1.02rem; line-height:1.5; max-width:46ch}
.stati .glavn .lid strong{color:var(--color-accent)}
.stati strong{white-space:nowrap}   /* «8–69» не рвётся по тире на телефоне */
.stati .glavn .citata{font-family:var(--f-display); font-weight:700; font-size:1.3rem; line-height:1.3; max-width:30ch;
  padding-left:var(--sp-4); border-left:3px solid var(--color-accent); margin:var(--sp-3) 0}
.stati .glavn .dalee{font-family:var(--f-mono); font-size:0.788rem; color:var(--color-accent)}
.stati .lenta{background:var(--color-surface); display:flex; flex-direction:column}
.stati .st{padding:var(--sp-4) var(--sp-5); border-bottom:1px solid var(--color-line); display:flex; flex-direction:column; gap:6px}
.stati .st:last-child{border-bottom:0}
.stati h4{margin:0; font-family:var(--f-display); font-weight:700; font-size:1rem; line-height:1.3}
.stati .k{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.14em; text-transform:uppercase; color:var(--color-accent)}
.stati .k i{font-style:normal; color:var(--color-text-muted)}
.stati .st p{font-size:0.875rem; line-height:1.45; color:var(--color-text-muted)}
.stati .st p strong{color:var(--color-text); font-weight:600}
.stati a:hover h3,.stati a:hover h4{color:var(--color-accent)}
@media (max-width:760px){.stati{grid-template-columns:1fr} .stati .glavn{padding:var(--sp-6) var(--sp-5)}}

.sec-row{display:flex; justify-content:space-between; align-items:flex-end; gap:var(--sp-5); flex-wrap:wrap}
.sec-row .more{font-family:var(--f-mono); font-size:0.788rem; color:var(--color-text-muted); padding:3px 0; border-bottom:1px solid var(--color-line)}
.sec-row .more:hover{color:var(--color-accent); border-color:var(--color-accent)}
.vg{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1px; background:var(--color-line); border:1px solid var(--color-line)}
.vg a{background:var(--color-surface); padding:var(--sp-5); display:flex; flex-direction:column; gap:var(--sp-3); min-height:280px; min-width:0}
.vg a:hover{background:var(--color-bg)}
.vg a:hover h3{color:var(--color-accent)}
.vg .k{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.14em; text-transform:uppercase; color:var(--color-accent)}
.vg h3{font-size:1.06rem; line-height:1.3; max-width:30ch}
.vg .plot{width:100%; height:178px; display:flex; flex-direction:column; justify-content:center; margin-top:var(--sp-2)}
.vg .plot svg{width:100%; height:auto; max-height:178px; display:block; overflow:visible}
.vg a.last .plot{justify-content:flex-end}
.vg .ans{margin-top:auto; font-size:0.925rem; line-height:1.45; color:var(--color-text)}
.vg .ans b{color:var(--color-accent); font-weight:700}
.vg .scale{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.02em; color:var(--color-text-muted); line-height:1.6}
.vg svg text{font-family:var(--f-mono); font-size:10px; fill:var(--color-text-muted)}
.vg svg text.big{font-family:var(--f-display); font-weight:800; font-size:22px; fill:var(--color-text); letter-spacing:-.02em}
.vg svg text.big.hot{fill:var(--color-accent)}
.vg svg text.dark{fill:var(--color-text)}
.vg svg text.acct{fill:var(--color-accent); font-family:var(--f-display); font-weight:700}
.vg svg .ax{stroke:var(--color-text-muted); stroke-width:1}
.vg svg .grid{stroke:var(--color-line); stroke-width:1}
.vg svg .acc{fill:var(--color-accent)} .vg svg .accs{stroke:var(--color-accent); stroke-width:3}
.vg svg .mut{fill:var(--color-text-muted)}
.vg svg .sunk{fill:var(--color-sunk)}
.vg svg .blue{fill:var(--color-poisk)}
.vg .waffle{display:grid; grid-template-columns:repeat(20,1fr); gap:2px}
.vg .waffle i{display:block; aspect-ratio:1; background:var(--color-sunk)}
.vg .waffle i.a{background:var(--color-accent)} .vg .waffle i.b{background:var(--color-poisk)}
.vg .legend2{display:flex; gap:var(--sp-4); flex-wrap:wrap; margin-top:8px; font-family:var(--f-mono); font-size:0.663rem; color:var(--color-text-muted)}
.vg .legend2 span{display:flex; gap:6px; align-items:center} .vg .legend2 i{width:9px; height:9px; display:block}
.vg .legend2 .c1 i{background:var(--color-accent)} .vg .legend2 .c2 i{background:var(--color-poisk)} .vg .legend2 .c0 i{border:1.5px solid var(--color-text-muted); box-sizing:border-box}
.vg .bign{font-family:var(--f-display); font-weight:800; font-size:3.6rem; line-height:1; letter-spacing:-.03em; font-variant-numeric:tabular-nums}
.vg .bign small{display:block; font-family:var(--f-body); font-weight:400; font-size:0.9rem; letter-spacing:0; color:var(--color-text-muted); margin-top:6px; line-height:1.4; max-width:28ch}
@media (max-width:900px){.vg{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.vg{grid-template-columns:1fr} .vg a{min-height:0} .vg .plot{height:auto}}

/* Графика плиток собирается, пока плитка входит в экран. Каждая форма рисует
   свой смысл: гантель тянется от дешёвого к дорогому, полосы долей
   заполняются по очереди, отметки уровней встают на места (дефицит
   последним), 141 клетка вафли проступают рядами — и ни одна не розовеет.
   Двигается только графика: заголовки, ответы, подписи и числа в SVG стоят
   на месте. Анимация привязана к прокрутке, скрипта нет. Браузер без
   animation-timeline и «уменьшить движение» показывают готовую картинку. */
@supports (animation-timeline:view()){
@media screen and (prefers-reduced-motion:no-preference){
  .vg .plot{view-timeline:--plot block}
  .vg svg .accs, .vg svg rect.acc{transform-box:fill-box; transform-origin:0 50%;
    animation:rastyazhka cubic-bezier(.16,1,.3,1) both; animation-timeline:--plot; animation-range:cover 8% cover 26%}
  .vg svg:has(.accs) circle.acc,
  .vg svg:has(.acct) circle:is(.mut,.acc){transform-box:fill-box; transform-origin:50% 50%;
    animation:tochka cubic-bezier(.16,1,.3,1) both; animation-timeline:--plot; animation-range:cover 20% cover 30%}
  .vg svg rect.acc:nth-of-type(4){animation-range:cover 11% cover 29%}
  .vg svg rect.acc:nth-of-type(6){animation-range:cover 14% cover 32%}
  .vg svg:has(.acct) circle:nth-of-type(3){animation-range:cover 8% cover 18%}
  .vg svg:has(.acct) circle:nth-of-type(6){animation-range:cover 11% cover 21%}
  .vg svg:has(.acct) circle:nth-of-type(11){animation-range:cover 14% cover 24%}
  .vg .waffle i{animation:kletka ease-out both; animation-timeline:view(); animation-range:cover 6% cover 20%}
}
}
@keyframes rastyazhka{from{transform:scaleX(0)}}
@keyframes tochka{from{transform:scale(0)}}
@keyframes kletka{from{opacity:.15; transform:scale(.6)}}
/* Тот же переход, что в шапке секции, продублирован под витриной: человек,
   долиставший плитки до конца, иначе упрётся в тупик. Секция — флекс-колонка
   с gap, поэтому отступ сверху задавать не нужно, он уже есть. */
.vg-vse{display:flex; justify-content:flex-end}
.vg-vse a{font-family:var(--f-mono); font-size:0.788rem; color:var(--color-text-muted); padding:8px 2px; border-bottom:1px solid var(--color-line)}
.vg-vse a:hover{color:var(--color-accent); border-color:var(--color-accent)}
/* На узком экране ссылка встаёт по центру и получает поле под палец. Рамку
   во всю ширину не делаем: пустая коробка на точечном фоне читается как дыра. */
@media (max-width:560px){.vg-vse{justify-content:center} .vg-vse a{padding:14px 10px}}

.rlist{display:flex; flex-direction:column; border-top:1px solid var(--color-line)}
/* Своя верхняя линейка нужна списку, только если над ним что-то есть.
   Первым в секции он рисовал вторую линию в сорока пикселях под линейкой
   самой секции, и между ними висела пустая полоса — та же болезнь, что
   у .factline выше, и лечится так же: линию рисует секция. */
.sec > .rlist:first-child{border-top:none}
.rlist a{display:grid; grid-template-columns:120px minmax(0,1fr) 250px; gap:var(--sp-3) var(--sp-6); padding:var(--sp-6) 0; border-bottom:1px solid var(--color-line); align-items:start}
.rlist a:hover h3{color:var(--color-accent)}
.rlist .no{display:flex; flex-direction:column; gap:4px}
.rlist .no b{font-family:var(--f-display); font-weight:800; font-size:1.7rem; line-height:1; color:var(--color-accent); font-variant-numeric:tabular-nums}
.rlist .no span{font-family:var(--f-mono); font-size:0.663rem; letter-spacing:.1em; text-transform:uppercase; color:var(--color-text-muted)}
.rlist h3{font-size:1.25rem; line-height:1.25; max-width:34ch}
.rlist .ans{font-size:0.95rem; line-height:1.5; margin-top:var(--sp-2); max-width:62ch}
.rlist .ans b{color:var(--color-accent)}
.rlist .scale{font-family:var(--f-mono); font-size:0.663rem; color:var(--color-text-muted); margin-top:var(--sp-2); line-height:1.6}
.rlist .num{border-left:1px solid var(--color-line); padding-left:var(--sp-5); display:flex; flex-direction:column; gap:4px}
.rlist .num b{font-family:var(--f-display); font-weight:800; font-size:2rem; line-height:1; font-variant-numeric:tabular-nums}
.rlist .num span{font-size:0.82rem; color:var(--color-text-muted); line-height:1.4}
/* Две цены столбиком, обе одного кегля: сверху сколько стоила бы работа
   по рынку, под ней сколько стоила на деле. Розовый на этом сайте значит
   себестоимость — так покрашена полоса фактов и колонка в витрине на
   главной, где «по рынку» просто жирная.
   Подпись идёт под своим числом бровью: моноширинный в разрядку прописными,
   тот же голос, что у рубрикаторов, шапок таблиц и даты под номером проекта.
   Отступы посчитаны от gap:4px у .num, поэтому здесь на четыре меньше.
   Правила метят .pod и b.seb, которых нет в списке исследований: там справа
   не цена, а результат, и трогать его незачем. */
.rlist .num b.seb{color:var(--color-accent); margin-top:10px}
.rlist .num b.raz{margin-top:10px}
.rlist .num .pod{display:block; margin-top:1px; font-family:var(--f-mono);
  font-size:0.663rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--color-text-muted); line-height:1.4}
/* Пояснение под бровью — тот же кегль, но строчными и без разрядки:
   ярлык и примечание не должны читаться одинаково. */
.rlist .num .kto{display:block; margin-top:2px; font-family:var(--f-mono);
  font-size:0.663rem; line-height:1.35; letter-spacing:.02em;
  text-transform:none; font-style:normal}
@media (max-width:760px){.rlist a{grid-template-columns:1fr} .rlist .num{border-left:0; padding-left:0; border-top:1px solid var(--color-line); padding-top:var(--sp-3)}}

/* ── Скругление внешних углов блоков (20.09.2026, решение Романа) ──
   То же правило, что в proekt.css: радиус у контейнера, внутри всё прямое.
   Реестр на главной — голая таблица со схлопнутыми рамками, радиус к ней
   не применяется; её оставили прямой намеренно. */
:root{--ugol:10px}
.vg,.verify-rows{border-radius:var(--ugol); overflow:hidden}
.cookie,.tw,.shot,.viz,.viz-chart,details.code{border-radius:var(--ugol)}
/* Реестр — таблица: радиус работает только при раздельных рамках. Строка «Итого»
   рисует свою линию сверху, поэтому у строки над ней нижнюю линию убираем. */
.reg{border-collapse:separate; border-spacing:0; border-radius:var(--ugol); overflow:hidden}
.reg tr:has(+ tr.total) td{border-bottom:none}
/* две крупные статьи слева, одна под другой (10.10.2026): одна крупная стояла посреди пустой колонки */
.stati .glavnye{display:grid; grid-template-rows:1fr 1fr; gap:1px; background:var(--color-line)}
/* строки ленты равной высоты: граница между двумя крупными слева приходится ровно
   на границу второй и третьей статьи справа (проверка дизайнера 10.10.2026: промах в 11–21 px) */
.stati .lenta{display:grid; grid-template-rows:repeat(4,1fr)}
.stati .glavnye .glavn{padding:var(--sp-6); justify-content:flex-start}
.stati .glavnye .glavn h3{font-size:var(--step-2); line-height:1.15; max-width:24ch}
.stati.bez-lenty{grid-template-columns:1fr}
@media (max-width:760px){
  .stati .lenta{grid-template-rows:none}
  .stati .glavnye .glavn{padding:var(--sp-5) var(--sp-5) var(--sp-6)}
  .stati .glavnye .glavn h3{font-size:1.4rem}
  /* на телефоне лента короче: описание до трёх строк */
  .stati .st p{display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden}
}
