/* Компоненты кабинета на токенах PEAKCUT.

   Две поверхности и правило выбора между ними:
   • .card   — светлое стекло, поверхность по умолчанию (списки, таблицы, формы);
   • .island — светлый остров с мягким свечением, редкая и «дорогая»
               поверхность: на ней живут блоки, ради которых клиент открывает
               кабинет (охват во времени, топ рилсов, шапка аккаунта).
   Если островов на экране больше двух — акцент размывается, и остров перестаёт
   что-либо значить. */

/* ---------- карточки ---------- */
/* Вид итерации 1 (референс handoff/dashboard-target.png): плотная белая
   поверхность, волосяная рамка и мягкая двухслойная тень вместо стекла.
   Полупрозрачное стекло с blur оставлено шапке — карточке оно придавало
   «вату» на градиентном фоне. */
/* Стекло без blur (Б-3, «больше liquid glass»): чуть просвечивающая поверхность и
   световая кромка сверху — как у острова. Размытие подложки карточкам по-прежнему не
   даётся: на градиентном фоне оно читалось «ватой» (см. выше), и это решение не
   пересматривается; глубина стекла здесь — из просвета и кромки, не из blur. */
.card{
  position:relative;min-width:0;
  border:1px solid var(--surface-card-line);border-radius:var(--r-panel);
  background:var(--surface-card-strong);
  box-shadow:var(--shadow-card),inset 0 1px 0 var(--glass-line);
}
.card.pad{padding:var(--card-pad-roomy);}

/* Карточка-колонка: заголовок, содержимое, подвал. Скругление обрезает таблицу и
   подвал по краю карточки, а колонка позволяет подвалу прижаться книзу
   (.push-down). Раньше это была инлайн-тройка style="overflow:hidden;display:flex;
   flex-direction:column" в шести шаблонах — и в двух из них без overflow. */
.card.stack{overflow:hidden;display:flex;flex-direction:column;}

/* Короткая заметка вместо блока: «Not measured yet.» и её родня. */
.card-note{padding:8px 0;color:var(--muted-2);font-size:12px;line-height:1.6;}
/* Если вся карточка-колонка — одна такая заметка, она центрируется по высоте:
   карточку тянет сосед по ряду, и заметка, прижатая к верху, читалась как обрыв. */
.card.stack>.card-note{margin-block:auto;}
a.card{transition:transform var(--dur-micro) var(--ease-standard),border-color var(--dur-micro) var(--ease-standard),box-shadow var(--dur-micro) var(--ease-standard);}
/* Ховер-лифт — в один пиксель: карточка обзора не «подпрыгивает», а чуть
   отрывается от фона, рамка темнеет до контрольной. */
a.card:hover{transform:translateY(-1px);border-color:var(--control-line);box-shadow:var(--shadow-lift);}

/* container-type — чтобы содержимое острова могло реагировать на ЕГО ширину:
   в бенто-сетке остров вдвое уже страницы, и медиазапрос по вьюпорту про это
   ничего не знает (см. .kpi-row.hero-kpi ниже). Ширина острова задаётся ячейкой
   сетки, от содержимого не зависит — inline-size тут безопасен. */
.island{
  position:relative;overflow:hidden;min-width:0;container-type:inline-size;
  padding:var(--card-pad-roomy);color:var(--on-island);
  background:var(--island-solid);border:1px solid var(--island-line);
  border-radius:var(--r-panel);box-shadow:var(--island-shadow);
}
.island::before{
  content:"";position:absolute;width:340px;height:340px;right:-120px;top:-160px;
  border-radius:50%;background:var(--island-glow-violet);filter:blur(70px);pointer-events:none;
}
.island::after{
  content:"";position:absolute;width:260px;height:260px;left:-110px;bottom:-150px;
  border-radius:50%;background:var(--island-glow-lime);filter:blur(70px);pointer-events:none;
}
.island>*{position:relative;z-index:2;}

.card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;margin-bottom:16px;}
.card-title{display:block;font:700 16px/1.2 var(--display);letter-spacing:-.015em;}
.card-sub{display:block;margin-top:3px;color:var(--muted-2);font-size:11.5px;line-height:1.45;}
.island .card-title{color:var(--on-island);font-size:18px;}
.island .card-sub{color:var(--on-island-muted);}

.rows-title{padding:var(--card-pad-roomy) var(--card-pad-roomy) 10px;font:700 16px var(--display);letter-spacing:-.015em;}

/* Заголовок списка с подписью справа: название по левой вертикали карточки,
   уточнение («by views · 30d») прижато к правому краю на общей базовой линии.
   Раньше эта раскладка жила инлайн-стилем в трёх шаблонах и там же разъезжалась. */
.rows-title.split{display:flex;align-items:baseline;justify-content:space-between;gap:10px;}
.rows-title.split .card-sub{margin:0;}

/* ---------- график охвата (остров) ---------- */
/* В ленте обзора остров стоит на всю ширину ряда; минимум держит полотно
   читаемым на любом экране. */
.reach-island{display:flex;flex-direction:column;min-height:330px;}
/* Сетка вместо flex: строка 1 — подписи оси и полотно, строка 2 — даты. В flex
   колонка подписей растягивалась на весь блок вместе с датами, и подписи
   расходились с линиями сетки. */
.chart-wrap{position:relative;display:grid;grid-template-columns:44px minmax(0,1fr);grid-template-rows:minmax(0,1fr) auto;column-gap:12px;flex:1;min-height:0;}
/* Колонка подписей занимает ровно первую строку сетки, то есть высоту полотна;
   внутри .ys подписи стоят на тех же процентах, что линии сетки. */
.chart-y{grid-column:1;grid-row:1;display:flex;flex-direction:column;color:var(--on-island-faint);font:11px var(--mono);}
.chart-y .ys{position:relative;flex:1;min-height:0;}
/* Такт первый: СЦЕНА ставится раньше линии. Оси проступают за первые 200мс, и
   линия рисуется на готовом поле, а не вместе с ним — иначе весь кадр едет одной
   плоской массой. Сама сетка внутри полотна такта не требует: на её прозрачности
   (.055) свип по ней не читается. */
.chart-y .ys span{position:absolute;right:0;transform:translateY(-50%);white-space:nowrap;
  animation:fadeIn .26s var(--ease-enter) both;}
.chart-y .ys span:nth-child(2){animation-delay:.03s;}
.chart-y .ys span:nth-child(3){animation-delay:.06s;}
.chart-y .ys span:nth-child(4){animation-delay:.09s;}
.chart-y .ys span:nth-child(5){animation-delay:.12s;}
.chart-plot{grid-column:2;grid-row:1;}
.chart-x{grid-column:2;grid-row:2;}

/* Высота гибкая: в fit-сетке дашборда график занимает всё, что дал ряд. */
.chart-plot{position:relative;flex:1;min-height:120px;display:flex;flex-direction:column;}
/* Полотно ПРОЯВЛЯЕТСЯ слева направо — тем же движением, которым читается сам
   график: от первого дня к сегодняшнему. Ведёт его маска с растушёванной
   кромкой, а не dash-reveal по длине штриха: тот на растянутом
   preserveAspectRatio=none полотне заворачивал паттерн и показывал линию рваными
   сегментами. Маска не знает ни про длину пути, ни про stroke — рвать ей нечего.

   Кромка мягкая, а не нож: последние 56px маски уходят в прозрачность, и линия
   не открывается заслонкой, а проступает. Растёт при этом РАЗМЕР маски
   (см. chartWipe) — так ширина растушёвки остаётся постоянной на любой ширине
   полотна, а конечные 110% гарантированно накрывают его целиком.

   Маска висит на всём полотне, а не на стопке путей: у элемента коробка — его
   рамка, которую svg и так обрезает. Маска по стопке считалась бы от bbox путей
   и после проигрыша срезала бы свечение над пиком.

   Там, где маски нет вовсе (очень старые движки), правило просто игнорируется и
   график виден сразу — деградация тихая. */
.chart{
  display:block;width:100%;flex:1;min-height:0;
  -webkit-mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 56px),transparent 100%);
  mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 56px),transparent 100%);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:left center;mask-position:left center;
  animation:chartWipe .9s var(--ease-sweep) both .15s;
}
/* Пятно света у кромки — тот такт, который превращает «открыли» в «ведут»: в
   кадре появляется источник движения, а не только его результат. Слой HTML и
   поверх полотна, поэтому svg не трогает вовсе. Едет тем же таймингом, что и
   маска: расхождение в пару пикселей размытие всё равно съедает. */
