/* breakout — витрина. Канон: DESIGN.md (Linear, midnight precision instrument). */

/* Единственная семья сервиса — Inter Variable, свои файлы в static/fonts:
   без @font-face каждый браузер рисовал случайным системным шрифтом (2026-09-01) */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-var-cyr-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: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-var-cyr.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-var-lat-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;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-var-lat.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 {
  --color-void:       #08090a;
  --color-carbon:     #0f1011;
  --color-obsidian:   #161718;
  --color-graphite:   #23252a;
  --color-smoke:      #383b3f;
  --color-ash:        #797d84;   /* был #62666d (3.45:1 на void) — 4.8:1, порог HIG 4.5:1 для текста до 17 pt (2026-09-15, apple-design) */
  --color-fog:        #8a8f98;
  --color-mist:       #d0d6e0;
  --color-bone:       #e5e5e6;
  --color-paper:      #ffffff;
  --color-acid-lime:  #e4f222;

  --font-ui:   "Inter", "Inter Variable", system-ui, -apple-system, sans-serif;
  /* цифры-метаданные — та же семья: разнобой убирает tabular-nums, не вторая семья */
  --font-num:  var(--font-ui);
  --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;   /* код на «MCP / CLI» (2026-09-15) */
  /* машинные строки (ключ, команда агента) — единственное место, где равноширинность несёт смысл */
  --font-code: ui-monospace, "SF Mono", Menlo, monospace;

  --spacing-4: 4px;   --spacing-8: 8px;   --spacing-12: 12px; --spacing-16: 16px;
  --side-w: 256px;   /* панель; .work отступает на неё же (ревью 2026-09-15: три литерала) */
  --spacing-20: 20px; --spacing-24: 24px; --spacing-32: 32px; --spacing-40: 40px;
  --spacing-64: 64px;

  --radius-card: 16px;
  --radius-btn: 8px;
  --radius-badge: 8px;
  --radius-pill: 9999px;

  --shadow-subtle: rgb(35, 37, 42) 0 0 0 1px inset;
  --shadow-xl: rgba(8, 9, 10, .6) 0 4px 32px 0;

  --page: 1200px;
}

* { box-sizing: border-box; }

/* Атрибут `hidden` прячет НАСМЕРТЬ. Браузерный дефолт `display: none` бьётся любым классом
   с display, и элемент выходит на экран, хотя разметка его прячет: так вылезли три вкладки
   шторки разом (2026-09-11) и поле переименования в каждой строке чата (2026-09-12).
   Одно правило вместо точечных `.foo[hidden]` у каждого нового блока. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  /* clip, не hidden: hidden делает body скролл-контейнером, и sticky-панель
     липнет к нему, а не к окну — то есть не липнет вовсе (баг 2026-08-30) */
  overflow-x: clip;
  background: var(--color-void);
  color: var(--color-mist);
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.6;
  letter-spacing: -.165px;
  /* табличные цифры всюду: колонки чисел стоят ровно без моноширинной семьи */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

/* iPhone (спека 2026-09-16, HIG › Dynamic Type): в Safari на телефоне корневой кегль берётся из системного размера
   текста, остальное — в rem от него. Только телефон и только там, где браузер это понимает; стол не трогаем */
@supports (font: -apple-system-body) {
  @media (max-width: 900px) and (hover: none) {
    html { font: -apple-system-body; }
    body { font-size: .88rem; }          /* 15 / 17 */
  }
}

a { color: inherit; text-decoration: none; }

.wrap { max-width: var(--page); margin: 0 auto; padding: 0 var(--spacing-24); }

/* ── каркас сервиса: панель слева, работа справа ──────────── */

.app { display: flex; align-items: flex-start; min-height: 100vh;
  padding: var(--spacing-12); gap: var(--spacing-12); }

/* панель прибита к экрану, не «прилипает» (2026-09-15): sticky-панель при масштабе экрана 1.25/1.5
   перерисовывалась на каждом шаге прокрутки со сдвигом в доли пикселя — тонкие значки дрожали
   (оператор: «скачет значок у Поиска и Сохранённого»); fixed от прокрутки не зависит вовсе.
   Место под неё в потоке держит .work своим отступом слева */
.side {
  position: fixed; top: var(--spacing-12); left: var(--spacing-12);
  width: var(--side-w); height: calc(100vh - var(--spacing-12) * 2);   /* 232 → 256 (оператор 2026-09-14: тесно) */
  display: flex; flex-direction: column; gap: var(--spacing-24);
  padding: var(--spacing-20) var(--spacing-16);
  background: var(--color-carbon);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-subtle);
}
.side .brand { font-size: 15px; font-weight: 510; color: var(--color-paper); }
/* маскот у словомарки (2026-09-15): бурый кабан с лаймовой холкой, как лиса у loore */
.brand { display: inline-flex; align-items: center; gap: 8px; }
.brand-mark { width: 24px; height: 24px; flex: 0 0 auto; }
.auth-card .brand-mark { width: 28px; height: 28px; }

/* раскрытые «Чаты» уезжали за карточку тарифа и профиль (оператор 2026-09-13): панель — колонка
   высотой в экран, прокручивается только список разделов, карточка тарифа и профиль стоят внизу */
.side-nav { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain; margin-right: -8px; padding-right: 8px;
  scrollbar-width: thin; scrollbar-color: var(--color-graphite) transparent; }
.side-group {
  margin: var(--spacing-16) 0 var(--spacing-4); padding: 0 var(--spacing-8);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-ash);
}
.side-i {
  display: flex; align-items: center; gap: var(--spacing-8);
  padding: 7px var(--spacing-8); border-radius: var(--radius-btn);
  font-size: 14px; color: var(--color-mist); letter-spacing: -.011em;
}
/* один набор значков (icons.py): семья Lucide, 24×24, штрих 1.5; размер задаёт контекст */
.ic { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.side-i svg {
  width: 16px; height: 16px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.side-i:hover { background: var(--color-obsidian); color: var(--color-paper); }
.side-i.on { background: var(--color-obsidian); color: var(--color-paper); box-shadow: var(--shadow-subtle); }
.side-i.off { color: var(--color-ash); cursor: default; }
.side-i.off:hover { background: none; color: var(--color-ash); }
.side-i:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }

.side-foot { display: flex; flex-direction: column; gap: var(--spacing-12); }
/* карточка тарифа: header (план + действие) / body (остаток токенов + полоска) — холст 2026-09-06 */
.plan { border-radius: var(--radius-btn); background: var(--color-obsidian); box-shadow: var(--shadow-subtle);
  display: flex; flex-direction: column; }
.plan-head { display: flex; justify-content: space-between; align-items: center; gap: var(--spacing-8);
  padding: 10px var(--spacing-12) 8px; }
.plan-id { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.plan-name { font-size: 13px; color: var(--color-paper); }
.plan-sub { font-size: 11px; color: var(--color-ash); white-space: nowrap; }
.plan-act { flex: 0 0 auto; font-size: 11px; color: var(--color-fog); padding: 3px 8px; border-radius: var(--radius-btn);
  box-shadow: var(--shadow-subtle); text-decoration: none; }
.plan-act:hover { color: var(--color-paper); box-shadow: inset 0 0 0 1px var(--color-smoke); }
.plan-act:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.plan-body { display: flex; flex-direction: column; gap: 6px; padding: 0 var(--spacing-12) var(--spacing-12); }
/* карточка — ссылка на Баланс (оператор 2026-09-15): ведёт себя как пункт меню, светлеет и на Балансе горит */
a.plan { text-decoration: none; color: inherit; transition: box-shadow .15s ease; }
a.plan:hover, a.plan.on { box-shadow: inset 0 0 0 1px var(--color-smoke); }
a.plan:hover .plan-act, a.plan.on .plan-act { color: var(--color-paper); }
a.plan:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }

/* Баланс — сетка loore /cabinet/billing (оператор 2026-09-15): карточка остатка, четыре плитки, «По дням»,
   «Операции»; наши цвета и шрифты, их пропорции (плитка 264×129, радиус карточки, подпись капителью) */
.bal-lead { padding-bottom: var(--spacing-16); }
.bal-card { background: var(--color-carbon); border-radius: var(--radius-card); box-shadow: var(--shadow-subtle);
  padding: var(--spacing-20); display: flex; flex-direction: column; gap: 6px; }
.bal-k { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-ash); }
.bal-big { font: 400 32px/1.15 var(--font-ui); color: var(--color-paper); letter-spacing: -.5px; }
.bal-sub { font-size: 12px; color: var(--color-ash); }
.bal-left { margin-bottom: var(--spacing-24); }
.bal-meter { margin: 6px 0 2px; }
.bal-h { margin: var(--spacing-8) 0 4px; font: 500 22px/1.3 var(--font-ui); color: var(--color-paper); letter-spacing: -.3px; }
.bal-p { margin: 0 0 var(--spacing-16); font-size: 14px; line-height: 1.5; color: var(--color-fog); max-width: 72ch; }
.bal-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--spacing-12); margin-bottom: var(--spacing-16); }
.bal-tile { min-height: 129px; justify-content: space-between; }
.bal-tile .bal-k { text-transform: none; letter-spacing: 0; font-size: 13px; color: var(--color-fog); }
.bal-chart { margin-bottom: var(--spacing-24); }
.bal-chart-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--spacing-12); }
.bal-title { font: 500 14px/1.3 var(--font-ui); color: var(--color-paper); }
.bal-hint { font-size: 12px; color: var(--color-ash); }
.bal-bars { display: flex; align-items: flex-end; gap: 10px; height: 200px; padding-top: var(--spacing-16); }
.bal-col { flex: 1 1 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: stretch; gap: 8px; }
.bal-bar { display: block; min-height: 3px; background: var(--color-acid-lime); border-radius: 4px 4px 2px 2px; }
.bal-bar.zero { background: var(--color-graphite); }
.bal-day { text-align: center; font: 400 11px/1 var(--font-num); color: var(--color-ash); }
.bal-label { display: block; margin: 0 0 var(--spacing-8); }
.bal-ops { padding: 0; gap: 0; }
.bal-row { display: grid; grid-template-columns: 96px 1.3fr 1.5fr 64px 48px; gap: var(--spacing-12); align-items: center;
  padding: 12px var(--spacing-20); font-size: 13px; color: var(--color-mist); border-top: 1px solid var(--color-obsidian); }
.bal-row:first-child { border-top: 0; }
.bal-when { font-size: 12px; color: var(--color-ash); }
.bal-note { color: var(--color-ash); }
.bal-key { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bal-key a { color: var(--color-paper); text-decoration: none; }
.bal-key a:hover { text-decoration: underline; }
.bal-door { font-size: 12px; color: var(--color-ash); }
.bal-n { text-align: right; font-family: var(--font-num); color: var(--color-fog); }
.bal-row.refund .bal-n { color: var(--color-acid-lime); }
.bal-none { margin: 0; padding: var(--spacing-20); font-size: 14px; color: var(--color-fog); }
.bal-foot { margin: var(--spacing-12) 0 var(--spacing-40); font-size: 12px; line-height: 1.5; color: var(--color-ash); max-width: 90ch; }
@media (max-width: 900px) {
  .bal-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bal-row { grid-template-columns: 80px 1fr 44px; }
  .bal-row > .bal-key, .bal-row > .bal-door { display: none; }
  .bal-bars { gap: 4px; height: 140px; }
}
.plan-row { display: flex; justify-content: space-between; gap: var(--spacing-8); font-size: 12px; }
.plan-k { color: var(--color-ash); }
.plan-v { color: var(--color-mist); font-family: var(--font-num); white-space: nowrap; }
.plan-v b { font-weight: 400; color: var(--color-paper); }
.meter { display: block; height: 4px; border-radius: var(--radius-pill); background: var(--color-graphite); overflow: hidden; }
.meter-fill { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--color-acid-lime); }
.plan-note { margin-top: var(--spacing-8); font-size: 11px; line-height: 1.4; color: var(--color-ash); }
.me { display: flex; align-items: center; gap: var(--spacing-8); font-size: 13px; color: var(--color-fog); }
/* меню профиля (2026-09-14): строка с именем — summary, всплывашка вверх на ширину панели */
.me-menu > summary { list-style: none; cursor: pointer; border-radius: var(--radius-btn); padding: 4px; margin: -4px; }
.me-menu > summary::-webkit-details-marker { display: none; }
.me-menu > summary:hover .me, .me-menu[open] > summary .me { color: var(--color-paper); }
.me .chev { margin-left: auto; width: 14px; height: 14px; }
.me-menu:not([open]) .chev { transform: rotate(0); }
.me-menu[open] .chev { transform: rotate(180deg); }
.me-menu .drop-menu { top: auto; bottom: calc(100% + 8px); left: 0; right: 0; min-width: 0; width: 100%; box-sizing: border-box; }
.me-menu .drop-menu form { display: block; }
.me-menu .drop-menu button { justify-content: flex-start; gap: 8px; }
.me-menu .drop-menu button > svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--color-fog); }
.me-dot {
  width: 24px; height: 24px; flex: 0 0 auto; border-radius: var(--radius-pill);
  background: var(--color-graphite); color: var(--color-mist);
  display: flex; align-items: center; justify-content: center; font-size: 12px;
}

.work { flex: 1 1 auto; min-width: 0; margin-left: calc(var(--side-w) + var(--spacing-12)); }   /* ширина панели + зазор */
.topbar {
  position: sticky; top: 0; z-index: 10;
  padding: var(--spacing-12) 0;
  background: var(--color-void); border-bottom: 1px solid var(--color-graphite);
}
/* рабочая область центрируется сама по себе, а не липнет к панели слева */
.topbar-in { display: flex; align-items: center; gap: var(--spacing-16); }
/* имя страницы — постоянный ориентир в полосе, на всех экранах в одном месте */
.page-title { font: 510 14px/1.3 var(--font-ui); color: var(--color-paper); letter-spacing: -.011em; white-space: nowrap; }
/* «назад» — на листовых страницах (ролик, автор): шаг в историю браузера, без истории — на Главную */
.back { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px;
  margin-right: calc(var(--spacing-16) * -1 + var(--spacing-8)); border-radius: var(--radius-btn); color: var(--color-fog); }
.back svg { width: 18px; height: 18px; }
.back:hover { color: var(--color-paper); background: var(--color-obsidian); }
/* 1200, не 1100: карточке нужна строка «аватар · имя · подписчики» без обрезания имени (2026-09-03) */
.work .wrap { max-width: 1200px; margin: 0 auto; }
/* имя страницы — у левого края рабочей области, рядом с панелью (оператор 2026-09-15): полоса не сужается до колонки
   содержимого, на широком экране заголовок не уезжает к центру; пара «Поиск + строка» по-прежнему центрируется */
.topbar .wrap { max-width: none; }

/* ── поиск: главный вход в инструмент ────────────────────── */

.search { display: flex; gap: var(--spacing-8); flex: 1 1 420px; max-width: 620px; }
.topbar-in:has(.search) { justify-content: center; }   /* пара «Поиск + строка» по центру полосы (оператор 2026-09-15, вариант E) */
.search-box { position: relative; flex: 1 1 auto; min-width: 0; display: flex; }

.search-in {
  flex: 1 1 auto; min-width: 0;
  background: var(--color-void);
  border: 1px solid var(--color-graphite);
  color: var(--color-paper);
  border-radius: var(--radius-btn);
  padding: 9px var(--spacing-12);
  font: 400 14px/1.3 var(--font-ui); letter-spacing: -.01em;
}
.search-in::placeholder { color: var(--color-ash); }
/* крестик «очистить» внутри строки поиска */
.search-x { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center; background: none; border: 0; cursor: pointer;
  color: var(--color-ash); border-radius: var(--radius-btn); }
.search-x:hover { color: var(--color-paper); background: var(--color-obsidian); }
.search-x svg { width: 14px; height: 14px; }
.search-box .search-in { padding-right: 36px; }
.search-in:hover { border-color: var(--color-smoke); }
.search-in:focus { outline: none; border-color: var(--color-fog); }
.search-in:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }

.search-go {
  flex: 0 0 auto; cursor: pointer;
  background: var(--color-bone); color: var(--color-void);
  border: 0; border-radius: var(--radius-btn);
  padding: 9px var(--spacing-16);
  font: 510 14px/1.3 var(--font-ui); letter-spacing: -.011em;
}
.search-go:hover { background: var(--color-paper); }
/* «Найти» в полосе Поиска — той же лаймовой, что «Найти» в «Анализе видео» (оператор 2026-09-15) */
.search-go.lime { background: var(--color-paper); }
.search-go.lime:hover { background: var(--color-bone); }
.search-go:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }

/* недавние запросы: панель ровно по ширине строки поиска */
.recent {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 20;
  padding: var(--spacing-4);
  background: var(--color-obsidian);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  box-shadow: var(--shadow-xl);
  max-height: 320px; overflow-y: auto;
}
.recent-i {
  display: flex; align-items: center; gap: var(--spacing-12);
  padding: 8px var(--spacing-12); border-radius: var(--radius-badge);
  color: var(--color-mist); font-size: 14px; line-height: 1.3;
}
.recent-i:hover, .recent-i:focus-visible { background: var(--color-graphite); color: var(--color-paper); outline: none; }
.recent-ic {
  width: 15px; height: 15px; flex: 0 0 auto; color: var(--color-ash);
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.recent-i:hover .recent-ic, .recent-i:focus-visible .recent-ic { color: var(--color-fog); }
.recent-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* улов и давность фразы (Q6); пустышка приглушена — этот ноль уже куплен */
.recent-meta {
  margin-left: auto; flex: 0 0 auto;
  font-size: 12px; color: var(--color-ash); white-space: nowrap;
}
.recent-i.dud .recent-t { color: var(--color-ash); }
.recent-foot {
  margin-top: var(--spacing-4); padding: 6px var(--spacing-12);
  border-top: 1px solid var(--color-graphite);
  font-size: 11px; color: var(--color-ash);
}

/* карточка автора из адресной строки (МА-Q6): цена видна до поступка */
.card-author {
  display: flex; align-items: center; gap: var(--spacing-16);
  margin: var(--spacing-40) 0; padding: var(--spacing-20);
  background: var(--color-carbon); border-radius: var(--radius-card);
  box-shadow: var(--shadow-subtle); max-width: 720px;
}
.card-author-body { flex: 1 1 auto; min-width: 0; }
.card-author h1 { margin: 0 0 4px; font: 400 20px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.24px; }
.card-author-sub { margin: 0; display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--color-fog); }
.card-author-sub.err { color: #eb5757; }
.card-author-acts { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: var(--spacing-4); }
.card-author-acts .search-go[disabled] { opacity: .45; cursor: default; }
@media (max-width: 560px) { .card-author { flex-wrap: wrap; } .card-author-acts { align-items: flex-start; } }

/* ── объяснение и статус ─────────────────────────────────── */

.note {
  display: flex; align-items: center; gap: var(--spacing-12);
  margin: var(--spacing-24) 0 0;
  padding: var(--spacing-12) var(--spacing-16);
  background: var(--color-carbon); box-shadow: var(--shadow-subtle);
  border-radius: var(--radius-btn); font-size: 14px; color: var(--color-mist);
}
.note.err { color: #eb5757; }

/* чек за действие (оператор 2026-09-15): правый нижний угол, как у claude.ai; поверх всего.
   На телефоне тот же угол, только с полем 16px с обеих сторон — узкий чек растёт во всю ширину */
.toasts {
  position: fixed; right: var(--spacing-24); left: auto;
  bottom: calc(var(--spacing-24) + env(safe-area-inset-bottom, 0px)); z-index: 40;
  display: flex; flex-direction: column; align-items: flex-end; gap: var(--spacing-8);
  max-width: min(560px, calc(100vw - var(--spacing-24) * 2)); pointer-events: none;
}
.toast {
  pointer-events: auto; display: flex; align-items: center; gap: var(--spacing-12);
  max-width: 100%; padding: var(--spacing-12) var(--spacing-12) var(--spacing-12) var(--spacing-16);
  background: var(--color-carbon); color: var(--color-paper); border: 1px solid var(--color-graphite);
  border-radius: var(--radius-btn); box-shadow: var(--shadow-xl); font-size: 14px; line-height: 1.45;
  animation: toast-in .2s ease; transition: opacity .25s ease, transform .25s ease;
}
.toast.err { color: #eb5757; border-color: rgba(235, 87, 87, .35); }
.toast.hide { opacity: 0; transform: translateY(8px); }
.toast-x {
  flex: 0 0 auto; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: 6px; color: var(--color-ash); cursor: pointer;
}
.toast-x svg { width: 14px; height: 14px; }
.toast-x:hover { color: var(--color-paper); background: var(--color-obsidian); }
.toast-x:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; transition: none; } }
.note span { flex: 1 1 auto; min-width: 0; }
/* крутилка внутри .note растягивалась правилом выше в «палку» до половины строки, когда текст
   шага короткий («Ищем ролики по вашей теме…») — оператор увидел 2026-09-06; ей расти нельзя */
.note .spin { flex: 0 0 auto; }
.note-go {
  flex: 0 0 auto; color: var(--color-mist);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  padding: 5px var(--spacing-12); font-size: 13px;
  /* класс носит и <a>, и <button> (повтор сбора в плашке отказа): у кнопки без сброса остаётся
     светлая подложка браузера, и текст mist на ней не читается — снимок 2026-09-17 */
  background: none; font-family: inherit; cursor: pointer;
}
.note-go:hover { border-color: var(--color-smoke); color: var(--color-paper); }
.spin {
  width: 12px; height: 12px; flex: 0 0 auto; border-radius: var(--radius-pill);
  border: 1.5px solid var(--color-graphite); border-top-color: var(--color-acid-lime);
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* долгая форма ждёт сервера (data-busy, 2026-09-13): кнопка — крутилка + текст, не бледнеет как
   запертая; на светлой кнопке крутилка тёмная, иначе лаймовый хвост на белом не видно */
.is-busy { display: inline-flex; align-items: center; gap: var(--spacing-8); cursor: progress; }
.is-busy[disabled], .card-author-acts .search-go.is-busy[disabled] { opacity: 1; cursor: progress; }
.search-go.is-busy .spin { width: 14px; height: 14px; border-width: 2px;
  border-color: rgba(0, 0, 0, .15); border-top-color: var(--color-void); }

.lead { padding: var(--spacing-40) 0 var(--spacing-8); max-width: 62ch; }
.lead h1 {
  margin: 0 0 var(--spacing-12);
  font: 400 24px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.288px;
}
.lead p { margin: 0; color: var(--color-ash); font-size: 14px; line-height: 1.6; }

/* Строка темы: фраза — заголовок объекта, слежение — действие при ней
   (паттерн trendsee). Если поисков несколько — заголовок сам и есть селект. */
.topic-row {
  display: flex; align-items: center; gap: var(--spacing-12);
  flex-wrap: wrap; padding-top: var(--spacing-32);
}
.topic-name { font: 400 20px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.24px; }
.topic-pick {
  appearance: none; -webkit-appearance: none; cursor: pointer;
  background: transparent; border: 0; border-radius: var(--radius-btn);
  color: var(--color-paper);
  font: 400 20px/1.33 var(--font-ui); letter-spacing: -.24px;
  padding: 2px 30px 2px var(--spacing-8); margin-left: calc(var(--spacing-8) * -1);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='7' viewBox='0 0 12 7'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%2362666d' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center;
  transition: background-color .15s ease;
}
.topic-pick:hover { background-color: var(--color-obsidian); }
.topic-pick:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }
.topic-pick option { background: var(--color-obsidian); color: var(--color-mist); font-size: 14px; }

/* Панель фильтров: два блока — фильтры и порядок, разделены волосяной чертой */
.controls {
  display: flex; align-items: flex-end; gap: var(--spacing-12) var(--spacing-24);
  flex-wrap: wrap; padding: var(--spacing-12) 0 var(--spacing-16);
}
.ctl-group { display: flex; align-items: flex-end; gap: var(--spacing-12); min-width: 0; }
.ctl-group + .ctl-group { border-left: 1px solid var(--color-graphite); padding-left: var(--spacing-24); }
/* порядок — не фильтр: живёт у правого края */
.ctl-sort { margin-left: auto; }
.ctl { display: flex; flex-direction: column; gap: var(--spacing-4); min-width: 0; }
.ctl-k { color: var(--color-ash); }   /* имя фильтра внутри кнопки: «Когда · за всё время» */

/* подписка на тему */
.watch-btn {
  display: inline-flex; align-items: center; gap: var(--spacing-8); cursor: pointer;
  background: none; color: var(--color-mist);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  padding: 7px var(--spacing-12);
  font: 400 13px/1.2 var(--font-ui); letter-spacing: -.01em;
}
.watch-btn:hover { border-color: var(--color-smoke); color: var(--color-paper); }
.watch-btn:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.watch-btn.on { color: var(--color-paper); border-color: var(--color-smoke); }
.watch-dot {
  width: 7px; height: 7px; border-radius: var(--radius-pill);
  background: var(--color-pulse-green, #27a644); flex: 0 0 auto;
}
/* кнопка-состояние подписки (_subbtn.html): слово «Вы подписаны» белое и на паузе — подписка
   живёт; серыми становятся только точка и значок паузы, они про обход (оператор 2026-09-15).
   Стрелка как у фильтров. Пункт «Отписаться» в меню — тише остальных */
.watch-btn.paused { color: var(--color-paper); border-color: var(--color-smoke); }
.watch-btn.paused .watch-dot { background: var(--color-ash); }
.watch-btn.paused .clk { color: var(--color-ash); opacity: 1; }
.drop.sub .drop-menu { min-width: 200px; }
.drop.sub[open] > summary .watch-btn { border-color: var(--color-smoke); color: var(--color-paper); }
.drop-menu button.quiet { color: var(--color-ash); }
.drop-menu button.quiet:hover { color: var(--color-paper); }
.drop-menu button.danger { color: #eb5757; }              /* «Отписаться» — красная на всех пультах */
.drop-menu button.danger:hover { color: #f08c8c; background: rgba(235, 87, 87, .08); }

/* наблюдение за автором — кнопка живёт на карточке ролика */
.watch-a { margin-top: var(--spacing-8); }
.watch-a-btn {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: none; color: var(--color-ash);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  padding: 5px var(--spacing-8);
  font: 400 12px/1.2 var(--font-ui); letter-spacing: -.01em;
}
.watch-a-btn:hover { border-color: var(--color-smoke); color: var(--color-mist); }
.watch-a-btn:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.watch-a-btn.on { color: var(--color-mist); border-color: var(--color-smoke); }

/* ── страница автора ─────────────────────────────────────── */

.a-head { padding: var(--spacing-40) 0 0; }
/* Шапка автора по канону Instagram (оператор 2026-09-17): аватар слева, справа от него имя и
   метрики столбцами, @ник — строкой под аватаром. Сетка, а не флекс: @ник стоит в разметке
   последним (читалка идёт по смыслу: имя → метрики → ссылка), а место ему задаёт своя область. */
.a-top { display: grid; grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "ava id" "nick nick"; gap: var(--spacing-8) var(--spacing-20); align-items: center; }
.a-top > .a-ava { grid-area: ava; }
.a-top > .a-id { grid-area: id; }
.a-top > .a-nick { grid-area: nick; }
/* Метрики — как на скрине Instagram оператора (2026-09-17): число крупнее подписи, обе прижаты
   к левому краю своего столбца, столбцы разнесены по ширине. Первая версия центрировала число с
   подписью и держала их мелкими — от этого блок читался как подпись под именем, а не как три
   счётчика. Имя над ними — тихая строка 16/510, не заголовок: в Instagram крупное имя — это @ник
   в верхней полосе, а у нас в полосе стоит «Автор». */
.a-nums { list-style: none; margin: var(--spacing-12) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--spacing-24); }
.a-nums li { display: flex; flex-direction: column; gap: 1px; align-items: flex-start; }
.a-nums b { font: 510 19px/1.2 var(--font-num); color: var(--color-paper); letter-spacing: -.015em; white-space: nowrap; }
.a-nums span { font-size: 13px; color: var(--color-ash); }
.a-head .a-nick { font-size: 13px; color: var(--color-mist); width: fit-content; }
.a-head .a-nick:hover { color: var(--color-paper); }
/* аватар автора — один круг в трёх размерах: шапка и карточка автора · строка пульта · карточка ролика.
   Без копии внутри буква; с копией это <img>, и object-fit держит круг. */
.a-ava, .line-ava, .who-ava {
  flex: 0 0 auto; border-radius: var(--radius-pill); object-fit: cover;
  background: var(--color-graphite); color: var(--color-mist);
  display: inline-flex; align-items: center; justify-content: center;
}
.a-ava { width: 56px; height: 56px; font-size: 22px; }
.a-head .a-ava { width: 72px; height: 72px; font-size: 28px; }   /* шапка автора: крупнее строки пульта */
.line-ava { width: 24px; height: 24px; font-size: 11px; }
.who-ava { width: 28px; height: 28px; font-size: 12px; }
.a-id { flex: 1 1 auto; min-width: 0; }
.a-id h1 { margin: 0; font: 510 16px/1.35 var(--font-ui); color: var(--color-paper); letter-spacing: -.011em; overflow-wrap: anywhere; }
.a-sub { margin: 0; font-size: 13px; color: var(--color-fog); }
.a-actions { display: flex; gap: var(--spacing-8); align-items: center; flex-wrap: wrap; }
/* шапка автора по канону Instagram web (2026-09-12): каждая ступень — своя строка, между
   ними воздух; шапка больше не центрируется по вертикали — аватар встаёт к первой строке */
.a-id > * + * { margin-top: 6px; }
.a-id .a-actions { margin-top: var(--spacing-12); }
.a-bio { margin: 0; font-size: 13px; line-height: 1.5; color: var(--color-mist); white-space: pre-line;
  max-width: 62ch; overflow-wrap: anywhere; }
/* «Сохранить» — кнопка-значок закладки над обложкой (оператор 2026-09-06: значок, не слово);
   слово живёт в title/aria-label. Пустая закладка — не сохранён, залитая (.on) — сохранён */
.save-btn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px;
  background: none; cursor: pointer; color: var(--color-mist);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-btn); padding: 0; }
.save-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
.save-btn:hover { border-color: var(--color-smoke); color: var(--color-paper); }
.save-btn:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.save-btn.on { color: var(--color-paper); border-color: var(--color-smoke); }
.save-btn.on svg { fill: currentColor; }

.tabs { display: flex; gap: var(--spacing-4); margin: var(--spacing-24) 0; border-bottom: 1px solid var(--color-graphite); }
.saved-tabs { margin-top: var(--spacing-40); }   /* без вводной строки вкладки держат её отступ от полосы */
@media (max-width: 560px) { .tabs { flex-wrap: wrap; } }   /* четыре вкладки «Разборов» не влезали в телефон — последняя уезжала за край (обход 2026-09-15) */
.tab { padding: var(--spacing-8) var(--spacing-12); font-size: 14px; color: var(--color-fog); }
.tab:hover { color: var(--color-mist); }
.tab.on { color: var(--color-paper); box-shadow: inset 0 -2px 0 var(--color-paper); }
.tab:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: -2px; }
.grid-sum { margin: var(--spacing-12) 0 0; font-size: 12px; color: var(--color-ash); }   /* «24 ролика · 12 авторов» над сеткой */
/* строка над сеткой (оператор 2026-09-15, один язык на Поиск и Ролики): слева счётчик, справа лупа и порядок */
.grid-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-12); margin: 0 0 var(--spacing-12); }
.grid-bar .grid-sum { margin: 0; }
.tab-n { margin-left: 4px; font-size: 11px; color: var(--color-ash); font-family: var(--font-num); }   /* счётчик на вкладке (комната «Анализ») */
.board .tabs { margin: var(--spacing-16) 0 var(--spacing-8); }

