@import url("/tokens.css");

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--fg);
  line-height: 1.55;
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
  padding-bottom: 48px;
}

/* ── Шапка ───────────────────────────────── */

header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  /* Отступ сверху задаёт телеграм: под его кнопками рисовать нельзя,
     а высота у разных телефонов разная. Плюс запас, чтобы наверняка. */
  padding: calc(var(--inset-top, 8px) + 10px) var(--step-4) var(--step-2);
}

/* Марка и дата. Ничего интерактивного справа сверху — там кнопки телеграма. */
#brand {
  display: flex;
  align-items: baseline;
  gap: var(--step-2);
}

#mark {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--accent-ink);
}

#today { font-size: 11px; color: var(--fg-muted); letter-spacing: 0.02em; }

/* Кто зашёл. Нейтрально и по делу: тревожные заголовки на первом экране
   каждый день читаются как крик и перестают работать. */
#who {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-top: 2px;
  line-height: 1.2;
}

#nav {
  display: flex;
  align-items: center;
  gap: var(--step-2);
  margin-top: var(--step-3);
}

#titles { flex: 1; min-width: 0; }

/* Кнопки шапки компактные: на телефоне важнее место под контент */
.chip-btn {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  appearance: none;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--fg);
  border-radius: 50%;
  font: inherit;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}

.chip-btn:active { background: var(--bg); }
.chip-btn[hidden] { display: none; }

/* Подсказка свайпа: мягкий сгусток света у края, который тянется за пальцем.
   Не прямая полоса во всю высоту — та читалась как грубая линейка поперёк
   экрана. Здесь линза: толще в середине, к верху и низу растворяется. Форму
   даёт маска-эллипс, мягкость — размытие, концы скругляет радиус. */
#swipe-hint {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  height: 56vh;
  left: auto; right: auto;
  width: 4px;
  border-radius: 999px;
  filter: blur(3px);
  -webkit-mask-image: radial-gradient(ellipse 170% 50% at 50% 50%, #000 22%, transparent 100%);
  mask-image: radial-gradient(ellipse 170% 50% at 50% 50%, #000 22%, transparent 100%);
  opacity: 0;
  pointer-events: none;
  z-index: 30;
  transition: opacity .12s ease-out;
}

/* Фирменный приём с сайта: тонкая золотая линия под шапкой */
header::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--accent);
}

#title { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
#subtitle { font-size: 12px; color: var(--fg-muted); }
#subtitle:empty { display: none; }

/* Ник площадки со значком: понятно и где мы, и чей это аккаунт. */
#subtitle.with-mark { display: flex; align-items: center; gap: 5px; }
#subtitle.with-mark .pmark { width: 13px; height: 13px; flex: 0 0 auto; }

main { padding: var(--step-1) var(--step-4) 0; }

/* ── Корень: контуры ─────────────────────── */

.contour {
  display: block;
  width: 100%;
  text-align: left;
  appearance: none;
  font: inherit;
  cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent-contour, var(--brand-gold));
  border-radius: var(--radius);
  padding: var(--step-4);
  margin-top: var(--step-3);
  color: var(--fg);
}

.contour:first-child { --accent-contour: var(--fg); }

.contour-name {
  display: block;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.contour-sub { display: block; font-size: 13px; color: var(--fg-muted); margin-top: 1px; }
.contour-empty { display: block; font-size: 13px; color: var(--fg-muted); margin-top: var(--step-3); }

.note {
  color: var(--fg-muted);
  font-size: 13px;
  margin: var(--step-5) 0 var(--step-4);
}

/* ── Контур: список разделов ─────────────── */

.group {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
  margin: var(--step-5) 0 var(--step-2);
}

.rows {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.row {
  display: flex;
  align-items: center;
  gap: var(--step-3);
  width: 100%;
  appearance: none;
  border: 0;
  border-top: 1px solid var(--line);
  background: none;
  font: inherit;
  color: var(--fg);
  text-align: left;
  padding: var(--step-3) var(--step-4);
  cursor: pointer;
}

.row:first-child { border-top: 0; }
.row[disabled] { color: var(--fg-muted); cursor: default; }
.row-title { flex: 1; }
.row-status { font-size: 12px; color: var(--fg-muted); }
.row-go { color: var(--accent-ink); font-size: 18px; line-height: 1; }

.state {
  color: var(--fg-muted);
  padding: 40px 0;
  text-align: center;
}

/* ── Документ (портрет) ──────────────────── */

.doc h1 { font-size: 21px; font-weight: 700; letter-spacing: -0.02em; margin: 22px 0 var(--step-2); }
.doc h2 { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; margin: 26px 0 var(--step-2); }
.doc h3 { font-size: 15px; font-weight: 700; margin: 20px 0 6px; }
.doc h1:first-child { margin-top: var(--step-3); }

/* Тонкая золотая насечка у заголовков разделов */
.doc h2::before {
  content: "";
  display: block;
  width: 28px;
  height: 2px;
  background: var(--accent);
  margin-bottom: var(--step-2);
}

.doc p { margin: 10px 0; }
.doc ul, .doc ol { margin: 10px 0 10px 20px; }
.doc li { margin: 5px 0; }
.doc hr { border: 0; border-top: 1px solid var(--line); margin: var(--step-5) 0; }
.doc strong { font-weight: 700; }
.doc em { color: var(--fg-muted); font-style: normal; }

.doc code {
  font-family: var(--font-mono);
  font-size: 12.5px;
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 1px 5px;
  border-radius: var(--radius-sm);
}

.doc blockquote {
  border-left: 2px solid var(--accent);
  padding: 2px 0 2px var(--step-3);
  margin: var(--step-3) 0;
  color: var(--fg-muted);
}

.table-wrap { overflow-x: auto; margin: 14px 0; -webkit-overflow-scrolling: touch; }

table { border-collapse: collapse; width: 100%; font-size: 14px; }

th, td {
  text-align: left;
  padding: var(--step-2) 10px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

th {
  font-weight: 600;
  color: var(--fg-muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom-color: var(--accent);
}

/* ── Смыслы ──────────────────────────────── */

.summary { display: flex; gap: var(--step-2); margin: 14px 0 var(--step-3); }

.stat {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--step-3);
}

.stat b {
  display: block;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.stat span { color: var(--fg-muted); font-size: 12px; }
.stat.warn b { color: var(--signal-fg); }

.filters {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 10px;
  margin-bottom: var(--step-1);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.filters::-webkit-scrollbar { display: none; }

.chip {
  flex: 0 0 auto;
  appearance: none;
  border: 1px solid var(--line);
  font: inherit;
  font-size: 13px;
  background: var(--surface);
  color: var(--fg);
  padding: 7px var(--step-3);
  border-radius: var(--radius-pill);
  cursor: pointer;
  white-space: nowrap;
}

/* Золотая плашка с тёмным текстом — единственный контрастный способ её применить */
.chip.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}

.chip.warn.is-active {
  background: var(--signal-fg);
  border-color: var(--signal-fg);
  color: var(--brand-white);
}

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 10px;
}

.card-head { display: flex; gap: 9px; align-items: baseline; }

.code {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  background: var(--bg);
  border: 1px solid var(--accent);
  color: var(--accent-ink);
  padding: 2px 7px;
  border-radius: var(--radius-sm);
}

.card-title { font-weight: 600; letter-spacing: -0.01em; }

.card-gap {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--signal-fg);
  white-space: nowrap;
}

.fields { margin-top: 10px; display: none; }
.card.is-open .fields { display: block; }

.field { padding: 7px 0; border-top: 1px solid var(--line); font-size: 14px; }

.field-label {
  color: var(--fg-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.field-value { margin-top: 1px; }
.field.gap .field-value { color: var(--signal-fg); }
.field em { font-style: normal; }

.toggle-hint { color: var(--fg-muted); font-size: 12px; margin-top: var(--step-2); }

details {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--step-3) 14px;
  margin: 10px 0;
}

details summary { font-weight: 600; cursor: pointer; }
details[open] summary { margin-bottom: var(--step-2); }
details table { font-size: 13px; }
details ol { margin-left: 18px; }
details li { margin: 6px 0; }

.updated { color: var(--fg-muted); font-size: 12px; margin: 18px 0 var(--step-1); text-align: center; }

/* ── Корневые карточки: цифра контура ────── */

.contour-figure {
  display: block;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-top: var(--step-3);
}

.contour-figure.up { color: var(--up); }
.contour-figure.down { color: var(--down); }
.contour-note { display: block; font-size: 12px; color: var(--fg-muted); }

/* ── Экран канала ────────────────────────── */

.block {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--step-4);
  margin-top: var(--step-3);
}

.block h3 {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
  margin-bottom: var(--step-2);
}

.block h3 .muted { text-transform: none; letter-spacing: 0; font-weight: 400; }
.muted { color: var(--fg-muted); font-size: 13px; }

/* ── Карточка метрики ─────────────────────
   Анатомия одна на все аналитические экраны: строка «подпись — изменение»,
   крупная цифра, кривая, полоса фактов. Каждая горизонталь занимает ширину
   целиком. До этого карточка была левой колонкой из подписи и числа, а правая
   половина оставалась пустой — на телефоне это половина экрана воздуха. */

.mhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--step-3);
  margin-bottom: var(--step-2);
}