.chart-sweep{
  position:absolute;top:0;bottom:0;width:64px;margin-left:-32px;z-index:2;
  pointer-events:none;opacity:0;mix-blend-mode:screen;filter:blur(9px);
  background:linear-gradient(90deg,transparent,rgba(157,107,255,.1) 58%,rgba(214,198,255,.24) 94%,transparent);
  /* Гаснет к верхней кромке: у верха полотна данных нет, и ровный по высоте
     столб света читался бы сканером, а не свечением у самой линии. */
  -webkit-mask-image:linear-gradient(180deg,transparent,#000 46%,#000 100%);
  mask-image:linear-gradient(180deg,transparent,#000 46%,#000 100%);
  animation:chartSweep .9s var(--ease-sweep) both .15s;
}
/* Текущее значение на конце линии: плашка НАД точкой (линия растёт слева
   направо, над концом всегда пусто), хвост линии остаётся видимым до края. */
.chart-endlab{
  position:absolute;transform:translate(calc(-100% + 6px),calc(-100% - 10px));white-space:nowrap;pointer-events:none;
  padding:3px 9px;border-radius:999px;background:var(--surface);
  border:1px solid var(--line);color:var(--text);
  font:700 11px var(--mono);font-variant-numeric:tabular-nums;
  box-shadow:0 8px 20px rgba(15,23,42,.14);animation:fadeIn .34s var(--ease-enter) both 1.15s;
}
/* Маркер последней точки — HTML-слой поверх svg: круг в svg с
   preserveAspectRatio=none растягивался в овал и резался краем полотна. */
.chart-dot{
  position:absolute;width:9px;height:9px;border-radius:50%;pointer-events:none;
  transform:translate(-50%,-50%);background:var(--accent-on-dark);
  border:2px solid var(--surface);box-shadow:0 0 0 3px rgba(145,70,255,.22);
}
.chart-grid{stroke:rgba(15,23,42,.06);stroke-width:1;}
/* Легенда острова — на месте бывшего переключателя величин (в шапке, справа от
   заголовка). Внутри полотна ей больше не место: чип накрывал угол графика, а
   рядов стало три. Образец цвета стоит рядом со своей подписью, поэтому ряд
   опознаётся и без цвета; сами подписи носят текстовый тон, а не тон ряда. */
.chart-keys{display:flex;align-items:center;flex-wrap:wrap;justify-content:flex-end;gap:6px 14px;}
.chart-keys .ck{display:inline-flex;align-items:center;gap:7px;color:var(--on-island-muted);font-size:11.5px;font-weight:600;white-space:nowrap;}
.chart-keys .ck i{width:9px;height:9px;flex:none;border-radius:3px;background:var(--series-1);box-shadow:0 0 12px var(--series-1-glow);}
.chart-keys .ck.alt i{background:var(--series-2);box-shadow:0 0 12px var(--series-2-glow);}
/* Наложение обычное, а порядок — «меньшая фигура сверху» (см. vm.chart). Через
   screen перекрытие двух полупрозрачных слоёв уходило в светло-серый: складывая
   свет, он смешивает и тона. Верхний слой просто плотнее нижнего, поэтому нижняя
   зона читается своим цветом, а полоса между линиями — своим. */
/* Заливка не проступает вместе с линией, а ПОДНИМАЕТСЯ от базовой линии следом
   за кромкой: сначала линию провели, потом под неё налилась площадь. Origin —
   низ bbox самой фигуры (transform-box:fill-box), то есть ровно базовая линия;
   без fill-box отсчёт пошёл бы от viewBox и фигура уезжала бы вбок. */
.chart-area{
  fill:url(#areaGrad);transform-box:fill-box;transform-origin:50% 100%;
  animation:areaFlood .6s var(--ease-standard) both .19s;
}
/* Второй слой (охваченные зрители) — лаймовая половина палитры и ниже по стопке:
   два слоя одного тона слиплись бы в одну фигуру. */
/* Верхний слой наливается ПОЗЖЕ нижнего: два слоя, поднявшиеся синхронно, — одна
   плоская фигура, а разнесённые на 90мс читаются как передний и задний план. */
.chart-area.alt{fill:url(#areaGrad2);animation-delay:.28s;}
.chart-line.alt{stroke:var(--series-2);stroke-width:1.6;opacity:.85;filter:none;}
/* Линия всегда цельная: НИКАКИХ stroke-dasharray/dashoffset. Dash-reveal при
   non-uniform SVG scaling на промежуточном кадре заворачивал паттерн и показывал
   два разорванных сегмента. Появление линии слева направо даёт clip полотна
   (chartWipe на .chart), он геометрии stroke не касается; здешний короткий fade
   лишь смягчает переднюю кромку свипа. */
/* Свечение под штрихом — тот самый «живой» слой: размытая копия линии, собранная
   фильтром в defs. Дублировать путь в разметке для этого не нужно. */
.chart-line{fill:none;stroke:var(--series-1);stroke-width:2.2;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke;filter:url(#lineGlow);animation:fadeIn .35s var(--ease-enter) both;}
/* Прибытие в конец линии — точка ПРИХОДИТ, а не проступает: масштаб с лёгким
   перелётом плюс одиночная волна. Это единственный акцент во всей анимации, и
   стоит он там, ради чего график открывают, — на сегодняшнем значении.
   Задержка равна концу свипа (.15 + .9): раньше точка висела бы в пустоте
   впереди линии. */
.chart-dot{animation:dotLand .42s var(--ease-standard) both 1.05s;}
.chart-dot::after{
  content:"";position:absolute;left:50%;top:50%;width:9px;height:9px;
  border-radius:50%;border:1.5px solid rgba(191,151,255,.7);
  animation:dotRing .9s var(--ease-enter) both 1.05s;
}
.chart-x{display:flex;justify-content:space-between;margin-top:8px;color:var(--on-island-faint);font:10.5px var(--mono);}
/* Даты — та же сцена, но стелется она по ходу свипа, слева направо. */
.chart-x span{animation:fadeIn .26s var(--ease-enter) both;}
.chart-x span:nth-child(2){animation-delay:.04s;}
.chart-x span:nth-child(3){animation-delay:.08s;}
.chart-x span:nth-child(4){animation-delay:.12s;}
.chart-x span:nth-child(5){animation-delay:.16s;}
/* Слой наведения: перекрестие + подсказка. Курсору не нужно попадать в маркер —
   подсвечивается ближайшая по горизонтали точка ряда. */
.chart-hover{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity var(--dur-feedback) var(--ease-standard);}
.chart-hover.on{opacity:1;}
.chart-cross{position:absolute;top:0;bottom:0;width:1px;background:rgba(15,23,42,.2);}
/* Подсказка перечисляет ВСЕ ряды замера: переключателя величин больше нет, и
   прочитать число ряда за конкретный день больше негде. Отсюда столбик строк
   вместо одной, и отсюда же перевороты — плашка на 4 строки у верхней кромки
   полотна не помещается. */
.chart-tip{
  position:absolute;transform:translate(-50%,calc(-100% - 12px));white-space:nowrap;
  display:flex;flex-direction:column;gap:3px;
  padding:7px 10px;border-radius:9px;background:var(--surface);
  border:1px solid var(--line);color:var(--text);
  font:650 11px var(--sans);font-variant-numeric:tabular-nums;
  box-shadow:0 8px 20px rgba(15,23,42,.16);
}
.chart-tip.below{transform:translate(-50%,12px);}
.chart-tip.at-start{transform:translate(-14px,calc(-100% - 12px));}
.chart-tip.at-start.below{transform:translate(-14px,12px);}
.chart-tip.at-end{transform:translate(calc(-100% + 14px),calc(-100% - 12px));}
.chart-tip.at-end.below{transform:translate(calc(-100% + 14px),12px);}
.chart-tip b{color:var(--on-island-muted);font:700 10px var(--mono);letter-spacing:.04em;text-transform:uppercase;}
.chart-tip .tr{display:flex;align-items:center;gap:7px;}
.chart-tip .tr .sw{width:8px;height:8px;flex:none;border-radius:3px;background:var(--series-1);}
.chart-tip .tr .sw.alt{background:var(--series-2);}
.chart-tip .tr em{margin-left:auto;padding-left:10px;font:750 11.5px var(--display);font-style:normal;}
.island-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:14px;color:var(--on-island-faint);font-size:10.5px;}

/* Плитка-KPI: подпись прижата к верху, величина — к низу. Контент по центру
   высокой ячейки оставлял равные пустые поля сверху и снизу, и плитка читалась
   как дыра; распорка между подписью и числом делает высоту осмысленной. */
.now-tile{
  min-width:0;display:flex;flex-direction:column;gap:4px;
  padding:var(--card-pad-compact);border:1px solid var(--line-soft);border-radius:var(--r-md);
  background:var(--surface-card);
}
.now-tile .l{display:flex;align-items:center;gap:6px;color:var(--muted);font-size:11px;font-weight:650;white-space:nowrap;overflow:hidden;}
.now-tile .l svg{flex:none;color:var(--accent-strong);}
.now-tile .v{margin-top:auto;font:700 19px/1.05 var(--display);letter-spacing:-.025em;font-variant-numeric:tabular-nums;}
.now-tile .s{color:var(--muted-2);font-size:10.5px;line-height:1.35;}
.now-tile .delta{align-self:flex-start;}

/* Дельта — пилюля со стрелкой: рост зелёный, падение красное, цвет не единственный
   носитель смысла. */
.delta{display:inline-flex;align-items:center;gap:3px;padding:2px 7px;border-radius:999px;font:700 10.5px var(--sans);font-variant-numeric:tabular-nums;white-space:nowrap;}
.delta::before{font-size:9px;line-height:1;}
.delta.up{background:var(--ok-surface);color:var(--ok);}
.delta.up::before{content:"▲";}
.delta.down{background:var(--danger-surface);color:var(--danger);}
.delta.down::before{content:"▼";}
.delta.flat{background:var(--unknown-surface);color:var(--unknown);}

/* ---------- полка рилсов ---------- */
/* Карточка построена по языку клип-карты админки (`.cc` в montage.css): тёмное
   поле с фиолетово-лаймовым свечением, вертикальная обложка слева, содержание
   справа. Тексты и метрики адаптированы под рилс: заголовок, аккаунт, реакции,
   когда вышел. */
/* Высота 138, а не 172: весь топ обязан вставать ОДНИМ рядом (три карточки по
   378px при окне 1440), и в горизонтальной карточке лишняя высота — это воздух, а
   не данные. Ранг уехал плашкой на обложку, и его строка освободила 25px. */
.reel{
  position:relative;display:flex;gap:0;height:138px;padding:6px;overflow:hidden;
  border:1px solid var(--island-line);border-radius:var(--r-xl);
  background:radial-gradient(125% 130% at 100% 50%,rgba(145,70,255,.06) 0%,rgba(83,252,24,.03) 34%,transparent 60%),var(--surface);
  color:var(--on-island);
  box-shadow:0 10px 24px -12px rgba(15,23,42,.16),inset 0 1px 0 rgba(255,255,255,.7);
  transition:transform var(--dur-micro) var(--ease-standard),border-color var(--dur-micro) var(--ease-standard);
}
.reel:hover{transform:translateY(-2px);border-color:var(--island-line-strong);}
/* Радиус обложки = радиус карточки МИНУС её отступ (12-6): при меньшем угол
   обложки наезжал на закругление карточки и кадр «выползал» за её край. */
.reel-cover{
  position:relative;width:84px;flex:none;border-radius:calc(var(--r-xl) - 6px);overflow:hidden;
  background:linear-gradient(150deg,var(--surface-3),var(--purple-100));
}
.reel-cover img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}
.reel-cover .ph{
  position:absolute;inset:0;display:grid;place-items:center;
  background:linear-gradient(150deg,rgba(145,70,255,.25),rgba(83,252,24,.12));
  color:var(--text);font:800 22px var(--display);
}
.durlab{
  position:absolute;right:6px;bottom:6px;z-index:3;padding:2px 7px;border-radius:6px;
  background:rgba(10,12,17,.82);color:#fff;font:650 10.5px var(--mono);
  backdrop-filter:blur(4px);
}

/* На узкой карточке (на 1080–1240px окна три колонки дают ей 265px) три величины
   требуют 203px при доступных 145 и обрезались молча. Уходит третья —
   сохранения: полные числа стоят в таблице постов ниже на этой же странице.
   Запрос по ширине КАРТОЧКИ: со свёрнутым сайдбаром на той же ширине окна места
   больше, и прятать уже нечего. */
.reel{container-type:inline-size;}

.metric{display:flex;align-items:center;gap:5px;color:var(--on-island-faint);font-size:11px;}
.metric b{color:var(--on-island);font:750 12.5px var(--display);font-variant-numeric:tabular-nums;}
.metric svg{width:13px;height:13px;flex:none;opacity:.7;}

/* На светлой карточке (в таблицах) метрика остаётся тёмной. */
.card:not(.reel) .metric{color:var(--muted);}
.card:not(.reel) .metric b{color:var(--text);}

/* ---------- строки-списки ---------- */
.rows{display:flex;flex-direction:column;}

.note-foot{padding:11px var(--card-pad-roomy);border-top:1px solid var(--line-soft);color:var(--muted-2);font-size:10.5px;line-height:1.5;}
/* Подвал-ссылка: пояснение слева, зов справа. Тоже был инлайн-стилем в четырёх
   местах, и в двух из них отличался. */
.note-foot.split{display:flex;align-items:center;justify-content:space-between;gap:8px;}

.acc-item{display:flex;align-items:center;gap:11px;padding-block:9px;border-radius:var(--r-sm);transition:background var(--dur-micro) var(--ease-standard);}
.acc-item:hover{background:var(--surface-2);}
.acc-item .nm{font-size:12.5px;font-weight:650;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.acc-item .sub{color:var(--muted-2);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* Середина ряда — общий блок для обоих списков: имя сверху, подпись под ним.
   Зазор после имени 5px, а не 2: на 2px ник и «2 310 followers» читались одним
   блоком в два кегля, а не именем и уточнением под ним. */
.acc-item .rid,.reel-row .rid{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px;}

/* ---------- аватар аккаунта ---------- */
.av{display:grid;place-items:center;flex:none;border-radius:7px;font:750 11px var(--display);letter-spacing:.02em;position:relative;overflow:hidden;}
/* Снимок аватарки лежит ПОВЕРХ инициалов, а не вместо них: он есть не у каждого
   аккаунта и может не доехать — тогда под ним остаётся цветной кружок, а не дыра. */
.av img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;}
/* Аватарка приходит снимком экрана Instagram вместе с фоном вокруг круга (В-38): фото в
   круглой плашке увеличено, фон уходит за край. Снять, когда PEAKCUT станет обрезать сам. */
.av.mono img{transform:scale(1.35);}
.av.s20{width:20px;height:20px;font-size:8px;border-radius:6px;}
.av.s26{width:26px;height:26px;font-size:9px;border-radius:8px;}
.av.s34{width:34px;height:34px;font-size:10.5px;border-radius:10px;}
.av.s38{width:38px;height:38px;border-radius:11px;}

.av.s54{width:54px;height:54px;font-size:15px;border-radius:15px;}
/* Монограмма — КРУГ: так плашка читается как аватарка профиля, а не как ещё одна
   обложка. Цвет и буквы приходят инлайном из vm.mono (устойчивый тон от ника),
   поэтому здесь только форма и кегль. */
.av.mono{border-radius:50%;font-weight:800;letter-spacing:0;}
.av.mono.s20{font-size:8.5px;}
.av.mono.s26{font-size:10px;}
.av.mono.s34{font-size:12px;}
.av.mono.s38{font-size:13px;}

.av.mono.s54{font-size:18px;}

.picon{flex:none;display:inline-grid;place-items:center;}

/* ---------- бейджи ---------- */

/* Тихая метка статуса аккаунта (О-3): точка приглушённого тона + текст обычного веса.
   Тона — из семантических токенов, красного нет: watch — янтарный, good — зелёный,
   quiet — серый. Пояснение живёт в title и в карточке, не в строке. */
.status{display:inline-flex;align-items:center;gap:7px;color:var(--text);font-size:12.5px;white-space:nowrap;}
.status .sdot{width:7px;height:7px;border-radius:50%;flex:none;background:var(--unknown);opacity:.75;}
.status.good .sdot{background:var(--ok);}
.status.watch .sdot{background:var(--warn);}
.status.quiet{color:var(--muted);}
/* Тренд в строке: стрелка и проценты, приглушённо; падение — янтарный, не красный. */
.trend{font:600 10.5px var(--display);font-variant-numeric:tabular-nums;color:var(--muted-2);white-space:nowrap;}
.trend.up{color:var(--ok);}
.trend.down{color:var(--warn);}
.trend.up::before{content:"▲ ";font-size:8px;}
.trend.down::before{content:"▼ ";font-size:8px;}
/* Последняя публикация дольше недели — выделение словом и тоном, не красным. */
.late{color:var(--warn);font-weight:600;}
/* Метка слоя у поста: «Full stats · updated 2 h ago». Устаревшие просмотры — янтарный. */
.layer{display:inline-block;color:var(--muted-2);font-size:10.5px;white-space:nowrap;}
.layer.stale{color:var(--warn);}
/* Pool health на обзоре: счётчики по статусам одной строкой. */
.pool-items{display:flex;flex-wrap:wrap;align-items:stretch;gap:10px 32px;padding:4px var(--card-pad-roomy) var(--card-pad-roomy);}
/* Разделитель между здоровыми и требующими взгляда (В-11а). */
.pool-sep{width:1px;background:var(--line-soft);margin:0 -8px;}
.pool-item{display:flex;flex-direction:column;gap:3px;min-width:96px;color:inherit;text-decoration:none;}
.pool-item .n{font:800 22px/1.05 var(--display);letter-spacing:-.03em;font-variant-numeric:tabular-nums;}
.pool-item .s{color:var(--muted-2);font-size:10.5px;line-height:1.35;max-width:180px;}
/* Таблица Accounts: причина словами в ячейке — мельче и приглушённо. */
.tbl .why{display:block;color:var(--muted-2);font-size:10.5px;line-height:1.35;white-space:normal;max-width:120px;}
.tbl td.num .why{margin-left:auto;text-align:right;}
/* Таблица Accounts: тренд — строкой под числом, иначе восемь колонок не входят в 1440. */
.chip{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;background:var(--surface-2);color:var(--muted);font:650 10.5px var(--sans);}
.chip.ours{background:var(--accent-ghost);color:var(--accent-strong);}
.island .chip{background:var(--island-raise);color:var(--on-island-muted);}

/* ---------- контролы ---------- */
/* Сегменты — пилюли, как .pc-page-controls в шапке админки. */
.seg{display:inline-flex;padding:3px;border-radius:999px;background:var(--surface-2);gap:2px;}
.seg a,.seg button{display:inline-flex;align-items:center;min-height:28px;padding:0 12px;border-radius:999px;color:var(--muted);font:600 11.5px var(--sans);cursor:pointer;white-space:nowrap;transition:background var(--dur-micro) var(--ease-standard),color var(--dur-micro) var(--ease-standard);}
.seg a:hover,.seg button:hover{color:var(--text);}
.seg a.active,.seg button.active{background:var(--surface);color:var(--text);box-shadow:var(--shadow-low);}

.island .seg{background:var(--island-raise);}
.island .seg a{color:var(--on-island-muted);}
.island .seg a.active{background:var(--surface-2);color:var(--text);box-shadow:none;}

/* Высота/радиус/вес — как у `.btn` в admin/peakcut.css, чтобы кнопка кабинета и
   кнопка админки были одной кнопкой. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:36px;padding:0 15px;border-radius:11px;background:var(--surface-2);border:1px solid var(--line);color:var(--text);font:500 13.5px var(--sans);cursor:pointer;white-space:nowrap;transition:background var(--dur-micro) var(--ease-standard),border-color var(--dur-micro) var(--ease-standard),transform var(--dur-feedback) var(--ease-standard);}
.btn svg{width:15px;height:15px;opacity:.85;}
.btn:active{transform:translateY(1px);}
.btn:hover{background:var(--surface-3);border-color:var(--control-line);}
.btn.accent{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 8px 20px -10px rgba(145,70,255,.9);}
.btn.accent:hover{background:var(--accent-dim);border-color:var(--accent-dim);}
.btn.ghost{background:transparent;border-color:transparent;color:var(--muted);}
.btn.ghost:hover{background:var(--surface);color:var(--text);}

.btn.sm{height:30px;padding:0 11px;font-size:12.5px;border-radius:9px;}
.btn.block{width:100%;}
.btn[disabled]{opacity:.55;pointer-events:none;}

.searchbox{display:flex;align-items:center;gap:8px;padding:0 12px;height:38px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface);color:var(--muted-2);}
.searchbox:focus-within{border-color:var(--control-line);box-shadow:0 0 0 3px var(--accent-ghost);}
.searchbox input{border:none;outline:none;background:none;width:210px;max-width:40vw;font-size:12.5px;color:var(--text);}
.searchbox input::placeholder{color:var(--muted-2);}

.fld{display:flex;flex-direction:column;gap:6px;}
.fld label{color:var(--muted);font-size:11.5px;font-weight:650;}
.fld input{padding:11px 13px;border:1px solid var(--line);border-radius:12px;background:var(--surface);font-size:13px;color:var(--text);outline:none;}
.fld input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-ghost);}

/* ---------- profile settings ---------- */
/* Профиль занимает ВСЮ ширину воркспейса, как остальные экраны. Потолок в 1060px
   держал две формы узкой колонкой посреди пустоты, и на большом мониторе экран
   читался как чужой (решение владельца 14.08). Ширину поля при этом ограничивает
   само поле — форма не превращается в ленту на 2К. */
.profile-screen{width:100%;}
.profile-intro{display:flex;align-items:center;gap:16px;padding:var(--card-pad-roomy);}
.profile-intro h2{margin:0;color:var(--on-island);font:700 22px/1.15 var(--display);letter-spacing:-.02em;}
.profile-intro p{margin:4px 0 0;color:var(--on-island-muted);font-size:12px;}
.profile-hero-avatar{
  width:52px;height:52px;flex:none;display:grid;place-items:center;border-radius:16px;
  background:linear-gradient(135deg,var(--accent),#c08bff);color:#fff;
  font:700 20px var(--display);box-shadow:0 12px 26px rgba(145,70,255,.26);
}
.profile-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--card-gap);align-items:start;}
/* Поле ввода не растягивается во всю ширину карточки: строка ввода длиной в
   700px не читается как поле, а пароль в неё всё равно вводят в 20 символов. */
.profile-form .fld input{max-width:520px;}
.profile-form{display:flex;flex-direction:column;gap:16px;}
.profile-form .card-head{margin-bottom:0;}
.form-icon{width:36px;height:36px;flex:none;display:grid;place-items:center;border-radius:var(--r-md);background:var(--purple-50);color:var(--accent-strong);}
.profile-password-fields{display:flex;flex-direction:column;gap:12px;}
.profile-form-foot{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-top:auto;padding-top:2px;}
.profile-form-foot>span{color:var(--muted-2);font-size:10.5px;line-height:1.4;}
.form-message{padding:10px 12px;border-radius:var(--r-md);font-size:12px;line-height:1.4;}
.form-message.success{background:var(--ok-surface);color:var(--ok);}
.form-message.error{background:var(--danger-surface);color:var(--danger);}

/* Фокус-кольцо админки: подложка цветом фона + акцент, без сдвига раскладки. */
:where(a,button,input,[tabindex]):focus-visible{outline:none;box-shadow:0 0 0 2px var(--bg),0 0 0 4px var(--accent);border-radius:6px;}

/* ---------- панель раздела ---------- */
/* Период уехал из шапки приложения сюда: элемент управления должен стоять рядом
   с тем, что он меняет, а не в глобальной панели над всем подряд. */
.toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;}

.toolbar .tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}

/* ---------- таблица ---------- */
.tblwrap{overflow-x:auto;}
.tbl{width:100%;border-collapse:collapse;font-size:12.5px;}
/* Шапка НЕ липкая и таблица не прокручивается внутри себя: вложенный скролл в
   карточке перехватывал колесо и терял место в списке. Страница скроллится
   целиком, таблица — просто длинная.

   Метрики шапки и строк — как у `.tbl` в admin/peakcut.css: заливки нет,
   разделитель снизу, трекинг .1em. */
.tbl th{
  padding:0 14px 11px;text-align:left;white-space:nowrap;
  color:var(--muted-2);font:600 11px var(--sans);
  letter-spacing:.1em;text-transform:uppercase;
  border-bottom:1px solid var(--line-soft);
}
/* Сортировка по клику: при 50 аккаунтах «глазами найти нужный» не работает. */
.tbl th[data-sort]{cursor:pointer;user-select:none;}
.tbl th[data-sort]:hover{color:var(--text);}
.tbl th[data-sort]::after{content:"";display:inline-block;width:0;height:0;margin-left:6px;vertical-align:middle;border:4px solid transparent;}
.tbl th[data-sort][aria-sort="descending"]::after{border-top-color:var(--accent);margin-bottom:-3px;}
.tbl th[data-sort][aria-sort="ascending"]::after{border-bottom-color:var(--accent);margin-top:-3px;}
.tbl tr[hidden]{display:none;}

.tbl td{padding:12px 14px;border-bottom:1px solid var(--line-soft);vertical-align:middle;}
.tbl tbody tr:last-child td{border-bottom:none;}
.tbl tbody tr{transition:background var(--dur-micro) var(--ease-standard);}
.tbl tbody tr:hover{background:var(--surface-2);}
/* Шапка карточки-таблицы (Accounts, В-7): заголовок и подпись слева, поиск и выгрузка
   справа — те же .card-title/.card-sub, что у карточек обзора, только с отступами
   карточки и разделителем снизу, потому что тело здесь — таблица без внутренних полей. */
/* Шапка карточки-списка (В-14): те же заголовок и подпись, что у .tbl-head, но без
   разделителя — тело начинается строками, у которых своя волосина. */
.list-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:var(--card-pad-roomy) var(--card-pad-roomy) 6px;}
/* Ссылка «All N →» — тихая пилюля: одна на карточку, в шапке. */
.link-pill{flex:none;display:inline-flex;align-items:center;min-height:28px;padding:0 12px;border:1px solid var(--line-soft);border-radius:999px;color:var(--muted-2);font:600 11.5px var(--sans);white-space:nowrap;transition:color var(--dur-micro) var(--ease-standard),border-color var(--dur-micro) var(--ease-standard);}
.link-pill:hover{color:var(--accent-strong);border-color:var(--control-line);}
.tbl-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:var(--card-pad) var(--card-pad-roomy);border-bottom:1px solid var(--line-soft);}
.tbl-head .tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
/* Шапка таблицы (В-39): поиск и действие — пилюли 32px, того же семейства, что чипы ниже. */
.tbl-head .searchbox,.tbl-head .btn{height:32px;border-radius:999px;border-color:var(--line-soft);}
.tbl-head .searchbox{padding:0 14px;}
.tbl-head .searchbox input{font-size:12px;}
.tbl-head .btn{padding:0 14px;font-size:12px;}

/* ---------- полоса управления списком под шапкой таблицы (В-36, В-37, В-39) ----------
   Сортировка, фильтры и список — одно семейство чипов на фоне --surface-1 (чуть серее
   белого): полоса не спорит с карточкой. Активный чип — салатовым, как пункт сайдбара, неактивный — как чип
   шапки (28px, 11.5/600, радиус 999). */
.filter-row{display:flex;align-items:center;gap:8px 6px;flex-wrap:wrap;padding:10px var(--card-pad-roomy);border-bottom:1px solid var(--line-soft);background:var(--surface-1);}
.filter-row .lbl{margin-right:2px;color:var(--muted-2);font:700 10px var(--sans);letter-spacing:.12em;text-transform:uppercase;}
.filter-sep{width:1px;height:18px;margin:0 4px;background:var(--line);}
/* Группа «подпись + чипы»: на десктопе прозрачна для раскладки, на телефоне — строка со свайпом (В-42). */
.fgroup{display:contents;}
.fchip{display:inline-flex;align-items:center;gap:6px;min-height:28px;padding:0 10px;border:1px solid var(--line-soft);border-radius:999px;background:var(--surface);color:var(--muted);font:600 11.5px var(--sans);white-space:nowrap;cursor:pointer;transition:color var(--dur-micro) var(--ease-standard),border-color var(--dur-micro) var(--ease-standard);}
.fchip b{color:var(--text);font-weight:700;}
.fchip:hover{color:var(--text);border-color:var(--control-line);}
/* Выбранный чип — как активный пункт сайдбара: салатовая заливка и кромка на токенах selection. */
.fchip.active{background:var(--selection-surface);border-color:var(--selection-line);color:var(--selection-text);}
.fchip.active b{color:var(--selection-text);}
.fchip.clear{border-style:dashed;}
.fchip .dir{font-size:10px;color:var(--selection-strong);}
.fsel{position:relative;display:inline-flex;align-items:center;}
.fsel select{appearance:none;-webkit-appearance:none;min-height:28px;padding:0 28px 0 12px;border:1px solid var(--line-soft);border-radius:999px;background:var(--surface);color:var(--text);font:600 11.5px var(--sans);cursor:pointer;}
.fsel select:focus{outline:none;border-color:var(--control-line);box-shadow:0 0 0 3px var(--accent-ghost);}
.fsel::after{content:"";position:absolute;right:12px;top:50%;width:6px;height:6px;border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);transform:translateY(-70%) rotate(45deg);pointer-events:none;}