.stat-k.small { font-size: 16px; line-height: 1.4; }
.hint-line { margin: var(--spacing-8) 0 0; font-size: 13px; color: var(--color-ash); }

.heat-sec { margin: var(--spacing-40) 0 var(--spacing-64); }
.heat-sec h2 { margin: 0 0 var(--spacing-4); font: 400 20px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.24px; }
.heat-wrap { overflow-x: auto; padding: var(--spacing-16) 0; }
.heat { display: grid; grid-template-columns: 28px repeat(24, 15px); gap: 3px; align-items: center; width: max-content; }
.heat-day { font: 400 11px/1 var(--font-num); color: var(--color-ash); }
.heat-hour { font: 400 11px/1 var(--font-num); color: var(--color-ash); text-align: center; }
.heat-cell { width: 15px; height: 15px; border-radius: 3px; background: var(--color-carbon); }
.heat-cell.h1 { background: var(--color-graphite); }
.heat-cell.h2 { background: var(--color-smoke); }
.heat-cell.h3 { background: var(--color-fog); }
.heat-cell.h4 { background: var(--color-bone); }
.ctl-l { font-size: 12px; line-height: 1.2; color: var(--color-ash); letter-spacing: -.01em; }

.field {
  background: transparent;
  border: 1px solid var(--color-graphite);
  color: var(--color-mist);
  border-radius: var(--radius-btn);
  padding: 7px var(--spacing-12);
  font: 400 13px/1.2 var(--font-ui);
  letter-spacing: -.01em;
  cursor: pointer;
}
.field:hover { border-color: var(--color-smoke); }
.field:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }

/* ── сводка ──────────────────────────────────────────────── */

.summary {
  display: flex; gap: var(--spacing-32); flex-wrap: wrap;
  padding: var(--spacing-24) 0;
}
.stat-k { font: 400 24px/1.33 var(--font-num); color: var(--color-paper); letter-spacing: -.288px; }
.stat-l { font-size: 13px; line-height: 1.2; color: var(--color-ash); }

/* ── сетка ───────────────────────────────────────────────── */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  gap: var(--spacing-16);
  padding-bottom: var(--spacing-64);
}

.card {
  background: var(--color-carbon);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-subtle);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: box-shadow .18s ease, transform .18s ease;
}
.card:hover { box-shadow: var(--shadow-subtle), var(--shadow-xl); transform: translateY(-2px); }
.card:focus-within { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }

.shot { position: relative; aspect-ratio: 9 / 16; background: var(--color-obsidian); display: block; }
/* заглушка лежит под обложкой и видна только если картинка не пришла */
.shot img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: cover; display: block; }
.shot .fallback {
  position: absolute; inset: 0; z-index: 0; display: grid; place-items: center;
  font: 400 32px/1 var(--font-num); color: var(--color-graphite);
}
.mult, .age { z-index: 2; }

/* множитель — единственный цветной элемент в системе */
.mult {
  position: absolute; top: var(--spacing-8); left: var(--spacing-8);
  background: var(--color-acid-lime); color: var(--color-void);
  font: 510 13px/1 var(--font-num);
  padding: 5px 8px; border-radius: var(--radius-badge);
  letter-spacing: -.013em;
}

.age {
  position: absolute; top: var(--spacing-8); right: var(--spacing-8);
  background: rgba(8, 9, 10, .72); color: var(--color-mist);
  font: 400 11px/1 var(--font-num);
  padding: 5px 7px; border-radius: var(--radius-badge);
  backdrop-filter: blur(4px);
}
.age.fresh { color: var(--color-paper); }

/* «новое» — принёс ночной обход. Второй ярлык под возрастом, лаймом не красим:
   лайм по канону только у множителя. */
.added {
  position: absolute; top: 36px; right: var(--spacing-8);
  background: var(--color-bone); color: var(--color-void);
  font: 510 11px/1 var(--font-ui); letter-spacing: -.01em;
  padding: 5px 7px; border-radius: var(--radius-badge);
}

/* ── счётчики полоской на обложке ────────────────────────── */

.stats {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; justify-content: space-around; align-items: center;
  gap: var(--spacing-4); padding: var(--spacing-8) var(--spacing-4);
  background: linear-gradient(to top, rgba(8, 9, 10, .88), rgba(8, 9, 10, 0));
}
.stat {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  font: 400 11px/1 var(--font-num); color: var(--color-mist);
  letter-spacing: -.013em; min-width: 0;
}
.stat svg {
  width: 15px; height: 15px; display: block;
  fill: none; stroke: var(--color-mist); stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}

.body { padding: var(--spacing-12); display: flex; flex-direction: column; gap: var(--spacing-8); }

/* ── линейка нормы: сигнатурный элемент ──────────────────── */
/* Показывает не «сколько просмотров», а насколько ролик встал над обычным
   уровнем автора. Засечка — норма, точка — этот ролик.                    */

/* высота вместе с подписью «обычно N»: раньше подпись вылезала из коробки и упиралась в аватар
   (оператор 2026-09-14 — «прям микро» воздуха от шкалы) */
.ruler { position: relative; height: 20px; margin-top: 2px; }
.ruler-track {
  position: absolute; left: 0; right: 0; top: 6px; height: 1px;
  background: var(--color-graphite);
}
.ruler-fill {
  position: absolute; left: 0; top: 6px; height: 1px;
  background: var(--color-smoke);
}
.ruler-norm {
  position: absolute; left: 0; top: 2px; width: 1px; height: 9px;
  background: var(--color-smoke);
}
.ruler-dot {
  position: absolute; top: 3px; width: 7px; height: 7px; margin-left: -3px;
  border-radius: var(--radius-pill);
  background: var(--color-acid-lime);
}
.ruler-cap {
  position: absolute; left: 0; top: 12px;
  font: 400 11px/1 var(--font-num); color: var(--color-ash);
}

/* автор в карточке — как канал под видео: аватар слева, имя и подписчики столбиком.
   Одной строкой имя резалось до «@…» на телефоне (27px под имя при 161px карточке). */
.who { display: flex; align-items: center; gap: var(--spacing-8); }
.who-col { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.who-name { font-size: 13px; color: var(--color-mist); letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who-subs { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 4px; min-width: 0; font: 400 11px/1.2 var(--font-num); color: var(--color-ash); white-space: nowrap; }
.who-n { overflow: hidden; text-overflow: ellipsis; max-width: 100%; }   /* узкая карточка (телефон): «подписаться» уходит на свою строку, число целое */
/* имя автора + точка подписки в одну строку; «подписаться» — ссылка тем же кеглем, не кнопка:
   вторая кнопка рядом с «Анализ» делала бы карточку шумной (оператор 2026-09-07) */
.who-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.who-sub { display: inline; }
.who-sub-btn { background: none; border: 0; padding: 0; font: inherit; color: var(--color-fog); cursor: pointer; }
.who-sub-btn:hover { color: var(--color-paper); }
.who-sub-btn:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; border-radius: 2px; }

.nums { display: flex; flex-wrap: wrap; gap: var(--spacing-8) var(--spacing-12); font: 400 12px/1.4 var(--font-num); color: var(--color-fog); }
.nums b { color: var(--color-mist); font-weight: 400; }

.cap {
  font-size: 13px; line-height: 1.45; color: var(--color-ash);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;   /* цепочка хэштегов без пробелов резалась по краю карточки (обход 2026-09-15) */
}

/* ── пусто ───────────────────────────────────────────────── */

.empty { padding: var(--spacing-64) 0; max-width: 56ch; }
.empty.col { margin: 0 auto; }   /* узкое — по центру колонкой (правило 2026-09-15) */
.empty h1 {
  font: 400 32px/1.13 var(--font-ui); color: var(--color-paper);
  letter-spacing: -.704px; margin: 0 0 var(--spacing-16);
}
.empty p { color: var(--color-mist); margin: 0 0 var(--spacing-12); font-size: 15px; }
.empty .hint { color: var(--color-ash); font-size: 14px; }
.empty .hint b { color: var(--color-mist); font-weight: 400; }

@media (max-width: 900px) {
  /* телефон (спека 2026-09-16): панели стола нет — её работу делают .tabbar и меню аватара в .m-head;
     до 2026-09-16 панель ложилась полосой сверху и резалась («БИБЛИОТЕКА» обрезана на каждом экране) */
  .app { flex-direction: column; padding: 0; }
  .side { display: none; }
  .work { width: 100%; margin: 0; padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--spacing-16)); }
  .wrap { padding: 0 var(--spacing-16); }
  .toasts { right: var(--spacing-16); max-width: calc(100vw - var(--spacing-16) * 2);
    bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--spacing-12)); }
  .topbar { display: none; }                                  /* имя экрана несёт .m-head */
  .topbar:has(.search) { display: block; position: static; border: 0; padding: 0 0 var(--spacing-12); }   /* Поиск: строка под шапкой */
  .topbar:has(.search) .page-title { display: none; }
  /* прокрутка-к-элементу (Tab, «Найти на странице», scrollIntoView) не знает про залипающую шапку
     и фиксированную панель — без запаса элемент у края уезжает под них (обход 2026-09-16:
     scroll_into_view_if_needed в tour.py клал «Сохранить» под аватар шапки, элемент #20 на /subs) */
  html { scroll-padding-top: 56px; scroll-padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
}

@media (max-width: 560px) {
  .wrap { padding: 0 var(--spacing-16); }
  .grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--spacing-12); }
  .summary { gap: var(--spacing-20); padding-top: var(--spacing-20); }
  /* padding-block, а не padding: сокращённая запись обнуляла боковые отступы
     от .wrap, и шапка прилипала к краю экрана */
  .top-in { height: auto; padding-block: var(--spacing-12); gap: var(--spacing-12); }
  .brand { font-size: 14px; }
  .search { flex: 1 1 100%; }
  .lead { padding-top: var(--spacing-24); }
  .lead h1 { font-size: 20px; line-height: 1.33; letter-spacing: -.24px; }
  .empty h1 { font-size: 24px; letter-spacing: -.288px; }
  /* в полосе с поиском имя страницы уступает место строке ввода:
     раздел на телефоне и так подсвечен в навигации сверху */
  .topbar-in:has(.search) .page-title { display: none; }
  .topic-row { padding-top: var(--spacing-24); }
  .controls { width: 100%; }
  /* блоки складываются в столбик — черта-разделитель на узком экране лишняя */
  .ctl-group { width: 100%; flex-wrap: wrap; }
  .ctl-group + .ctl-group { border-left: 0; padding-left: 0; }
  .ctl-sort { margin-left: 0; }
  .ctl { flex: 1 1 auto; }
  .field { flex: 1 1 auto; min-width: 0; }
  .cap { -webkit-line-clamp: 3; }
}

/* ── дашборд договоров: второй этаж Разведки (Q6) ─────────── */

/* плитки недели: числа текстом, без графиков-украшений */
.kpis {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--spacing-16); padding: var(--spacing-20) 0 var(--spacing-8);
}
.kpi {
  background: var(--color-carbon); border-radius: var(--radius-card);
  padding: var(--spacing-16) var(--spacing-20);
  box-shadow: var(--shadow-subtle);
  display: flex; flex-direction: column; gap: 2px;
}
.kpi-v { font: 400 26px/1.2 var(--font-ui); color: var(--color-paper); letter-spacing: -.4px; }
.kpi-v small { font-size: 12px; color: var(--color-fog); letter-spacing: -.01em; }
.kpi-l { font-size: 12px; color: var(--color-ash); }
.kpi-spark { width: 150px; height: 26px; display: block; overflow: visible; margin-top: var(--spacing-8); }

.board { margin-bottom: var(--spacing-64); }
.board h2 {
  margin: var(--spacing-24) 0 var(--spacing-4);
  font: 400 20px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.24px;
}
.board-sum { margin: 0 0 var(--spacing-12); font-size: 14px; color: var(--color-fog); }
.board > .board-sum:first-child { margin-top: var(--spacing-40); }   /* доска без своего заголовка: ритм как у .lead */
/* доска в карточке — та же плитка, что у чисел недели над ней (оператор 2026-09-15);
   разделители и подсветка строки на тон светлее карточки, иначе на её фоне пропадают */
.board-card { background: var(--color-carbon); border-radius: var(--radius-card); box-shadow: var(--shadow-subtle); }
.board-head, .line {
  display: grid; align-items: center; gap: var(--spacing-16);
  /* последняя колонка фиксированная: у заголовка она пустая, и на auto
     сетка шапки разъезжалась с сеткой строк (замечено снимком 2026-09-01) */
  grid-template-columns: minmax(0, 1.6fr) 200px 120px minmax(0, 1fr) 190px;
  padding: var(--spacing-12) var(--spacing-16);
}
.board-head {
  font-size: 12px; color: var(--color-ash); letter-spacing: -.01em;
  border-bottom: 1px solid var(--color-graphite);
}
.line { border-bottom: 1px solid var(--color-obsidian); }
.line:last-child { border-bottom: 0; border-radius: 0 0 var(--radius-card) var(--radius-card); }
.line:hover { background: var(--color-obsidian); }
.line:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: -2px; }

.line-topic { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* строка автора: аватар в одной строке с ником, статус под ним от края — как у темы */
.line-head { display: flex; align-items: center; gap: var(--spacing-8); min-width: 0; }
.line-name {
  color: var(--color-paper); font-size: 15px; letter-spacing: -.011em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.line-state { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--color-ash); }
.line-state.on { color: var(--color-fog); }
.line-when { font-size: 12px; color: var(--color-ash); }

/* сигнатура дашборда: пульс-линия (МТ-Q6а). Пиковая точка — лаймом:
   лайм = «самое громкое», как у множителя (поправка канона Q6а). */
.pulse-wrap { display: flex; flex-direction: column; min-width: 0; }
.spark { width: 150px; height: 34px; display: block; overflow: visible; }
.spark polyline, .kpi-spark polyline {
  fill: none; stroke: var(--color-fog); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.spark-peak { fill: var(--color-acid-lime); }
/* точка дня — одна, под курсором: зона дня зажигает свою точку и гасит за
   собой; в покое линия чистая (правка оператора 2026-09-01, второй заход) */
.spark-day {
  fill: var(--color-bone); stroke: var(--color-void); stroke-width: 1.5;
  opacity: 0; transition: opacity .12s ease;
}
.spark-day.on { opacity: 1; }
.line.is-paused .spark polyline { stroke: var(--color-smoke); }
.line.is-paused .spark-peak, .line.is-paused .spark-day { fill: var(--color-ash); }
.spark-hit { fill: transparent; }
.pulse-cap { font: 400 11px/1.3 var(--font-ui); color: var(--color-fog); margin-top: 3px; }

/* вход одной волной (Q6а): линия рисуется штрихом, пик проявляется следом — только в плитке
   недели; строки доски стоят на месте, восемь линий разом — шум (оператор 2026-09-15) */
.kpi-spark .spark-l {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: spark-draw .7s cubic-bezier(.2, .7, .2, 1) .15s forwards;
}
.kpi-spark .spark-peak { opacity: 0; animation: peak-in .25s ease .8s forwards; }
@keyframes spark-draw { to { stroke-dashoffset: 0; } }
@keyframes peak-in { to { opacity: 1; } }

/* динамическая подсказка точки: день · прибавка */
.tip {
  position: fixed; z-index: 40; pointer-events: none;
  background: var(--color-obsidian); border: 1px solid var(--color-graphite);
  border-radius: var(--radius-btn); padding: 4px 8px;
  font: 400 12px/1.3 var(--font-ui); color: var(--color-mist);
  box-shadow: var(--shadow-xl); white-space: nowrap;
}

/* «Обход» отодвинут от «Лучшего выброса»: колонкам с разной природой — воздух */
.board-head > :nth-child(4), .line > :nth-child(4) { padding-left: var(--spacing-16); }

.num { text-align: right; font: 400 13px/1 var(--font-num); }
.board-head .num { font-family: var(--font-ui); font-size: 12px; }
.plus { color: var(--color-mist); }
.best { color: var(--color-acid-lime); }
/* лучший выброс — дверь к самому ролику: подчёркивание только под курсором */
a.best { text-decoration: none; }
a.best:hover, a.best:focus-visible { text-decoration: underline; text-underline-offset: 3px; }


@media (max-width: 720px) {
  /* на телефоне колонки не помещаются: строка складывается — тема сверху,
     под ней числа и пульс в один ряд */
  .board-head { display: none; }
  .line { display: flex; flex-wrap: wrap; gap: var(--spacing-8) var(--spacing-12); }
  .line-topic { flex: 1 1 100%; }
  .num { text-align: left; }
  .pulse-wrap { margin-left: auto; }
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  .card { transition: none; }
  .card:hover { transform: none; }
  .spark-l { animation: none; stroke-dashoffset: 0; }
  .spark-peak { animation: none; opacity: 1; }
  .spark-day { transition: none; }
}

.sched { margin: var(--spacing-32) 0 var(--spacing-24); max-width: 560px; }
.sched h2 { margin: 0 0 var(--spacing-4); font: 400 20px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.24px; }
.sched .cadence, .gear-menu .cadence { display: flex; flex-direction: column; gap: var(--spacing-8); margin-top: var(--spacing-12); align-items: flex-start; }
.sched-o { display: flex; gap: var(--spacing-8); font-size: 14px; color: var(--color-mist); cursor: pointer; }
.sched-o b { font-weight: 510; color: var(--color-paper); }
.sched-o input { margin-top: 4px; }
.sched-days { display: flex; gap: var(--spacing-4); flex-wrap: wrap; padding-left: 22px; }
/* «Свои дни»: чипы и кнопка раскрываются только при выбранном варианте —
   два других применяются по клику и в кнопке не нуждаются (2026-09-02) */
.cadence .sched-days { display: none; }
.cadence .knob-days { display: flex; padding-left: 0; }
.cadence .knob { margin-top: var(--spacing-4); }
.cadence:has(input[value="custom"]:checked) .sched-days { display: flex; }
a.cadence-insight { color: var(--color-fog); text-decoration: none; }
a.cadence-insight:hover { color: var(--color-mist); text-decoration: underline; text-underline-offset: 3px; }
.cadence-foot { margin-top: var(--spacing-4); }
.day {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  padding: 4px 9px; font-size: 13px; color: var(--color-mist);
}
.day:hover { border-color: var(--color-smoke); }

.eyebrow { margin: 0 0 var(--spacing-4); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--color-ash); }

/* ролик не выброс — ярлык гаснет: лайм остаётся только у настоящего сигнала */
.mult.low { background: rgba(8, 9, 10, .72); color: var(--color-fog); }

/* кнопка карточки — прибита к низу (подписи разной длины качали её вверх-вниз) и во всю ширину,
   со значком (оператор 2026-09-06) */
/* …и чтобы «прибита» стало правдой, расти обязан .body: карточки ряда растянуты по самой высокой
   (.grid — grid без align-items, значит stretch), а .body без flex-grow оставался ростом со своё
   содержимое — запас копился ПОД ним, внутри .card, и раздавать margin-top: auto было нечего.
   Замер на /videos 1440px: 8 рядов из 25 разъехались на 19px — ровно строка подписи; без подписи
   кнопка уезжала вверх на 72px. — 2026-09-17, «они то одна ниже, то другая выше» */
.card .body { flex: 1 1 auto; }
/* nowrap, а не wrap: «Проанализировать» — одно длинное слово, его min-content не давал кнопке
   сжаться, и в узком рельсе «Подписок» (5 колонок по 175-207px) закладка сваливалась на вторую
   строку — полоса действий росла с 38 до 76px и ряд разъезжался. Теперь ужимается подпись, а пара
   «кнопка + закладка» остаётся одной строкой. — 2026-09-17 */
.card-actions { display: flex; gap: var(--spacing-8); margin-top: auto; padding-top: var(--spacing-8); align-items: center; flex-wrap: nowrap; }
/* высота в ровень с закладкой рядом (33×30, ниже по файлу): 26px против 30px читались как
   две разные вещи, а это одна полоса действий. — 2026-09-17 */
.card-go { flex: 1 1 auto; min-width: 0; height: 30px; justify-content: center; display: inline-flex; align-items: center; gap: 6px; text-align: center; }
.card-go .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-go svg { width: 14px; height: 14px; }
.card-actions .watch-a { margin-top: 0; }

/* страница ролика — вариант D с холста (2026-09-03): слева «Разбор», справа обложка с
   цифрами, линейкой нормы, автором и описанием — как пост, по закону Якоба */
.reel-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--spacing-16);
  padding: var(--spacing-40) 0 var(--spacing-20);
}
.reel-id { flex: 1 1 auto; min-width: 0; }
.reel-head h1 { margin: 0; font: 400 24px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.288px; overflow-wrap: anywhere; }
.reel-cols { display: flex; gap: var(--spacing-32); align-items: flex-start; padding-bottom: var(--spacing-64); }
.reel-main { flex: 1 1 auto; min-width: 0; }
.rz-head h2 { margin: 0 0 var(--spacing-12); font: 400 20px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.24px; }
.rz .note { margin: 0; }
.media { flex: 0 0 300px; width: 300px; display: flex; flex-direction: column;
  /* липкая колонка (оператор 2026-09-06: «у loore обложка прикреплена, анализ прокручивается»):
     стоит под верхней полосой (.topbar ≈ 45px), как левое меню; выше окна — прокручивается
     внутри себя, чтобы автор и подпись не стали недостижимы на низком экране */
  position: sticky; top: 57px; max-height: calc(100vh - 57px - var(--spacing-12));
  overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--color-graphite) transparent; }