.mhead h3 { margin-bottom: 0; }

/* Изменение — плашка, а не просто цветной текст. Цветной текст в углу
   карточки читался как обрывок подписи; плашка держит правый угол и сама
   говорит, что это отдельная величина. */
.pill {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  color: var(--fg-muted);
  background: color-mix(in srgb, var(--fg-muted) 12%, transparent);
}

.pill.up   { color: var(--up);   background: color-mix(in srgb, var(--up) 13%, transparent); }
.pill.down { color: var(--down); background: color-mix(in srgb, var(--down) 13%, transparent); }
.pill.sm { font-size: 11px; padding: 2px 7px; }

.mvalue { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.mvalue b {
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.mvalue .unit { font-size: 14px; font-weight: 500; color: var(--fg-muted); }

/* Полоса фактов. Равные доли и разделители — так три коротких числа
   расходятся по всей ширине карточки вместо кучки у левого края. */
.facts {
  display: flex;
  margin-top: var(--step-3);
  padding-top: var(--step-3);
  border-top: 1px solid var(--line);
}

.fact { flex: 1; min-width: 0; padding-left: var(--step-3); border-left: 1px solid var(--line); }
.fact:first-child { padding-left: 0; border-left: 0; }

.fact b {
  display: block;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.fact b.up { color: var(--up); }
.fact b.down { color: var(--down); }
.fact span { display: block; margin-top: 1px; font-size: 11px; color: var(--fg-muted); line-height: 1.25; }

/* ── Две метрики в одной карточке ─────────
   Сторис и рилсы поодиночке — короткое число и полкарточки воздуха.
   Рядом они занимают ширину и читаются как сравнение форматов. */
.duo { display: flex; }

.duo-item {
  flex: 1;
  min-width: 0;
  padding-left: var(--step-4);
  border-left: 1px solid var(--line);
}

.duo-item:first-child { padding-left: 0; border-left: 0; padding-right: var(--step-4); }

.duo-head { display: flex; align-items: center; justify-content: space-between; gap: var(--step-2); }
.duo-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
}

.duo-value {
  display: block;
  margin-top: 6px;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}

.duo-unit { display: block; margin-top: 3px; font-size: 12px; color: var(--fg-muted); line-height: 1.3; }
.duo-note { display: block; margin-top: 5px; font-size: 11px; color: var(--fg-muted); opacity: 0.85; }

/* Календарь публикаций: клетка на день, закрашена значит пост был */
.calendar {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 5px;
}

.cell {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  border-radius: 5px;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--fg-muted);
}

.cell.on {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}

/* Клетка дня, про который мы ничего не знаем: сбор тогда ещё не шёл.
   Отличается от пропуска намеренно — пропуск это факт о Никите, а это факт
   о нас. Пунктир вместо сплошной рамки, цифра приглушена. */
.cell.is-blind {
  background: none;
  border-style: dashed;
  color: color-mix(in srgb, var(--fg-muted) 55%, transparent);
}

.cal-since { opacity: 0.75; }

/* Клетка-кнопка: ведёт к посту этого дня в списке ниже. Кнопка тащит за собой
   свой шрифт и обводку фокуса — гасим, чтобы от соседних клеток не отличалась. */
.cell.tap {
  font-family: inherit;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  transition: transform .12s ease-out;
}
.cell.tap:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.cell.tap:active { transform: scale(0.88); }

.calendar-foot { font-size: 13px; color: var(--fg-muted); margin-top: var(--step-3); }
.calendar-foot .ok { color: var(--up); }
.calendar-foot .miss { color: var(--down); font-weight: 600; }

.post { padding: var(--step-3) 0; border-top: 1px solid var(--line); }
.post:first-of-type { border-top: 0; }

.post-head { display: flex; gap: var(--step-3); align-items: baseline; }
.post-date { flex: 0 0 auto; font-family: var(--font-mono); font-size: 11px; color: var(--fg-muted); }

.post-text {
  flex: 1;
  font-size: 14px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.post-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: var(--step-3);
  margin-top: 5px;
  padding-left: 34px;
  font-size: 12px;
  color: var(--fg-muted);
}

.post-metrics .vs.up { color: var(--up); }
.post-metrics .vs.down { color: var(--down); }
.post-metrics i { font-style: normal; opacity: 0.7; }

/* ── Блоки метрик ────────────────────────── */

.note-inline { font-size: 12px; color: var(--fg-muted); margin-top: var(--step-3); line-height: 1.45; }

/* Кривая под цифрой. Цвет задаётся через color, потому что заливка — градиент
   на currentColor: одна и та же функция рисует и акцентом контура, и цветом
   роста, не заводя второго варианта разметки. */
.spark {
  display: block;
  width: 100%;
  height: 52px;
  margin-top: var(--step-3);
  color: var(--accent-ink);
  overflow: visible;
}

.spark-line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.spark-fill { stroke: none; }

/* ── Вкладки: сегмент-контрол ──────────────
   Капсула с бегунком: подложка едет от старого раздела к новому, а не
   перекрашивается на месте — движение само показывает, откуда и куда.
   Переключение только тапом: горизонтальный свайп занят навигацией. */
.tabs {
  position: relative;
  display: flex;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px;
  margin-top: var(--step-3);
  isolation: isolate;
}

/* Бегунок — отдельный слой под текстом. Двигается трансформацией, а не
   сменой left: так браузер анимирует его на видеокарте и не пересчитывает
   раскладку на каждом кадре. */
.tabs-thumb {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 3px;
  border-radius: 999px;
  background: var(--surface);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: transform .26s cubic-bezier(.32, .72, 0, 1), width .26s cubic-bezier(.32, .72, 0, 1);
  z-index: -1;
}

/* Пока ширины не измерены, бегунок не показываем — иначе на первом кадре
   он прыгает из левого угла на своё место. */
.tabs-thumb:not(.ready) { opacity: 0; }

.tab {
  flex: 1;
  appearance: none;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--fg-muted);
  background: none;
  border: 0;
  border-radius: 999px;
  padding: 8px 6px;
  cursor: pointer;
  transition: color .2s;
  -webkit-tap-highlight-color: transparent;
}