/* Подвал подгрузки (В-35): «Showing 25 of 156» и кнопка-запас. */
.tbl-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px var(--card-pad-roomy);border-top:1px solid var(--line-soft);color:var(--muted-2);font-size:11.5px;}
.tbl-foot b{color:var(--text);}
.btn.small{height:32px;padding:0 14px;font-size:12px;border-radius:999px;}
/* Семантика колонки — по наведению на заголовок: пунктир под словом, не иконка. */
.tbl th[title]{text-decoration:underline dotted;text-decoration-color:var(--line);text-underline-offset:4px;}
/* Группа строк другой площадки (YouTube) — своим tbody под тихим разделителем; фильтр
   прячет группу целиком, когда в ней ничего не совпало. */
.tbl tbody[hidden]{display:none;}
.tbl tr.group-row td{padding:6px 14px;background:var(--surface-2);color:var(--muted-2);font:600 10px var(--sans);letter-spacing:.1em;text-transform:uppercase;border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft);}
.tbl tbody tr.group-row:hover{background:transparent;}
.tbl tbody+tbody tr:last-child td{border-bottom:none;}
.tbl .num{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums;white-space:nowrap;}
.tbl .num.strong{font-weight:750;}
.tbl .muted{color:var(--muted-2);}
.cell-title{display:flex;align-items:center;gap:8px;min-width:0;}
/* Заголовок поста — до ДВУХ строк: в одну из «An average cumulus cloud weighs
   around 500 tons — about 100 elephants…» оставалось «…about 10…», и таблица
   постов перестала отвечать на «какой это пост». Ограничение по ширине остаётся:
   иначе заголовок отжимает колонки величин. */