/* панель действий у медиа — «Сохранить» над обложкой, к правому краю */
.media .m-tools { display: flex; justify-content: flex-end; gap: 8px; margin: 0 0 var(--spacing-8); flex: 0 0 auto; }
.media .m-cover { flex: 0 0 auto; }
.m-cover { position: relative; border-radius: var(--radius-card); overflow: hidden; box-shadow: var(--shadow-subtle); background: var(--color-obsidian); }
.m-cover img { display: block; width: 100%; height: auto; }
/* дверь в Instagram — чип в нижнем углу обложки, в тон .age; сама обложка — ссылка с 2026-09-03,
   кнопка «Открыть в Instagram» из шапки снята как вторая дверь в ту же комнату (2026-09-06) */
.m-cover .ig { position: absolute; right: var(--spacing-8); bottom: var(--spacing-8); z-index: 2;
  background: rgba(8, 9, 10, .72); color: var(--color-mist); font: 400 11px/1 var(--font-ui);
  padding: 5px 7px; border-radius: var(--radius-badge); backdrop-filter: blur(4px); }
.m-cover .ig:hover { color: var(--color-paper); }
.m-cover .fallback { aspect-ratio: 9 / 16; display: grid; place-items: center; font: 400 32px/1 var(--font-num); color: var(--color-graphite); }
.m-stats { display: flex; justify-content: space-between; padding: var(--spacing-12) var(--spacing-4) 0; }
.m-stat { display: flex; flex-direction: column; align-items: center; gap: 3px; font: 400 12px/1 var(--font-num); color: var(--color-mist); }
.m-stat svg { width: 16px; height: 16px; display: block; fill: none; stroke: var(--color-fog); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.media .ruler { margin: var(--spacing-12) var(--spacing-4) 0; }
.m-who { display: flex; align-items: center; gap: var(--spacing-8); margin-top: 18px;   /* 24 − 6: шкала подросла, воздух прежний */ padding: 0 var(--spacing-4); font-size: 13px; color: var(--color-mist); min-width: 0; flex-wrap: wrap; }
.m-who .dim { color: var(--color-ash); }
.m-cap { margin: var(--spacing-8) var(--spacing-4) 0; font-size: 13px; line-height: 1.5; color: var(--color-mist); white-space: pre-line; overflow-wrap: anywhere; }
.m-cap.clamp { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; white-space: normal; }
.more { display: inline-block; align-self: flex-start; margin: var(--spacing-4) var(--spacing-4) 0; background: none; border: 0; padding: 0; cursor: pointer; font: 400 13px/1.6 var(--font-ui); color: var(--color-ash); }
.more:hover { color: var(--color-mist); }
.media .hint-line { margin: var(--spacing-12) var(--spacing-4) 0; }
button.watch-btn { background: none; cursor: pointer; display: inline-flex; align-items: center; gap: var(--spacing-8); }
.watch-btn.on { color: var(--color-paper); border-color: var(--color-smoke); }

/* блок «Анализ» — с холста (docs/mockups/razbor): карточки канона, таймкод-чип, тройной хук */
.rz-head { display: flex; align-items: baseline; gap: var(--spacing-12); flex-wrap: wrap; }
.rz-meta { font-size: 13px; color: var(--color-fog); }
.rz-go { display: flex; align-items: center; gap: var(--spacing-12); flex-wrap: wrap; margin-top: var(--spacing-12); }
.rz-go .hint-line { margin: 0; }
.rz-card { background: var(--color-carbon); border-radius: var(--radius-card); box-shadow: var(--shadow-subtle); padding: var(--spacing-20) var(--spacing-24); margin-bottom: var(--spacing-12); }
.rz-card h3 { margin: 0 0 14px; font: 510 15px/1.2 var(--font-ui); color: var(--color-paper); letter-spacing: -.01em; }
/* суть (схема 3): первая строка карточки «Структура», перед частями — вступление к
   тому, как устроено, без монтажной сцены; тема (.rz-topic) переехала в заголовок
   страницы и своей карточной вёрстки больше не имеет — спека v2.2 §2/§3, 2026-09-05 */
.rz-essence { margin: 0 0 14px; font-size: 14px; line-height: 1.5; color: var(--color-mist); }
.tc { flex: 0 0 auto; font: 400 12px/1 var(--font-num); color: var(--color-fog); padding: 5px 7px; border: 1px solid var(--color-graphite); border-radius: var(--radius-btn); min-width: 44px; text-align: center; }
.rz-fold { display: flex; flex-direction: column; margin-top: var(--spacing-4); }
.rz-row { border-bottom: 1px solid var(--color-carbon); border-radius: var(--radius-btn); font-size: 14px; color: var(--color-mist); }
.rz-row > summary { display: flex; align-items: center; gap: var(--spacing-12); padding: 12px 8px; cursor: pointer; list-style: none; }
.rz-row > summary::-webkit-details-marker { display: none; }
.rz-row > summary::before { content: ""; width: 6px; height: 6px; border-right: 1.5px solid var(--color-ash); border-bottom: 1.5px solid var(--color-ash); transform: rotate(45deg); flex: 0 0 auto; transition: transform .15s ease; margin-top: -3px; }
.rz-row[open] > summary::before { transform: rotate(225deg); margin-top: 3px; }
.rz-row .sub { font-size: 12px; color: var(--color-ash); margin-left: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rz-row ul { margin: 0 0 var(--spacing-12) 30px; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--color-mist); }
.rz-row .tc { display: inline-block; min-width: 0; padding: 2px 5px; font-size: 11px; margin-right: 6px; }
.rz-step { display: flex; align-items: baseline; gap: 10px; margin: 0 0 14px; }
.rz-step h3 { margin: 0; }
.rz-step .q { font-size: 13px; color: var(--color-ash); }
/* поля воронки — тот же канон, что у прежних каналов хука, только четыре ячейки
   остались — спека v2.1 §1; хук снят целиком дельтой v2.3, .grid4 держит только воронку */
.grid4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--spacing-16); }
.grid4 > div { font-size: 13px; color: var(--color-mist); line-height: 1.45; }
.grid4 .k { display: block; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-ash); margin-bottom: 4px; }
.grid4 p { margin: 0; }
.tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.tag { display: inline-flex; align-items: center; background: rgba(255,255,255,.05); color: var(--color-mist); border-radius: var(--radius-pill); padding: 3px 10px; font: 400 12px/1.6 var(--font-ui); letter-spacing: -.01em; }
/* чипы формата и ниш под заголовком (спека v2.3 §1–2): карточка «Примерка» снята, тема
   уже в заголовке — этим двум полям осталась только шапка. Тот же вид, что у .fmt-row/
   .niches до неё, дублировать канон не нужно — один .k/.tag/.pill на обе шапки */
.hd-chips { display: flex; align-items: center; gap: var(--spacing-12); flex-wrap: wrap; margin-top: var(--spacing-8); }
.hd-chips .k { flex: 0 0 auto; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-ash); }
.scenes { display: flex; flex-direction: column; }
/* разделитель вместо рельсы (восстановлен из v2, спека v2.2 §2, 2026-09-05: нить и точки
   не оправдали строку — читались декором, не смыслом). Кадры остаются слева у каждой части. */
.scene { display: flex; align-items: flex-start; padding: 14px 0; border-top: 1px solid var(--color-graphite); }
.scene:first-child { border-top: 0; padding-top: 0; }
.scene img, .scene-noimg { display: block; width: 44px; height: 78px; object-fit: cover; border-radius: var(--radius-btn); flex: 0 0 auto; background: var(--color-obsidian); box-shadow: var(--shadow-subtle); }
/* чип .tc живёт внутри .body в разметке (узкий телефон кладёт его первой строкой над
   текстом), но на столе .body — grid: role/what/text встают во вторую колонку, чип — в
   первую на всю высоту строки. — находка 1, 2026-09-04 */
.scene .body { flex: 1 1 auto; min-width: 0; margin-left: var(--spacing-16); display: grid;
  grid-template-columns: 76px 1fr; grid-template-areas: "tc part" "tc techs";
  column-gap: var(--spacing-16); row-gap: 6px; }
.scene .tc { grid-area: tc; align-self: start; }
/* строка части — «.part», не «.line»: .line занят таблицей комнаты (app.css ~590), имя класса
   ловило чужую сетку и рвало текст по слову (снимок 2026-09-06) */
.scene .part { grid-area: part; margin: 0; font-size: 14px; line-height: 1.5; color: var(--color-mist); }
.scene .part-name { font-weight: 500; color: var(--color-paper); }
.scene .role { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-fog); }
/* каналы хука — строками под именем части (бриф: что показать, что сказать/написать);
   подпись курсивом-ярлыком, как «речь:» в транскрибации — 2026-09-06 */
.scene .ch { display: block; }
.scene .ch i { font-style: normal; color: var(--color-fog); }
/* приёмы части — чипами под «зачем» (спека v2.3 §2): второго места у приёмов больше
   нет, дублирующий блок «Детали» снят целиком. Тише обычного .tag — читаются подписью,
   не кнопкой */
.scene .techs { grid-area: techs; margin: 0; }
/* подпись ряда «приёмы» — как .hd-chips .k в шапке: без неё три чипа читались как три варианта
   одного приёма (оператор, 2026-09-06) */
.scene .techs .k { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-ash); margin-right: var(--spacing-8); }
.tag-sm { font-size: 11px; line-height: 1.5; padding: 2px 8px; color: var(--color-ash); }
.rz-inner { padding: 0 8px 12px; }
.grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--spacing-24); margin-left: 30px; }
.grid3 p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--color-mist); }
.grid3 .k { display: block; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-ash); margin-bottom: 6px; }
.funnel { margin: 0; font-size: 14px; color: var(--color-paper); }   /* воронка теперь карточка верхнего уровня, не .rz-inner — без отступа в 30px, спека v2.1 §1 */
@media (max-width: 560px) {
  .grid3, .grid4 { grid-template-columns: 1fr; }
  .scene img, .scene-noimg { width: 36px; height: 64px; }
  /* находка 1: на узком экране чип развёрстан обратно в первую строку .body, а не
     зажат в 76px-колонке рядом с текстом — иначе на 390px тексту остаётся ~150px */
  .scene .body { display: flex; flex-direction: column; gap: 6px; }
  .scene .tc { align-self: flex-start; }
}

/* комната «Анализ» — список в семье «Слежения» */
.an-grid { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) 100px 270px 110px; }
a.line { color: inherit; }
.an-reel { display: flex; align-items: center; gap: var(--spacing-12); min-width: 0; }
.an-reel img { width: 36px; height: 64px; object-fit: cover; border-radius: 6px; flex: 0 0 auto; display: block; background: var(--color-obsidian); }
.reel-col { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.st { display: flex; align-items: center; gap: var(--spacing-8); font-size: 13px; color: var(--color-mist); }
.st.off { color: var(--color-ash); }
.dot { width: 7px; height: 7px; border-radius: var(--radius-pill); flex: 0 0 auto; background: var(--color-pulse-green, #27a644); }
.dot.wait { background: var(--color-smoke); }
.dot.err { background: #eb5757; }
.when { font-size: 12px; color: var(--color-ash); }
.num.dim { color: var(--color-ash); }
@media (max-width: 720px) { .an-grid.line { display: flex; flex-wrap: wrap; } }

/* панель авторов: добавление и пауза */
.line-acts { display: flex; gap: var(--spacing-4); justify-content: flex-end; align-items: center; }
/* шестерёнка в ряду рычагов — того же роста, что «пауза» и «отписаться» */
.line-acts .tool-btn { width: 30px; height: 26px; }
.line.is-paused .line-name, .line.is-paused .num { color: var(--color-ash); }

/* бейдж «Сохранённого» + пульс при добавлении: микровзаимодействие-подтверждение */
/* бейдж «нового» (2026-09-15, как у Telegram): горит, пока место не открыли. В панели — сумма
   по «Без папки» и папкам, на вкладке и плитке папки — своё число; тот же цвет всюду */
.side-badge, .new-n {
  display: inline-block; font: 400 11px/1 var(--font-num); padding: 2px 6px; border-radius: var(--radius-pill);
  background: var(--color-bone); color: var(--color-void);
}
.side-badge { margin-left: auto; }
.new-n { margin-left: 4px; }
.ftile-new { position: absolute; top: calc(var(--spacing-12) + 8px); right: calc(var(--spacing-12) + 8px); margin: 0; }
.side-i.pulse .side-badge { animation: badge-pop .9s ease; }
@keyframes badge-pop {
  0%   { transform: scale(.5); opacity: .2; }
  45%  { transform: scale(1.3); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) { .side-i.pulse .side-badge { animation: none; } }

/* вход и регистрация */
.auth-body { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: var(--spacing-24); }
.auth-card {
  width: 100%; max-width: 360px;
  background: var(--color-carbon); border-radius: var(--radius-card);
  box-shadow: var(--shadow-subtle), var(--shadow-xl);
  padding: var(--spacing-32);
}
.auth-card .brand { margin: 0 0 var(--spacing-16); font-size: 15px; font-weight: 510; color: var(--color-paper); }
.auth-card h1 { margin: 0; font: 400 24px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.288px; }
.auth-sub { margin: var(--spacing-4) 0 var(--spacing-20); font-size: 13px; color: var(--color-fog); }
.auth-form { display: flex; flex-direction: column; gap: var(--spacing-12); }
.auth-go { margin-top: var(--spacing-8); }
.auth-alt { margin: var(--spacing-20) 0 0; font-size: 13px; color: var(--color-fog); }
.auth-alt a { color: var(--color-mist); text-decoration: underline; text-underline-offset: 3px; }
.auth-alt a:hover { color: var(--color-paper); }
.auth-card .note { margin: 0 0 var(--spacing-12); }
.me-out { margin-left: auto; display: flex; }
.me-out button { background: none; border: 0; cursor: pointer; padding: 4px; color: var(--color-ash); display: flex; }
.me-out button:hover { color: var(--color-mist); }
.me-out svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }

/* ── «MCP / CLI» по канону loore `/cabinet/mcp` (2026-09-18): семь вкладок клиентов, переключатель
   MCP / CLI, три шага в ряд. Размеры вкладок сняты с loore: 34px, 13.5/500, зазор значка 7px. ── */
.ctabs-row { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-12);
  margin: var(--spacing-16) 0 var(--spacing-16); }
.ctabs { display: flex; gap: 4px; flex-wrap: wrap; min-width: 0; }
.ctabs button { display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 13px; flex-shrink: 0;
  border-radius: var(--radius-pill); border: 1px solid transparent; background: none; cursor: pointer;
  font: 500 13.5px/1 var(--font-ui); color: var(--color-fog); white-space: nowrap; }
.ctabs button svg { width: 15px; height: 15px; flex-shrink: 0; }
.ctabs button .brand { color: var(--color-fog); }   /* ChatGPT, Cursor, Hermes — currentColor; остальные — своей заливкой */
.ctabs button.on .brand { color: var(--color-paper); }
.ctabs button:hover { color: var(--color-paper); }
.ctabs button.on { color: var(--color-paper); background: var(--color-carbon); border-color: var(--color-graphite); }
.seg { display: inline-flex; flex-shrink: 0; padding: 3px; border-radius: var(--radius-pill); background: var(--color-carbon); border: 1px solid var(--color-graphite); }
.seg button { padding: 5px 14px; border: 0; border-radius: var(--radius-pill); background: none; cursor: pointer;
  font: 500 12.5px/1.2 var(--font-ui); color: var(--color-fog); }
.seg button.on { background: var(--color-graphite); color: var(--color-paper); }
.steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--color-graphite);
  border-radius: var(--radius-card); background: var(--color-carbon); overflow: hidden; }
.step { display: flex; flex-direction: column; gap: var(--spacing-8); padding: var(--spacing-20); min-width: 0; border-left: 1px solid var(--color-graphite); }
.step:first-child { border-left: 0; }
.step-n { width: 26px; height: 26px; border-radius: var(--radius-pill); display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-obsidian); border: 1px solid var(--color-graphite); font: 400 12px/1 var(--font-num); color: var(--color-mist); }
.step h3 { margin: 4px 0 0; font: 510 15px/1.3 var(--font-ui); color: var(--color-paper); }
.step p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--color-fog); }
.step p code { font-family: var(--font-mono); font-size: 12px; color: var(--color-mist); }
.step-act { align-self: flex-start; margin-top: auto; display: inline-flex; align-items: center; gap: 6px; }
.step-act .ic, .step-act .chev { width: 13px; height: 13px; }   /* шеврон вниз — к блоку ключа ниже, как ↓ у loore */
.step-go { margin-top: auto; display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; }
.step-go .brand { width: 16px; height: 16px; }
.step-note { font-size: 12px !important; color: var(--color-ash) !important; }
.step-more summary { cursor: pointer; font-size: 12.5px; color: var(--color-fog); list-style: none; display: flex; align-items: center; gap: 6px; }
.step-more summary::-webkit-details-marker { display: none; }
.step-more summary::before { content: "▸"; font-size: 10px; color: var(--color-ash); transition: transform .15s; }
.step-more[open] summary::before { transform: rotate(90deg); }
.step-more p { margin-top: var(--spacing-8); font-size: 12.5px; }
.code { position: relative; border-radius: var(--radius-btn); background: var(--color-obsidian); border: 1px solid var(--color-graphite); }
.code.at-foot { margin-top: auto; }   /* у Claude адрес стоит низом, вровень с кнопкой соседнего шага */
.code pre { margin: 0; padding: 12px 40px 12px 12px; font: 400 12px/1.55 var(--font-mono); color: var(--color-mist);
  white-space: pre-wrap; overflow-wrap: anywhere; }
.code .copy { position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border-color: transparent; color: var(--color-ash); }
.code .copy:hover { color: var(--color-paper); background: var(--color-graphite); }
.code .copy svg { width: 14px; height: 14px; }
.steps-note { margin: var(--spacing-8) 0 var(--spacing-24); }
.mcp-addr { margin: var(--spacing-16) 0 0; font-size: 12px; color: var(--color-ash); }
.mcp-addr code { font-family: var(--font-mono); color: var(--color-ash); }
@media (max-width: 900px) { .steps { grid-template-columns: minmax(0, 1fr); } .step { border-left: 0; border-top: 1px solid var(--color-graphite); } .step:first-child { border-top: 0; } }
/* телефон, как у loore: переключатель — над вкладками, вкладки — лентой вбок до края экрана */
@media (max-width: 640px) {
  .ctabs-row { flex-direction: column; align-items: flex-start; }
  .seg { order: -1; }
  .ctabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; align-self: stretch;
    margin: 0 calc(-1 * var(--spacing-16)); padding: 0 var(--spacing-16); }   /* поля .wrap на телефоне — 16px */
  .ctabs::-webkit-scrollbar { display: none; }
}
/* ключ: заголовок и подпись над карточкой, форма — в карточке (как «Ключи» у loore) */
.keys h2 { margin: 0 0 4px; font: 510 16px/1.3 var(--font-ui); color: var(--color-paper); }
.keys-sub { margin: 0 0 var(--spacing-12); font-size: 13px; color: var(--color-fog); }
.keys-card { background: var(--color-carbon); border: 1px solid var(--color-graphite); border-radius: var(--radius-card);
  padding: var(--spacing-20); }
.key-form { display: flex; align-items: center; gap: var(--spacing-12); flex-wrap: wrap; }
.key-form .hint-line { margin: 0; flex: 1; min-width: 200px; }
.key-form .search-go { display: inline-flex; align-items: center; gap: 6px; }
.key-form .search-go .ic { width: 14px; height: 14px; }
.apps-h { margin-top: var(--spacing-24) !important; }
.apps { padding: var(--spacing-8) var(--spacing-20); }
.app-row { display: flex; align-items: center; gap: var(--spacing-12); padding: var(--spacing-12) 0; }
.app-row + .app-row { border-top: 1px solid var(--color-graphite); }
.app-name { font-size: 14px; color: var(--color-paper); }
.app-since { flex: 1; font-size: 12px; color: var(--color-ash); }
/* REST — «Без MCP», как у loore: подпись капсом над карточкой, в карточке база, curl и ссылка на методы */
.rest { margin-top: var(--spacing-24); }
.rest-k { margin: 0 0 var(--spacing-8); font: 510 11px/1 var(--font-ui); letter-spacing: .08em; text-transform: uppercase; color: var(--color-ash); }
.rest-head { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-12); margin-bottom: 4px; }
.rest-head h2 { margin: 0; font: 510 15px/1.3 var(--font-ui); color: var(--color-paper); }
.rest-head .copy { position: static; width: 28px; height: 28px; }
.rest .keys-sub code { font-family: var(--font-mono); font-size: 12px; color: var(--color-mist); }
.rest .code .copy { display: none; }   /* копирование — кнопкой в шапке карточки, как у loore */
.rest-more { display: inline-block; margin-top: var(--spacing-12); font-size: 13px; color: var(--color-mist); }
.rest-more:hover { color: var(--color-paper); }
/* согласие OAuth (/oauth/consent) — продолжение карточки входа */
.consent-who { font-weight: 510; color: var(--color-paper); }
.consent-can { margin: 0 0 var(--spacing-20); padding-left: 18px; display: flex; flex-direction: column; gap: 6px;
  font-size: 13px; line-height: 1.5; color: var(--color-mist); }

.key-box, .cmd-box {
  display: flex; align-items: stretch; gap: var(--spacing-8);
  margin: 0 0 var(--spacing-8);
}
.key-raw, .cmd {
  flex: 1; min-width: 0; margin: 0; overflow-x: auto; white-space: pre;
  background: var(--color-void); border: 1px solid var(--color-graphite);
  border-radius: var(--radius-btn); padding: var(--spacing-12);
  font: 400 13px/1.5 var(--font-code); color: var(--color-mist);
}
.key-raw { color: var(--color-paper); }
.copy { flex-shrink: 0; align-self: center; }