.tab.is-active { color: var(--fg); }

@media (prefers-reduced-motion: reduce) {
  .tabs-thumb { transition: none; }
}

/* ── Сторис: строка дня ───────────────────
   Единица — день, а не отдельная сторис: они выходят пачками по 5–15 штук,
   и двести карточек подряд не читаются. */
.sday { padding: var(--step-3) 0; border-top: 1px solid var(--line); }
.sday:first-of-type { border-top: 0; }

.sday-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--step-3); }
.sday-date { font-family: var(--font-mono); font-size: 11px; color: var(--fg-muted); }
.sday-reach { font-size: 17px; font-weight: 700; }

.sday-bar {
  height: 6px;
  margin-top: 7px;
  border-radius: 999px;
  background: var(--bg);
  overflow: hidden;
}

.sday-bar i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

.sday-facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--step-3);
  margin-top: 7px;
  font-size: 12px;
  color: var(--fg-muted);
}

/* ── Лента сторис одного дня ──────────────
   Средняя цифра за день не говорит, какая из пятнадцати сторис удержала
   людей, а какая их растеряла, — а именно это решает, что снимать завтра.
   Листается вбок; общий свайп «назад/вперёд» уступает ей, пока лента может
   проехать в ту же сторону (`scrollerAt` в app.js).

   Отрицательные поля с обратным padding — чтобы лента доезжала до самого
   края карточки и было видно, что она продолжается. Обрубленная по отступу,
   она читается как аккуратный ряд, который весь на виду. */
.strip {
  display: flex;
  gap: var(--step-2);
  margin: var(--step-3) calc(-1 * var(--step-4)) 0;
  padding: 0 var(--step-4);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.strip::-webkit-scrollbar { display: none; }

.scard { flex: 0 0 auto; width: 72px; scroll-snap-align: start; }

/* Кадр 9:16 — форма самой сторис. Квадратом обрезать нельзя: у сторис вся
   композиция вертикальная, и квадрат срезал бы ровно то, ради чего снимали. */
.scard-shot {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
}

.scard-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Превью не скачалось или уже вычищено по возрасту. Заглушка сдержанная:
   цифры на карточке всё равно есть, и обрушивать на них внимание нечем. */
.scard-shot.is-empty::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(-45deg,
    transparent 0 6px, color-mix(in srgb, var(--fg-muted) 12%, transparent) 6px 12px);
}

/* Номер по порядку. Процент досматриваемости стоял здесь и был непонятен:
   число на кадре читается как «показатель этого кадра», а досматриваемость
   бывает только у пачки целиком — она переехала в шапку блока. Номер же
   отвечает ровно на тот вопрос, который возникает при взгляде на ленту:
   какая это по счёту и на какой охват начал падать. */
.scard-no {
  position: absolute;
  left: 3px;
  bottom: 3px;
  min-width: 16px;
  text-align: center;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  padding: 3px 4px;
  border-radius: var(--radius-pill);
  color: #fff;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(4px);
}

.scard-reach {
  display: block;
  margin-top: 5px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.scard-time { display: block; font-size: 10px; color: var(--fg-muted); font-family: var(--font-mono); }

/* Значок + число. Слова на четырёх цифрах подряд превращали строку в кашу. */
.mchip { display: inline-flex; align-items: center; gap: 4px; }

.mchip svg {
  width: 13px; height: 13px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linejoin: round;
  opacity: 0.65;
}

.mchip svg path[d^="M4 2.2"], .mchip svg path[d^="M2 13.4"],
.mchip svg path[d^="M8 13.6"] { fill: currentColor; stroke: none; }

.mchip.good, .mchip.bad { font-weight: 600; }
.mchip.good { color: var(--up); }
.mchip.bad { color: var(--down); }
.mchip.good svg, .mchip.bad svg { opacity: 1; }

/* ── Реакции самими реакциями ─────────────
   Эмодзи и число рядом, группой. Эмодзи чуть крупнее цифры: символ мельче
   12 пикселей превращается в разноцветное пятно, по которому не понять,
   сердце это или огонь. */
.rx { display: inline-flex; align-items: center; gap: var(--step-2); }
.rx-one { display: inline-flex; align-items: center; gap: 3px; font-variant-numeric: tabular-nums; }
.rx-one i { font-style: normal; font-size: 14px; line-height: 1; }
.rx-more { opacity: 0.7; }

.kv .rx { justify-content: flex-end; flex-wrap: wrap; }

.post.is-link { cursor: pointer; }
.post.is-link:active { opacity: 0.55; }

/* ── График прихода и ухода ───────────────
   Две линии на общей шкале: приход зелёной, уход красной. Столбики вверх-вниз
   от нулевой оси здесь были раньше и читались хуже — глаз сравнивал длины в
   разные стороны, а вопрос всегда один: чего было больше и когда.

   Кривые сглажены монотонной кубической интерполяцией: она проходит через все
   точки и между ними не выходит за их пределы, в отличие от обычного сплайна,
   который на всплеске уводил бы линию ниже нуля. */
.chart { margin-top: var(--step-2); }

/* Поле и колонка подписей — рядом, а не друг на друге. Раньше подписи
   стояли поверх графика с подложкой цвета карточки и разрезали кривую в тех
   местах, где она проходила у правого края. Своя колонка стоит 44 пикселя
   ширины и снимает вопрос совсем. */
.chart-body {
  display: flex;
  align-items: stretch;
  height: 148px;
  margin-top: var(--step-2);
}

.chart-plot {
  position: relative;
  flex: 1;
  min-width: 0;
  color: var(--accent-ink);
  touch-action: pan-y;
}

.chart-axis { position: relative; flex: 0 0 44px; }

/* Приход и уход — единственный график с двумя рядами, и заливка под ним
   принадлежит приходу. Остальные графики красятся акцентом контура: они не
   про «хорошо или плохо», а про «сколько». */
.chart.lchart .chart-plot { color: var(--up); }
.chart.achart .chart-line { stroke: var(--accent-ink); }
.chart.achart .chart-dot { background: var(--accent-ink); }

.chart-plot svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* Сетка нарочно бледная: она разметка, а не содержимое. */
.chart-grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 2 5; opacity: 0.7; }
.chart-area { stroke: none; }