.cell-title .tt{
  max-width:min(38vw,380px);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.cell-thumb{
  width:30px;height:40px;flex:none;border-radius:var(--r-sm);overflow:hidden;position:relative;
  display:grid;place-items:center;
  background:linear-gradient(150deg,rgba(145,70,255,.16),rgba(83,252,24,.10));
  color:var(--muted);font:750 12px var(--display);
}
.cell-thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;}
.acc-cell{display:inline-flex;align-items:center;gap:7px;color:var(--muted);white-space:nowrap;}
.acc-cell b{color:var(--text);font-weight:650;}
.tbl tr[data-href]{cursor:pointer;}
/* Таблица v2 (.tbl-v2: Accounts, Posts карточки аккаунта) — ПОСЛЕ всех базовых правил
   .tbl (th, td, .num, .why): специфичность равная, побеждает порядок. Числа по левому
   краю шрифтом брендбука, слова в числовых ячейках — Inter, длинные метки переносятся. */
.tbl-v2 .trend{display:block;margin-top:2px;}
/* Воздух в ячейках: 16px по горизонтали, крайние колонки — на отступ карточки, чтобы
   текст стоял на одной вертикали с заголовком карточки; шапке таблицы — верхний отступ. */
.tbl-v2 th{padding:14px 12px 10px;}
.tbl-v2 td{padding:12px 12px;}
.tbl-v2 th:first-child,.tbl-v2 td:first-child{padding-left:var(--card-pad-roomy);}
.tbl-v2 th:last-child,.tbl-v2 td:last-child{padding-right:var(--card-pad-roomy);}
/* Ширины колонок Accounts — долями карточки, раскладка фиксированная: таблица не
   растёт от содержимого и не уезжает за карточку. Posts широкая, чтобы
   «28 posted · 0 measured» не переносилось; US share — причина словами в две строки.
   Только на десктопе: на узких экранах колонки .m-hide скрыты и доли не сходятся. */
@media (min-width:1080px){
  .acc-table{table-layout:fixed;}
  .acc-table .c-account{width:18%;}
  .acc-table .c-status{width:13%;}
  .acc-table .c-followers{width:10%;}
  .acc-table .c-views{width:12%;}
  .acc-table .c-last{width:9%;}
  .acc-table .c-posts{width:16%;}
  .acc-table .c-leads{width:10%;}
  .acc-table .c-us{width:12%;}
}
.tbl-v2 td .why{max-width:150px;}
/* Числа — по левому краю, как текст: при фиксированных долях колонок правый край
   уводил числа далеко от заголовков, и Followers/Views читались вразнобой. Тренд —
   в строку с числом, а не под ним: строка ниже, таблица плотнее. */
.tbl-v2 th.num,.tbl-v2 td.num{text-align:left;}
/* Цифры — шрифтом цифр брендбука (Avenir Next, табличные), а не моно из админки:
   уже и спокойнее, «28 posted · 0 measured» помещается в свою долю. Ячейка может
   переноситься, само число — нет: в тесноте тренд уходит под число, а не за край. */
.tbl-v2 td.num{font-family:var(--display);font-size:13px;}
.acc-table td.num{white-space:normal;}
.tbl-v2 td.num b{white-space:nowrap;font-weight:650;}
.tbl-v2 td.num .why{margin-left:0;text-align:left;}
.tbl-v2 .trend{display:inline;margin:0 0 0 6px;vertical-align:1px;}
/* Слова в числовых ячейках — причины и подписи слоя — текстовым шрифтом, не моно:
   «Instagram gives no post stats» в моноширинном читалось как код. */
.tbl-v2 td.num .why,.tbl-v2 td.num .muted{font-family:var(--sans);}
/* Вторая строка ячейки аккаунта: значок площадки и слово, дата подключения — под
   ником, на его вертикали (аватар 26 + зазор 7). */
.tbl-v2 .acc-meta{display:flex;align-items:center;gap:5px;max-width:none;margin:4px 0 0;white-space:nowrap;}
/* Длинные статусы («Audience mix unknown», «Not tracked for YouTube») переносятся,
   а не лезут в соседнюю колонку: метка тихая, вторая строка ей не вредит. */
.tbl-v2 .status{white-space:normal;align-items:flex-start;line-height:1.3;}
.tbl-v2 .status .sdot{margin-top:5px;}
.tbl-v2 .acc-meta .picon{flex:none;}
/* Таблица Posts карточки аккаунта (В-21): семь колонок, заголовок поста в одну строку,
   дата второй строкой, разбивка реакций — по наведению. */
@media (min-width:1080px){
  .posts-table{table-layout:fixed;}
  .posts-table .c-post{width:36%;}
  .posts-table .c-views{width:10%;}
  .posts-table .c-viewers{width:10%;}
  .posts-table .c-react{width:10%;}
  .posts-table .c-follows{width:9%;}
  .posts-table .c-watch{width:9%;}
  .posts-table .c-stats{width:16%;}
}
.posts-table .cell-text{min-width:0;display:flex;flex-direction:column;gap:2px;}
.posts-table .cell-text .tt-row{display:flex;align-items:center;gap:8px;min-width:0;}
.posts-table .cell-text .tt{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;min-width:0;}
.posts-table .cell-text .chip.ours{flex:none;}
.posts-table td .why{max-width:none;}
.posts-table .layer{white-space:normal;}
/* Таблица Videos (В-27): шесть колонок, «uploaded · posted to» одной строкой под названием. */
@media (min-width:1080px){
  .videos-table{table-layout:fixed;}
  .videos-table .c-video{width:38%;}
  .videos-table .c-views{width:14%;}
  .videos-table .c-react{width:13%;}
  .videos-table .c-follows{width:9%;}
  .videos-table .c-us{width:12%;}
  .videos-table .c-stats{width:14%;}
}
.videos-table .cell-text{min-width:0;display:flex;flex-direction:column;gap:2px;}
.videos-table .cell-text .tt{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;}
.videos-table td .why{max-width:none;}
.videos-table .layer{white-space:normal;}
/* В шторке ролика полоса реакций ужата: пять плиток на 680px. */
.drawer .react-strip{gap:8px;}
.drawer .react-strip .now-tile .v{font-size:17px;}
.drawer .react-foot{padding:0 0 var(--card-pad);}
.by-account-table td .why{max-width:none;}

/* ---------- таблицы на телефоне: приоритет колонок ----------
   Горизонтальный скролл — страховка, а не способ читать таблицу: на ≤720
   второстепенные колонки (.m-hide) прячутся, а их контекст (аккаунт, дата,
   подписчики) переезжает подстрокой .m-sub в первую ячейку. Сортировка
   по индексу колонки живёт: display:none не меняет порядок children. */