a.plan-row { text-decoration: none; border-radius: var(--radius-badge); }
a.plan-row:hover .plan-k, a.plan-row:hover .plan-v { color: var(--color-paper); }
a.plan-row:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }

/* ── полировка 2026-08-30: доводка деталей до одного комплекта ── */

/* селекты — вид полей, а не системных выпадашек: без нативной стрелки,
   своя (цвет = --color-ash, в data-URI переменные не работают) */
select.field {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2362666d' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
}
select.field option { background: var(--color-obsidian); color: var(--color-mist); }

/* микровзаимодействия: один ритм отклика на всём интерактивном, а не только
   у карточек — состояние меняется переходом, не прыжком */
.side-i, .watch-btn, .search-go, .note-go, .field, .search-in, .day,
.recent-i, .line, a.plan-row, .me-out button, .auth-alt a, .tab {
  transition: color .15s ease, background-color .15s ease,
              border-color .15s ease, box-shadow .15s ease;
}

/* чипы (дни недели, авторы в «Все видео»): состояние носит сама пилюля,
   нативный квадратик чекбокса из другого мира — прячем */
.day { position: relative; }
.day input { position: absolute; opacity: 0; pointer-events: none; }
.day:has(input:checked) {
  background: var(--color-bone); border-color: var(--color-bone);
  color: var(--color-void);
}
.day:has(input:focus-visible) { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .side-i, .watch-btn, .search-go, .note-go, .field, .search-in, .day,
  .recent-i, .line, a.plan-row, .me-out button, .auth-alt a, .tab,
  .topic-pick { transition: none; }
}

/* радио графика обхода — из того же комплекта, что чипы: свой кружок вместо
   системного, отмеченный заливается bone; лайм остаётся только у множителя */
.sched-o input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  width: 14px; height: 14px; flex: 0 0 auto;
  border: 1px solid var(--color-smoke); border-radius: var(--radius-pill);
  background: transparent; cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease;
}
.sched-o input[type="radio"]:checked { background: var(--color-bone); border-color: var(--color-bone); }
.sched-o input[type="radio"]:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }

/* хвосты той же чистовой отделки: тёмный скроллбар и выделение в цветах канона */
html { scrollbar-color: var(--color-smoke) transparent; }
.cmd, .key-raw, .heat-wrap { scrollbar-width: thin; }
::selection { background: var(--color-bone); color: var(--color-void); }

/* ── Разведка: примеры новичка — спека Q2/Q4a/Q4b; доска фраз упразднена (Q6):
      история живёт в выпадашке строки поиска ── */

/* примеры формулировок: только состояние новичка, клик подставляет фразу в строку */
.pills { display: flex; flex-wrap: wrap; gap: var(--spacing-8); margin-top: var(--spacing-12); }
.pill {
  display: inline-flex; align-items: center; cursor: pointer;
  background: rgba(255, 255, 255, .05); color: var(--color-mist);
  border: 0; border-radius: var(--radius-pill); padding: 4px var(--spacing-12);
  font: 400 13px/1.6 var(--font-ui); letter-spacing: -.01em;
}
.pill:hover { background: rgba(255, 255, 255, .09); color: var(--color-paper); }
.pill:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }

/* один оркестрованный вход ленты: карточки волной, движение гаснет за полсекунды */
.grid .card { animation: card-in .45s ease backwards; }
.grid .card:nth-child(1)  { animation-delay: .05s; }
.grid .card:nth-child(2)  { animation-delay: .1s; }
.grid .card:nth-child(3)  { animation-delay: .15s; }
.grid .card:nth-child(4)  { animation-delay: .2s; }
.grid .card:nth-child(5)  { animation-delay: .25s; }
.grid .card:nth-child(6)  { animation-delay: .3s; }
.grid .card:nth-child(7)  { animation-delay: .35s; }
.grid .card:nth-child(8)  { animation-delay: .4s; }
.grid .card:nth-child(n+9) { animation-delay: .45s; }
@keyframes card-in { from { opacity: 0; transform: translateY(10px); } }

@media (prefers-reduced-motion: reduce) {
  .grid .card { animation: none; }
}

/* ── действия панелей (Склад-Q5б, вариант А): лупа-поле и порядок-кнопка ── */

.tools-acts { display: flex; align-items: center; gap: var(--spacing-8); margin-left: auto; }

.tool-btn {
  width: 33px; height: 33px; flex: 0 0 auto; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--color-graphite);
  border-radius: var(--radius-btn); color: var(--color-mist);
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.tool-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.tool-btn:hover { border-color: var(--color-smoke); color: var(--color-paper); }
.tool-btn:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }

/* лупа: кнопка, растущая в поле по фокусу; с введённым словом остаётся открытой */
.s-box {
  display: flex; align-items: center; gap: var(--spacing-8); height: 33px;
  border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  padding: 0 8px; cursor: text;
  transition: border-color .15s ease;
}
.s-box svg { width: 15px; height: 15px; flex: 0 0 auto; fill: none;
  stroke: var(--color-ash); stroke-width: 1.5; stroke-linecap: round; }
.s-box:hover { border-color: var(--color-smoke); }
.s-box input {
  width: 0; opacity: 0; border: 0; background: transparent; padding: 0;
  color: var(--color-paper); font: 400 13px/1.2 var(--font-ui); outline: none;
  transition: width .25s ease, opacity .2s ease;
}
.s-box input::placeholder { color: var(--color-ash); }
.s-box:focus-within, .s-box.open { border-color: var(--color-smoke); padding: 0 var(--spacing-12); }
.s-box:focus-within input, .s-box.open input { width: 180px; opacity: 1; }

/* выпадашка канона: details-меню, пункт — submit той же формы. Один компонент
   на все селекты витрины — нативная выпадашка браузера канон не носит. */
.drop { position: relative; }
.drop > summary { list-style: none; cursor: pointer; }
.drop > summary::-webkit-details-marker { display: none; }
.drop[open] > summary .tool-btn,
.drop[open] > summary .field { border-color: var(--color-smoke); color: var(--color-paper); }
.drop-menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  min-width: 200px; max-height: 320px; overflow-y: auto; padding: var(--spacing-4);
  background: var(--color-obsidian); border: 1px solid var(--color-graphite);
  border-radius: var(--radius-btn); box-shadow: var(--shadow-xl);
  animation: menu-in .18s ease both;
}
.drop.right .drop-menu { left: auto; right: 0; min-width: 232px; }
.drop.flip .drop-menu { left: auto; right: 0; }          /* не влезло справа — к правому краю кнопки (скрипт в _shell) */
.drop.right.flip .drop-menu { left: 0; right: auto; }
/* Объяснение перед первым разбором (макрос `_analyzebtn.html`, решение оператора 2026-09-17):
   панель раскрывается вверх от прижатой кнопки. Шторкой снизу её делать нельзя — кнопка живёт в
   слайде ленты и в фиксированной `.rz-go`, у обеих свой слой, из которого шторка не поднимается
   над панелью вкладок и обрезается ею (снимок 2026-09-17). Внутри — обычный текст и белая кнопка,
   поэтому правила пунктов меню (`.drop-menu button`) здесь снимаются. */
.teach .drop-menu { left: 0; right: 0; top: auto; bottom: calc(100% + 8px);
  min-width: 0; max-width: none; box-sizing: border-box; max-height: 60vh;
  padding: var(--spacing-16); border-radius: var(--radius-card); }
.teach .drop-menu h3 { margin: 0 0 var(--spacing-8); font: 510 17px/1.3 var(--font-ui); color: var(--color-paper); }
.teach .drop-menu p { margin: 0 0 var(--spacing-12); font-size: 14px; line-height: 1.45; color: var(--color-mist); }
.teach .drop-menu p.hint { color: var(--color-ash); }
.teach .drop-menu p:last-child { margin: var(--spacing-8) 0 0; font-size: 13px; }
.teach .drop-menu .btn { width: 100%; height: 48px; justify-content: center;
  background: var(--color-paper); color: var(--color-void); font: 510 15px/1 var(--font-ui); padding: 0; }
.teach .drop-menu .btn:hover { background: var(--color-paper); color: var(--color-void); }
.teach > summary.btn { width: 100%; }
.drop-head { display: none; }   /* заголовок — только у телефонной шторки (правило в конце файла) */
.drop-menu button > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }   /* длинный пункт (имя папки) — с многоточием */
@keyframes menu-in { from { opacity: 0; transform: translateY(-4px); } }
.drop-menu button {
  /* значок и подпись рядом, слева: галочку выбранного пункта отодвигает вправо она сама
     (`button.on::after { margin-left: auto }`), поэтому space-between здесь был не нужен — зато он
     разгонял «значок … подпись» по краям в каждом меню с иконками («Выйти», «Поделиться»;
     оператор увидел 2026-09-17, до того чинилось точечными переопределениями) */
  display: flex; align-items: center; justify-content: flex-start; gap: var(--spacing-8);
  width: 100%; max-width: 360px; text-align: left; cursor: pointer; white-space: nowrap;
  background: none; border: 0; border-radius: var(--radius-btn);
  padding: 7px var(--spacing-12); font: 400 13px/1.3 var(--font-ui);
  color: var(--color-mist);
}
.drop-menu button:hover { background: var(--color-graphite); color: var(--color-paper); }
.drop-menu button.on { color: var(--color-paper); }
.drop-menu button.on::after { content: "✓"; color: var(--color-ash); font-size: 12px; }

/* шестерёнка на строке автора (МА-Q6): всплывашка с тем же блоком графика,
   что на странице автора; на телефоне — шторка снизу */
/* потолок высоты обычной выпадашки всплывашке не нужен: семь дней и кнопка
   «Сохранить» должны быть видны без прокрутки (снимок 2026-09-02) */
.gear-menu { padding: var(--spacing-16); }
/* специфичность: .drop.right .drop-menu задаёт ширину — перебиваем тем же весом */
.drop.gear .drop-menu { min-width: 400px; max-height: none; }
.gear-head { font-size: 13px; color: var(--color-paper); margin-bottom: var(--spacing-4); }
.gear-menu .sched-o { font-size: 13px; }
/* «Сохранить график» — обычная кнопка сита, а не пункт меню: правило
   .drop-menu button целится в любой <button> внутри всплывашки и красит его
   в свой канон; возвращаем вид .watch-a-btn отдельным правилом повыше по
   специфичности (два класса против класс+тег), лейблов дней это не касается —
   они не <button>, правило их не видит */
.gear-menu .watch-a-btn {
  display: inline-flex; width: auto; text-align: inherit; white-space: nowrap;
  background: none; border: 1px solid var(--color-graphite);
  padding: 5px var(--spacing-8); font: 400 12px/1.2 var(--font-ui); color: var(--color-ash);
}
.gear-menu .watch-a-btn:hover { background: none; border-color: var(--color-smoke); color: var(--color-mist); }
@media (max-width: 560px) {
  .drop.gear .drop-menu { max-height: 80vh; }   /* в шестерёнке график — ей можно выше */
}

/* шеврон — базовый аффорданс выпадашки (Склад-Q5г, вариант А каталога);
   вращается при открытии за 0.15s */
.drop summary .field { display: inline-flex; align-items: center; gap: var(--spacing-8); }
.chev { width: 10px; height: 6px; flex: 0 0 auto; transition: transform .15s ease; }
.chev path { fill: none; stroke: var(--color-ash); stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round; }
.drop[open] .chev { transform: rotate(180deg); }

/* точка активности: порядок не дефолтный — «здесь что-то настроено»;
   bone, как пульс бейджа — лайм остаётся у множителя */
.tool-btn { position: relative; }
.tool-dot { position: absolute; top: -3px; right: -3px; width: 7px; height: 7px;
  border-radius: var(--radius-pill); background: var(--color-bone); }

@media (prefers-reduced-motion: reduce) {
  .s-box input { transition: none; }
  .drop-menu { animation: none; }
  .chev { transition: none; }
}

/* ---- страница автора по макету E (2026-09-10): шапка, Аналитика ---- */
.a-row { display: flex; align-items: center; gap: var(--spacing-12); flex-wrap: wrap; }
.a-name { display: inline-flex; align-items: center; gap: 6px; color: inherit; }
.a-name svg { width: 14px; height: 14px; fill: none; stroke: var(--color-ash); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.a-name:hover svg { stroke: var(--color-paper); }
.a-nick { font-size: 14px; color: var(--color-fog); text-decoration: none; }
.a-nick:hover { color: var(--color-paper); }
.a-sub b { font-weight: 500; color: var(--color-paper); }
/* тихая кнопка ряда действий: та же форма, что у соседей, но голосом ниже — «Загрузить историю»
   стоит токен и нужна не всем, кто зашёл на страницу (оператор 2026-09-12) */
.watch-btn.quiet { color: var(--color-fog); }
.watch-btn.quiet:hover:not(:disabled) { color: var(--color-paper); }
.watch-btn.quiet:disabled { color: var(--color-ash); cursor: not-allowed; }
.clk { display: inline-flex; opacity: .85; }
.clk svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
/* пауза — залитая: обводкой два тонких прямоугольника читаются как «стоп», а не как пауза */
.clk.icon-pause svg { fill: currentColor; stroke: none; width: 12px; height: 12px; }
.drop.sub .drop-menu { min-width: 340px; max-height: none; }
.sub-sched { padding: var(--spacing-8) var(--spacing-12) var(--spacing-4); }
.sub-sched .cadence { display: flex; flex-direction: column; gap: var(--spacing-8); align-items: flex-start; margin-top: var(--spacing-8); }
.sub-sched .sched-o { font-size: 13px; }
.menu-div { height: 1px; background: var(--color-graphite); margin: 6px 4px; }

.a-kpis { padding-top: var(--spacing-16); }
.kpi-cmp { font-size: 13px; color: var(--color-fog); line-height: 1.4; margin-top: var(--spacing-4); }
.vchip { display: inline-block; padding: 2px 7px; border-radius: var(--radius-badge); font: 510 11px/1.4 var(--font-num); margin-right: 8px; background: var(--color-graphite); color: var(--color-paper); vertical-align: middle; }
.vchip.up { background: var(--color-acid-lime); color: var(--color-void); }
.a-card { background: var(--color-carbon); border-radius: var(--radius-card); box-shadow: var(--shadow-subtle); padding: var(--spacing-16) var(--spacing-20); margin-top: var(--spacing-16); display: flex; flex-direction: column; gap: var(--spacing-8); min-width: 0; }
.growth-box { position: relative; }
.growth-wrap { overflow-x: auto; }   /* на телефоне график листается, не сжимается в нитку */
.growth { width: 100%; min-width: 640px; height: auto; display: block; }
.growth-grid { stroke: var(--color-graphite); stroke-width: 1; stroke-dasharray: 3 4; }
.growth-tick { font: 400 10px var(--font-num); fill: var(--color-ash); }
.growth-line { fill: none; stroke: var(--color-acid-lime); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.growth-end { font: 400 12px var(--font-num); fill: var(--color-paper); }
/* наведение на график (2026-09-11): точка на каждый день, курсор-линия, подсказка с роликами дня */
svg.growth { cursor: crosshair; }
.growth-hover { visibility: hidden; pointer-events: none; }
.growth-hover.on { visibility: visible; }
.growth-cursor { stroke: var(--color-fog); stroke-width: 1; transition: transform .18s ease; }
.growth-focus { fill: var(--color-carbon); stroke: var(--color-paper); stroke-width: 1.5; transition: transform .18s ease; }
.growth-tip { position: absolute; top: 8px; z-index: 5; min-width: 170px; max-width: 300px; padding: 10px 12px;
  background: var(--color-obsidian); border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  box-shadow: var(--shadow-xl); font-size: 12px; transition: left .18s ease, top .18s ease;
  pointer-events: none; }   /* мышь проходит сквозь карточку к точкам за ней (оператор 2026-09-11) */
.gt-gain { font: 500 15px/1.2 var(--font-num); color: var(--color-paper); white-space: nowrap; }
.gt-date { color: var(--color-ash); margin: 2px 0 6px; white-space: nowrap; }
.gt-cum { color: var(--color-ash); margin-top: 6px; white-space: nowrap; }
.gt-row { display: flex; justify-content: space-between; gap: 12px; padding: 2px 0; color: var(--color-mist); }
.gt-row.hit .gt-num { color: var(--color-acid-lime); }
.gt-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gt-num { flex: 0 0 auto; font-family: var(--font-num); white-space: nowrap; }
.top { display: flex; flex-direction: column; }
.top-head, .top-row { display: grid; grid-template-columns: 48px minmax(0, 1fr) 110px 90px; gap: var(--spacing-16); align-items: center; padding: 8px var(--spacing-8); }
.top-head { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-ash); border-bottom: 1px solid var(--color-graphite); }
.top-row { border-bottom: 1px solid var(--color-carbon); border-radius: var(--radius-btn); font-size: 13px; color: var(--color-mist); }
.top-row:hover { background: var(--color-obsidian); }
.top-row img { width: 36px; height: 64px; object-fit: cover; border-radius: 6px; background: var(--color-obsidian); display: block; }
.top-cell { min-width: 0; }
.top-cap { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.top-when { display: block; font-size: 12px; color: var(--color-ash); margin-top: 2px; }
.top-num { font-family: var(--font-num); color: var(--color-paper); }
.top-mult { display: inline-block; background: var(--color-acid-lime); color: var(--color-void); font: 510 12px/1 var(--font-num); padding: 4px 7px; border-radius: var(--radius-badge); }
.how { margin-top: var(--spacing-12); font-size: 13px; color: var(--color-ash); }
.how summary { cursor: pointer; color: var(--color-fog); list-style: none; }
.how summary::before { content: "?"; display: inline-block; width: 16px; height: 16px; border-radius: 9999px; border: 1px solid var(--color-graphite); font-size: 10px; line-height: 14px; text-align: center; margin-right: 8px; }
.how p { margin: var(--spacing-8) 0 0; line-height: 1.5; max-width: 80ch; }
@media (max-width: 720px) {
  .a-kpis { grid-template-columns: 1fr; }
  .top-head { display: none; }
  .top-row { grid-template-columns: 40px minmax(0, 1fr) 64px 56px; gap: var(--spacing-8); }
  .drop.sub .drop-menu { min-width: 280px; }
}

/* ---- Инсайты по этажам (2026-09-10): вопрос → плитки → вывод ---- */
.floor { background: var(--color-carbon); border-radius: var(--radius-card); box-shadow: var(--shadow-subtle); padding: var(--spacing-20) var(--spacing-24); margin-top: var(--spacing-16); display: flex; flex-direction: column; gap: var(--spacing-16); min-width: 0; }
.floor-h { display: flex; align-items: baseline; gap: 10px; }
.floor-h h3 { margin: 0; font: 510 15px/1.2 var(--font-ui); color: var(--color-paper); letter-spacing: -.01em; }
.floor-h .q { font-size: 13px; color: var(--color-ash); }
.tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--spacing-16); }
.tiles.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.tile .stat-l { margin-top: 2px; }
.stat-k.dim { color: var(--color-ash); }
.floor .kpi-t { margin: 0; font-size: 13px; line-height: 1.45; color: var(--color-mist); }
.floor .kpi-t b { font-weight: 510; color: var(--color-paper); }
.legend { display: flex; gap: var(--spacing-16); flex-wrap: wrap; font-size: 11px; color: var(--color-ash); }
.legend i { display: inline-block; width: 8px; height: 8px; border-radius: 9999px; margin-right: 5px; vertical-align: middle; }
.legend .lg-hit { background: var(--color-acid-lime); }
.legend .lg-norm { background: var(--color-fog); }
.heat-cell.hit { background: var(--color-acid-lime); }
.react { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--spacing-24); }
.react-h { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-ash); margin-bottom: var(--spacing-8); }
.react-row { display: flex; align-items: center; gap: var(--spacing-12); padding: 8px 0; border-top: 1px solid var(--color-graphite); color: var(--color-mist); }
.react-row:first-of-type { border-top: 0; }
.react-row img, .react-row .noimg { width: 36px; height: 64px; object-fit: cover; border-radius: 6px; background: var(--color-obsidian); flex: 0 0 auto; display: block; }
.react-cap { flex: 1 1 auto; min-width: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.react-cap small { display: block; font-size: 12px; color: var(--color-ash); margin-top: 2px; }
.react-v { font-family: var(--font-num); color: var(--color-paper); white-space: nowrap; text-align: right; }
.react-v small { display: block; font-size: 12px; color: var(--color-acid-lime); }
.floor-h h3 { white-space: nowrap; }
.react-row { min-width: 0; }
@media (max-width: 720px) {
  .tiles, .tiles.two, .react { grid-template-columns: minmax(0, 1fr); }
  .floor { padding: var(--spacing-16); }
}

/* чат с агентом (спека 2026-09-10) */
.side-list { display: contents; }   /* обёртка строк: на столе прозрачна, на телефоне — полоса */
.side-chats > summary { list-style: none; cursor: pointer; }
.side-chats > summary::-webkit-details-marker { display: none; }
/* стрелка раздела — тот же шеврон, что у фильтров (оператор 2026-09-11: «▾» был слишком мелким) */
.side-chats > summary { display: flex; align-items: center; }
.side-chats > summary .chev { margin-left: auto; width: 14px; height: 14px; }
/* раздел раскрывается вниз: закрыт — шеврон вправо, открыт — вниз (не как у выпадашек; оператор 2026-09-11) */
.side-chats:not([open]) > summary .chev { transform: rotate(-90deg); }
/* наведение на заголовок раздела — белым весь ряд: имя, стрелка «все» и шеврон (оператор 2026-09-15) */
.side-chats > summary { cursor: pointer; border-radius: var(--radius-btn); transition: color .15s ease; }
.side-chats > summary:hover { color: var(--color-paper); }
.side-chats > summary:hover .chev path { stroke: var(--color-paper); }
.side-chats > summary:hover .side-go { color: var(--color-paper); }
.side-chat { gap: 8px; }
/* названия чатов приглушены: разделы — навигация, чаты — история, и одним цветом они спорили
   (канон claude.ai, оператор 2026-09-12). Активный и наведённый — в полную силу */
.side-chat-t { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--color-fog); }
.side-chat:hover .side-chat-t, .side-chat.on .side-chat-t { color: var(--color-paper); }
.side-chat-w { font-size: 11px; color: var(--color-ash); white-space: nowrap; flex: 0 0 auto; }
/* акцент лаймом на двух завязках чата — «Анализ профиля» и «Отправить»: как и множитель,
   это точка, где человек платит действие или ждёт ответ, остальной интерфейс монохромный */
.watch-btn.lime { background: var(--color-paper); color: var(--color-void); border-color: var(--color-paper); }
.watch-btn.lime:hover { background: var(--color-bone); border-color: var(--color-bone); color: var(--color-void); }
/* значок у кнопок захода в чат: без размера SVG растягивался до дефолта браузера
   (~40px) и гнул кнопку в две строки — ревью 2026-09-10 */
.chat-ic { width: 16px; height: 16px; flex: 0 0 auto; }
.chat-btn { white-space: nowrap; }
/* выпадашка выбора проекта у «Обсудить с ИИ» (Task 7, 2026-09-14): шеврон тем же размером,
   что у других выпадашек кнопки */
.chat-door .chev { width: 12px; height: 12px; margin-left: 2px; }
/* колонка чата по центру рабочей области (оператор 2026-09-14: «смещён, не по середине»):
   шапка, лента и окно ввода — одна ширина, margin auto */
.chat-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0;
  border-bottom: 1px solid var(--color-graphite); max-width: 820px; width: 100%; margin: 0 auto; }
.chat-obj { display: flex; align-items: center; gap: 10px; color: inherit; text-decoration: none; }
.chat-obj img { width: 40px; height: 40px; border-radius: 8px; object-fit: cover; }
.chat-obj small { display: block; color: var(--color-ash); }
/* проект чата в шапке (Task 7): тише самого объекта — справочная строка, не действие */
/* страница чата занимает высоту экрана: лента растёт, окно ввода прижато к низу — иначе оно
   висело посреди пустоты, а у конкурента стоит внизу (оператор 2026-09-12) */
.chat-feed { display: flex; flex-direction: column; gap: 12px; padding: 16px 0; max-width: 820px; width: 100%;
  margin: 0 auto; flex: 1 1 auto; }
body:has(.chat-dock) main { display: flex; flex-direction: column; min-height: calc(100vh - 110px); }
.msg { padding: 12px 14px; border-radius: 12px; line-height: 1.45; }
.msg p { margin: 0 0 8px; white-space: pre-line; }
.msg p:last-child { margin-bottom: 0; }
.msg.user { align-self: flex-end; background: var(--color-graphite); max-width: 80%; }
.msg.assistant { align-self: flex-start; background: var(--color-carbon); max-width: 92%; position: relative; margin-left: 32px; }
/* аватар агента — маскот слева от пузыря; у «думает» и «сорвалось» тоже (это тот же .msg.assistant) */
.msg.assistant::before { content: ""; position: absolute; left: -32px; top: 6px; width: 24px; height: 24px;
  background: url("brand/mascot-96.png") center / contain no-repeat; }