.chart-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
/* Подпись величины на месте легенды: без неё поле с делениями отвечает
   «сколько», но не отвечает «чего». */
.chart-legend { color: var(--fg-muted); font-size: 11px; }
.chart-line.up { stroke: var(--up); }
/* Уход тоньше и мягче: он почти всегда меньше прихода и на общей шкале идёт
   у самого низа. Одинаковая толщина превращала бы его в подчёркивание оси. */
.chart-line.down { stroke: var(--down); stroke-width: 1.6; opacity: 0.85; }

/* Подписи сетки — обычные блоки поверх графика, а не текст внутри svg:
   svg растянут по ширине через preserveAspectRatio="none", и текст в нём
   растянулся бы вместе с картинкой. */
/* Подпись стоит вровень со своей линией: она про неё и есть. */
.chart-tick {
  position: absolute;
  right: 0;
  transform: translateY(-50%);
  padding-left: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1;
  white-space: nowrap;
  color: var(--fg-muted);
  opacity: 0.8;
}

/* Вертикаль и точки под пальцем. Тоже блоки, и по той же причине: круг внутри
   растянутого svg стал бы овалом. */
.chart-guide, .chart-dot { position: absolute; opacity: 0; pointer-events: none; }

.chart-guide {
  top: -4px; bottom: -4px;
  width: 1px;
  margin-left: -0.5px;
  background: var(--fg-muted);
  opacity: 0;
}

.chart-dot {
  width: 9px; height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  border: 2px solid var(--surface);
}

.chart-dot.up { background: var(--up); }
.chart-dot.down { background: var(--down); }
.chart-vals b { color: var(--fg); }

.chart.is-reading .chart-guide { opacity: 0.35; }
.chart.is-reading .chart-dot { opacity: 1; }

/* Строка над графиком работает на два состояния: пока палец не касается —
   период и легенда, под пальцем — день и его числа. Одна строка вместо двух,
   и высота карточки не прыгает. Подсказки «проведи пальцем» нет намеренно:
   на графике в половину карточки жест находится сам, а легенда нужна затем,
   что подписанных цифр под графиком больше не стоит. */
.chart-read {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--step-3);
  min-height: 18px;
  font-size: 12px;
  color: var(--fg-muted);
}

.chart-range, .chart-date { font-family: var(--font-mono); letter-spacing: -0.01em; }
.chart-date, .chart-vals { display: none; }
.chart.is-reading .chart-range, .chart.is-reading .chart-legend { display: none; }
.chart.is-reading .chart-date { display: block; }
.chart.is-reading .chart-vals { display: flex; }

.chart-vals { gap: var(--step-3); }
.chart-vals b { font-size: 13px; font-variant-numeric: tabular-nums; }
.chart-vals .up { color: var(--up); }
.chart-vals .down { color: var(--down); }

.chart-legend { display: flex; align-items: center; gap: 5px; font-size: 11px; }
.chart-legend i { width: 12px; height: 2px; border-radius: 2px; display: inline-block; }
.chart-legend i.up { background: var(--up); }
.chart-legend i.down { background: var(--down); margin-left: var(--step-2); }


/* ── Рилс: строка с превью ────────────────
   Обложка нужна затем, что по цифрам не вспомнить, какой это ролик,
   а подпись обрезана и часто состоит из одних эмодзи. */
.reel {
  display: flex;
  gap: var(--step-3);
  padding: var(--step-3) 0;
  border-top: 1px solid var(--line);
}

.reel:first-of-type { border-top: 0; }
.reel.is-link { cursor: pointer; }
.reel.is-link:active { opacity: 0.55; }

/* ── Залетело за неделю ───────────────────
   Строка новости, а не строка списка: обложка, число крупно, подпись мелко.
   В отличие от ленты рилсов здесь нет ни полосы, ни значков — сравнивать
   не с чем и незачем, эти три ролика уже отобраны. */
.hits { margin-top: var(--step-2); }

.hit {
  display: flex;
  align-items: center;
  gap: var(--step-3);
  padding: var(--step-2) 0;
  border-top: 1px solid var(--line);
}

.hit:first-child { border-top: 0; padding-top: 0; }
.hit.is-link { cursor: pointer; }
.hit.is-link:active { opacity: 0.55; }

.hit-body { flex: 1; min-width: 0; }
.hit-views { display: block; font-size: 18px; font-weight: 700; letter-spacing: -0.02em; }

.hit-text {
  display: block;
  font-size: 12px;
  color: var(--fg-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hit-text i { font-style: normal; opacity: 0.7; }
.hit .reel-thumb { width: 44px; height: 44px; }
.hit .reel-x { font-size: 10px; padding: 2px 5px; }

/* Плашка-подпись у заголовка. Не цифра и не изменение, поэтому нейтральная
   по цвету: акцентом здесь уже отмечены сами ролики. */
.pill.accent { color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 14%, transparent); }

/* ── Залетевший ролик ─────────────────────
   В списке из сорока строк с одинаковыми цифрами глазом не видно, какой из
   них выстрелил, — а это первое, что хочется знать. Подсветка сделана слоем
   под строкой, а не фоном самой строки: у строки нет боковых отступов, и фон
   обрубался бы ровно по буквам. Тот же приём, что у вспышки перехода к посту. */
.reel.is-top { position: relative; }

.reel.is-top::before {
  content: "";
  position: absolute;
  inset: 2px -10px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  pointer-events: none;
}

.reel.is-top > * { position: relative; }

/* Кольцо у обложки: при быстрой прокрутке взгляд идёт по левому краю списка,
   и там подсветка строки почти не читается. */
.reel.is-top .reel-thumb {
  border-color: transparent;
  box-shadow: 0 0 0 2px var(--accent);
}

/* Кратность — плашкой на обложке, а не в строке метрик. В строке она
   добавляла шестую цифру, и у роликов с шестизначными просмотрами метрики
   переносились на вторую строку. На обложке она к тому же попадает ровно
   туда, куда идёт взгляд при прокрутке, — в левый край списка. */
.reel-media { position: relative; flex: 0 0 auto; }

.reel-x {
  position: absolute;
  right: -3px;
  bottom: -2px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
  padding: 3px 6px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  border: 2px solid var(--surface);
}

.mchip.is-top { color: var(--fg); font-weight: 600; }
.mchip.is-top svg { opacity: 0.9; }

/* Круглая обложка. Вертикальный кадр обрезается по центру — для рилса это
   почти всегда лицо или крупный объект, и круг его не портит. */
.reel-thumb {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--line);
}