.m-sub{display:none;}
@media (max-width:720px){
  .tbl .m-hide{display:none;}
  .m-sub{display:block;color:var(--muted-2);font-size:10.5px;line-height:1.4;margin-top:3px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
  /* Подстрока встаёт под текст, а не под миниатюру/аватар. */
  .tbl td .cell-title + .m-sub{margin-left:38px;}
  .tbl td .acc-cell + .m-sub{margin-left:33px;}
  /* Заголовку поста — фиксированный потолок: вместе с чипом «ours» и одной
     числовой колонкой строка обязана влезать в 375px без скролла. */
  .cell-title .tt{max-width:44vw;}
}

/* ---------- шаги обработки ---------- */

.step{display:flex;flex-direction:column;align-items:center;gap:6px;flex:none;width:88px;text-align:center;}

.step .lb{color:var(--muted-2);font-size:10.5px;line-height:1.3;}
.step.done .lb,.step.active .lb{color:var(--text);font-weight:600;}

/* ---------- загрузка ---------- */

.dropzone{
  /* Это <button>: без width:100% он ужимается по содержимому и зона промаха
     оказывается вдвое уже колонки. */
  width:100%;
  display:flex;flex-direction:column;align-items:center;gap:9px;padding:38px 24px;text-align:center;
  border:2px dashed var(--line);border-radius:var(--r-xl);background:var(--surface);cursor:pointer;
  transition:border-color var(--dur-micro) var(--ease-standard),background var(--dur-micro) var(--ease-standard);
}
/* .drag ставит остров upload-box.js при перетаскивании файла. */
.dropzone:hover,.dropzone.drag{border-color:var(--accent);background:var(--purple-50);}
.dropzone .ico{width:52px;height:52px;display:grid;place-items:center;border-radius:var(--r-sm);background:var(--purple-50);color:var(--accent-strong);}
.dropzone .h{font:750 15px var(--display);}
.dropzone .p{color:var(--muted-2);font-size:12px;line-height:1.55;max-width:420px;}

.progress{height:7px;border-radius:99px;background:var(--surface-2);overflow:hidden;}
.progress>i{display:block;height:100%;border-radius:99px;background:var(--accent);transition:width var(--dur-panel) var(--ease-standard);}
.upload-batch{margin-top:12px;padding:var(--card-pad-roomy);display:flex;flex-direction:column;gap:16px;}
.upload-batch-head,.upload-batch-actions{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;}
.upload-batch-head>div{display:flex;min-width:0;flex-direction:column;gap:3px;}
.upload-batch-head b{font:700 14px var(--display);}
.upload-batch-head span,.upload-batch-actions>span{color:var(--muted-2);font-size:11.5px;line-height:1.45;}
.upload-file-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;}
.upload-file{
  display:grid;grid-template-columns:46px minmax(0,1fr);gap:11px;align-items:center;
  min-height:78px;padding:10px;border:1px solid var(--line-soft);border-radius:var(--r-md);
  background:var(--surface-2);overflow:hidden;
}
.upload-file.is-ok{border-color:var(--ok);background:var(--ok-surface);}
.upload-file.is-error{border-color:var(--danger);background:var(--danger-surface);}
.upload-file-thumb{width:46px;height:58px;object-fit:cover;border-radius:8px;background:var(--surface-3);}
.upload-file-main{display:flex;min-width:0;flex-direction:column;gap:5px;}
.upload-file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-weight:650;}
.upload-file-state{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--muted-2);font-size:10.5px;}
.upload-file.is-ok .upload-file-state{color:var(--ok);}
.upload-file.is-error .upload-file-state{color:var(--danger);}
.upload-file .progress{height:5px;}
.upload-file.is-ok .progress>i{background:var(--ok);}
.upload-file.is-error .progress>i{background:var(--danger);}

/* Выбор типа загрузки — две карточки-радио (В-30): иконка, имя, «что мы с этим сделаем»,
   форматы и лимит; выбранная обведена акцентом. */