.msg.thinking, .msg.failed { color: var(--color-ash); display: flex; align-items: center; gap: 8px; }
.msg-meta { margin-top: 6px; font-size: 11px; color: var(--color-ash); }
.msg-next { align-self: flex-start; max-width: 92%; display: flex; flex-wrap: wrap; gap: 6px; margin-top: -4px; }
.msg-next button {
  cursor: pointer; padding: 6px 12px; text-align: left; font: 400 13px/1.3 var(--font-ui);
  color: var(--color-mist); background: transparent; border: 1px solid var(--color-graphite);
  border-radius: var(--radius-pill); transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.msg-next button:hover { color: var(--color-paper); border-color: var(--color-smoke); background: var(--color-carbon); }
.msg-next button:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }
@media (max-width: 640px) { .msg.user { max-width: 100%; } .msg.assistant { max-width: calc(100% - 32px); } }

/* ── папки на «Сохранённом» (холст 2026-09-11) ─────────────────────── */
/* вкладки с значком: «Без папки» — лоток, «Папки» — папка */
.tab { display: inline-flex; align-items: center; gap: 6px; }
.tab svg { width: 14px; height: 14px; }
.tab-hint { margin: calc(var(--spacing-8) * -1) 0 var(--spacing-16); font-size: 13px; color: var(--color-ash); }
/* плитки-коробки: коллаж 2×2 из обложек, имя, счётчик; «Новая папка» — пунктир с полем */
.ftiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--spacing-16);
  padding-bottom: var(--spacing-64); }
.ftile { position: relative; display: flex; flex-direction: column; gap: var(--spacing-8); padding: var(--spacing-12);
  background: var(--color-carbon); border-radius: var(--radius-card); box-shadow: var(--shadow-subtle);
  transition: box-shadow .18s ease, transform .18s ease; }
.ftile:hover { box-shadow: var(--shadow-subtle), var(--shadow-xl); transform: translateY(-2px); }
.ftile:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.ftile-cov { aspect-ratio: 4 / 3; border-radius: var(--radius-btn); overflow: hidden; display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); gap: 2px;
  background: var(--color-graphite); }
.ftile-cov img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ftile-cov span { display: block; background: var(--color-obsidian); }
.ftile-name { display: flex; align-items: center; gap: var(--spacing-8); font-size: 14px; color: var(--color-paper);
  letter-spacing: -.011em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ftile-name svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--color-fog); }
.ftile-name > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }   /* длинное имя — многоточие, не обрез (обход 2026-09-15) */
.ftile-n { font: 400 11px/1.2 var(--font-num); color: var(--color-ash); }
.ftile.new { background: none; box-shadow: none; border: 1px dashed var(--color-graphite); }
.ftile.new:hover { transform: none; box-shadow: none; border-color: var(--color-smoke); }
.ftile-cov.plus { display: grid; place-items: center; background: none; color: var(--color-ash); }
.ftile-cov.plus svg { width: 24px; height: 24px; }
.ftile.new .nf-in { width: 100%; }
.ftile.new .watch-a-btn { align-self: flex-start; }
/* поле «новая папка» — в меню закладки, на плитке и в «⋯» папки */
.nf-row { display: flex; align-items: center; gap: 6px; padding: 4px 6px 2px; }
.nf-in { flex: 1 1 auto; min-width: 0; background: transparent; border: 1px solid var(--color-graphite);
  color: var(--color-mist); border-radius: var(--radius-btn); padding: 6px 10px;
  font: 400 13px/1.2 var(--font-ui); letter-spacing: -.01em; }
.nf-in::placeholder { color: var(--color-ash); }
.nf-in:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }
/* правило .drop-menu button красит любой <button> в пункт меню — «+» и «Переименовать» возвращаем */
/* «+» стоит в колонке значков (14px, как у пунктов), без рамки; поле — остаток строки */
.drop-menu .nf-btn { width: 14px; height: 30px; flex: 0 0 auto; display: inline-flex; align-items: center;
  justify-content: center; padding: 0; border: 0; color: var(--color-fog); }
.drop-menu .nf-btn svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; }
.drop-menu .nf-btn:hover { background: none; color: var(--color-paper); }
.drop.save .nf-row { gap: 8px; }
/* пункт меню со значком и подстрочником */
.drop-menu button svg.ic { width: 14px; height: 14px; flex: 0 0 auto; color: var(--color-fog); }
.drop.save .drop-menu button { justify-content: flex-start; gap: 8px; }
.drop.save .drop-menu button > span:first-of-type { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.drop-menu button .sub { display: block; font: 400 11px/1.3 var(--font-ui); color: var(--color-ash); }
.drop-menu button.on::after { margin-left: auto; }
/* закладка-меню: на странице ролика 36×36, на карточке — компактнее, рядом с «Анализ» */
.drop.save > summary .save-btn { pointer-events: none; }
.drop.save[open] > summary .save-btn { border-color: var(--color-smoke); color: var(--color-paper); }
.drop.save .drop-menu { min-width: 240px; }
/* заголовок и строка «новая папка» — в ту же колонку, что пункты (12px от края, как у кнопок);
   оператор 2026-09-11: «Сохранить» липло к левому краю, «+» — к правому */
.drop.save .gear-head { padding: 6px 12px 2px; }
.drop.save .nf-row { padding: 6px 12px 4px; }
.card-actions .drop.save { flex: 0 0 auto; }
.card-actions .save-btn { width: 33px; height: 30px; }
.card-actions .save-btn svg { width: 16px; height: 16px; }
/* открытая папка: имя и «⋯» в одной строке; меню «⋯» уже шестерёнки */
.folder-head { display: flex; align-items: flex-start; gap: var(--spacing-16); padding: var(--spacing-40) 0 var(--spacing-8); }
.folder-id { flex: 1 1 auto; min-width: 0; }
.folder-head h1 { margin: 0; font: 400 24px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.288px; overflow-wrap: anywhere; }
.folder-head .tool-btn { border-color: var(--color-smoke); color: var(--color-paper); }
.drop.gear .drop-menu.folder-menu { min-width: 320px; padding: var(--spacing-8); }
.folder-menu .nf-row { padding: 4px 4px 2px; }
.folder-menu .watch-a-btn { display: inline-flex; width: auto; white-space: nowrap; background: none;
  border: 1px solid var(--color-graphite); padding: 6px var(--spacing-8); font: 400 12px/1.2 var(--font-ui); color: var(--color-ash); }
.folder-menu .watch-a-btn:hover { background: none; border-color: var(--color-smoke); color: var(--color-mist); }
@media (max-width: 560px) {
  .ftiles { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--spacing-12); }
  .folder-head { padding-top: var(--spacing-24); }
  .folder-head h1 { font-size: 20px; }
}
/* колонка обложки прокручивается внутри себя (overflow-y: auto) — и режет всё, что вылезает
   вбок. Меню закладки поэтому ставим от правого края панели действий, а не от кнопки:
   240px помещаются в 300px колонки (снимок 2026-09-11) */
.media .m-tools { position: relative; }
.media .drop.save { position: static; }
/* карточка режет содержимое скруглением (overflow: hidden) и при наведении становится
   своим слоем — открытое меню закладки уходило под соседнюю карточку. Раскрытая карточка
   отпускает края и всплывает над соседями */
.card:has(.drop[open]) { overflow: visible; position: relative; z-index: 5; }
.card:has(.drop[open]) .shot { border-radius: var(--radius-card) var(--radius-card) 0 0; overflow: hidden; }
/* Закладка на телефоне — шторка снизу: карточка вдвое уже меню, правый край левой карточки резал
   список (снимок 2026-09-11). Своё правило снято 2026-09-17: с общим языком шторок
   (`.drop:not(.keep-drop)`, ниже) оно ничего не добавляло на карточках, а на слайде ленты — ломало.
   Там закладка помечена `keep-drop` и обязана быть панелькой у кнопки, как «···», но это правило
   всё равно делало её шторкой, да ещё запертой в слое `.slide-col`: она выезжала ПОД именем автора,
   живой строкой и кнопкой «Проанализировать» (оператор 2026-09-17: «она спрятана на заднем фоне»). */
/* ── режим «Выбрать» на полке (оператор 2026-09-11) ─────────────────── */
.tab-row { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-16); }
.tab-row .tab-hint { margin-bottom: var(--spacing-16); }
.pick-enter { flex: 0 0 auto; margin-bottom: var(--spacing-16); }
.pick-enter svg, .pick-off svg { width: 14px; height: 14px; }
.folder-head .pick-enter { margin: 6px 0 0; }
/* галочка поверх обложки: круг с рамкой, отмечен — лайм с птичкой; возраст и «новое» в режиме
   выбора прячем — угол занят */
.card.picking { position: relative; }
.card.picking .age, .card.picking .added { display: none; }
.pick { position: absolute; top: var(--spacing-8); right: var(--spacing-8); z-index: 3; width: 26px; height: 26px; cursor: pointer; }
.pick input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.pick span { position: absolute; inset: 0; border-radius: var(--radius-pill); border: 1.5px solid var(--color-paper);
  background: rgba(8, 9, 10, .55); backdrop-filter: blur(4px); }
.pick input:checked + span { background: var(--color-paper); border-color: var(--color-paper); }
/* галочка — по центру кружка через transform, а не жёсткими left/top: те были посчитаны под
   один размер и в других местах уезжали из центра (оператор 2026-09-17) */
.pick input:checked + span::after { content: ""; position: absolute; left: 50%; top: 50%;
  width: 5px; height: 9px; border: 2px solid var(--color-void); border-top: 0; border-left: 0;
  transform: translate(-50%, -60%) rotate(45deg); }
.pick input:focus-visible + span { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.card.picking:has(.pick input:checked) { box-shadow: var(--shadow-subtle), 0 0 0 2px var(--color-acid-lime); }
/* полоска действий: липнет к низу окна, меню папок открывается вверх */
/* Строка списка как метка выбора (чаты, оператор 2026-09-17): тап в любое место ставит галочку —
   попадать в кружок не нужно. Кружок и галочка те же, что на карточках полки. */
.pick-row { cursor: pointer; gap: var(--spacing-12); }
.pick-row input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.pick-dot { flex: 0 0 auto; position: relative; width: 22px; height: 22px; border-radius: var(--radius-pill);
  border: 1.5px solid var(--color-smoke); }
.pick-row input:checked + .pick-dot { background: var(--color-paper); border-color: var(--color-paper); }
.pick-row input:checked + .pick-dot::after { content: ""; position: absolute; left: 50%; top: 50%;
  width: 5px; height: 9px; border: 2px solid var(--color-void); border-top: 0; border-left: 0;
  transform: translate(-50%, -60%) rotate(45deg); }
.pick-row input:focus-visible + .pick-dot { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.pick-row .proj-chat { flex: 1 1 auto; min-width: 0; border-top: 0; }
.pick-row:hover .proj-chat { color: var(--color-paper); }

.pickbar { position: sticky; bottom: var(--spacing-12); z-index: 20; display: flex; align-items: center; gap: var(--spacing-12);
  flex-wrap: wrap; margin-top: calc(var(--spacing-64) * -1 + var(--spacing-16)); margin-bottom: var(--spacing-16);
  padding: var(--spacing-8) var(--spacing-12); background: var(--color-obsidian); border: 1px solid var(--color-graphite);
  border-radius: var(--radius-card); box-shadow: var(--shadow-xl); }
.pick-n { font-size: 13px; color: var(--color-ash); white-space: nowrap; }
.pick-n b { font-weight: 400; color: var(--color-paper); }
.pickbar .drop.up .drop-menu { top: auto; bottom: calc(100% + 6px); }
.pickbar .drop-menu button { justify-content: flex-start; gap: 8px; }
.pickbar .pick-off { color: #eb5757; border-color: var(--color-graphite); }
.pickbar .pick-off:hover { color: #f08c8c; border-color: var(--color-smoke); }
.pickbar .pick-clear { margin-left: auto; }
.pickbar .pick-done { margin-left: 0; }
@media (max-width: 560px) {
  .pickbar { position: fixed; left: var(--spacing-12); right: var(--spacing-12); bottom: var(--spacing-12); margin: 0; }
  .pickbar .pick-done { margin-left: 0; }
}

/* ── «+» у поля ввода чата и вложения (2026-09-11) ─────────────────── */
.chat-dock { position: sticky; bottom: 0; max-width: 820px; width: 100%; margin: 0 auto; padding: 8px 0 16px;
  background: var(--color-void); }
.chat-box {
  display: flex; flex-direction: column; gap: 6px; padding: 6px 6px 6px 8px;
  background: var(--color-carbon); border: 1px solid var(--color-graphite); border-radius: 20px;
  transition: border-color .15s ease;
}
.chat-box:focus-within { border-color: var(--color-smoke); }
/* ряд кнопок под полем: «+» слева, отправка справа (колонка, как у Virale — 2026-09-12) */
.chat-row { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
.chat-price { display: flex; align-items: center; gap: 6px; margin: 0; padding: 2px 6px 4px;
  font-size: 12px; color: var(--color-fog); }
.chat-price svg { width: 13px; height: 13px; flex: 0 0 auto; fill: none; stroke: currentColor;
  stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
/* вложенное — карточками в окне ввода, как у Virale (2026-09-11) */
.chat-cards { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 4px 0; }
.chat-card { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 5px 6px 5px 9px;
  font-size: 12px; color: var(--color-mist); background: var(--color-obsidian);
  border: 1px solid var(--color-graphite); border-radius: 10px; }
.chat-card > svg { width: 13px; height: 13px; color: var(--color-fog); flex: 0 0 auto; }
.chat-card-t { min-width: 0; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-card-w { flex: 0 0 auto; font-size: 11px; color: var(--color-ash); }
/* крестик — ТОЛЬКО прямой потомок карточки: как потомковый селектор он красил и пункты
   выпадашки среза внутри карточки (те же 18×18 без отступов), и два пункта вставали в одну
   строку внахлёст. Найдено замером в браузере, 2026-09-12 */
.chat-card > button { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
  padding: 0; border: 0; border-radius: var(--radius-pill); background: none; color: var(--color-ash); cursor: pointer; }
.chat-card > button:hover { color: var(--color-paper); background: var(--color-graphite); }
.chat-card > button svg { width: 11px; height: 11px; color: inherit; }
/* карточка объекта чата: снять нельзя, зато у автора есть срез — какие ролики видит агент */
.chat-card.obj { padding: 4px 4px 4px 4px; }
.chat-card-c { width: 22px; height: 22px; flex: 0 0 auto; border-radius: 6px; object-fit: cover; }
.chat-card-c.ph { display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; color: var(--color-fog); background: var(--color-graphite); }
.chat-card.obj > .chat-card-t { color: var(--color-paper); }
.drop.scope > summary { list-style: none; cursor: pointer; }
.drop.scope > summary::-webkit-details-marker { display: none; }
.scope-t { display: inline-flex; align-items: center; gap: 2px; padding: 2px 4px 2px 7px; border-radius: 8px;
  color: var(--color-fog); white-space: nowrap; }
.scope-t:hover, .drop.scope[open] .scope-t { background: var(--color-graphite); color: var(--color-paper); }
.scope-t .chev { width: 12px; height: 12px; }
.drop.scope .drop-menu { top: auto; bottom: calc(100% + 6px); left: auto; right: 0; width: 320px; min-width: 0; }
.drop.scope .drop-menu button { justify-content: flex-start; gap: 8px; align-items: flex-start;
  white-space: normal; }
.drop.scope .drop-menu button > span:first-of-type { flex: 1 1 auto; min-width: 0; }
.drop.scope .drop-menu button.on { color: var(--color-paper); }
.drop.scope .drop-menu .sub-act { border-top: 1px solid var(--color-graphite); margin-top: 4px; padding-top: 8px; }
.chat-box .drop.plus { flex: 0 0 auto; }
.chat-box .drop.plus .tool-btn { width: 32px; height: 32px; border-radius: 50%; border-color: transparent; color: var(--color-fog); }
.chat-box .drop.plus .tool-btn:hover, .chat-box .drop.plus[open] > summary .tool-btn {
  background: var(--color-graphite); border-color: transparent; color: var(--color-paper); }
.chat-box .drop.plus .drop-menu button { align-items: center; }
.chat-box .drop.plus .drop-menu button > svg { width: 16px; height: 16px; color: var(--color-fog); flex: 0 0 auto; }
.chat-box .chat-form { display: flex; min-width: 0; }
.chat-box textarea {
  /* высокое окно (оператор 2026-09-12): черновик разбора — это десяток строк, и они должны
     помещаться целиком, а не обрезаться. Дальше поле само прокручивается */
  flex: 1 1 auto; width: 100%; min-width: 0; resize: none; min-height: 32px;
  max-height: min(340px, 40vh); overflow-y: auto;
  padding: 7px 6px; background: transparent; border: 0; color: var(--color-mist);
  font: 400 14px/1.4 var(--font-ui);
}
.chat-box textarea:focus { outline: none; }
.chat-box textarea::placeholder { color: var(--color-ash); }
.send-btn {
  width: 32px; height: 32px; flex: 0 0 auto; cursor: pointer; border: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-paper); color: var(--color-void); transition: filter .15s ease, opacity .15s ease;
}
.send-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.send-btn:hover { filter: brightness(1.1); }
.send-btn:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.chat-box textarea:disabled, .send-btn:disabled { opacity: .5; cursor: not-allowed; }
/* «вверх от кнопки» — настольная раскладка; на телефоне меню «+» приходит шторкой снизу, как все
   остальные (оператор 2026-09-17: «сделай так, чтобы она открывалась как все эти шторки») */
@media (min-width: 901px) {
  .drop.plus.up .drop-menu { top: auto; bottom: calc(100% + 6px); left: 0; right: auto; min-width: 280px; }
}
.drop.plus .drop-menu button { justify-content: flex-start; gap: 8px; }
.drop.plus .drop-menu button > span:first-of-type { flex: 1 1 auto; min-width: 0; }
.drop.plus .gear-head { padding: 6px 12px 2px; }
.drop.plus .nf-row { padding: 6px 12px 4px; gap: 8px; }
@media (max-width: 560px) {
  /* .drop.plus.up — та же специфичность, что у правила «открывать вверх»: иначе bottom: 100% при
     position: fixed уводит шторку за верх экрана (снимок 2026-09-11) */
  .drop.plus.up .drop-menu {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; min-width: 0;
    border-radius: var(--radius-card) var(--radius-card) 0 0; max-height: 80vh; overflow: auto; padding: var(--spacing-12);
  }
}

/* ── шторка «Добавить контент» (как у Virale, 2026-09-11): снизу и на столе, и на телефоне ── */
/* Окно «Агент отвечает только по складу» — один раз на браузер, после первой отправки
   (образец — Virale, скрин 65; текст свой: чужого обучения и памяти между чатами у нас нет) */
dialog.hello {
  padding: 0; margin: auto; width: min(420px, calc(100vw - 32px)); max-width: none;
  background: var(--color-obsidian); color: var(--color-mist);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-card);
  box-shadow: var(--shadow-xl); animation: menu-in .2s ease both;
}
dialog.hello::backdrop { background: rgba(0, 0, 0, .6); }

/* подтверждение необратимого (оператор 2026-09-15): та же коробка, что «hello», кнопки в ряд справа,
   «Удалить» красная — единственная красная заливка в интерфейсе, чтобы читалась как необратимое */
dialog.confirm {
  padding: 0; margin: auto; width: min(400px, calc(100vw - 32px)); max-width: none;
  background: var(--color-obsidian); color: var(--color-mist);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-card);
  box-shadow: var(--shadow-xl); animation: menu-in .2s ease both;
}
dialog.confirm::backdrop { background: rgba(0, 0, 0, .6); }
.confirm-in { display: flex; flex-direction: column; gap: var(--spacing-8); padding: var(--spacing-24); }
.confirm-in h2 { margin: 0; font: 500 16px/1.4 var(--font-ui); color: var(--color-paper); letter-spacing: -.01em;
  overflow-wrap: anywhere; }
.confirm-in p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--color-fog); }
.confirm-acts { display: flex; justify-content: flex-end; gap: var(--spacing-8); margin-top: var(--spacing-12); }
.confirm-acts button {
  padding: 8px var(--spacing-16); cursor: pointer; font: 500 14px/1.2 var(--font-ui);
  border-radius: var(--radius-btn); border: 1px solid var(--color-graphite);
  background: transparent; color: var(--color-mist);
}
.confirm-acts button:hover { border-color: var(--color-smoke); color: var(--color-paper); }
.confirm-acts button:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.confirm-acts .confirm-yes { background: #eb5757; border-color: #eb5757; color: #fff; }
.confirm-acts .confirm-yes:hover { background: #f06a6a; border-color: #f06a6a; color: #fff; }
@media (max-width: 560px) { .confirm-acts { flex-direction: column-reverse; } .confirm-acts button { width: 100%; } }
.hello-in { display: flex; flex-direction: column; align-items: center; gap: var(--spacing-12);
  padding: var(--spacing-24) var(--spacing-24) var(--spacing-16); text-align: center; }
img.hello-ic { width: 56px; height: 56px; }
.hello-ic { width: 40px; height: 40px; color: var(--color-acid-lime); flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.hello-in h2 { margin: 0; font: 500 17px/1.35 var(--font-ui); color: var(--color-paper); letter-spacing: -.01em; }
.hello-in p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--color-fog); }
.hello-note { padding: var(--spacing-12); border-radius: var(--radius-btn);
  background: var(--color-carbon); box-shadow: var(--shadow-subtle); }
.hello-in button { width: 100%; margin-top: var(--spacing-4); padding: 9px var(--spacing-16); cursor: pointer;
  font: 500 14px/1.2 var(--font-ui); color: var(--color-void); background: var(--color-paper);
  border: 0; border-radius: var(--radius-btn); }
.hello-in button:hover { background: var(--color-bone); }

/* Шторка снизу, ростом по содержимому (оператор 2026-09-17: «открывается за экран, сделай как все
   шторки»). Было `inset: 80px 0 0 0; height: calc(100vh - 80px)` — панель почти во весь экран, и на
   телефоне её низ уходил под браузерную полосу, потому что `100vh` больше видимой высоты. Теперь
   потолок в `dvh` (динамическая высота, Safari считает её честно), а список внутри скроллится сам. */
dialog.sheet {
  position: fixed; inset: auto 0 0 0; margin: 0; width: 100%; max-width: none;
  height: auto; max-height: 85vh; max-height: 85dvh;
  padding: 0; border: 1px solid var(--color-graphite); border-bottom: 0;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  background: var(--color-obsidian); color: var(--color-mist); box-shadow: var(--shadow-xl); overflow: hidden;
}
/* Шторка — флекс-колонка (2026-09-17). Было: `height: auto; max-height: 85dvh` у диалога и
   `max-height: 100%` у `.sheet-in` — а процент от высоты родителя, у которого высота не задана, по
   спецификации читается как `none`. Колонка внутри росла по содержимому мимо потолка диалога, а тот
   режет лишнее (`overflow: hidden`): при 16 закреплённых кнопка «Загрузить файл» уезжала на 1006px
   при экране 844, список не скроллился (`clientHeight == scrollHeight`, жест и колесо ничего не
   двигали) — замерено на стенде. Флекс-контейнер с потолком отдаёт детям определённую высоту, и
   `flex: 1 1 auto; min-height: 0` даёт списку сжаться и прокрутиться. `[open]` обязателен: голый
   `display: flex` перебил бы `display: none` у закрытого диалога, и он был бы виден всегда.
   Это лечит и старую шторку «Добавить контент» — там же тонул список из тридцати папок. */
dialog.sheet[open] { display: flex; flex-direction: column; }
dialog.sheet::backdrop { background: rgba(0, 0, 0, .55); }
/* анимация классами, не [open]: заполненная анимация перебивала бы inline-transform при перетаскивании */
dialog.sheet.opening { animation: sheet-up .22s ease both; }
dialog.sheet.opening::backdrop { animation: fade-in .22s ease both; }
dialog.sheet.closing { animation: sheet-down .2s ease both; }
dialog.sheet.closing::backdrop { animation: fade-out .2s ease both; }
dialog.sheet.settle { transition: transform .2s ease; }
dialog.sheet.dragging .sheet-in { cursor: grabbing; }
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } }
@keyframes sheet-down { from { transform: none; } to { transform: translateY(100%); } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
/* колонка 528px по центру — как у них; тап по полям шторки вне колонки закрывает */
.sheet-in { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; width: 100%; max-width: 528px; margin: 0 auto;
  padding: 8px var(--spacing-16) calc(var(--spacing-24) + env(safe-area-inset-bottom, 0px)); }
/* список — единственное, что тянется и скроллится: от него зависит рост шторки до потолка.
   `.sheet-scroll` — то же для шторок без вкладок (список файлов проекта); имя знает и жест «потянуть
   вниз» в каркасе: прокрученный список тянуть нельзя, иначе листание закрывало бы шторку */
.sheet-in .sheet-list, .sheet-in .sheet-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
/* действие шторки прижато низом, над safe-area (`.sheet-in` её уже держит) */
.sheet-foot { flex: 0 0 auto; margin-top: var(--spacing-12); }
.sheet-foot .btn { white-space: nowrap; }
@media (max-width: 560px) {
  /* четыре вкладки (2026-09-14, документы) в один ряд на узком экране: min-width:0 выше даёт
     кнопкам сжаться, здесь — чем жертвуем первым (иконка, потом подкладка), чтобы подписи
     остались целиком читаемы, без многоточия («Документы» обрезанное до «Документ» — не годится,
     ревью 2026-09-15) */
  .sheet-tabs button { padding: 8px 6px; gap: 0; }
  .sheet-tabs button svg { display: none; }
}
/* ручка и заголовок — зона хвата: touch-action none, чтобы палец тянул шторку, а не страницу */
.sheet-handle { width: 36px; height: 4px; flex: 0 0 auto; margin: 0 auto 10px; border-radius: 2px; background: var(--color-graphite);
  box-sizing: content-box; border: 8px solid transparent; background-clip: padding-box; cursor: grab; touch-action: none; }
.sheet-head { display: flex; align-items: center; justify-content: center; margin-bottom: 14px; cursor: grab; touch-action: none; user-select: none; }
.sheet-head b { font-size: 15px; font-weight: 500; color: var(--color-paper); }
.sheet-find { display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px;
  background: var(--color-carbon); border: 1px solid var(--color-graphite); border-radius: var(--radius-btn); }
.sheet-find:focus-within { border-color: var(--color-smoke); }
.sheet-find > svg { width: 15px; height: 15px; flex: 0 0 auto; color: var(--color-ash); }
.sheet-find input { flex: 1 1 auto; min-width: 0; background: transparent; border: 0; color: var(--color-mist);
  font: 400 14px/1.4 var(--font-ui); }
.sheet-find input:focus { outline: none; }
.sheet-find input::placeholder { color: var(--color-ash); }
.sheet-in > .hint-line { margin: 8px 0 12px; }
.sheet-tabs { display: flex; gap: 4px; margin-bottom: 10px; }
.sheet-tabs button { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 8px 10px; cursor: pointer; font: 500 13px/1.2 var(--font-ui); color: var(--color-ash);
  background: transparent; border: 0; border-radius: var(--radius-btn); transition: color .15s ease, background-color .15s ease; }
.sheet-tabs button svg { width: 14px; height: 14px; flex: 0 0 auto; }
.sheet-tabs button:hover { color: var(--color-paper); }
.sheet-tabs button.on { color: var(--color-paper); background: var(--color-graphite); }
.sheet-list { display: flex; flex-direction: column; gap: 2px; min-height: 140px; overflow-y: auto; }
/* display у класса сильнее атрибута hidden — прячем явно, иначе три вкладки видны разом (снимок 2026-09-11) */
.sheet-list button { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px; cursor: pointer;
  text-align: left; color: var(--color-mist); background: transparent; border: 0; border-radius: var(--radius-btn);
  font: 400 14px/1.3 var(--font-ui); }
.sheet-list button:hover { color: var(--color-paper); background: var(--color-graphite); }
.sheet-list button:disabled { opacity: .5; cursor: default; }
.sheet-list button > svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--color-fog); }
.sheet-list button > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheet-list button > span > span { display: block; font-size: 12px; color: var(--color-ash); overflow: hidden; text-overflow: ellipsis; }
.sheet-list .sheet-on { margin-left: auto; flex: 0 0 auto; font: 400 11px/1 var(--font-ui); font-style: normal; color: var(--color-ash); }
.sheet-ava { width: 40px; height: 40px; flex: 0 0 auto; border-radius: 50%; object-fit: cover; background: var(--color-graphite);
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px; color: var(--color-paper); }
.sheet-cover { width: 40px; height: 40px; flex: 0 0 auto; border-radius: 8px; object-fit: cover; background: var(--color-graphite); }