/* Ссылка Меты подписанная и может протухнуть между прогонами. Тогда вместо
   битой картинки — ровный кружок-заглушка. */
.reel-thumb.is-empty { display: block; }

.reel-body { flex: 1; min-width: 0; }
.reel-head { display: flex; gap: var(--step-2); align-items: baseline; }

/* Подпись рилса — ровно одна строка, в отличие от поста в телеграме.
   Две строки тянули карточку вверх, а вторая строка почти всегда оказывалась
   хвостом эмодзи и хештегов: места отнимала, читать в ней нечего. */
.reel .post-text { -webkit-line-clamp: 1; }

/* Значки метрик начинаются там же, где полоса просмотров. Общий стиль
   .post-metrics отступает на 34 px — это ширина колонки с датой у постов
   телеграма. У рилса даты в колонке нет, и от этого отступа строка начиналась
   где-то от середины карточки, а последний значок не влезал. */
/* Пять значков подряд, и у залетевших роликов цифры пятизначные. Шрифт и
   зазор здесь чуть плотнее общих: иначе такая строка переносится, а перенос
   на строке метрик читается как второй ролик. */
.reel .post-metrics { padding-left: 0; gap: 6px; font-size: 11.5px; }

/* Полоса просмотров: длину видно раньше, чем прочитаешь число.
   Считается от девяностой процентили, а не от максимума — иначе один
   залетевший ролик сплющивает все остальные в невидимую нитку. */
.reel-bar {
  height: 4px;
  margin: 7px 0;
  border-radius: 999px;
  background: var(--bg);
  overflow: hidden;
}

.reel-bar i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

/* ── Три показателя качества ролика ───────
   Зацеп, досмотр и отклик. Равными долями с разделителями — тот же приём,
   что у полосы фактов в карточках метрик, и по той же причине: так три
   коротких числа расходятся по ширине вместо кучки у левого края.
   Главное же в равных долях то, что цифры выстраиваются в колонки: при
   прокрутке строка из трёх зелёных видна, не читая ни одной подписи.

   Цвет тут ярче, чем в строке метрик выше: там счётные величины, здесь —
   свойства самого ролика, и именно они объясняют разрыв в просмотрах. */
.qual { display: flex; margin-top: 7px; }

.qual-one {
  flex: 1;
  min-width: 0;
  padding-left: 8px;
  border-left: 1px solid var(--line);
}

.qual-one:first-child { padding-left: 0; border-left: 0; }