.kind-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--card-gap);margin-bottom:var(--card-gap);}
.kind-card{position:relative;display:flex;gap:14px;align-items:flex-start;padding:18px var(--card-pad-roomy);border:1px solid var(--surface-card-line);border-radius:var(--r-panel);background:var(--surface-card-strong);box-shadow:var(--shadow-card),inset 0 1px 0 var(--glass-line);cursor:pointer;transition:border-color var(--dur-micro) var(--ease-standard),box-shadow var(--dur-micro) var(--ease-standard);}
.kind-card:hover{border-color:var(--control-line);}
.kind-card input{position:absolute;opacity:0;pointer-events:none;}
.kind-card:has(input:checked){border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),var(--shadow-card);}
.kind-card:has(input:disabled){cursor:default;opacity:.7;}
.kind-card .kc-ico{width:40px;height:40px;flex:none;display:grid;place-items:center;border-radius:var(--r-lg);background:var(--purple-50);color:var(--accent-strong);}
.kind-card .kc-body{display:flex;flex-direction:column;gap:4px;min-width:0;padding-right:28px;}
.kind-card .kc-title{font:700 15px/1.2 var(--display);letter-spacing:-.01em;}
.kind-card .kc-text{font-size:12.5px;line-height:1.45;color:var(--text);}
.kind-card .kc-meta{font-size:11.5px;color:var(--muted-2);}
.kind-card .kc-radio{position:absolute;right:16px;top:18px;width:16px;height:16px;border-radius:50%;border:1.5px solid var(--line);background:var(--surface);}
.kind-card:has(input:checked) .kc-radio{border:5px solid var(--accent);}
.upload-wrap .dropzone{margin-bottom:var(--card-gap);}
.hist-rows{display:flex;flex-direction:column;}
.hist-item{display:flex;align-items:center;gap:12px;padding:12px var(--card-pad-roomy);border-top:1px solid var(--line-soft);}
.hist-item .fname .chip.kind{margin-left:6px;vertical-align:1px;}
.hist-item .fico{width:36px;height:36px;flex:none;display:grid;place-items:center;border-radius:6px;background:var(--surface-2);color:var(--muted);}
.hist-item .fmid{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
.hist-item .fname{font-size:12.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.hist-item .fmeta{color:var(--muted-2);font-size:11px;}

/* ---------- пустое состояние: ОДИН компонент, три размера (В-31) ----------
   Макрос empty_state в ui.html. Размеры: .page — карточка сама по себе и в стекле;
   .in-card — внутри карточки, списка, таблицы; .on-island — на острове (график без
   точек, остров аккаунта без замеров), чёрточка-градиент вместо иконки. */
.empty{display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;}
.empty .ico{display:grid;place-items:center;border-radius:var(--r-md);background:var(--purple-50);color:var(--accent-strong);}
.empty .h{font:750 17px/1.2 var(--display);letter-spacing:-.02em;}
.empty .p{max-width:420px;color:var(--muted);font-size:12.5px;line-height:1.6;}
.empty .when{color:var(--muted-2);font:10.5px var(--mono);}
.empty .foot{margin-top:4px;color:var(--muted-2);font-size:11px;}
.empty .btn{margin-top:4px;}
.empty.page{gap:10px;padding:40px 28px 34px;border:1px solid var(--surface-card-line);border-radius:var(--r-panel);background:var(--surface);box-shadow:var(--shadow-card);}
.empty.page .ico{width:52px;height:52px;border-radius:var(--r-xl);}
.empty.page .h{font-size:19px;}
.empty.in-card{padding:22px 16px;}
.empty.in-card .ico{width:36px;height:36px;}
.empty.in-card .h{font-size:13.5px;}
.empty.in-card .p{font-size:11.5px;max-width:360px;}
/* В таблице пустое состояние стоит в единственной строке без линии сверху. */
.tbl tr.empty-row>td{padding:0;border-top:none;}
.tbl tr.empty-row .empty.in-card{padding:28px 16px;}
.empty.on-island{flex:1;justify-content:center;gap:10px;padding:30px 24px;max-width:440px;margin:0 auto;}
.empty.on-island .mark{width:42px;height:5px;border-radius:99px;background:linear-gradient(90deg,var(--accent),var(--signal));box-shadow:0 0 26px var(--island-glow-violet);}
.empty.on-island .p{color:var(--on-island-muted);font-size:12px;}
.empty.on-island .when{color:var(--on-island-faint);}

/* ---------- стекло пустого экрана (В-31) ----------
   Под стеклом — настоящая раскладка на образцах (aria-hidden, inert), ростом в один
   вьюпорт, чтобы страница не скроллилась; поверх — размытие с бликом и карточка
   сообщения по центру ОБЛАСТИ КОНТЕНТА (не экрана: сайдбар не в счёт). */
.glass-scope{position:relative;overflow:hidden;border-radius:var(--r-panel);min-height:560px;
  height:calc(100dvh - var(--topbar-height) - var(--shell-gutter) * 2 - var(--card-gap));
  /* Запас контейнера под док (--tabbar-clear) стеклу не нужен: иначе пустой экран
     скроллится на 60px ради пустоты под ним. Низ стекла — на нижнем поле оболочки. */
  margin-bottom:calc(var(--shell-gutter) - var(--tabbar-clear));}
.glass-scope>.screen{pointer-events:none;user-select:none;}
.glass{position:absolute;inset:0;z-index:5;border-radius:var(--r-panel);overflow:hidden;
  background:linear-gradient(135deg,rgba(255,255,255,.62),rgba(255,255,255,.34) 55%,rgba(246,240,255,.5));
  border:1px solid var(--glass-line);box-shadow:inset 0 1px 0 rgba(255,255,255,.95),var(--shadow-low);
  backdrop-filter:blur(18px) saturate(140%);-webkit-backdrop-filter:blur(18px) saturate(140%);}
.glass::before{content:"";position:absolute;left:-10%;top:-40%;width:70%;height:90%;border-radius:50%;
  background:radial-gradient(closest-side,rgba(255,255,255,.75),rgba(255,255,255,0));transform:rotate(-12deg);pointer-events:none;}
.glass::after{content:"";position:absolute;right:-15%;bottom:-45%;width:60%;height:80%;border-radius:50%;
  background:radial-gradient(closest-side,var(--island-glow-violet),rgba(145,70,255,0));pointer-events:none;}
/* Без backdrop-filter стекло становится почти глухим: образцы под ним читаться не должны. */
@supports not (backdrop-filter:blur(1px)){.glass{background:var(--glass-strong);opacity:.98;}}
.glass .empty.page{position:absolute;z-index:2;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(480px,calc(100% - 40px));background:var(--glass-strong);border-color:var(--glass-line);box-shadow:var(--shadow-overlay);}

/* ---------- ожидание аналитики ----------
   Силуэт реального дашборда остаётся позади сообщения: экран не выглядит пустым,
   но blur + отсутствие чисел не выдают placeholder за собранные данные. */

.infobar{display:flex;align-items:center;gap:10px;padding:11px 15px;border:1px solid var(--surface-card-line);border-radius:var(--r-lg);background:var(--surface-card);color:var(--muted);font-size:12px;line-height:1.5;}
.infobar svg{flex:none;color:var(--muted-2);}

.backlink{display:inline-flex;align-items:center;gap:6px;color:var(--muted-2);font-size:11.5px;font-weight:600;}
.backlink:hover{color:var(--accent-strong);}

/* ---------- шапка аккаунта (остров) ---------- */
.acc-hero{display:flex;flex-direction:column;gap:18px;}
.acc-hero-id{display:flex;align-items:center;gap:13px;}
.acc-hero-name{min-width:0;flex:1;}
/* Ник обрезается многоточием, а не уезжает за край: на 375px рядом с плашкой
   54px и чипом «Open profile» ему остаётся 180px. */
.acc-hero-id .hn{font:800 21px/1.1 var(--display);letter-spacing:-.03em;color:var(--on-island);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.acc-hero-id .hs{display:flex;align-items:center;gap:6px;margin-top:3px;color:var(--on-island-muted);font-size:11.5px;}
/* Пять плиток KPI внутри острова карточки аккаунта (В-19, В-21): тот же .kpi-row, что на
   обзоре и над таблицей Accounts, на токенах острова — углубление, а не стекло поверх. */
/* .kpi-row.hero-kpi — с двумя классами: базовый .kpi-row стоит ниже по файлу и на равной
   специфичности перебивал бы пять колонок своими четырьмя. */
.kpi-row.hero-kpi{grid-template-columns:repeat(5,minmax(0,1fr));border:1px solid var(--island-line);border-radius:var(--r-lg);background:var(--island-raise);}
.kpi-row.hero-kpi>div{padding:14px 16px;border-left:1px solid var(--island-line);}
.kpi-row.hero-kpi>div:first-child{border-left:none;}
.hero-kpi .l{color:var(--on-island-faint);}
.hero-kpi .v{font-size:24px;color:var(--on-island);}
.hero-kpi .v.muted{color:var(--on-island-faint);}
.hero-kpi .foot{color:var(--on-island-faint);}
/* Карточка поста: шесть плиток (В-24) и герой-ролик — обложка 54×72, название до двух
   строк, аккаунт второй строкой; чипы действий справа. */
.kpi-row.hero-kpi.six{grid-template-columns:repeat(6,minmax(0,1fr));}
.kpi-row.hero-kpi.six .v{font-size:22px;}
.post-hero-id{align-items:center;}
.post-cover{position:relative;width:54px;height:72px;flex:none;border-radius:var(--r-lg);overflow:hidden;background:var(--ink-raised);box-shadow:inset 0 0 0 1px rgba(15,23,42,.1);}
.post-cover img{width:100%;height:100%;object-fit:cover;display:block;}
.post-cover .ph{position:absolute;inset:0;display:grid;place-items:center;background:linear-gradient(150deg,rgba(145,70,255,.3),rgba(83,252,24,.14));color:var(--text);font:800 18px var(--display);}
.acc-hero-id .hn.post-hn{font-size:19px;line-height:1.25;white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;}
.acc-hero-id .hs a{color:inherit;font-weight:600;}
.acc-hero-id .hs a:hover{color:var(--accent-strong);}
.hero-acts{margin-left:auto;flex:none;display:flex;gap:8px;align-items:center;}
.hero-acts .chip{white-space:nowrap;}
@media (max-width:1079px){.kpi-row.hero-kpi.six{grid-template-columns:repeat(3,minmax(0,1fr));}}
@media (max-width:1079px){
  .kpi-row.hero-kpi{grid-template-columns:repeat(2,minmax(0,1fr));}
  .kpi-row.hero-kpi>div{border-left:none;border-top:1px solid var(--island-line);}
  .kpi-row.hero-kpi>div:nth-child(-n+2){border-top:none;}
  .kpi-row.hero-kpi>div:nth-child(even){border-left:1px solid var(--island-line);}
}
/* Реакции аккаунта — полосой из пяти плиток на всю ширину карточки (В-21). */
.react-strip{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;padding:6px var(--card-pad-roomy) 0;}
.react-foot{padding:12px var(--card-pad-roomy) var(--card-pad-roomy);}
.list-head .coverage{margin-top:2px;text-align:right;max-width:40%;}
@media (max-width:1079px){.react-strip{grid-template-columns:repeat(2,minmax(0,1fr));}}

/* Статусы аккаунта словами в острове (волна 3): метка и подпись рядом, одной строкой. */
.hero-statuses{display:flex;flex-wrap:wrap;gap:8px 22px;}
.hero-status{display:inline-flex;align-items:baseline;gap:8px;}
.hero-status .status{color:var(--on-island);}
.hero-status .status.quiet{color:var(--on-island-muted);}
.hero-status .hs{color:var(--on-island-faint);font-size:11px;}

/* Дельта на тёмном: светлые ok-surface/danger-surface на острове превращались в
   светящиеся плашки. Цвета — из тёмной половины токенов. */
.island .delta.up{background:rgba(74,222,128,.15);color:var(--ok-on-dark);}
.island .delta.down{background:rgba(255,122,130,.16);color:var(--danger-on-dark);}
.island .delta.flat{background:var(--island-raise);color:var(--on-island-faint);}

/* ---------- тост ---------- */
.toast{position:fixed;left:50%;bottom:28px;z-index:300;transform:translateX(-50%);padding:11px 18px;border-radius:11px;background:var(--ink);color:var(--white);font-size:12.5px;font-weight:600;box-shadow:var(--shadow-overlay);animation:toastIn .22s var(--ease-enter) both;}

/* ---------- ритм рядов списков обзора ----------
   В ленте (итерация 2) высоту списка задаёт содержимое, и шаг ряда держит
   ВОЛОСИНА между строками: список читается как таблица, а не как россыпь.
   Подсветка ховера вылетает за текст ряда на 8px в обе стороны, поэтому ряд
   отодвинут внутрь карточки ровно на эти же 8px — текст стоит на одной
   вертикали с заголовком и подвалом (--card-pad-roomy). */
/* Список v2 (В-16): строка 56px, ховер-подложка вылетает за текст на 12px, и ровно на
   них ряд отодвинут внутрь карточки (8px контейнера + 12px ряда = 20px = --card-pad-roomy). */
.reel-rows,.acc-scroll{display:flex;flex-direction:column;padding:0 8px 10px;}
/* Одна высота строки у всех списков ряда: у роликов заголовок в две строки задаёт 64px,
   строки аккаунтов и лидов подтягиваются к ним — иначе карточки ряда кончаются на
   разной высоте, и под короткими остаётся пустота. */
.acc-item,.reel-row{padding:8px 12px;min-height:64px;gap:12px;border-radius:var(--r-md);}
.reel-row{display:flex;align-items:center;transition:background var(--dur-micro) var(--ease-standard);}
.reel-row:hover{background:var(--surface-2);}
.reel-rows>*+*,.acc-scroll>*+*{box-shadow:0 -1px 0 var(--line-soft);}
.reel-row.top1 .acc-rank{color:var(--text);}
.rthumb{
  position:relative;width:32px;height:46px;flex:none;border-radius:var(--r-sm);overflow:hidden;
  background:var(--ink-raised);box-shadow:inset 0 0 0 1px rgba(15,23,42,.1);
}
.rthumb img{width:100%;height:100%;object-fit:cover;}
.rthumb .ph{
  position:absolute;inset:0;display:grid;place-items:center;
  background:linear-gradient(150deg,rgba(145,70,255,.3),rgba(83,252,24,.14));
  color:var(--text);font:800 14px var(--display);
}
/* Заголовок рилса — РОВНО две строки, всегда. В одну строку с обрезкой из
   «An average cumulus cloud weighs around 500 tons — about 100 elephants…»
   оставалось «An average cumulus clo…», то есть ни одного факта. А место под
   вторую строку держится и когда заголовок короткий: иначе соседние ряды одного
   списка имели бы разную высоту содержимого и разъезжались бы по вертикали. */
.reel-row .nm{
  font-size:12.5px;font-weight:650;line-height:1.32;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  min-height:calc(2em * 1.32);
}
.reel-row .sub{color:var(--muted-2);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* У публикаций за сутки заголовки короткие: резерв под вторую строку оставлял дыру
   между названием и подписью. Резерв — только у топа роликов. */
[data-last24] .reel-row .nm{min-height:0;}
/* Правая колонка величин — общая с .acc-item: величина крупно, единица мелко и
   приглушённо, вторая строка мельче. Одно правило для всех списков дашборда. */
.rvals{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:1px;}
.rvals .val{font:750 14px var(--display);letter-spacing:-.01em;font-variant-numeric:tabular-nums;white-space:nowrap;}
.rvals .val small{color:var(--muted-2);font:600 10px var(--sans);letter-spacing:0;}
.rvals .sub2{color:var(--muted-2);font-size:10.5px;white-space:nowrap;}

/* ---------- раскладка обзора (итерация 2: лента из прототипа) ----------
   Три такта сверху вниз: KPI-ряд одной карточкой, график с «сейчас на странице»,
   тройка карточек «кто везёт». Обзор скроллится, как обычная страница, — прежняя
   fit-сетка «ровно в один вьюпорт» ушла вместе с требованием вмещаться.

   Классы .cell-accounts/.cell-leads/.cell-reels остались именами КАРТОЧЕК
   обзора (не мест в сетке): на них висят контейнерные запросы узкой карточки. */

/* KPI-ряд: ОДНА карточка, четыре величины, разделители-волосины. Плитка —
   подпись мелким капсом, число крупно, дельта/уточнение снизу. */
.kpi-row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));}
.kpi-row>div{
  display:flex;flex-direction:column;gap:6px;min-width:0;
  padding:18px var(--card-pad-roomy);
  border-left:1px solid var(--line-soft);
}
.kpi-row>div:first-child{border-left:none;}
.kpi-row .l{display:flex;align-items:center;gap:7px;color:var(--muted);font:700 10px var(--sans);letter-spacing:.12em;text-transform:uppercase;white-space:nowrap;overflow:hidden;}
.kpi-row .l svg{flex:none;color:var(--muted-2);}
.kpi-row .v{font:700 28px/1.05 var(--display);letter-spacing:-.03em;font-variant-numeric:tabular-nums;}
.kpi-row .foot{display:flex;align-items:center;gap:7px;min-height:18px;color:var(--muted-2);font-size:10.5px;line-height:1.35;}
@media (max-width:1079px){
  /* В две колонки те же волосины: вертикальные — внутри пары, горизонтальные —
     между парами. Кегль держится: в 165px помещается и число, и подпись. */
  .kpi-row{grid-template-columns:repeat(2,minmax(0,1fr));}
  .kpi-row>div{border-left:none;border-top:1px solid var(--line-soft);}
  .kpi-row>div:nth-child(-n+2){border-top:none;}
  .kpi-row>div:nth-child(even){border-left:1px solid var(--line-soft);}
}

/* Ряд 2: остров графика стоит на всю ширину ряда — соседа-карточки у него
   нет (живого «прямо сейчас» API не отдаёт, охват за период дублировал бы
   график; см. комментарий в dashboard.html). */

/* Ряд 3: тройка «кто везёт». Географии — шире списков: карта мира требует
   ширины, а списку хватает своей колонки. */
.dash-trio{display:grid;gap:var(--card-gap);grid-template-columns:repeat(3,minmax(0,1fr));align-items:stretch;}
/* Ряд 4: публикации за сутки шириной в две карточки тройки, YouTube — в одну (В-13);
   без каналов список занимает всю ширину. */
.dash-duo{display:grid;gap:var(--card-gap);grid-template-columns:minmax(0,2fr) minmax(0,1fr);align-items:start;}
.dash-duo.solo{grid-template-columns:minmax(0,1fr);}
.dash-duo>.card{display:flex;flex-direction:column;min-width:0;}
.dash-trio>.card{display:flex;flex-direction:column;min-width:0;}
@media (max-width:1079px){
  .dash-trio,.dash-duo{grid-template-columns:minmax(0,1fr);}
}

/* container-type — чтобы контейнерные запросы ниже мерили шириной СВОЕЙ
   карточки: в тройке списку достаётся треть строки, и на 1120px это ~270px,
   а вьюпорт об этом молчит. */
.cell-accounts,.cell-reels{overflow:hidden;container-type:inline-size;}
.cell-accounts .acc-item{gap:11px;}
/* Лидерборд топ-аккаунтов: ранг-чип вместо сравнительной полосы — полоса
   визуализировала, насколько остальные отстают от лидера, и владелец её
   забраковал. Топ-1 подсвечен selection-поверхностью (зелёный = «лучшее»). */
/* Ранг — цифра без рамки (В-16): рамки у второстепенного шумели; первый темнее. */
.acc-rank{width:14px;flex:none;text-align:center;color:var(--muted-2);font:700 12px var(--display);font-variant-numeric:tabular-nums;}
.acc-item.top1 .acc-rank{color:var(--text);}
/* Хвост списка лидов: «Other N accounts» — тихая строка с плашкой «+N». */
.acc-item.rest .nm,.acc-item.rest .rvals .val{color:var(--muted-2);font-weight:600;}

.acc-item .sub2{color:var(--muted-2);font-size:10.5px;white-space:nowrap;}
/* Средняя карточка тройки — «Leads by account» (с 12.09; до того — география, ушедшая
   с обзора по решению П-8). Столбик долей во всю ширину, карты нет. */
.cell-leads{display:flex;flex-direction:column;overflow:hidden;container-type:inline-size;}

/* Узкая карточка списка: вторая строка величин («366.2K people reached» — 127px
   при доступных 254) выдавливала ник аккаунта в НОЛЬ, и ряд оставался без
   главного — без имени. Здесь она уходит, а плашка и величина возвращаются к
   компактному размеру: имя важнее второй метрики, полные числа живут на
   /analytics (ссылка в подвале карточки).

   Компенсация нужна только тройке, где ширину карточки диктует сетка, поэтому
   запрос по контейнеру вложен в min-width:1080px: в потоке карточка во всю
   ширину экрана, там второй метрике место есть даже на телефоне. */
@media (min-width:1080px){
  @container (max-width:344px){
    .cell-accounts .acc-item,.cell-reels .reel-row{gap:10px;}
    .cell-accounts .av.s34{width:34px;height:34px;font-size:12px;}
    .cell-accounts .acc-rank,.cell-reels .acc-rank{width:22px;height:22px;border-radius:var(--r-sm);font-size:10.5px;}
    .cell-reels .rthumb{width:32px;height:46px;}
    .cell-accounts .rvals .val,.cell-reels .rvals .val{font-size:13.5px;}
    .cell-accounts .rvals .sub2,.cell-reels .rvals .sub2{display:none;}
    /* И единица величины: «by views · 30d» уже стоит в заголовке карточки, а эти
       30px решают, увидит клиент ник целиком или обрезанным по третьей букве. */
    .cell-accounts .rvals .val small,.cell-reels .rvals .val small{display:none;}
  }
}

/* ---------- вход ---------- */
.login-wrap{min-height:100vh;display:grid;place-items:center;padding:24px;background:
  radial-gradient(70% 90% at 15% 0,rgba(145,70,255,.16),transparent 60%),
  radial-gradient(60% 80% at 100% 100%,rgba(83,252,24,.10),transparent 55%),var(--bg);}
.login-card{width:min(408px,100%);display:flex;flex-direction:column;gap:16px;padding:30px;border:1px solid var(--surface-card-line);border-radius:var(--r-xl);background:var(--surface-card-strong);box-shadow:var(--shadow-raised);backdrop-filter:blur(12px);}
.login-logo{display:flex;align-items:center;gap:10px;}
/* Словесный знак POPULI (В-29а): прописные Avenir Next Heavy с разрядкой, кольцо с точкой
   на месте «O» ростом с прописную (0.86em при кольце 20.2/24 viewBox). Общий для сайдбара
   и логина — у логина нет cabinet.css. */
.wordmark{display:block;width:auto;color:var(--text);}
.login-logo .wordmark{color:var(--text);}
.login-h{font:700 21px/1.15 var(--display);letter-spacing:-.025em;}
.login-sub{color:var(--muted);font-size:12.5px;line-height:1.55;}
.login-err{padding:10px 13px;border-radius:6px;background:var(--danger-surface);color:var(--danger);font-size:12px;font-weight:600;}
.login-foot{color:var(--muted-2);font-size:11px;line-height:1.55;text-align:center;}

@media (max-width:720px){
  /* Заголовок и переключатель не помещаются в строку: на узком экране сегмент
     уезжает под заголовок на всю ширину, иначе заголовок ломается по слогам. */
  .card-head{flex-direction:column;align-items:stretch;gap:10px;}
  .card-head .chip{align-self:flex-start;}
  .card-head .seg{display:flex;width:100%;}
  .card-head .seg button{flex:1;}
  .card.pad,.island{padding:15px;}
  .rows-title{padding:15px 15px 8px;}
  .note-foot,.hist-item{padding-left:15px;padding-right:15px;}
  
  
  
  /* Подписи оси на телефоне сняты (решение было и раньше: 44px ширины дороже
     подписей), а вместе с ними обязана исчезнуть и КОЛОНКА под них — иначе
     полотно теряет те же 44px на пустоту. Полоса подписчиков остаётся: она
     единственное место, где видна их динамика, но становится ниже. */
  /* Обе колонки подписей, включая колонку полосы: в одноколоночной сетке она
     легла бы поверх самой полосы. Числа полосы дают подсказка по тапу и плитка
     «Followers» под графиком. */
  .chart-y{display:none;}
  .chart-wrap{grid-template-columns:minmax(0,1fr);}
  .chart-plot,.chart-x{grid-column:1;}
  .step{width:74px;}
  
  
  
  
  .profile-grid{grid-template-columns:1fr;}
  .profile-intro{padding:var(--card-pad);}
  .profile-form-foot{align-items:stretch;flex-direction:column;}
  .profile-form-foot .btn{width:100%;}
  /* Ячейки таблиц плотнее: на 375px каждые 4px паддинга — это колонка. */
  .tbl th{padding:0 10px 9px;}
  .tbl td{padding:11px 10px;}
  /* Выбор типа загрузки — стопкой, две радио-карты рядом не читаются. */
  .upload-file-grid{grid-template-columns:1fr;}
  .upload-batch{padding:15px;}
  .upload-batch-actions .btn{width:100%;}
}

/* Рил без описания. Подпись поста — то, чем клиент отличает один рил от другого, и
   у части роликов её нет вовсе (у аккаунта они опубликованы без текста). Раньше на
   этом месте стояла дата или слово «Reel», то есть отсутствие имени выглядело как
   имя. Теперь стоит признание — и приглушённо: тем же весом, что подписи соседей,
   оно читалось бы как ещё одно название. */
.nm.untitled,.tt.untitled{
  color:var(--muted-2);font-style:italic;font-weight:600;
}

/* Правый угол шапки острова: сегмент величин + легенда рядов столбиком. */
.head-tools{display:flex;flex-direction:column;align-items:flex-end;gap:8px;flex:none;}

/* ---------- шторка (волна 4) ----------
   Первая модальная поверхность кабинета. Слои: сайдбар 70, шапка 60, таб-док 80 —
   подложка и шторка выше всех. Подложка — ссылка на адрес без шторки, поэтому
   закрывается и без JS; JS добавляет клавиши. */
.drawer-scrim{position:fixed;inset:0;z-index:90;background:var(--scrim);display:block;}
.drawer{
  position:fixed;top:var(--shell-gutter);right:var(--shell-gutter);bottom:var(--shell-gutter);z-index:91;
  width:min(720px,calc(100vw - 2 * var(--shell-gutter)));
  display:flex;flex-direction:column;overflow:hidden;
  background:var(--surface);border:1px solid var(--surface-card-line);border-radius:var(--r-panel);
  box-shadow:var(--shadow-overlay),inset 0 1px 0 var(--glass-line);
  animation:drawerIn var(--dur-panel) var(--ease-enter) both;
}
@keyframes drawerIn{from{transform:translateX(28px);opacity:0}to{transform:none;opacity:1}}
.drawer-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:var(--card-pad-roomy);border-bottom:1px solid var(--line-soft);}
.drawer-title{min-width:0;display:flex;flex-direction:column;gap:3px;}
.drawer-title .t{font:700 17px var(--display);letter-spacing:-.015em;line-height:1.25;}
.drawer-title .s{color:var(--muted-2);font-size:11.5px;}
.drawer-nav{display:flex;gap:6px;flex:none;}
.drawer-nav .btn{width:36px;padding:0;font-size:18px;}
.drawer-nav .btn.disabled{opacity:.35;pointer-events:none;}
.drawer-body{flex:1;min-height:0;overflow:auto;padding:var(--card-pad-roomy);display:flex;flex-direction:column;gap:var(--card-gap);}
/* Дети тела шторки не сжимаются: карточки-колонки (.card.stack, .react-grid с flex:1)
   в flex-колонке с прокруткой схлопывались бы до заголовка. Высоту задаёт содержимое. */