/* ── «⋯» у чата в панели (2026-09-11): появляется при наведении, время уступает ему место ── */
.side-chat-row { position: relative; display: flex; align-items: center; }
.side-rename { flex: 1 1 auto; min-width: 0; display: flex; padding: 1px 0; }
.side-rename .nf-in { font-size: 14px; padding: 5px 7px; }
.side-chat-row .side-chat { flex: 1 1 auto; min-width: 0; }
.side-chat-t svg { width: 11px; height: 11px; margin-right: 4px; vertical-align: -1px; color: var(--color-ash); }
/* без transform: он заводит свой слой, и соседние строки панели рисовались поверх меню (снимок 2026-09-11) */
.side-more { position: absolute; right: 2px; top: 50%; margin-top: -12px; opacity: 0; transition: opacity .15s ease; }
.side-chat-row:hover .side-more, .side-more[open], .side-more:focus-within { opacity: 1; }
.side-chat-row:has(.side-more[open]) { z-index: 40; }
/* «⋯» освобождает место справа — время прячется при наведении */
.side-chat-row:hover .side-chat-w, .side-chat-row:has(.side-more[open]) .side-chat-w { visibility: hidden; }
.side-more .tool-btn { width: 24px; height: 24px; border-color: transparent; color: var(--color-ash); }
.side-more .tool-btn:hover, .side-more[open] > summary .tool-btn { background: var(--color-graphite); border-color: transparent; color: var(--color-paper); }
.side-more .tool-btn svg { width: 14px; height: 14px; }
/* запас от края прокрутки панели, когда меню «⋯» докручивается в вид (2026-09-13) */
.side-more .drop-menu { scroll-margin: 8px; }
.drop.right.side-more .drop-menu { width: 224px; min-width: 0; box-sizing: border-box; }   /* = ширина панели внутри отступов: шире — режется её overflow */
.side-more .drop-menu form { display: block; }
/* по КНОПКЕ, а не по «кнопке внутри формы»: «Переименовать» — единственный пункт без формы,
   и слово уезжало вправо от значка на общем `space-between` (замер в браузере 2026-09-12) */
.side-more .drop-menu button { justify-content: flex-start; gap: 8px; }
.side-more .drop-menu button > svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--color-fog); }
.side-more .drop-menu button.danger > svg { color: inherit; }
@media (hover: none) { .side-more { opacity: .6; } }
@media (max-width: 900px) {
  /* панель на телефоне — тесная полоса: меню чата шторкой снизу, как у закладки и «+» */
  .drop.right.side-more .drop-menu, .drop.right.side-more.cmenu .drop-menu, .side-nav .drop.right.cmenu .drop-menu {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; min-width: 0; width: auto;
    border-radius: var(--radius-card) var(--radius-card) 0 0; max-height: 80vh; overflow: auto; padding: var(--spacing-12);
  }
}
/* подменю «Переместить в проект ›» (оператор 2026-09-14): на столе — flyout сбоку от меню, position: fixed —
   иначе панель (overflow-y: auto) и само меню (max-height) его режут; на телефоне — шторка снизу поверх меню.
   Координаты ставит скрипт оболочки */
.cmenu .drop-panel { position: fixed; z-index: 40; width: 232px; padding: var(--spacing-4); box-sizing: border-box;
  background: var(--color-obsidian); border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  box-shadow: var(--shadow-xl); }
.cmenu .drop-back .back-chev { display: none; }          /* на столе «назад» не нужен — панель рядом */
@media (max-width: 900px) {
  .cmenu .drop-panel { left: 0 !important; right: 0; bottom: 0; top: auto !important; width: auto;
    border-radius: var(--radius-card) var(--radius-card) 0 0; padding: var(--spacing-12); max-height: 70vh; overflow: auto; }
  .cmenu .drop-back .back-chev { display: inline; }
}
/* «⋯» на карточке проекта (страница проектов): в правом верхнем углу, как у строки в панели */
.proj-card-row { position: relative; }
.proj-card-row .side-more { top: 10px; right: 10px; margin-top: 0; }
.proj-card-row .side-rename { padding: var(--spacing-16); border: 1px dashed var(--color-graphite); border-radius: var(--radius-card); }
.cmenu .drop-menu button > span:first-of-type { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* специфичность выше, чем у .drop[open] .chev (та крутит шеврон открытой выпадашки на 180°) */
.drop.cmenu[open] .sub-chev, .cmenu .sub-chev { width: 12px; height: 12px; transform: rotate(-90deg); color: var(--color-ash); }
.drop.cmenu[open] .back-chev, .cmenu .back-chev { width: 12px; height: 12px; transform: rotate(90deg); color: var(--color-ash); }
/* в полосе чата «⋯» — обычный элемент строки, не абсолютный и не прячущийся до наведения, как в панели */
.crumbs-bar .side-more { position: static; margin: 0; opacity: 1; flex: 0 0 auto; }
.cmenu .drop-back { color: var(--color-ash); font-size: 12px; border-bottom: 1px solid var(--color-graphite);
  border-radius: 0; margin-bottom: 4px; }
.cmenu .drop-back:hover { background: none; color: var(--color-paper); }
.drop.right.cmenu .drop-menu { width: 232px; }
/* в панели — 200px, как у чата: панель режет всё левее своего края (overflow-y: auto), и более
   широкое меню теряло значки за левым краем (снимок 2026-09-14) */
.side-nav .drop.right.cmenu .drop-menu { width: 224px; }
/* фильтр с галочками (авторы на «Роликах», 2026-09-15): пункты-лейблы в каноне пунктов меню */
.drop-checks { min-width: 240px; }
.drop-check { display: flex; align-items: center; gap: 10px; padding: 7px var(--spacing-12); cursor: pointer;
  border-radius: var(--radius-btn); font: 400 13px/1.3 var(--font-ui); color: var(--color-mist); }
.drop-check:hover { background: var(--color-graphite); color: var(--color-paper); }
.drop-check input { width: 14px; height: 14px; margin: 0; accent-color: var(--color-acid-lime); }
.drop-check:has(input:checked) { color: var(--color-paper); }
/* инструмент «Ролик по ссылке»: одно поле и кнопка в строку, на узком — стопкой */
.tool-col { max-width: 640px; margin: 0 auto; }
.link-form { display: flex; gap: var(--spacing-8); margin: var(--spacing-40) 0 var(--spacing-8); }
.link-form .nf-in { flex: 1 1 auto; min-width: 0; font-size: 14px; padding: 9px 12px; }
@media (max-width: 560px) { .link-form { flex-direction: column; } }
/* выбранный проект в панели подсвечивается всей строкой, не словом (оператор 2026-09-14): ссылка
   растягивается, как у чата */
.side-chat-row > .side-i { flex: 1 1 auto; min-width: 0; }
/* карточки проектов одной высоты: обёртка со строкой-меню растягивает карточку на всю ячейку сетки */
.proj-card-row { align-items: stretch; }
.proj-card-row .proj-card { flex: 1 1 auto; }
/* стрелка «перейти» у заголовка «Проекты» — видна при наведении, шеврон отходит вправо от неё */
.side-go { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; margin-left: auto;
  border-radius: var(--radius-btn); color: var(--color-ash); opacity: 0; transition: opacity .15s ease; }
.side-go svg { width: 12px; height: 12px; }
.side-projects > summary:hover .side-go, .side-chats > summary:hover .side-go, .side-go:focus-visible { opacity: 1; }
.side-go:hover { color: var(--color-paper); background: var(--color-graphite); }
.side-chats > summary .side-go ~ .chev { margin-left: 4px; }   /* стрелка занимает auto-отступ, шеврон жмётся к ней (2026-09-15: у «Чатов» стрелка висела посередине) */
@media (hover: none) { .side-go { opacity: .6; } }
/* «Последние» на странице проекта: строка с «⋯» при наведении, время уступает ему место */
.proj-chat-row { border-top: 1px solid var(--color-graphite); }
.proj-chat-row .proj-chat { flex: 1 1 auto; min-width: 0; border-top: 0; }
.proj-chat-row:hover .proj-chat small, .proj-chat-row:has(.side-more[open]) .proj-chat small { visibility: hidden; }
.proj-chat-row .side-rename { padding: 6px 0; }
/* пункт-заглушка: не кнопка (проектов пока нет), выглядит как выключенный пункт меню */
.drop-off { display: flex; align-items: center; gap: 8px; padding: 7px 10px; font: 400 13px/1.3 var(--font-ui);
  color: var(--color-ash); opacity: .55; cursor: default; }
.drop-off svg { width: 14px; height: 14px; flex: 0 0 auto; }
.drop-off .sub { display: block; font-size: 11px; }
/* подменю «Переместить в проект» внутри «⋯» чата (Task 7, 2026-09-14): заголовок тем же
   стилем, что и разделы панели, пункты — с отступом под значок заголовка */
.drop-sub-h { display: flex; align-items: center; gap: 8px; padding: 6px 10px 2px; font-size: 12px;
  color: var(--color-ash); }
/* заголовок — не <button>, соседние правила на svg внутри .drop-menu button его не видят;
   без размера значок рисовался в разы крупнее пункта над ним (снимок 8124) */
.drop-sub-h svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--color-fog); }
.drop-menu .sub-item { padding-left: 32px; }

/* ── проекты (2026-09-14) ─────────────────────────────────────────── */
/* «Новый проект» — последняя строка раздела (оператор 2026-09-14): приглушённая, как подсказка,
   в полную силу при наведении; клик подменяет её полем — тот же .side-rename, что у чата */
.side-newp-btn { width: 100%; background: none; border: 0; cursor: pointer; text-align: left;
  font-family: inherit; color: var(--color-fog); }
.side-newp-btn:hover { color: var(--color-paper); background: var(--color-graphite); }
.side-newp .side-rename { padding: 1px var(--spacing-8); }
/* страница проекта по канону claude.ai (оператор 2026-09-14, Screenshot_67): крошки в шапке,
   заголовок с «⋯» на всю ширину, ниже вровень: окно ввода → «Последние» и колонка карточек
   Инструкции · Память · Контекст (правка оператора 2026-09-14: карточки на уровне окна ввода) */
.crumbs { display: flex; align-items: center; gap: var(--spacing-8); min-width: 0; font-size: 13px; color: var(--color-fog); }
.crumbs a { color: var(--color-fog); white-space: nowrap; flex: 0 0 auto; }   /* имя проекта целиком (оператор 2026-09-14) */
@media (max-width: 900px) { .crumbs a { max-width: 50%; overflow: hidden; text-overflow: ellipsis; } }   /* на телефоне длинное имя — с многоточием, короткое «Проекты» целиком (обход 2026-09-15) */
.crumb-rn { display: flex; align-items: center; min-width: 0; flex: 1 1 auto; }
.crumbs a:hover { color: var(--color-paper); }
.crumbs b { font-weight: 510; color: var(--color-paper); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crumb-sep { color: var(--color-ash); }
/* полоса чата (2026-09-14): крошки слева, «⋯» справа; имя переименовывается полем на месте */
.crumbs-bar { justify-content: space-between; }
.crumb-rename { flex: 1 1 auto; max-width: 420px; }
.crumb-rename .nf-in { font-size: 13px; padding: 4px 7px; }
/* страница проектов (оператор 2026-09-14): карточки, как боковая колонка проекта; «Новый проект» — поле на месте */
.projects-head { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-12);
  margin: var(--spacing-40) 0 var(--spacing-16); }
.projects-head h1 { margin: 0; font: 400 26px/1.25 var(--font-ui); color: var(--color-paper); letter-spacing: -.3px; }
.projects-new { display: flex; align-items: center; gap: var(--spacing-8); }
.projects-new .side-rename { width: 260px; }
.projects-new .watch-a-btn svg { width: 14px; height: 14px; margin-right: 6px; }
.proj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--spacing-16); }
.proj-card { display: flex; flex-direction: column; gap: var(--spacing-8); min-height: 120px; padding: var(--spacing-16);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-card); background: var(--color-carbon);
  color: var(--color-mist); text-decoration: none; }
.proj-card:hover { border-color: var(--color-smoke); }
.proj-card b { display: flex; align-items: center; gap: 8px; font-weight: 510; color: var(--color-paper); }
.proj-card b svg { width: 16px; height: 16px; color: var(--color-fog); flex: 0 0 auto; }
.proj-card p { margin: 0; font-size: 13px; line-height: 1.45; color: var(--color-fog); display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.proj-card small { margin-top: auto; color: var(--color-ash); }
/* карточки вложений в окне на странице проекта — крестик текстом, не значком */
.proj-compose .chat-cards { padding: 8px 8px 0; }
.proj-compose .chat-card > button { font: 400 15px/1 var(--font-ui); }
.proj { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--spacing-24); }
.proj-pads { display: none; }   /* две двери под именем — только телефон (правило ниже, в @media 900) */
.proj-main { min-width: 0; }
.proj-title { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--spacing-12);
  margin: var(--spacing-24) 0 var(--spacing-16); }
/* меню «⋯» проекта: свой класс, не .gear (тот — всплывашка графика на 400px, и общий space-between
   у пунктов уносил слово вправо от значка; снимок оператора 2026-09-14) */
.drop.pmenu .drop-menu { width: 260px; min-width: 0; box-sizing: border-box; }
.drop.pmenu .drop-menu form { display: block; }
.drop.pmenu .drop-menu button { justify-content: flex-start; gap: 8px; }
.drop.pmenu .drop-menu button > svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--color-fog); }
.drop.pmenu .drop-menu button.danger > svg { color: inherit; }
.drop.pmenu .drop-menu button > span:first-of-type { flex: 1 1 auto; min-width: 0; }
/* «+» → выбор файла: пока сервер читает файл, сама кнопка крутится (значок прячется, кольцо на его месте) */
[data-file].is-busy { cursor: progress; }
[data-file].is-busy > svg { display: none; }
[data-file].is-busy::after { content: ""; width: 12px; height: 12px; flex: 0 0 auto; border-radius: var(--radius-pill);
  border: 1.5px solid var(--color-graphite); border-top-color: var(--color-acid-lime); animation: spin .9s linear infinite; }
.pcard-empty.is-busy::after { display: inline-block; margin-left: 8px; vertical-align: middle; }
.proj-name { margin: 0; font: 400 26px/1.25 var(--font-ui); color: var(--color-paper); letter-spacing: -.3px; overflow-wrap: anywhere; }
.proj-rename { flex: 1 1 auto; }
.proj-rename .nf-in { font-size: 20px; width: 100%; }
.proj-compose .chat-form { display: flex; }
.proj-recent { margin-top: var(--spacing-24); }
/* страница всех чатов (2026-09-15): колонка по центру рабочей области, текст слева — как у claude.ai;
   строки как «Последние» у проекта */
.chats-page { max-width: 820px; margin: 0 auto; }
.chats-tools { display: flex; align-items: center; gap: var(--spacing-8); margin-top: var(--spacing-40); }
.chats-tools .chats-find { flex: 1 1 auto; min-width: 0; display: flex; }
.chats-page .board-sum { margin-top: var(--spacing-12); }
.chats-tools .pick-enter { margin-bottom: 0; }
.chats-tools .watch-btn svg { width: 14px; height: 14px; margin-right: 4px; }
.chats-page .pick { position: relative; top: auto; right: auto; width: 22px; height: 22px; flex: 0 0 auto; margin-right: var(--spacing-8); }
.chats-page .pick-off.danger { color: #eb5757; }
.chat-new { max-width: 820px; margin: var(--spacing-40) auto 0; }   /* черновик общего чата: та же колонка, что список */
.chat-new .chat-box { margin-top: var(--spacing-16); }
.chat-new .chat-row { justify-content: flex-end; }   /* без «+» слева кнопка отправки одна — справа, как в чате */
.proj-recent h2 { margin: 0 0 var(--spacing-4); font: 400 13px/1.3 var(--font-ui); color: var(--color-fog); }
.proj-chat { display: flex; justify-content: space-between; gap: var(--spacing-12); padding: 10px 0;
  border-top: 1px solid var(--color-graphite); color: var(--color-mist); }
.proj-chat span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proj-chat small { flex: 0 0 auto; white-space: nowrap; }
.proj-chat span svg { width: 12px; height: 12px; vertical-align: -1px; margin-right: 4px; color: var(--color-ash); }   /* кнопка-булавка закреплённого: без размера рисовалась во всю строку (2026-09-15) */
.proj-chat .proj-of { font-style: normal; }
@media (max-width: 560px) { .proj-chat .proj-of { display: none; } }   /* на телефоне имени проекта не хватает места — оно в крошках чата */
.proj-chat:hover { color: var(--color-paper); }
.proj-chat small { color: var(--color-ash); white-space: nowrap; }
.proj-side { align-self: start; min-width: 0; border: 1px solid var(--color-graphite); border-radius: var(--radius-card);
  background: var(--color-carbon); }
.pcard { padding: var(--spacing-16); border-top: 1px solid var(--color-graphite); }
.pcard:first-child { border-top: 0; }
.pcard-h { display: flex; align-items: center; justify-content: space-between; gap: var(--spacing-8); }
.pcard-h h3 { margin: 0; font: 510 14px/1.3 var(--font-ui); color: var(--color-paper); }
.pcard-n { font: 400 12px/1 var(--font-num); color: var(--color-ash); margin-left: 4px; }
.pcard-h .tool-btn { width: 26px; height: 26px; border-color: transparent; color: var(--color-fog); }
.pcard-h .tool-btn:hover { color: var(--color-paper); background: var(--color-graphite); }
.pcard-hint { margin: 4px 0 0; font-size: 12px; line-height: 1.45; color: var(--color-ash); }
.pcard-text { margin: 6px 0 0; font-size: 13px; line-height: 1.45; color: var(--color-mist); white-space: pre-line; overflow-wrap: anywhere; }
.pcard-form { display: flex; flex-direction: column; gap: var(--spacing-8); margin-top: var(--spacing-8); }
.pcard-form textarea { width: 100%; resize: vertical; background: var(--color-obsidian); color: var(--color-mist);
  border: 1px solid var(--color-graphite); border-radius: var(--radius-btn); padding: 8px 10px; font: 400 13px/1.45 var(--font-ui); }
.pcard-form textarea:focus { outline: none; border-color: var(--color-smoke); }
.pcard-acts { display: flex; gap: var(--spacing-8); }
.watch-a-btn.quiet { color: var(--color-ash); }
.pcard-items { display: flex; flex-direction: column; gap: 4px; margin-top: var(--spacing-8); }
.pcard-item { display: flex; align-items: center; gap: var(--spacing-8); padding: 6px 6px 6px 8px; border-radius: var(--radius-btn);
  background: var(--color-obsidian); font-size: 13px; color: var(--color-mist); }
.pcard-item > svg { width: 14px; height: 14px; color: var(--color-fog); flex: 0 0 auto; }
.pcard-item .t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pcard-item .w { flex: 0 0 auto; font-size: 11px; color: var(--color-ash); }
.pcard-item > button { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; flex: 0 0 auto;
  padding: 0; border: 0; border-radius: var(--radius-pill); background: none; color: var(--color-ash); cursor: pointer; }
.pcard-item > button:hover { color: var(--color-paper); background: var(--color-graphite); }
.pcard-item > button svg { width: 11px; height: 11px; }
.pcard-empty { display: block; width: 100%; margin-top: var(--spacing-8); padding: 20px 12px; cursor: pointer; text-align: center;
  border: 1px dashed var(--color-graphite); border-radius: var(--radius-btn); background: none;
  font: 400 12px/1.45 var(--font-ui); color: var(--color-ash); }
.pcard-empty:hover { color: var(--color-mist); border-color: var(--color-smoke); }
@media (max-width: 900px) {
  .proj { grid-template-columns: minmax(0, 1fr); gap: var(--spacing-16); }
  /* Правая колонка уезжает в шторки (оператор 2026-09-17): на телефоне она лежала ПОД «Последними» —
     чтобы дописать инструкции, надо было прокрутить мимо всех чатов. Теперь «Инструкции» и «Добавить
     файлы» — две двери строкой под именем, а под ними сразу строки чатов. Карточки сами никуда не
     делись: это тот же контекст и та же форма, только в шторке снизу */
  .proj-side { display: none; }
  .proj-title { margin: var(--spacing-12) 0; }        /* имя стоит и в залипающей шапке — верхний воздух режем */
  /* Двери делят ширину ровно пополам (`flex: 1 1 0`), но не уже своей подписи
     (`min-width: fit-content`) — на самом узком телефоне (320) «Добавить файлы» не влезало в
     половину и обрезалось до «Добавить …» (замер 119 нужно / 83 есть). Перенос строки флексбокс
     считает как раз по этому минимуму: на 360 и выше двери стоят в ряд, на 320 честно встают друг
     под друга во всю ширину, подпись целиком. — 2026-09-17 */
  .proj-pads { display: flex; flex-wrap: wrap; gap: var(--spacing-8); margin: 0 0 var(--spacing-24); }
  .proj-pads button { flex: 1 1 0; min-width: fit-content; height: 44px; padding: 0 6px;
    display: inline-flex; align-items: center; justify-content: center; gap: 5px; cursor: pointer;
    background: var(--color-carbon); color: var(--color-mist);
    border: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
    font: 400 15px/1.2 var(--font-ui); letter-spacing: -.011em; }
  .proj-pads button > svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--color-fog); }
  .proj-pads button > span:first-of-type { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .proj-pads button .pcard-n { margin: 0; flex: 0 0 auto; }
  .proj-recent { margin-top: 0; }                     /* отступ уже дал ряд кнопок */
}