.qual-one b {
  display: block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.qual-one b.good { color: var(--up); }
.qual-one b.bad { color: var(--down); }

/* Замер не дошёл или длительность не прочиталась. Прочерк не должен весить
   столько же, сколько цифра: «нет данных» — не результат ролика. */
.qual-one b.none { color: var(--fg-muted); font-weight: 500; }

.qual-one > span {
  display: block;
  margin-top: 1px;
  font-size: 10px;
  line-height: 1.2;
  color: var(--fg-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Ролик выше потолка: полоса полная, и это отмечено штриховкой, чтобы
   не путать «очень много» с «ровно как у верхней десятки». */
.reel-bar.is-over i {
  background: repeating-linear-gradient(
    -45deg, var(--accent) 0 5px, color-mix(in srgb, var(--accent) 55%, transparent) 5px 10px);
}

.empty { font-size: 14px; color: var(--fg-muted); line-height: 1.5; }

/* ── Пост: карточка в списке ─────────────── */

.post {
  display: block;
  width: 100%;
  text-align: left;
  appearance: none;
  background: none;
  border: 0;
  border-top: 1px solid var(--line);
  font: inherit;
  color: var(--fg);
  padding: var(--step-3) 0;
  cursor: pointer;
}

.post:first-of-type { border-top: 0; }
.post .row-go { flex: 0 0 auto; }

/* Вспышка после перехода из календаря: в списке одинаковых строк иначе
   непонятно, на какую именно тебя привезли. Гаснет сама, следов не оставляет.
   Подсветка сделана отдельным слоем, а не фоном строки: у строки нет боковых
   отступов, и фон обрубался бы ровно по буквам. Слой вылезает за края. */
.post { position: relative; }

.post.flash::after {
  content: "";
  position: absolute;
  inset: 0 -10px;
  border-radius: 8px;
  background: var(--accent);
  pointer-events: none;
  opacity: 0;
  animation: post-flash 1.7s ease-out;
}

@keyframes post-flash {
  0%, 25% { opacity: 0.22; }
  100%    { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .post.flash::after { animation-duration: .01ms; }
}

/* ── Экран поста ─────────────────────────── */

.post-full { font-size: 15px; line-height: 1.5; }
.post-full i { color: var(--fg-muted); font-style: normal; }

.tg-link {
  display: inline-block;
  margin-top: var(--step-3);
  color: var(--accent-ink);
  font-weight: 600;
  text-decoration: none;
  font-size: 14px;
}

.kv {
  display: flex;
  justify-content: space-between;
  gap: var(--step-3);
  padding: 9px 0;
  border-top: 1px solid var(--line);
  font-size: 14px;
}

.kv:first-of-type { border-top: 0; }
.kv span { color: var(--fg-muted); }
.kv b { font-weight: 600; }

.snap-row {
  display: flex;
  justify-content: space-between;
  gap: var(--step-2);
  margin-top: var(--step-2);
  font-size: 11px;
  color: var(--fg-muted);
  text-align: center;
}

.snap-row b { display: block; color: var(--fg); font-size: 13px; }

/* Переключатель периода на экране канала */
.filters.period { margin: var(--step-3) 0 0; padding-bottom: 0; }
.filters.period .chip { font-size: 13px; }

/* Порядок в списке рилсов. Раньше кнопки уезжали вбок: перенос на две строки
   съедал высоту у самого списка, ради которого сюда зашли, а пяти кнопок и
   так почти хватало ширины.
   С досмотром и откликом их стало семь, и уезжающий ряд перестал работать:
   три последних порядка не видно вовсе, а прокручиваемый ряд без края
   выглядит законченным. Кнопка, о которой не знаешь, не существует —
   поэтому теперь переносятся. Тридцать лишних пикселей один раз дешевле
   спрятанной трети выбора. */
.filters.sorts {
  flex-wrap: wrap;
  row-gap: 6px;
  overflow-x: visible;
  margin: var(--step-2) calc(-1 * var(--step-4)) var(--step-3);
  padding: 0 var(--step-4) 2px;
}

/* Кнопки порядка плотнее общих: их семь, и от размера чипса напрямую
   зависит, во сколько рядов они лягут. При обычном размере получалось три
   ряда — столько кнопок на входе в список читаются как отдельный экран
   настроек, а не как переключатель. */
.filters.sorts .chip { font-size: 12px; padding: 5px 11px; }

/* На референсах рядов три: порядок, формат, период. Между собой они жмутся
   плотнее — иначе три ряда кнопок съедают пол-экрана до первой обложки,
   ради которой сюда и зашли. */
.filters.sorts + .filters.sorts { margin-top: calc(-1 * var(--step-2)); }

/* ── Аватарки и иконки площадок ──────────── */

.contour-head { display: flex; align-items: center; gap: var(--step-3); }

.ava {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg);
  border: 1px solid var(--line);
}

.row-ava {
  flex: 0 0 auto;
  width: 28px; height: 28px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg);
  border: 1px solid var(--line);
}

.row-icon {
  flex: 0 0 auto;
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--fg-muted);
}

.row[disabled] .row-icon { opacity: 0.55; }
.pico { width: 15px; height: 15px; display: block; }

/* Фирменные значки площадок */
.pmark { width: 26px; height: 26px; flex: 0 0 auto; display: block; border-radius: 8px; }
.prow.is-off .pmark { opacity: 0.5; }

/* ── Первый экран: контур + список площадок ── */

.num { font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }

/* Контур и его площадки — одна карточка: иначе непонятно, что строки внизу
   относятся к заголовку сверху. Разделяет их линия, а не пробел. */
.cblock {
  margin-top: var(--step-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

/* Заголовок контура — рубрика, а не кнопка. Кнопкой он был, пока существовал
   отдельный экран контура; экран убран, потому что не содержал ничего своего,
   и заголовок вместе с ним перестал куда-либо вести. Аватарка осталась: она
   единственное, что различает контуры с одного взгляда. */
.chead {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  padding: 10px var(--step-4);
}
.chead-ava { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
.chead-name {
  flex: 1; min-width: 0;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--fg-muted);
}

/* Рубрика внутри карточки: «Идеи», «Стратегия», «Бренд». Отделяет разделы без
   цифр от площадок сверху — иначе документ читается как ещё одна площадка,
   у которой почему-то не собралась статистика. */
.cgroup {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--fg-muted);
  opacity: 0.8;
  padding: var(--step-3) var(--step-4) 4px;
  border-top: 1px solid var(--line);
}

/* Строка раздела: только название и стрелка. Ниже площадки по весу
   намеренно — на первом экране главное цифры, а это дверь к тексту. */
.srow {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  appearance: none;
  font: inherit;
  font-size: 14px;
  text-align: left;
  color: var(--fg);
  background: none;
  border: 0;
  padding: 9px var(--step-4);
  cursor: pointer;
}

.srow:active { background: var(--bg); }
.srow-name { flex: 1; min-width: 0; }


.prow {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  appearance: none;
  font: inherit;
  text-align: left;
  color: var(--fg);
  background: none;
  border: 0;
  border-top: 1px solid var(--line);
  padding: 11px var(--step-4);
  cursor: pointer;
}

.prow:first-of-type { border-top: 0; }
.prow:active { background: var(--bg); }
.prow.is-off { cursor: default; color: var(--fg-muted); }
.prow.is-off .row-icon { opacity: 0.55; }

.prow-name { flex: 1; min-width: 0; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prow-status { font-size: 12px; color: var(--fg-muted); white-space: nowrap; }

/* Цифра и прирост столбиком у правого края. Раньше они стояли в строку, и
   колонка чисел ехала: у длинного названия число уползало вправо, у короткого
   влево, и сравнить площадки взглядом сверху вниз было нельзя. */
.prow-num {
  flex: 0 0 auto;
  min-width: 78px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.15;
}

.prow-value { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.prow-delta { font-size: 11px; font-weight: 600; color: var(--fg-muted); white-space: nowrap; }
.prow-delta.up { color: var(--up); }
.prow-delta.down { color: var(--down); }

.mini { width: 56px; height: 22px; flex: 0 0 auto; color: var(--fg-muted); }
.mini.up { color: var(--up); }
.mini.down { color: var(--down); }
.mini-line { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.mini-fill { stroke: none; }
.mini-empty { width: 56px; text-align: center; color: var(--fg-muted); flex: 0 0 auto; }

/* Появление экрана: одно короткое движение, не карусель эффектов */
body { opacity: 0; }
body.ready { opacity: 1; transition: opacity .18s ease; }

body.ready #who,
body.ready .cblock {
  animation: rise .32s cubic-bezier(.22,.7,.3,1) both;
}

body.ready .cblock:nth-of-type(2) { animation-delay: .05s; }

@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  body.ready #who,
  body.ready .cblock { animation: none; }
  body.ready { transition: none; }
}

/* Марка и вердикт живут только на главном экране */
body:not(.at-root) #brand,
body:not(.at-root) #who { display: none; }
body.at-root #nav { margin-top: var(--step-3); }
body.at-root #titles { display: none; }

body:not(.at-root) #nav { margin-top: 0; }

/* ── Референсы ────────────────────────────
   Разбор чужого аккаунта. Единственный экран, где данные не наши и не
   хранятся: каждый запрос идёт в Мету заново. */

.ref-search {
  display: flex;
  gap: var(--step-2);
  margin: var(--step-3) 0 var(--step-2);
}

.ref-search input {
  flex: 1;
  min-width: 0;
  appearance: none;
  font: inherit;
  font-size: 15px;
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 10px var(--step-4);
}

/* 16 px на айфоне — граница, ниже которой Safari сам зумит страницу при
   фокусе в поле. Наш шрифт 15, поэтому размер поднимаем только на время
   ввода: так и вёрстка не едет, и подпись остаётся в общем масштабе. */
.ref-search input:focus { font-size: 16px; outline: none; border-color: var(--accent); }
.ref-search input::placeholder { color: var(--fg-muted); }

.ref-search button {
  flex: 0 0 auto;
  appearance: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--on-accent);
  background: var(--accent);
  border: 0;
  border-radius: var(--radius-pill);
  padding: 10px var(--step-4);
  cursor: pointer;
}

.ref-search button:active { opacity: 0.7; }

/* Уже открытые аккаунты. Переносятся по строкам, а не уезжают вбок:
   прокручиваемый ряд быстрее на трёх аккаунтах и невыносим на двадцати —
   нужный приходится искать вслепую. */
.ref-saved {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: var(--step-3);
}

/* Чипс из двух кнопок: имя открывает, крестик убирает. Крестик сразу видно,
   а не по долгому нажатию — жест, о котором нигде не написано, не существует.
   Разделяет их линия, чтобы палец не промахивался «открыть» вместо «убрать». */
.ref-chip {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.ref-chip button {
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  color: var(--fg);
  cursor: pointer;
}

.ref-chip-go { font-size: 13px; padding: 6px 4px 6px var(--step-3); }

.ref-chip-x {
  font-size: 15px;
  line-height: 1;
  padding: 0 9px 2px;
  color: var(--fg-muted);
  border-left: 1px solid var(--line) !important;
}

.ref-chip button:active { background: var(--bg); }

.ref-chip.is-active {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.ref-chip.is-active .ref-chip-go { color: var(--accent-ink); font-weight: 600; }

.ref-head { display: flex; align-items: center; gap: var(--step-3); }

.ref-ava {
  flex: 0 0 auto;
  width: 48px; height: 48px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg);
  border: 1px solid var(--line);
}

.ref-ava.is-empty { display: block; }
.ref-who { min-width: 0; }
.ref-who b { display: block; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.ref-who span { display: block; font-size: 13px; color: var(--fg-muted); }

/* Сетка, а не список: у чужого аккаунта сначала смотришь на кадр — что за
   обложка, что за приём, — и только потом на цифру. У своего наоборот,
   там обложку и так помнишь. */
.rgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--step-2);
  margin-top: var(--step-2);
}

.rtile { min-width: 0; }
.rtile.is-link { cursor: pointer; }
.rtile.is-link:active { opacity: 0.6; }

.rtile-shot {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
}

.rtile-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }

.rtile-shot.is-empty::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(-45deg,
    transparent 0 6px, color-mix(in srgb, var(--fg-muted) 12%, transparent) 6px 12px);
}

/* Формат меткой в углу: рилс, карусель или фото. Словом подписывать негде,
   а различать надо — у рилса и карусели разные правила игры. */
.rtile-kind {
  position: absolute;
  right: 4px; top: 4px;
  font-size: 10px;
  line-height: 1;
  padding: 3px 4px;
  border-radius: 4px;
  color: #fff;
  background: rgba(0, 0, 0, 0.45);
}

/* Кратность к обычной публикации этого же аккаунта. Порог вдвое: у чужого
   аккаунта мы ищем не «чуть выше нормы», а то, что выстрелило. */
.rtile-x {
  position: absolute;
  left: 4px; bottom: 4px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  padding: 3px 6px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
}

.rtile-main {
  display: block;
  margin-top: 5px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.rtile-sub { display: block; font-size: 10px; color: var(--fg-muted); }

.ref-more {
  display: block;
  width: 100%;
  margin-top: var(--step-3);
  appearance: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 11px;
  cursor: pointer;
}

.ref-more:active { opacity: 0.7; }

/* ── Идеи в канал ────────────────────────────
   Экран решения, а не чтения: крючок виден всегда, состав поста
   раскрывается тапом, кнопки стоят на месте и не прыгают. */

.idea {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 10px;
}

.idea-head { display: flex; gap: 9px; align-items: baseline; }
.idea-title { font-weight: 600; letter-spacing: -0.01em; }
.idea-head .pill { margin-left: auto; }

/* Крючок это первая строка будущего поста, и решение принимается по нему.
   Поэтому он крупнее остального и отбит слева акцентом контура. */
.idea-hook {
  margin-top: 9px;
  padding-left: 10px;
  border-left: 2px solid var(--accent);
  font-size: 15px;
  line-height: 1.45;
}

.idea-more { display: none; margin-top: 10px; }
.idea.is-open .idea-more { display: block; }
.idea-more .field-label { margin-top: 9px; }
.idea-more .field-value { font-size: 14px; line-height: 1.45; }

.idea-foot {
  display: flex;
  align-items: center;
  gap: var(--step-2);
  flex-wrap: wrap;
  margin-top: 12px;
}

.idea-acts { display: flex; gap: 8px; }

.ibtn {
  appearance: none;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--fg);
  cursor: pointer;
}

/* «В работу» — единственная зелёная кнопка в приложении, и это намеренно:
   она означает согласие, а не рост. Отклонение красным не красим: отказ от
   идеи это нормальная работа, а не авария. */
.ibtn.ok {
  background: var(--up);
  border-color: var(--up);
  color: var(--brand-white);
}

.ibtn.no { color: var(--fg-muted); }
.ibtn.ghost { color: var(--fg-muted); }
.ibtn:active { opacity: 0.7; }
.ibtn:disabled { opacity: 0.45; }

.idea-by { margin-left: auto; font-size: 12px; color: var(--fg-muted); }

/* Число новых идей на строке раздела. Заливка акцентом, а не приглушённый
   текст: это единственное место на первом экране, которое зовёт открыть,
   а не сообщает цифру. */
.row-new {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
}

/* ── Воронка в боте ───────────────────────
   Строка со шкалой — один и тот же приём на три списка: ступени маршрута,
   категории и услуги. Устроена как строка дня у сторис: подпись и число по
   краям, полоса под ними. Заводить для похожих чисел второй способ показа
   значило бы заставлять читать каждый список заново. */
.frow { padding: var(--step-3) 0; border-top: 1px solid var(--line); }
.frow:first-of-type { border-top: 0; }

.frow-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--step-3);
}