.drawer-body>*{flex:none;}

body.has-drawer{overflow:hidden;}
.video-hero{display:grid;grid-template-columns:120px minmax(0,1fr);gap:16px;align-items:start;}
.video-cover{width:120px;height:213px;}
.video-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;}
@media (prefers-reduced-motion:reduce){.drawer{animation:none;}}

/* ---------- раздел «скоро»: стекло поверх заглушки ----------
   Под стеклом лежат ТОЛЬКО константы (components/soon.html): блюр снимается в
   devtools, и настоящих чисел в DOM быть не должно. Блок растёт на всю карточку,
   бейдж и подсказка — по её центру. */
.cell-leads{display:flex;flex-direction:column;}
.soon-block{position:relative;flex:1;display:flex;flex-direction:column;border-radius:inherit;}
.soon-under{flex:1;filter:blur(6px);opacity:.5;pointer-events:none;user-select:none;}
.soon-glass{position:absolute;inset:0;display:grid;place-items:center;align-content:center;
  gap:6px;padding:0 16px;border-radius:inherit;background:var(--glass);
  -webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);}
.soon-badge{display:inline-flex;align-items:center;gap:7px;padding:6px 13px;
  border:1px solid var(--glass-line);border-radius:999px;
  background:var(--glass-strong);box-shadow:var(--shadow-card);
  font-size:var(--text-xs);font-weight:600;color:var(--text);}
.soon-hint{max-width:320px;text-align:center;font-size:var(--text-xs);color:var(--muted-2);}

/* ---------- «скоро»: пилюля вместо числа (В-45) ----------
   Одна пилюля на все места, где величины ещё нет: плитка KPI и ячейка таблицы. Тот же
   вид, что у меток .th-soon/.seg-soon рядом. Блюра нет: он мешал читать слова. */
.soon-pill{display:inline-flex;align-items:center;min-height:24px;padding:0 10px;border-radius:999px;
  background:var(--surface-2);color:var(--muted);font:700 10px var(--sans);letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap;vertical-align:middle;}
.kpi-row .v .soon-pill{position:relative;top:-3px;}
.tbl .soon-pill{min-height:20px;padding:0 8px;font-size:9px;}
/* Метка «soon» у заголовка колонки и у пилюли переключателя величины. */
.th-soon,.seg-soon{display:inline-block;margin-left:6px;padding:2px 7px;border-radius:999px;
  background:var(--surface-2);color:var(--muted-2);font:700 9.5px var(--sans);
  letter-spacing:.08em;text-transform:uppercase;vertical-align:middle;}
.seg-soon{margin-left:0;align-self:center;}