/* ── документы (2026-09-14) ─────────────────────────────────────── */
.docs-up { display: flex; flex-wrap: wrap; align-items: center; gap: var(--spacing-8); margin-top: var(--spacing-8); }
.docs-text { flex-direction: column; align-items: flex-start; max-width: 720px; }
.docs-text .nf-in, .docs-text textarea { width: 100%; }
.docs-text textarea { resize: vertical; background: var(--color-carbon); color: var(--color-mist); border: 1px solid var(--color-graphite);
  border-radius: var(--radius-btn); padding: 8px 10px; font: 400 14px/1.45 var(--font-ui); }
.doc-row { display: flex; align-items: center; gap: var(--spacing-8); padding: 6px 0; border-bottom: 1px solid var(--color-graphite); }
.doc-row > svg { width: 14px; height: 14px; color: var(--color-fog); flex: 0 0 auto; }
.doc-name { color: var(--color-mist); }
.doc-row small { color: var(--color-ash); flex: 1 1 auto; }
.doc-row .tool-btn { width: 24px; height: 24px; border-color: transparent; color: var(--color-ash); }
.sheet-more { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px; color: var(--color-fog);
  font: 400 13px/1.3 var(--font-ui); background: none; border: 0; cursor: pointer; text-align: left; }
.sheet-more:hover { color: var(--color-paper); }
.sheet-more > svg { width: 14px; height: 14px; flex: 0 0 auto; }

/* ── Главная (спека 2026-09-15; пересборка по design-taste-frontend тем же вечером) ──
   Панели, сетки и свечения нет: страница стоит на голом фоне, как у claude.ai и Perplexity —
   одна колонка 800, заголовок с брендом первым словом, поле, тихая строка MCP; ниже двери строками.
   Единственный акцент — лаймовая стрелка отправки; движение — только hover/active */
.hero {
  width: min(800px, 100%); margin: 0 auto; padding: 72px 0 0;
  display: flex; flex-direction: column; align-items: center; gap: var(--spacing-24); text-align: center;
}
.hero-mascot { width: 88px; height: 88px; margin-bottom: calc(var(--spacing-8) * -1); }
.hero-name {
  margin: 0; font: 500 28px/1.3 var(--font-ui); letter-spacing: -.022em; color: var(--color-paper);   /* две строки на 800px при one-liner из трёх глаголов */
  text-wrap: balance;
}
.hero-name b { font-weight: 650; }
/* поле — то же окно, что в чате и на странице проекта */
.hero-box { width: 100%; text-align: left; box-shadow: 0 1px 0 rgba(255, 255, 255, .03) inset; }
.hero-box textarea { font-size: 15px; }

/* двери — строки, как доска в «Подписках»: значок · имя · одна строка */
.doors { width: min(800px, 100%); margin: 72px auto var(--spacing-64); display: flex; flex-direction: column; }
.door {
  display: grid; grid-template-columns: 20px 148px minmax(0, 1fr); align-items: center; gap: var(--spacing-16);
  padding: 14px var(--spacing-12); border-top: 1px solid var(--color-graphite); border-radius: var(--radius-btn);
  text-decoration: none; color: inherit; transition: background-color .12s ease;
}
.door:first-child { border-top: 0; }
.door:hover { background: var(--color-carbon); }
.door:hover + .door { border-top-color: transparent; }
.door:active { transform: translateY(1px); }
.door:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: -2px; }
.door svg { width: 18px; height: 18px; fill: none; stroke: var(--color-fog); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.door b { font-weight: 500; font-size: 15px; color: var(--color-paper); letter-spacing: -.011em; }
.door span { font-size: 14px; color: var(--color-fog); }
.door:hover svg { stroke: var(--color-paper); }
@media (max-width: 720px) {
  .hero { padding-top: var(--spacing-40); }
  .hero-name { font-size: 22px; }
  .doors { margin-top: var(--spacing-40); }
  .door { grid-template-columns: 20px minmax(0, 1fr); grid-template-rows: auto auto; row-gap: 2px; padding: 14px var(--spacing-8); }
  .door svg { grid-row: 1; }
  .door span { grid-column: 2; }
}
@media (prefers-reduced-motion: reduce) { .door { transition: none; } .door:active { transform: none; } }

/* рельс «новое от подписок» над пультом «Подписок» (спека Главной 2026-09-15) */
.rail { padding-top: var(--spacing-20); }
.rail-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--spacing-12); margin-bottom: var(--spacing-12); }
.rail-head h2 { margin: 0; font: 400 20px/1.33 var(--font-ui); color: var(--color-paper); letter-spacing: -.24px; }
.rail-all { font-size: 13px; color: var(--color-fog); text-decoration: none; white-space: nowrap; }
.rail-all:hover { color: var(--color-paper); }
.rail .grid { grid-template-columns: repeat(5, minmax(0, 1fr)); padding-bottom: 0; }
@media (max-width: 1100px) { .rail .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 720px) { .rail .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* потолок ходов в день — та же строка, что цена разбора, только про отказ */
.chat-cap { color: var(--color-mist); }

/* ── apple-design pass (2026-09-15, ветка apple-design) ──
   На телефоне кнопки-значки 30×26 были ниже минимума 28×28 pt (accessibility.md › Mobility);
   текст чата 14px читается как подпись, а не как основное содержимое (typography.md: iOS 17 pt по умолчанию) */
@media (max-width: 720px) {
  .tool-btn { width: 36px; height: 36px; }
  .save-btn, .send-btn { width: 40px; height: 40px; }
  .watch-a-btn { padding: 8px var(--spacing-12); }
  .side-i { min-height: 40px; }
  .msg { font-size: 15px; }
}

/* ── телефон: каркас (спека 2026-09-16). Шапка «имя экрана + действия» и панель из пяти — только ≤ 900 ──── */
.m-head, .tabbar { display: none; }
.ib { width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  border-radius: var(--radius-btn); color: var(--color-mist); background: none; border: 0; padding: 0; cursor: pointer; }
.ib svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.ib:hover { color: var(--color-paper); }
.ib:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 1px; }
.drop-menu a { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px; border-radius: var(--radius-btn);
  font: 400 13px/1.3 var(--font-ui); color: var(--color-mist); }
.drop-menu a:hover { background: var(--color-graphite); color: var(--color-paper); }
.drop-menu a > svg { width: 16px; height: 16px; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round; color: var(--color-fog); }
/* линейка с двумя концами и живая строка — телефонные (спека «Страница ролика», 2026-09-16); стол их не рисует.
   Правило вне медиазапроса, чтобы телефонное объявление ниже (та же специфичность) побеждало по каскаду */
.normb, .m-tick { display: none; }
@media (max-width: 900px) {
  /* z-index 13 — выше .tabbar (12), не 10 (fix round 2, controller ruling): `position: sticky` делает .m-head
     собственным контекстом наслоения — z-index 30 у выпадашки «···» внутри него состязался только
     с соседями внутри .m-head, а сама голова с z-index 10 проигрывала .tabbar (12) целиком; шторка «···»
     открывалась под панелью — замер elementFromPoint по «Удалить» (cy 816) возвращал значок вкладки */
  .m-head { display: flex; align-items: center; gap: var(--spacing-4); height: 56px; padding: 0 var(--spacing-8) 0 var(--spacing-16);
    position: sticky; top: 0; z-index: 13; background: var(--color-void); }
  .m-title { flex: 1 1 auto; min-width: 0; margin: 0; font: 590 28px/1.1 var(--font-ui); letter-spacing: -.56px;
    color: var(--color-paper); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: font-size .15s ease; }
  .m-head.sub .m-title, .m-head.small .m-title { font-size: 17px; letter-spacing: -.011em; font-weight: 510; }
  /* поле «Переименовать» чата прямо в заголовке (fix round 2): обёртка не рисует свой бокс —
     `display: contents` держит <b> прямым потомком h1 по вёрстке, чтобы white-space/ellipsis
     у .m-title продолжали резать длинное имя как раньше; форма при показе — обычный .side-rename */
  .m-title-rn { display: contents; }
  /* carried item задачи 6 (ревью задачи 5): `<b>` вокруг имени чата в заголовке рисуется 700 —
     тяжелее потолка проекта (590) и жирнее соседних заголовков (510/590). Наследуем вес от .m-title */
  .m-title-rn b { font-weight: inherit; }
  .m-title .side-rename .nf-in { font-size: 16px; padding: 4px 7px; }   /* 16px — Safari не зумит при фокусе */
  .m-head .m-back { margin-left: calc(var(--spacing-8) * -1); }
  .m-acts { display: flex; align-items: center; gap: var(--spacing-4); flex: 0 0 auto; }
  .m-acts .save-btn { width: 44px; height: 44px; border: 0; }   /* закладка страницы ролика в шапке телефона (спека «Страница ролика») */
  .m-me > summary { list-style: none; cursor: pointer; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; }
  .m-me > summary::-webkit-details-marker { display: none; }
  .m-me .me-dot { width: 32px; height: 32px; border-radius: var(--radius-pill); background: var(--color-obsidian); color: var(--color-paper);
    font: 510 14px/1 var(--font-ui); display: flex; align-items: center; justify-content: center; }
  .m-me .drop-menu { min-width: 224px; }
  /* пункты меню аватара — значок и подпись рядом. `.drop-menu button` разложен space-between (для
     сит: пункт слева, галочка справа), и «Выйти» уезжало к правому краю от своего значка. На столе
     это уже переопределено у `.me-menu`; телефонное меню — свой класс, правило до него не доходило.
     — оператор увидел 2026-09-17 */
  .m-me .drop-menu button { justify-content: flex-start; gap: var(--spacing-8); }
  .m-me .drop-menu button > svg { width: 14px; height: 14px; flex: 0 0 auto; color: var(--color-fog); }
  .m-me .drop-menu form { display: block; }
  .tabbar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 12;
    height: calc(56px + env(safe-area-inset-bottom, 0px)); padding: 6px var(--spacing-8) env(safe-area-inset-bottom, 0px);
    background: rgba(15, 16, 17, .86); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
    border-top: 1px solid var(--color-graphite); }
  /* свой класс .mtab, не .tab (ревью 2026-09-16, находка №1): «Разборы» и «Сохранённое» уже держат
     ряд фильтров классом .tab (analysis.html, saved.html) с бесхозным `.tab.on { box-shadow: inset
     0 -2px 0 …; }` и `.tab { padding: … }` — .tabbar .tab перебивал не всё, что наследует бесклассовый
     .tab (подчёркивание оставалось, паддинг ужимал контент 39px значок+зазор+подпись в 36px). Свой
     класс ничего не наследует */
  .tabbar .mtab { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 4px; height: 48px; padding-top: 4px;
    color: var(--color-ash); font: 400 11px/1 var(--font-ui); letter-spacing: -.01em; }
  .tabbar .mtab .ic { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
  .tabbar .mtab.on { color: var(--color-paper); }
  .tabbar .mtab.on .ic { stroke-width: 2.25; }
  .tabbar .mtab.on .ic .fl { fill: currentColor; }
  .tabbar .mtab:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: -2px; border-radius: var(--radius-btn); }
  /* сита одной строкой (спека «Сита одной строкой»): чипы 36 пилюлями, лента листается вбок, последний торчит за край;
     выпадашка сита — шторка снизу, как меню чата в панели */
  .controls { display: flex; flex-wrap: nowrap; gap: var(--spacing-8); overflow-x: auto; scrollbar-width: none;
    margin: 0 calc(var(--spacing-16) * -1); padding: 0 0 var(--spacing-12) var(--spacing-16); }
  .controls::-webkit-scrollbar { display: none; }
  .ctl-group { display: contents; }
  .ctl { flex: 0 0 auto; }
  .ctl-l { display: none; }
  .ctl .field { height: 36px; padding: 0 14px; border-radius: var(--radius-pill); font-size: 14px; white-space: nowrap;
    display: inline-flex; align-items: center; gap: 6px; }
  .ctl .field.on { background: var(--color-paper); border-color: var(--color-paper); color: var(--color-void); }
  /* --color-ash на белом — 4.13:1, ниже порога 4.5:1 из комментария :root (ревью 2026-09-16, находка №4);
     --color-smoke ≈ 11:1 */
  .ctl .field.on .ctl-k { color: var(--color-smoke); }
  /* карточка молчит (спека «Карточка молчит»): на обложке множитель и возраст, под ней автор и подпись —
     просмотры, линейка, подписчики и кнопки живут на странице ролика */
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--spacing-12); padding-bottom: var(--spacing-24); }
  .card { background: none; box-shadow: none; border-radius: 0; }
  .card:hover { box-shadow: none; transform: none; }
  .shot { border-radius: var(--radius-card); overflow: hidden; }
  .card .stats, .card .ruler, .card .who-subs, .card .card-actions, .card .added { display: none; }
  .card .body { padding: var(--spacing-8) 0 0; gap: 6px; }
  .card .cap { -webkit-line-clamp: 2; }
  .card .who-ava { width: 24px; height: 24px; font-size: 11px; }   /* было 28px по умолчанию (ревью 2026-09-16, находка №1) */
  .rail .grid { display: flex; overflow-x: auto; scrollbar-width: none; margin: 0 calc(var(--spacing-16) * -1); padding: 0 0 0 var(--spacing-16); }
  .rail .grid::-webkit-scrollbar { display: none; }
  .rail .grid .card { flex: 0 0 150px; }

  /* страница ролика (спека «Страница ролика»): обложка первой, под ней автор с живой строкой, тема, чипы, линейка,
     ниже — разбор; кнопка «Анализ» прижата над панелью. На столе порядок прежний */
  body:has(.reel-cols) main.wrap { display: flex; flex-direction: column; }
  .reel-cols { display: contents; }
  /* без колонки-стола 300px: .media становится обычным элементом потока во всю ширину;
     max-height/overflow дальше — эти два были живы в старом снесённом правиле (2026-09-03),
     без них десктопные `position: sticky; max-height: calc(100vh …); overflow-y: auto` из
     базового `.media` (app.css ~940) остаются в силе и на телефоне — обложка обрезалась по
     высоте колонки, а отрицательные поля `.m-cover` резались по рамке overflow, не доходя
     до края экрана (ревью, раунд 1 — измерено elementFromPoint) */
  .media { order: 1; position: static; flex: 1 1 auto; width: auto; max-height: none; overflow: visible; }
  .reel-head { order: 2; }
  /* без разбора заголовок дублирует `.m-cap` — ту же подпись целиком, показанную строкой выше
     (`.media` — order:1 — идёт перед `.reel-head` — order:2); одна подпись видна на телефоне,
     заголовок молчит, «ещё» у `.m-cap` раскрывает (финальное ревью 2026-09-16, находка №4) */
  .reel-head h1.echo-cap { display: none; }
  .normb { order: 3; }                                      /* между шапкой темы и разбором — см. .normb ниже, вынесена из .media */
  .reel-main { order: 4; }
  /* специфичность решает: голое `.m-tools` (0-1-0) проигрывает десктопному `.media .m-tools`
     (0-2-0) — полоса «Обсудить»/закладка оставалась над обложкой и на телефоне (ревью, раунд 1) */
  .media .m-tools { display: none; }                        /* чат и закладка — в меню «···» шапки и на слайде ленты */
  .m-cover { position: relative; margin: 0 calc(var(--spacing-16) * -1); border-radius: 0; height: 400px; overflow: hidden; }
  .m-cover img { width: 100%; height: 100%; object-fit: cover; }
  .m-cover .ig { display: none; }
  .m-cover .mult { display: none; }                         /* множитель — в живой строке, крупной цифры на обложке нет (оператор) */
  .m-stats, .media .ruler, .m-who .dim { display: none; }
  .m-tick { display: block; flex: 1 1 100%; min-width: 0; }   /* снимает display:none со стола (правило вне медиазапроса) */
  .m-who { flex-wrap: wrap; row-gap: 4px; }
  /* линейка нормы вынесена из .media в reel.html (ревью, раунд 1 — controller ruling): раньше
     лежала внутри колонки обложки и рендерилась сразу после неё, до автора/темы/чипов —
     порядок в разметке не совпадал с порядком в этом же комментарии. Теперь отдельный блок
     в потоке `.reel-cols`, порядок держит `order` выше */
  /* задача 6, fix round 1: постоянный отступ у `.normb` тут не решение — кнопка (48) + зазор (12) +
     панель (56) = 116px = ровно весь промежуток [728, 844], свободного места под линейку там нет
     ни при каком постоянном margin; читаемость линейки закрывает прокрутка (`.reel-main` ниже),
     не сдвиг самого блока */
  .normb { display: flex; flex-direction: column; gap: 6px; padding: var(--spacing-8) 0 0; }
  .normb-h { display: flex; justify-content: space-between; align-items: flex-end; }
  .normb .k { display: block; font-size: 11px; color: var(--color-ash); line-height: 1.2; }
  .normb .v { display: block; font-size: 13px; color: var(--color-paper); line-height: 1.3; }
  .normb .rt { text-align: right; }
  .ruler2 { position: relative; height: 14px; }
  .ruler2 .t { position: absolute; left: 0; right: 0; top: 6px; height: 1px; background: var(--color-smoke); }
  .ruler2 .f { position: absolute; left: 0; top: 6px; height: 1px; background: var(--color-mist); }
  .ruler2 .n { position: absolute; left: 0; top: 2px; width: 1px; height: 9px; background: var(--color-mist); }
  .ruler2 .m { position: absolute; top: 4px; width: 1px; height: 5px; background: var(--color-smoke); }
  .ruler2 .e { position: absolute; right: 0; top: 2px; width: 1px; height: 9px; background: var(--color-smoke); }
  .ruler2 .d { position: absolute; top: 3px; width: 7px; height: 7px; margin-left: -3px; border-radius: var(--radius-pill); background: var(--color-acid-lime); }
  .rz-go { position: fixed; left: 16px; right: 16px; bottom: calc(56px + env(safe-area-inset-bottom, 0px) + 12px); z-index: 11; margin: 0; }
  /* кнопка заказа лежит внутри формы или внутри `details` с объяснением первого раза (макрос
     `_analyzebtn.html`): без своей доли во флексе обёртка сжимается по тексту, и прижатая кнопка
     становится 206px вместо всей ширины (живой тест 2026-09-17) */
  .rz-go > form, .rz-go > .teach { flex: 1 1 100%; min-width: 0; }
  .rz-go .hint-line { display: none; }                      /* наезжала на эйбрау/заголовок под прижатой кнопкой (ревью, раунд 1) */
  /* задача 6, fix round 1: линейка нормы (.normb выше) читается через прокрутку, не через
     постоянный отступ — кнопка (48px) + зазор (12px) + панель (56px) = 116px = ровно весь
     промежуток [728, 844], свободного места там нет ни при какой длине подписи. Запас снизу
     должен раскрыть ЛЮБУЮ подпись: кнопка + зазор + панель + safe-area (вырез снизу у iPhone) +
     воздух (16px) — прокрутка до конца документа всегда поднимает линейку выше и кнопки, и панели,
     сколько бы места ни забрала подпись сверху. Только на ролике БЕЗ разбора (`.rz-go` — кнопка
     есть только там): на готовом разборе кнопки нет, и хвост снизу не нужен — там и так много контента */
  body:has(.rz-go) .reel-main { padding-bottom: calc(48px + 12px + 56px + env(safe-area-inset-bottom, 0px) + var(--spacing-16)); }

  /* чат (спека «Чат»): пузыри и поле 16px — единственный экран, где читают абзацами, и Safari не увеличит страницу
     при фокусе. `position: fixed`, не sticky — на «Новом чате» страница короче экрана, родитель
     `.chat-new` не даёт sticky-элементу запаса высоты для хода, замерено в браузере: с `sticky` композер
     стоял в потоке (не у панели), пока не докрутишь то, чего некуда крутить. `.rz-go` страницы ролика
     решает ту же задачу так же. Уезжает вверх вместе с клавиатурой через --kb.
     Селектор — `.chat-box:not(.hero-box)`: тот же класс несёт окно «Спросите…» на Главной —
     `.hero-box { width: 100% }` спорит с `right: 16px` у fixed и обрезает кнопку отправки за
     краем экрана (ревью, раунд 1 — controller ruling, замер x=406 при экране 390), а само окно
     разъезжается вниз и накрывает «Разборы». У «Чем помочь по проекту?» hero-box нет — композер
     проекта та же дверь, что у чата, и остаётся прижатым (controller ruling) */
  .msg, .chat-box textarea { font-size: 16px; }
  /* 16px у полей внутри шторок — иначе Safari при фокусе увеличивает всю страницу, и шторка
     «уезжает за экран», как будто экран сам вырос (оператор 2026-09-17). Правило у нас уже было
     для чата и переименования, а поиск в шторке «Добавить контент» стоял на 14px — и её поле
     получает фокус сразу при открытии */
  /* весь класс, а не одно место: `.nf-in` носят поля «новая папка», «имя проекта»,
     переименование и «Ролик по ссылке» (у последнего ещё и `autofocus` — зум ловился при входе
     на «Анализ видео»; нашло облачное ревью 2026-09-17). `.link-form .nf-in` перечислен отдельно:
     у него свой вес 0,2,0, и общий `.nf-in` его не перебил бы. `.s-box input` (лупа, 13px) и
     `.search-in` (строка поиска, 14px — а спека требует 16 именно у неё) нашёл уже сам тест;
     он и держит правило дальше, вместо перечисления мест по памяти */
  /* `.sheet-in textarea` — поле инструкций в шторке: базовые 13px у `.pcard-form textarea`
     (app.css ~2176) дали бы ровно тот зум, от которого это правило и завели */
  .sheet-find input, .nf-in, .link-form .nf-in, .s-box input, .search-in, .sheet-in textarea { font-size: 16px; }
  /* шторка с полем ввода и клавиатура: `inset: auto 0 0 0` считает низ по layout viewport, и поле
     инструкций оказалось бы под клавиатурой. --kb приходит из visualViewport (скрипт в конце
     _shell.html) и обновляется, пока шторка открыта */
  dialog.sheet { bottom: var(--kb, 0px); max-height: calc(85dvh - var(--kb, 0px)); }
  /* без своего фона (fix round 2): `.chat-box` уже непрозрачна («--color-carbon», база строки 1697+) —
     `background: var(--color-void)` красила композер в цвет страницы внутри собственной рамки, на
     телефоне он единственный так и выглядел (на столе и на Главной — обычная карточка) */
  /* В РАЗГОВОРЕ панели вкладок нет (оператор спросил про канон 2026-09-17): у Telegram, WhatsApp и
     переписки Instagram нижние вкладки на экране разговора уступают место композеру — иначе внизу
     два ряда управления, а между ними полоска, в которой мелькает уезжающий текст (снимок). Список
     чатов вкладки сохраняет: он раздел, а не разговор. Возврат — «назад» в шапке.
     Откат, если не понравится: снять этот display: none. */
  body.chat-open .tabbar { display: none; }
  /* тот же композер прижат и на странице проекта, где панель вкладок остаётся, — поэтому запас над
     панелью держим по умолчанию, а без панели (в разговоре) убираем именно у `chat-open` */
  .chat-box:not(.hero-box) { position: fixed; left: var(--spacing-16); right: var(--spacing-16); margin: 0;
    bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--kb, 0px) + 10px); z-index: 13; }
  body.chat-open .chat-box:not(.hero-box) {
    bottom: calc(env(safe-area-inset-bottom, 0px) + var(--kb, 0px) + 10px); }
  /* панель вкладок прячется только пока открыта настоящая клавиатура прижатого композера — фокус
     в поле поиска или где угодно ещё не должен гасить вкладки (спека «Каркас»: «вкладки не
     прячутся»; ревью, раунд 1 — было глобальным по body.kb). Обе строки на один и тот же `:has()`-guard —
     для симметрии, не только за счёт того, что потомковый селектор и так требует наличия элемента (fix round 2) */
  body.kb:has(.chat-box:not(.hero-box)) .tabbar { display: none; }
  body.kb:has(.chat-box:not(.hero-box)) .chat-box:not(.hero-box) { bottom: var(--kb, 0px); }
  /* fixed выпал из потока — без запаса последний пузырь чата и черновик «Нового чата» прятались под
     композером. `.work` уже держит 56px+safe-area+16px под панель на каждой телефонной странице —
     здесь добавляем только высоту самого композера сверх этого, не дублируя её; высота настоящая
     (--composer-h, скрипт в конце _shell.html), не круглое число: 200px давали задвоенный запас и
     118–160px пустоты при замеренных 96–138px (ревью, раунд 1) */
  body:has(.chat-box:not(.hero-box)) main.wrap { padding-bottom: calc(var(--composer-h, 140px) + var(--spacing-16)); }
  /* «···» у чата в шапке телефона (ревью, раунд 1 — controller ruling): то же меню, что в крошках
     на столе, — крошки телефон прячет, без своего входа «Переименовать/Переместить/Удалить» с
     телефона было не достать. `.side-more` по умолчанию — невидимая нашлёпка строки списка
     (`position: absolute; opacity: 0`, видна по hover); `.crumbs-bar .side-more` уже её гасит для
     стола — тот же сброс нужен и здесь, иначе значок лежит прозрачным поверх аватара (замер: без
     сброса — не видно на снимке, стоит с тем же прямоугольником, что у аватара). Цель 44px, как у
     соседних значков .m-acts */
  .m-acts .side-more { position: static; margin: 0; opacity: 1; flex: 0 0 auto; }
  .m-acts .cmenu > summary { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; }

  /* пустые состояния (спека 2026-09-16 «Пустые состояния»): базовый `.empty` (app.css ~713) —
     широкая настольная колонка с текстом слева; на телефоне — по центру узкой колонкой, кабан
     сверху, одна кнопка вместо текстовой ссылки `.hint`/`.watch-btn` */
  .empty { padding: var(--spacing-40) var(--spacing-24); text-align: center; max-width: none; display: flex; flex-direction: column; align-items: center; gap: var(--spacing-8); }
  .empty h1 { font-size: 20px; letter-spacing: -.24px; margin: 0; }
  .empty p { margin: 0; max-width: 30ch; }
  .empty .btn { margin-top: var(--spacing-12); width: auto; min-width: 200px; padding: 0 var(--spacing-24); }
}
@media (max-width: 900px) and (prefers-reduced-motion: reduce) { .m-title { transition: none; } }
@media (min-width: 901px) {
  /* ▶ — телефонная дверь в плеер; на столе обложка остаётся ссылкой на Instagram, как была
     (ревью, раунд 1 — controller ruling). Селектор через `.media`, не голый `.play`: лента
     свой ▶ на столе держит (`.slide-media .play`) */
  .media .play { display: none; }
  /* без телефонной колонки-стола кнопка «Анализ» возвращается к прежнему виду `.search-go`
     (компактная, бежевая, 14px) — раньше это и был класс `.search-go`, переименован в `.btn`
     заодно с текстом кнопки; здесь тот же вид другим именем (ревью, раунд 1: реальный
     размер на 1280px замерили 608×48 белой — компактный вид пропал) */
  .rz-go .btn { width: auto; height: auto; padding: 9px var(--spacing-16); background: var(--color-bone); font-size: 14px; }
  /* fix round 1 (controller ruling): пустые состояния несёт и стол — их формы `.empty col` с
     кабаном ставит ещё лента (задача 4). Базовый `.btn` (app.css ~2489) — 48px высотой, width:
     100% зоны; на телефоне это вся ширина минус поля, на столе `.empty` шире (max-width: 56ch) и
     кнопка во всю ширину читалась чужеродно — полоса 504px от края до края там, где остальной
     интерфейс не растягивает кнопки. `width: auto` (первая правка ревью) её не сжал — замерено:
     осталась 504px. Причина в самой природе блочной коробки: `.btn` — `display: flex`, но
     `flex`/`inline-flex` в CSS решают РАЗНОЕ — `flex` всё равно блочный уровень отображения, а
     `width: auto` у блочного элемента в потоке (не флекс-item, не float, не absolute) по спецификации
     заполняет родителя, а не сжимается по контенту — `.empty` на столе обычный блок, не флекс-
     контейнер, сжимать нечему. `fit-content` — явное указание сжаться по содержимому, замерено:
     113–205px на разных текстах кнопки */
  .empty .btn { width: fit-content; min-width: 0; padding: 0 var(--spacing-24); }
}