.frow-name { font-size: 14px; min-width: 0; }

.frow-val {
  flex: 0 0 auto;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* Доля рядом с числом, но мельче и приглушённо: главное здесь сколько людей,
   процент — уточнение. */
.frow-val small {
  margin-left: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--fg-muted);
}

.frow-bar {
  height: 6px;
  margin-top: 7px;
  border-radius: 999px;
  background: var(--bg);
  overflow: hidden;
}

.frow-bar i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
}

/* Отвал — приглушённой строкой под полосой, а не цветом. Уход части людей
   на шаге это нормальная работа воронки, а не авария: красным здесь была бы
   покрашена каждая вторая строка, и цвет перестал бы что-либо значить. */
.frow-drop { margin-top: 5px; font-size: 11px; color: var(--fg-muted); }

/* ── Человек в списке ─────────────────────
   Единственное место в приложении, где строка это живой человек, а не
   публикация. Поэтому имя стоит первым и крупным, а всё остальное — мелким
   под ним: сначала кто, потом что он сделал. */
.pcard-head { display: flex; align-items: baseline; gap: 7px; }
.pcard-nick { font-size: 12px; color: var(--fg-muted); }

.pcard-at {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--fg-muted);
  white-space: nowrap;
}

.pcard-line { margin-top: 5px; font-size: 13px; color: var(--fg-muted); }
.pcard-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.pcard-path { font-size: 12px; color: var(--fg-muted); line-height: 1.5; }

/* Фильтры воронки переносятся по строкам. Их три, и последний упирался в
   край экрана: прокручиваемый ряд из трёх кнопок — это спрятанная кнопка,
   а не экономия места. */
.filters.wrap { flex-wrap: wrap; row-gap: 6px; overflow-x: visible; }

/* Фильтры людей идут сразу под рядом периодов, и без отступа две полосы
   кнопок слипались в одну сетку: глазом не видно, где кончается «за какой
   срок» и начинается «кого показывать». */
#funnel-body > .filters.wrap { margin-top: var(--step-4); }

/* ── Готовые посты ──────────────────────────────────────────────
   Карточка наследует .idea целиком: человек уже знает этот экран, и второй
   способ принимать решения ему учить незачем. Отличия только там, где
   решают не по заготовке, а по готовому тексту. */