/* ---------- телефон (В-41…В-44, 13.09.2026) ----------
   Один блок на все экраны: таблица Accounts списком карточек, полоса фильтров группами со
   свайпом, Export CSV спрятан, герой поста и шторки — обложка сверху и плитки в две колонки. */
@media (max-width:720px){
  /* Шапка таблицы: поиск во всю строку, скачивание на телефоне не нужно (В-43). */
  .tbl-head .tools{width:100%;}
  .tbl-head .tools .searchbox{flex:1;min-width:0;}
  .tbl-head .tools .searchbox input{width:100%;max-width:none;}
  .tbl-head .tools [data-csv-export]{display:none;}
  /* Полоса фильтров: каждая группа — строка, чипы уезжают вбок пальцем (В-42). */
  .filter-row{flex-direction:column;align-items:stretch;gap:6px;padding:8px 0;}
  .fgroup{display:flex;align-items:center;gap:6px;overflow-x:auto;padding:0 var(--pad);scrollbar-width:none;-webkit-overflow-scrolling:touch;}
  .fgroup::-webkit-scrollbar{display:none;}
  .fgroup .lbl{flex:none;min-width:54px;}
  .fgroup .fchip,.fgroup .fsel{flex:none;}
  .filter-sep,.filter-row>.fchip.clear{display:none;}
  /* Accounts (В-41, А1 второго прохода): строка одной анатомии с «Top accounts» обзора —
     аватар · ник, второй строкой статус и подписчики; справа просмотры с трендом и
     последний пост. Разметка таблицы та же: строка — сетка 4 колонки × 2 ряда; ячейка
     аккаунта и статуса прозрачны (display:contents), их дети ложатся по областям; ячейки
     чисел — блоки в своих областях. Скрытия — в конце блока, чтобы их не перебило. */
  .acc-table,.acc-table tbody{display:block;width:100%;}
  .acc-table tr{display:grid;grid-template-columns:34px auto minmax(0,1fr) auto;grid-template-rows:auto auto;column-gap:8px;row-gap:3px;align-items:center;padding:10px var(--pad);border-bottom:1px solid var(--line-soft);}
  .acc-table tbody:last-child tr:last-child{border-bottom:none;}
  .acc-table td,.acc-table td.num{display:block;padding:0;border:none;font-size:12.5px;min-width:0;}
  .acc-table td:nth-child(1),.acc-table td:nth-child(1) .acc-cell,.acc-table td:nth-child(2){display:contents;}
  .acc-table .acc-cell .av{grid-column:1;grid-row:1/3;width:34px;height:34px;font-size:12px;}
  .acc-table .acc-cell>b{grid-column:2/4;grid-row:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;}
  .acc-table td:nth-child(2) .status{grid-column:2;grid-row:2;font-size:11px;white-space:nowrap;}
  .acc-table td:nth-child(3){grid-column:3;grid-row:2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:11px;color:var(--muted);}
  .acc-table td:nth-child(3) b{font:600 11px var(--sans);color:var(--muted);}
  .acc-table td:nth-child(3) b:not(:has(+ .why))::after{content:" followers";}
  /* Тренд подписчиков на телефоне не показываем: строка узкая, тренд просмотров справа
     говорит о движении аккаунта; подписчики с трендом — в карточке. */
  .acc-table td:nth-child(3) .trend{display:none;}
  .acc-table td:nth-child(3) .why{display:inline;margin-left:3px;}
  .acc-table td:nth-child(4){grid-column:4;grid-row:1;text-align:right;white-space:nowrap;}
  .acc-table td:nth-child(4) b{font:700 14px var(--display);}
  .acc-table td:nth-child(4) b:not(:has(+ .why))::after{content:" views";font:500 10.5px var(--sans);color:var(--muted-2);}
  .acc-table td:nth-child(4) .trend{font-size:10.5px;margin-left:4px;}
  .acc-table td:nth-child(4) .muted{font-size:11px;}
  .acc-table td:nth-child(4) b+.why{display:none;}   /* «measured Shorts only» у канала — в заголовке группы */
  .acc-table td:nth-child(4) .why:first-child{font-size:11px;}
  .acc-table td:nth-child(5){grid-column:4;grid-row:2;text-align:right;font-size:10.5px;color:var(--muted-2);white-space:nowrap;}
  .acc-table td:nth-child(5).late{color:var(--warn);}
  .acc-table tr.group-row{display:block;padding:6px var(--pad);}
  .acc-table tr.group-row td{display:block;padding:0;}
  /* Скрытия — последними: шапка, лишние колонки, вторая строка под ником. */
  .acc-table thead,.acc-table colgroup{display:none;}
  .acc-table tr[hidden]{display:none;}
  .acc-table td:nth-child(n).m-hide:not(:nth-child(5)){display:none;}
  .acc-table td:nth-child(1) .acc-meta,.acc-table td:nth-child(1) .m-sub,.acc-table td:nth-child(3) .why+.why{display:none;}
  /* Герой аккаунта и поста: ник в строку, чипы ниже, плитки в две колонки (В-44). */
  .acc-hero-id{flex-wrap:wrap;}
  .acc-hero-name{flex:1;min-width:0;}
  .acc-hero-name .hn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .acc-hero-name .post-hn{white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;}
  /* Имя занимает остаток первой строки, чип «Open profile» переносится на вторую своей ширины. */
  .acc-hero-name{flex-basis:calc(100% - 67px);}
  .acc-hero-id>.chip{margin-left:0;}
  .hero-acts{margin-left:0;flex-basis:100%;}
  .hero-acts{flex-wrap:wrap;}
  /* Шторка ролика (В-44, Б1): обложка слева, метрики списком справа — главная цифра
     крупно, остальные строками «подпись · число». */
  .video-hero{grid-template-columns:84px minmax(0,1fr);gap:10px;}
  .video-cover{width:84px;height:auto;aspect-ratio:9/16;}
  .video-metrics{display:grid;grid-template-columns:minmax(0,1fr);gap:0;border:1px solid var(--line-soft);border-radius:var(--r-lg);overflow:hidden;}
  .video-metrics .now-tile{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"l v" "s v";column-gap:10px;row-gap:1px;align-items:center;padding:8px 12px;border:none;border-radius:0;border-top:1px solid var(--line-soft);background:transparent;}
  .video-metrics .now-tile:first-child{display:flex;flex-direction:column;align-items:flex-start;gap:3px;border-top:none;padding:10px 12px 12px;background:var(--surface-1);}
  .video-metrics .now-tile:first-child .v{font-size:26px;}
  .video-metrics .now-tile .l{grid-area:l;white-space:normal;overflow:visible;font:600 12px var(--sans);color:var(--text);}
  .video-metrics .now-tile:first-child .l{font:700 10px var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--muted);}
  .video-metrics .now-tile .v{grid-area:v;margin:0;font-size:15px;white-space:nowrap;}
  .video-metrics .now-tile .s{grid-area:s;font-size:10.5px;}
  /* Тип загрузки — карточки стопкой. */
  .kind-cards{grid-template-columns:1fr;}
  /* Переключатель графика уезжает вбок, а не ломается в две строки. */
  .card-head .seg{overflow-x:auto;scrollbar-width:none;}
  .card-head .seg::-webkit-scrollbar{display:none;}
  .card-head .seg a{flex:none;}
}

/* ---------- телефон, плотность и читаемость (13.09.2026, второй проход) ----------
   Что было не так на 390px: подписи плиток KPI ужимались в столбик рядом с пилюлей
   дельты, статусы в списке аккаунтов ломались на две строки, причины «not measured»
   в узкой колонке уходили в семь строк, счётчики Pool health стояли крупными
   квадратами с пустотой, подзаголовки карточек делили строку с заголовком. */
@media (max-width:720px){
  /* Плитка KPI: дельта и подпись — друг под другом во всю ширину плитки, подпись
     переносится, а не рубится; сама плитка компактнее. */
  .kpi-row>div{padding:12px 14px;gap:4px;}
  .kpi-row .l{white-space:normal;overflow:visible;line-height:1.3;}
  .kpi-row .v{font-size:24px;}
  .kpi-row .foot{flex-direction:column;align-items:flex-start;gap:4px;min-height:0;font-size:10.5px;}
  .kpi-row.hero-kpi>div{padding:12px 14px;}
  /* Заголовок карточки и его подпись справа — стопкой: справа остаётся только ссылка,
     и она не уезжает под заголовок даже при длинной подписи. */
  .list-head{flex-wrap:wrap;}
  .list-head>div:first-child{flex:1;min-width:0;}
  /* Пилюля «Leads · soon» в переключателе графика — в одну строку. */
  .card-head .seg a,.card-head .seg a *,.card-head .seg .seg-soon{white-space:nowrap;flex:none;}
  .list-head>span.card-sub,.list-head .coverage{flex-basis:100%;max-width:none;text-align:left;margin-top:0;}
  /* Pool health: счётчик и статус в одну строку, две колонки. */
  .pool-items{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 12px;}
  .pool-item{flex-direction:row;align-items:center;gap:8px;min-width:0;}
  .pool-item .n{font-size:18px;min-width:20px;}
  .pool-item .s{max-width:none;}
  /* Причина «not measured» — коротко и в одну строку, хвост спрятан (.m-hide). */
  .tbl-v2 td .why{max-width:none;}
  .tbl-v2 td.num .why{white-space:nowrap;}
  /* Мета поста под названием — обычным текстом, без flex-зазоров между кусками. */
  .acc-hero-id .hs{display:block;line-height:1.45;}
  .acc-hero-id .hs .av{display:inline-grid;vertical-align:-4px;margin-right:4px;}
  /* Полоса реакций: пятая плитка — во всю ширину, а не одна в углу. */
  .react-strip>div:last-child:nth-child(odd){grid-column:1/-1;}
  /* Шторка: заметка о слое — компактнее. */
  .drawer .card-note{font-size:11.5px;line-height:1.5;}
}

/* ---------- телефон, герой списком (Б1, 13.09.2026) ----------
   Как Instagram Insights: первая плитка — главная цифра крупно с дельтой, остальные —
   строки «подпись и пояснение слева · число справа». Пояснения (слой, окно) остаются
   видны, числа не режутся. Разметка плиток та же. */
@media (max-width:720px){
  .kpi-row.hero-kpi,.kpi-row.hero-kpi.six{grid-template-columns:minmax(0,1fr);}
  .kpi-row.hero-kpi>div:nth-child(n){display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"l v" "foot v";column-gap:12px;row-gap:2px;align-items:center;padding:9px 14px;border-left:none;border-top:1px solid var(--island-line);}
  .kpi-row.hero-kpi>div:nth-child(n) .l{grid-area:l;white-space:normal;overflow:visible;font:600 12.5px var(--sans);letter-spacing:0;text-transform:none;color:var(--text);}
  .kpi-row.hero-kpi>div:nth-child(n) .l svg{display:none;}
  .kpi-row.hero-kpi>div:nth-child(n) .v{grid-area:v;font-size:16px;white-space:nowrap;text-align:right;}
  .kpi-row.hero-kpi>div:nth-child(n) .foot{grid-area:foot;flex-direction:row;flex-wrap:wrap;gap:4px 6px;font-size:10.5px;}
  /* Главная цифра — первой плиткой, во всю ширину, крупно. */
  .kpi-row.hero-kpi>div:first-child{display:flex;flex-direction:column;align-items:flex-start;gap:4px;padding:12px 14px 13px;border-top:none;background:var(--surface-1);}
  .kpi-row.hero-kpi>div:first-child .l{font:700 10px var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--muted);}
  .kpi-row.hero-kpi>div:first-child .v{font-size:30px;text-align:left;}
  .kpi-row.hero-kpi>div:first-child .foot{margin-top:2px;}
}