/* ── лента (спека 2026-09-16 «Лента», вариант 3) ─────────────────────────────────────────────────────── */
/* поля рабочей области снимаем оба: слайд и так вычитает панель из высоты экрана, а нижний отступ
   телефона добавлял 16px прокрутки под лентой (ревью 2026-09-16) */
.feed-page .work { padding-top: 0; padding-bottom: 0; }
.feed-page .m-head, .feed-page .topbar { display: none; }
/* `clip` — чтобы уехавшая вбок лента (жест ниже) не раздвигала страницу вширь; скролл-контейнера не создаёт */
.feed-page main.wrap { max-width: none; padding: 0; overflow-x: clip; }
/* первая строка — запасная: браузер без dvh отбросил бы только её, иначе лента схлопнулась бы в ноль */
.feed { height: calc(100vh - 56px - env(safe-area-inset-bottom, 0px)); }
.feed { height: calc(100dvh - 56px - env(safe-area-inset-bottom, 0px)); overflow-y: auto; scroll-snap-type: y mandatory;
  overscroll-behavior: contain; scrollbar-width: none; background: var(--color-void); touch-action: pan-y; }
.feed::-webkit-scrollbar { display: none; }
/* свайп вправо — назад в сетку (решение оператора 2026-09-17): вертикаль занята листанием выдачи, поэтому
   «свернуть ролик» живёт на горизонтали. `touch-action: pan-y` выше отдаёт браузеру только вертикаль —
   горизонталь ведёт скрипт ленты; переход включается лишь на отпускании, чтобы кадры шли за пальцем */
.feed.swipe-back { transition: transform .18s ease-out, opacity .18s ease-out, border-radius .18s ease-out; }

/* ── Ролик уезжает карточкой, сетка встаёт под ним ─────────────────────────────────────────────────────
   Механика с показанного оператором экрана Instagram (2026-09-17): полноэкранный ролик — карточка поверх
   сетки, уходит вправо со скруглёнными углами, а под ней уже видна выдача. Сетка живёт на другой странице,
   поэтому сшивает их переход между документами (`@view-transition`, Chrome 126+ / Safari 18.2+): лента
   отдаёт снимок карточки, новая страница доигрывает — карточка вправо, сетка из-под неё.
   Мы просим ровно один такой переход, остальные гасит скрипт в `_shell.html`, чтобы витрина не «поплыла»
   вся. Браузер без переходов и `prefers-reduced-motion` работают по-старому: лента уезжает сама. */
/* ── Цена картинки на телефоне (замеры 2026-09-17, оператор: «постоянно какие-то лаги») ─────────────
   Размытие (`backdrop-filter`) — самый дорогой эффект на телефоне, а мы насчитали 101 штуку на одной
   сетке (ярлык возраста на каждой карточке) и по пять на каждом слайде. Держим его там, где он правда
   работает: у слайда, который на экране. Во время тяги гасим совсем — иначе каждый кадр пересчитывает
   подложку под уезжающей лентой. Ярлыки на карточках и так лежат на тёмной плашке .55–.72 — без
   размытия они читаются так же. */
@media (max-width: 900px) {
  .age, .m-cover .ig { backdrop-filter: none; -webkit-backdrop-filter: none; }
  .slide:not(.live) .glass, .slide:not(.live) .save-btn, .slide:not(.live) .slide-age, .slide:not(.live) .play,
  .feed.dragging .glass, .feed.dragging .save-btn, .feed.dragging .slide-age, .feed.dragging .play {
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  .feed.dragging { will-change: transform; }
  /* карточки вне экрана не раскладываются и не рисуются: сетка под слоем ленты перестаёт стоить денег
     на каждом кадре, а снимок для перехода — на каждом открытии */
  .card { content-visibility: auto; contain-intrinsic-size: auto 420px; }
}

/* ── Лента слоем поверх сетки (оператор 2026-09-17: «склей в один лист») ────────────────────────────
   Тап по обложке кладёт ленту слоем на ту же страницу, поэтому под уезжающей обложкой видна сама
   сетка, а не пустая тёмная страница ленты. Фона у слоя НЕТ намеренно: он есть у самой ленты, и
   когда она уезжает вбок, из-под неё показывается выдача. Панель вкладок (z 12) остаётся сверху —
   она общая у обоих видов. */
/* z 14 — выше шапки страницы (13): она `sticky` и, стоя наверху сетки, перехватывала тап по стрелке
   «назад» в слое, хотя и не была видна (поймал обход кликами 2026-09-17). Панель вкладок (12) остаётся
   ниже слоя, но слой до неё и не достаёт — она работает, как на странице ленты. */
.feed-layer { position: fixed; left: 0; right: 0; top: 0; z-index: 14;
  bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
/* Страница ленты держится ровно так же, как слой: прибита к экрану, а не посчитана в `dvh`. На айфоне
   полоса браузера то съедает высоту, то отдаёт, и посчитанная лента не доставала до панели — снизу
   оставалась тёмная полоса, которая не уходила при листании (оператор 2026-09-17). Заодно два вида
   ленты держатся одной механикой. */
@media (max-width: 900px) {
  .feed-page .feed { position: fixed; left: 0; right: 0; top: 0; height: auto;
    bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
}
.feed-layer .feed { height: 100%; }
.feed-ph { position: absolute; inset: 0; background: var(--color-void); }   /* обложка, пока едет разметка */
.feed-ph img { width: 100%; height: 100%; object-fit: cover; opacity: .5; }
.feed-layer.closing .feed, .feed-layer.closing .feed-ph { transition: transform .22s ease-out; transform: translateX(100%); }
/* Замок прокрутки под слоем снят намеренно (2026-09-17): когда страница перестаёт прокручиваться,
   Safari на айфоне разворачивает свою нижнюю полосу, и в момент открытия всё «выезжало снизу».
   Сетке под слоем замок и не нужен: слой ловит касания сам, а у ленты `overscroll-behavior: contain`,
   так что прокрутка в страницу не протекает. */

/* морф «клетка ⇄ экран» внутри страницы: своё имя снимка, чтобы настраивать отдельно от шва между
   страницами; мягкая кривая и чуть длиннее браузерных 250 мс — оператор просил плавности */
::view-transition-group(feedcell) { animation-duration: .34s; animation-timing-function: cubic-bezier(.32, .72, 0, 1); }
::view-transition-old(feedcell), ::view-transition-new(feedcell) { animation-duration: .34s; }

@view-transition { navigation: auto; }
html[data-vt="back"]::view-transition-old(root) { animation: none; opacity: 0; }
html[data-vt="back"]::view-transition-new(root) { animation: grid-under .3s cubic-bezier(.32, .72, 0, 1) both; }
html[data-vt="back"]::view-transition-old(feedcard) { animation: card-away .3s cubic-bezier(.32, .72, 0, 1) both; }
html[data-vt="back"]::view-transition-group(feedcard) { z-index: 2; }
@keyframes grid-under { from { transform: scale(.96); opacity: .7; } to { transform: none; opacity: 1; } }
@keyframes card-away { to { transform: translateX(100%); } }
.slide { position: relative; height: 100%; scroll-snap-align: start; scroll-snap-stop: always; overflow: hidden; background: var(--color-obsidian); }
.slide-media { position: absolute; inset: 0; }
.slide-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.slide-grad { position: absolute; left: 0; right: 0; bottom: 0; height: 55%; pointer-events: none;
  background: linear-gradient(to top, rgba(8, 9, 10, .94), rgba(8, 9, 10, 0)); }
/* Дверь в Instagram: кружок с ▶ и без подписи (оператор 2026-09-17 — «просто оставь кнопку без
   слова Instagram»; до того пробовали подпись под кружком — легла на вшитые титры — и пилюлю с
   именем места). Куда ведёт, знает `aria-label`; для глаза — ролик открывается там, где он живёт */
.play { position: absolute; left: 50%; top: 44%; transform: translate(-50%, -50%);
  width: 64px; height: 64px; border: 0; z-index: 2;
  border-radius: var(--radius-pill); background: rgba(8, 9, 10, .55); backdrop-filter: blur(6px); color: var(--color-paper);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.play svg { width: 28px; height: 28px; margin-left: 3px; flex: 0 0 auto; }
.play:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.glass { background: rgba(8, 9, 10, .55); border-radius: var(--radius-pill); color: var(--color-paper); backdrop-filter: blur(6px); }
.slide-back { position: absolute; top: max(12px, env(safe-area-inset-top, 0px)); left: 12px; z-index: 3; }
/* возраст ролика — тем же чипом, что в сетке (оператор 2026-09-17: «добавь дату, как и в сетке»);
   встал в правый угол, освободившийся от дублирующей стрелки «в Instagram» */
.slide-age { position: absolute; top: max(12px, env(safe-area-inset-top, 0px)); right: 12px; z-index: 3;
  background: rgba(8, 9, 10, .55); backdrop-filter: blur(6px); color: var(--color-mist);
  font: 400 11px/1 var(--font-num); padding: 7px 9px; border-radius: var(--radius-pill); }
.slide-age.fresh { color: var(--color-paper); }
.slide-ctx { position: absolute; top: max(24px, calc(env(safe-area-inset-top, 0px) + 12px)); left: 60px; right: 60px; margin: 0; z-index: 3;
  text-align: center; font-size: 13px; color: var(--color-mist); text-shadow: 0 1px 2px rgba(8, 9, 10, .6);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* столбик стёкол выше имени автора и кнопки по слою (z 5 против 3): у него открываются меню, а
   равный z-index отдавал их соседям, идущим ниже по разметке (оператор 2026-09-17). Перекрытия у
   самих стёкол с ними нет — столбик стоит справа, выше нижней кнопки */
.slide-col { position: absolute; right: 12px; bottom: 88px; z-index: 5; display: flex; flex-direction: column; gap: var(--spacing-8); align-items: center; }
.slide-col .save-btn { width: 44px; height: 44px; border: 0; background: rgba(8, 9, 10, .55); backdrop-filter: blur(6px); color: var(--color-paper); border-radius: var(--radius-pill); }
.slide-col .save-btn svg { width: 24px; height: 24px; }
.slide-col summary { list-style: none; }
.slide-col summary::-webkit-details-marker { display: none; }
.slide-col .drop-menu { right: 0; bottom: 52px; top: auto; }
.slide-info { position: absolute; left: 16px; right: 72px; bottom: 88px; z-index: 3; }
.who2 { display: flex; align-items: center; gap: 10px; }
.who2 .ava { width: 32px; height: 32px; border-radius: var(--radius-pill); object-fit: cover; flex: 0 0 auto;
  background: var(--color-graphite); color: var(--color-paper); font: 510 14px/32px var(--font-ui); text-align: center; }
.who2-col { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.who2-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.who2 .name { font-size: 15px; color: var(--color-paper); letter-spacing: -.011em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.who2 .sub { font-size: 13px; color: var(--color-mist); }
/* «подписаться» под автором — обведённая кнопка, как в Instagram и Edits (оператор 2026-09-17).
   Рамку пишем здесь же, а не отдельным правилом ниже: `.who2 .lnk` сбрасывал border/padding в ноль
   с тем же весом и стоял позже — первая попытка не доехала до экрана (оператор: «ничего не
   поменялось», замер 2026-09-17: border 0px none) */
.who2 .lnk { flex: 0 0 auto; padding: 3px var(--spacing-8); border: 1px solid var(--color-smoke);
  border-radius: var(--radius-btn); background: rgba(8, 9, 10, .35); cursor: pointer;
  font: 400 12px/1.4 var(--font-ui); color: var(--color-paper); }
.who2 .lnk:hover { border-color: var(--color-paper); }
.who2 form { display: contents; }
.tick { position: relative; height: 18px; font-size: 13px; line-height: 18px; color: var(--color-mist); overflow: hidden; cursor: default; }
.tick span { position: absolute; left: 0; top: 0; white-space: nowrap; opacity: 0; animation: tick 8s infinite; }
.tick span:nth-child(2) { animation-delay: 4s; }
/* В ЛЕНТЕ смена остаётся, но каждый слайд начинает её заново с множителя (оператор 2026-09-17:
   «пусть начинается с множителя, а дальше уже динамическая смена»). Механика: анимация висит не на
   строке, а на `.slide.live` — класс ставит наблюдатель на том слайде, который на экране, и само
   появление класса запускает анимацию с нуля. Перелистнул — снова множитель на четыре секунды. */
.slide-info .tick { cursor: pointer; }
.slide-info .tick span { animation: none; opacity: 0; }
.slide-info .tick span:first-child { opacity: 1; }
.slide.live .slide-info .tick span { animation: tick 8s infinite; }
.slide.live .slide-info .tick span:nth-child(2) { animation-delay: 4s; }
.tick b { color: var(--color-acid-lime); font-weight: 510; }
.tick .ico { display: flex; align-items: center; gap: 4px; }
.tick .ico .ic { width: 15px; height: 15px; margin-left: 8px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.tick .ico .ic:first-child { margin-left: 0; }
@keyframes tick { 0% { opacity: 0; transform: translateY(8px); } 6% { opacity: 1; transform: none; }
  44% { opacity: 1; transform: none; } 50% { opacity: 0; transform: translateY(-8px); } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .tick span, .slide.live .slide-info .tick span { animation: none; }
  .tick span:first-child { opacity: 1; }
  .tick.alt span:first-child { opacity: 0; }
  .tick.alt span:nth-child(2) { opacity: 1; }
}
.slide-cta { position: absolute; left: 16px; right: 16px; bottom: 16px; z-index: 3; }
.btn { height: 48px; width: 100%; border: 0; border-radius: var(--radius-btn); background: var(--color-paper); color: var(--color-void);
  font: 510 15px/1 var(--font-ui); letter-spacing: -.011em; display: flex; align-items: center; justify-content: center; gap: 8px; cursor: pointer; }
.btn > svg { width: 16px; height: 16px; flex: 0 0 auto; }   /* без размера значок растягивался во всю кнопку (снимок 2026-09-17) */
.btn .s { color: var(--color-ash); font-weight: 400; }
.btn:disabled { opacity: .5; cursor: default; }
.btn:focus-visible { outline: 2px solid var(--color-acid-lime); outline-offset: 2px; }
.slide-cap { margin: 6px 0 0; font-size: 12px; color: var(--color-mist); text-align: center; text-shadow: 0 1px 2px rgba(8, 9, 10, .6); }
.shot-go { display: none; }
/* у ленты .wrap без отступов (слайд во весь экран) — поля экрана возвращаем пустому состоянию */
.feed-page .empty { padding-left: var(--spacing-16); padding-right: var(--spacing-16); }
.empty-mascot { display: block; margin: 0 auto var(--spacing-8); }

/* Скелет загрузки (спека 2026-09-16 «Компоненты и токены»): обложки obsidian на месте сетки.
   Живёт на `.grid`, поэтому колонки берёт у сетки — две на телефоне, auto-fill на столе, и
   заглушка встаёт ровно там, где потом встанут карточки. Пульс — самый тихий признак жизни;
   `prefers-reduced-motion` его снимает, форма остаётся. */
.sk-card { background: var(--color-carbon); border-radius: var(--radius-card); overflow: hidden; }
.sk-shot { aspect-ratio: 9 / 16; background: var(--color-obsidian); }
.sk-line { height: 10px; margin: var(--spacing-12) var(--spacing-12) 0; border-radius: 5px; background: var(--color-obsidian); }
.sk-line.short { width: 55%; margin-bottom: var(--spacing-12); }
.sk-card { animation: sk-pulse 1.6s ease-in-out infinite; }
.sk-card:nth-child(even) { animation-delay: .2s; }
@keyframes sk-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) { .sk-card { animation: none; } }

/* Экран ошибки: форма пустого состояния, но вторая дверь — тихой строкой, не второй кнопкой
   (правило «одна кнопка», спека 2026-09-16 «Пустые состояния»). Интерактивный текст — mist. */
.err-state .quiet-go { color: var(--color-mist); font-size: 15px; margin-top: var(--spacing-8);
  min-height: 44px; display: inline-flex; align-items: center; }
.err-state .quiet-go:hover { color: var(--color-paper); }
@media (max-width: 900px) {
  /* накладка ростом ровно с обложку (`.shot` — aspect-ratio 9/16), не по всей карточке: @имя под ней остаётся
     дверью на страницу автора (спека 2026-09-16: «тап по карточке — в ленту, по имени автора — на страницу автора») */
  .shot-go { display: block; position: absolute; inset: 0 0 auto 0; aspect-ratio: 9 / 16; z-index: 3; }
  .card { position: relative; }
}
@media (min-width: 901px) {
  .feed { max-width: 430px; margin: var(--spacing-12) auto; height: calc(100vh - 24px); border-radius: var(--radius-card); }   /* на столе лента — колонка телефона по центру */
}

/* ── Один язык шторок на телефоне (решение оператора 2026-09-17) ───────────────────────────
   Было разноязычие: в шторку снизу превращались только сита и шестерёнка, а закладка, подписка,
   «···», меню аватара, сортировка и папка оставались настольными выпадашками 200–232px у кнопки —
   с мелкими строками под курсор. Теперь любое меню выбора на телефоне — шторка снизу: полная
   ширина, скруглённый верх, строки под палец, поля под home-бар. Исключение помечается классом
   `keep-drop` (слайд ленты: там «···» висит поверх видео, и шторка накрыла бы сам ролик). */
@media (max-width: 900px) {
  .drop:not(.keep-drop) .drop-menu {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 30;
    min-width: 0; width: auto; max-width: none; box-sizing: border-box;
    border-radius: var(--radius-card) var(--radius-card) 0 0;
    max-height: 70vh; overflow: auto;
    padding: var(--spacing-12) var(--spacing-12) calc(var(--spacing-12) + env(safe-area-inset-bottom, 0px));
    animation: sheet-in .18s ease both;
  }
  /* ручка сверху: знак, что шторку можно смахнуть вниз (жест — скрипт в _shell.html). Та же
     ручка, что у «Добавить контент», чтобы жест читался одинаково (оператор 2026-09-17) */
  .drop:not(.keep-drop) .drop-menu::before {
    content: ""; display: block; width: 36px; height: 4px; margin: 2px auto 10px;
    border-radius: var(--radius-pill); background: var(--color-smoke);
  }
  /* имя пульта в шапке шторки (на столе спрятано: там меню висит под своей кнопкой) */
  .drop:not(.keep-drop) .drop-menu > .drop-head {
    display: block; padding: 4px var(--spacing-12) var(--spacing-12);
    font: 400 13px/1.3 var(--font-ui); color: var(--color-ash);
    border-bottom: 1px solid var(--color-graphite); margin-bottom: var(--spacing-4);
  }
  /* строки — под касание, не под курсор: цель 44px и телефонный кегль 15px, не настольные 30px/13px.
     Касание есть касание, поэтому правило и для исключений (`keep-drop`) тоже */
  .drop .drop-menu button,
  .drop .drop-menu > a,
  .drop .drop-menu .drop-check {
    min-height: 44px; padding: 10px 12px; font-size: 15px; max-width: none;
  }
  /* исключение раскрывается вверх от своей кнопки (полоса выбора, композер чата, «+»): ему нужна
     только защита от выезда за край — ширины у них настольные (280–320px) */
  .drop.keep-drop .drop-menu { max-width: calc(100vw - var(--spacing-24)); }
  /* затемнение позади: шторка — слой поверх страницы, а не ярлычок у кнопки. Тап мимо её закрывает
     (общий pointerdown в _shell.html), поэтому фону свои обработчики не нужны */
  .drop:not(.keep-drop)[open]::before {
    content: ""; position: fixed; inset: 0; z-index: 29; background: rgba(8, 9, 10, .5);
  }
  @keyframes sheet-in { from { transform: translateY(16px); } }
  /* шапка автора на телефоне (канон Instagram): аватар крупнее, метрики делят ширину поровну */
  .a-head { padding-top: var(--spacing-16); }
  .a-head .a-ava { width: 84px; height: 84px; font-size: 32px; }
  /* три счётчика в один ряд: переносим подпись внутри столбца (`nowrap` у ряда + `min-width: 0`
     у столбцов), иначе третий столбец с длинной подписью уезжал на вторую строку целиком
     (снимок 2026-09-17). Числа не переносятся никогда — у них свой `white-space: nowrap` */
  .a-nums { gap: var(--spacing-16); flex-wrap: nowrap; }
  .a-nums li { flex: 0 1 auto; min-width: 0; }
  .a-nums span { font-size: 12px; }
  .a-actions { margin-top: var(--spacing-12); }

  /* Строка чата: имя с многоточием · дата · «···» — три места в одной строке. Было: точки лежат
     полупрозрачной нашлёпкой поверх правого края (настольный приём «видно при наведении»), а на
     телефоне наведения нет — они смешивались с датой и не читались (оператор 2026-09-17) */
  /* `.proj-chat-row`, а не только `.chats-page`: те же строки стоят в «Последних» на странице
     проекта, и язык у них один (оператор 2026-09-17) */
  .proj-chat-row { gap: var(--spacing-8); }
  .proj-chat-row .side-more { position: static; opacity: 1; margin: 0; flex: 0 0 auto; }
  .proj-chat-row .side-more .tool-btn { width: 44px; height: 44px; border-color: transparent; }
  .proj-chat-row:hover .side-chat-w { visibility: visible; }
  .proj-chat-row .proj-chat { flex: 1 1 auto; min-width: 0; }


  /* «···» на слайде ленты остаётся выпадашкой и без стекла (решение оператора 2026-09-17): точки
     поверх видео, тень вместо кружка — стекло делало из них третью «кнопку-стакан» в столбике */
  .slide-more > summary.ib { background: none; backdrop-filter: none; -webkit-backdrop-filter: none;
    filter: drop-shadow(0 1px 2px rgba(8, 9, 10, .8)); }
}
@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .drop:not(.keep-drop) .drop-menu { animation: none; }
}