/* Текст поста виден сразу и целиком, без раскрытия по тапу. У идеи под
   тапом лежит состав будущего поста, то есть служебное; здесь под тапом
   лежал бы сам предмет решения, и прятать его значит просить одобрить
   вслепую. Моноширинного шрифта нет намеренно: пост надо читать так, как
   его увидят в канале, а не как код. */
.post-body {
  margin-top: 10px;
  padding: 12px 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 15px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

.post-meta {
  margin-top: 8px;
  font-size: 12px;
  color: var(--fg-muted);
}

/* Чего не хватает до публикации. Показывается и Никите тоже: без этого
   одобренный пост, лежащий неделю, выглядит забытым, а он ждёт фактуры. */
.post-todo {
  margin-top: 10px;
  padding-left: 10px;
  border-left: 2px solid var(--line);
}
.post-todo .field-value { font-size: 13px; line-height: 1.45; }

.post-publish { margin-top: 12px; }

/* Кнопка публикации во всю ширину и отбита сверху линией: это единственное
   действие в приложении, которое уходит наружу, и оно не должно стоять в
   одном ряду с обратимыми. */
.post-publish .ibtn.pub {
  display: block;
  width: 100%;
  padding: 12px;
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* Предупреждение перед вторым тапом. Красное здесь оправдано, в отличие от
   отклонения идеи: там отказ это нормальная работа, а тут действие правда
   необратимо. */
.post-warn {
  font-size: 13px;
  line-height: 1.4;
  color: var(--down);
  margin-bottom: 10px;
}

/* «Не надо» стоит первой и занимает то же место, где до этого была кнопка
   публикации: промах по старому месту отменяет отправку, а не запускает её. */
.post-confirm { display: flex; gap: 8px; }
.post-confirm .ibtn { flex: 1; }
.post-confirm .ibtn.danger {
  background: var(--down);
  border-color: var(--down);
  color: var(--brand-white);
}

.idea.post.is-confirming { border-color: var(--down); }

/* Фильтры на экране постов переносятся по строкам, а не уезжают вбок.
   Та же причина, что у порядков в списке рилсов: последний чипс за краем —
   это кнопка, о которой не знаешь, а значит её нет. Здесь их всего четыре,
   и в две строки они укладываются без потери высоты под сами посты. */
#post-filters { flex-wrap: wrap; overflow-x: visible; }

.post-date { font-size: 13px; color: var(--fg-muted); }
.idea.post .idea-head .pill { margin-left: auto; }

/* ── Барабан выбора времени ─────────────────────────────────────
   Крутится родной инерцией прокрутки плюс scroll-snap: ни одной строчки
   анимации, поэтому ведёт себя ровно как системный выбор времени в
   телефоне, включая докрут и подхват на лету. */

.wheels {
  position: relative;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
  gap: 4px;
  height: 200px;
  margin: 4px 0 12px;
  overflow: hidden;
}

.wheel {
  /* Барабаны лежат поверх полосы: абсолютный элемент иначе рисуется выше
     статических и накрывает собой ровно ту строку, ради которой всё
     затевалось — выбранную. */
  position: relative;
  z-index: 1;
  height: 200px;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
  /* Прокрутка барабана не должна утягивать за собой страницу: без этого
     докрут до края листает экран под ним. */
  overscroll-behavior: contain;
  text-align: center;
}
.wheel::-webkit-scrollbar { display: none; }

/* Отступы ровно в 80 px сверху и снизу ставят первый и последний пункт в
   центр окна: 200 высоты минус 40 строки, пополам. */
.wheel-pad { height: 80px; }

.wheel-item {
  height: 40px;
  line-height: 40px;
  scroll-snap-align: center;
  font-size: 17px;
  color: var(--fg-muted);
  transition: color 0.12s, opacity 0.12s;
  opacity: 0.55;
}

/* Выбранное значение темнее и плотнее остальных. Подсветкой не красим:
   цвет здесь означал бы состояние, а состояние тут одно — «на нём стоим». */
.wheel-item.is-on {
  color: var(--fg);
  opacity: 1;
  font-weight: 600;
}

/* Полоса под центральной строкой, как у системного выбора. Лежит под
   барабанами и не перехватывает касания. */
.wheel-band {
  position: absolute;
  z-index: 0;
  left: 0; right: 0;
  top: 80px;
  height: 40px;
  border-radius: 10px;
  background: var(--bg);
  pointer-events: none;
}

.post-publish .ibtn.sched {
  display: block;
  width: 100%;
  padding: 12px;
  margin-top: 8px;
}

.post-when {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 8px;
}

/* Репетиция подписывается вверху экрана, а не только на кнопке: подменённый
   адресат публикации это ровно та вещь, о которой забывают и потом
   удивляются, куда делся пост. */
.post-rehearsal {
  padding: 10px 12px;
  margin-bottom: var(--step-1);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  font-size: 13px;
  color: var(--fg-muted);
}

/* ── Окно выбора времени ────────────────────────────────────────
   Барабан жил внутри карточки и уезжал под фактуру поста: до него
   приходилось прокручивать ровно тогда, когда человек уже принял решение.
   Теперь окно по центру экрана, а список под ним заморожен. */

.modal-veil {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(0, 0, 0, 0.45);
  /* Затемнение проявляется, а не возникает: мгновенная чёрная заливка
     читается как сбой отрисовки. */
  animation: veil-in 0.15s ease-out;
}

@keyframes veil-in { from { opacity: 0; } to { opacity: 1; } }

.modal {
  position: fixed;
  z-index: 61;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(320px, calc(100vw - 40px));
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 16px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.35);
  animation: modal-in 0.16s ease-out;
}

/* Окно слегка подрастает, а не выезжает снизу: выезд снизу в вебвью
   телеграма читается как его собственная шторка, и палец тянется закрыть
   его свайпом вниз, то есть закрыть само приложение. */
@keyframes modal-in {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.96); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.modal-title {
  font-size: 15px;
  font-weight: 600;
  text-align: center;
  margin-bottom: 4px;
}

/* Выбранное целиком и по-человечески. Три колонки читаются как три числа,
   а решение принимается по одной фразе: «завтра в 09:00». */
.modal-when {
  text-align: center;
  font-size: 15px;
  font-weight: 600;
  color: var(--accent-ink);
  margin-bottom: 12px;
}

.modal .wheels { margin: 0 0 10px; }

/* Пока окно открыто, список под ним не прокручивается: иначе фон уезжает
   от касаний мимо барабана, и окно выглядит отклеившимся. */
body.is-locked { overflow: hidden; }

/* Время смотрящего. Показывается только тому, кто сидит не в Иркутске:
   планируется всё по времени Никиты, и для него вторая строка повторяла бы
   первую. Максиму она нужна — он в Польше, а сервер в Амстердаме. */
.modal-yours {
  text-align: center;
  font-size: 13px;
  color: var(--fg-muted);
  margin: -8px 0 12px;
}

.post-when-yours {
  font-size: 12px;
  color: var(--fg-muted);
  margin: -6px 0 8px;
}
