/* Мини-апп рассылки ВК.
 *
 * Палитра своя, в стилистике ВК, а не из темы Telegram: приложение должно
 * выглядеть одинаково в любом клиенте, а «светло/темно» берём у системы
 * (или у Telegram, если он подсказал) и вешаем на <html data-theme>.
 *
 * Системных контролов в интерфейсе не осталось: селект — лист выбора снизу,
 * подтверждение — свой лист, аккордеон — свой, время — свои барабаны в
 * 24-часовом формате (родное поле берёт формат у системы и показывает AM/PM,
 * который на части телефонов не переключается).
 */

:root {
  color-scheme: light;

  --vk-blue: #0077ff;
  --vk-blue-press: #0064d8;

  --bg: #ffffff;
  --bg-elevated: #ffffff;      /* карточки на светлом фоне */
  --bg-sunken: #f0f2f5;        /* фон страницы под карточками */
  --bar: rgba(255, 255, 255, .82);

  --text: #000000;
  --text-2: #818c99;
  --text-3: #99a2ad;

  --accent: var(--vk-blue);
  --accent-soft: rgba(0, 119, 255, .1);
  --on-accent: #ffffff;

  --danger: #e64646;
  --danger-soft: rgba(230, 70, 70, .1);
  --ok: #4bb34b;
  --ok-soft: rgba(75, 179, 75, .12);
  --warn: #ffa000;
  --warn-soft: rgba(255, 160, 0, .14);

  --line: rgba(0, 0, 0, .08);
  --line-strong: rgba(0, 0, 0, .14);
  --fill: rgba(0, 0, 0, .04);
  --shadow: 0 8px 32px rgba(0, 0, 0, .16);

  /* стекло плавающего островка вкладок */
  --glass: rgba(255, 255, 255, .72);
  --glass-edge: rgba(255, 255, 255, .6);
  --glass-shine: rgba(255, 255, 255, .9);

  --s1: 4px;  --s2: 8px;  --s3: 12px;  --s4: 16px;  --s5: 24px;  --s6: 32px;
  --radius: 14px;
  --radius-sm: 10px;
  --radius-lg: 20px;
  --control-h: 44px;

  --ease: cubic-bezier(.22, .61, .36, 1);
  --fast: .16s var(--ease);
  --slow: .28s var(--ease);
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #19191a;
  --bg-elevated: #232324;
  --bg-sunken: #19191a;
  --bar: rgba(25, 25, 26, .82);

  --text: #e1e3e6;
  --text-2: #909499;
  --text-3: #76787a;

  --accent: #4d92f7;
  --accent-soft: rgba(77, 146, 247, .16);
  --on-accent: #ffffff;

  --danger: #ff5c5c;
  --danger-soft: rgba(255, 92, 92, .16);
  --ok: #4bb34b;
  --ok-soft: rgba(75, 179, 75, .16);
  --warn: #ffa000;
  --warn-soft: rgba(255, 160, 0, .18);

  --line: rgba(255, 255, 255, .09);
  --line-strong: rgba(255, 255, 255, .16);
  --fill: rgba(255, 255, 255, .06);
  --shadow: 0 8px 32px rgba(0, 0, 0, .5);

  --glass: rgba(44, 44, 46, .72);
  --glass-edge: rgba(255, 255, 255, .12);
  --glass-shine: rgba(255, 255, 255, .08);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 16px/1.4 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, sans-serif;
  background: var(--bg-sunken);
  color: var(--text);
  padding-bottom: calc(84px + env(safe-area-inset-bottom));
  -webkit-tap-highlight-color: transparent;
  /* Долгий тап в интерфейсе не должен выделять текст и звать меню копирования —
     это про справку и подписи, из-за них экран выглядел «сломанным». */
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}

/* Выделения в интерфейсе нет нигде, кроме полей ввода.
   Перечислять «какие элементы не выделять» бесполезно: правило с body
   наследуется не во всех движках, часть возвращает элементам `user-select: auto`,
   и от долгого тапа по любой подписи вылезала синяя полоса выделения — экран
   выглядел так, будто из него собрались копировать. Поэтому запрет тотальный,
   а исключение ровно одно: то, что человек сам печатает. */
*, *::before, *::after {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
input, textarea {
  -webkit-user-select: text; user-select: text;
  -webkit-touch-callout: default;
}
/* На всякий случай гасим и саму подсветку: отдельные движки рисуют её даже
   при user-select: none — например, когда выделение тянут мышью через блок. */
::selection { background: transparent; }
input::selection, textarea::selection { background: var(--accent-soft); }

/* Обводка по тапу не нужна — она остаётся висеть после нажатия. Для клавиатуры
   фокус возвращаем: без него по интерфейсу нельзя ходить табом.
   Но именно возвращаем — и только там, где есть настоящая клавиатура и мышь.
   На телефоне :focus-visible срабатывает и от пальца: часть движков считает
   «видимым» фокус после тапа по кнопке, и на справке, шапке и кнопке темы
   оставалась висеть синяя рамка, похожая на выделение текста. */
:where(button, .picker, input, textarea, a, label, summary):focus { outline: none; }
@media (hover: hover) and (pointer: fine) {
  button:focus-visible, .picker:focus-visible, input:focus-visible,
  textarea:focus-visible, a:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px;
  }
}

.hidden { display: none !important; }

/* ---------- шапка в духе iOS: объёмная плашка + большой заголовок ---------- */

.appbar {
  position: sticky; top: 0; z-index: 20;
  /* До прокрутки шапка сливается с фоном страницы — ровно как в тёмной теме.
     На светлой она была белой поверх серого фона и торчала отдельной плашкой,
     хотя показывать там до прокрутки нечего. */
  background: var(--bg-sunken);
  padding-top: env(safe-area-inset-top);
  /* Скруглённый низ и мягкая тень появляются вместе: шапка отделяется
     от страницы только тогда, когда под неё что-то уехало. */
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
  transition: box-shadow var(--slow), background var(--slow);
}
.appbar.scrolled {
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(22px);
  backdrop-filter: saturate(180%) blur(22px);
  box-shadow: 0 6px 24px -12px rgba(0, 0, 0, .35), 0 1px 0 var(--line);
}
.appbar-inner {
  display: flex; align-items: center; gap: var(--s2);
  height: 58px; padding: 0 var(--s3);
}
.appbar-title {
  flex: 1; min-width: 0; font-size: 17px; font-weight: 600; text-align: center;
  opacity: 0; transform: translateY(8px);
  transition: opacity var(--fast), transform var(--fast);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  pointer-events: none;
}
.appbar.scrolled .appbar-title { opacity: 1; transform: none; }

/* Крупный заголовок страницы — он же уезжает вверх при прокрутке. */
.large-title {
  margin: var(--s3) 0 var(--s4);
  font-size: 34px; line-height: 1.1; font-weight: 700; letter-spacing: -.03em;
}

/* чип текущей страницы ВК и круглые кнопки шапки */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 34px; max-width: 46vw; padding: 0 var(--s2) 0 4px;
  border: 0; border-radius: 999px; background: var(--fill); color: var(--text);
  font-size: 14px; font-weight: 500; cursor: pointer;
  transition: transform var(--fast), background var(--fast);
}
.chip:active { transform: scale(.96); background: var(--line); }
.chip.off { opacity: .55; }
.chip b { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip .ava {
  width: 26px; height: 26px; flex: none; border-radius: 50%;
  background: var(--accent); color: var(--on-accent);
  display: grid; place-items: center; font-size: 12px; font-weight: 600;
  background-size: cover; background-position: center;
}
.chip .ava.img { color: transparent; }        /* аватарка страницы ВК */
.chip .ava.all { background: var(--fill); color: var(--text-2); }
.icon-btn {
  width: 34px; height: 34px; flex: none; display: grid; place-items: center;
  border: 0; border-radius: 50%; background: var(--fill); color: var(--text);
  font-size: 15px; cursor: pointer; transition: transform var(--fast), background var(--fast);
}
.icon-btn:active { transform: scale(.92); }
.icon-btn.danger { color: var(--danger); background: var(--danger-soft); }

/* ---------- нижние вкладки ---------- */

/* Нижние вкладки — плавающим островком, как в свежих iOS: полоса во всю ширину
   выглядит приклеенной к низу, а островок читается как отдельный элемент
   поверх страницы. Стекло собрано слоями: размытие + полупрозрачная заливка +
   светлая грань сверху и мягкая тень снизу. */
.tabbar {
  position: fixed; z-index: 20;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--s2) + env(safe-area-inset-bottom));
  width: min(calc(100% - var(--s4)), 520px);
  display: flex;
  background: var(--glass);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
  backdrop-filter: saturate(180%) blur(24px);
  border: 1px solid var(--glass-edge);
  border-radius: 22px;
  box-shadow: 0 10px 30px -8px rgba(0, 0, 0, .28), inset 0 1px 0 var(--glass-shine);
  overflow: hidden;
}
.tabbar button {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: none; border: 0; color: var(--text-3);
  padding: 10px 2px 9px; font-size: 10px; font-weight: 500; cursor: pointer;
  transition: color var(--fast);
}
.tabbar button svg {
  width: 24px; height: 24px; display: block;
  transition: transform var(--slow), stroke-width var(--slow);
}
.tabbar button:active svg { transform: scale(.86); }
.tabbar button.active { color: var(--accent); }
.tabbar button.active svg { transform: translateY(-1px); stroke-width: 2.1; }

/* ---------- каркас ---------- */

.view { padding: 0 var(--s3) var(--s6); animation: fade-up .22s var(--ease); }
@keyframes fade-up { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Единый вертикальный ритм внутри вкладки. Раньше кнопка «Новый пост» и первая
   карточка стояли впритык, а пояснение под заголовком слипалось со списком. */
.toolbar { margin-bottom: var(--s3); }
.view > .hint { margin-bottom: var(--s3); }
.view > .btn.wide,
.view > .ghost.wide { margin-top: var(--s2); }
.view > .list + .ghost.wide,
.view > .card + .btn.wide { margin-top: var(--s3); }

.empty, .loader {
  color: var(--text-2); text-align: center; padding: var(--s6) var(--s3); font-size: 15px;
}
.empty b { color: var(--text); }

.section-title {
  margin: var(--s5) 0 var(--s2); font-size: 13px; color: var(--text-2);
  font-weight: 600; display: flex; align-items: center; gap: var(--s2);
}
.section-title .grow { flex: 1; }
.section-title:first-child { margin-top: var(--s2); }

.hint { color: var(--text-2); font-size: 14px; margin: var(--s2) 0 0; line-height: 1.4; }
.hint b { color: var(--text); font-weight: 600; }

/* ---------- карточки и списки ---------- */

.card {
  background: var(--bg-elevated); border-radius: var(--radius);
  padding: var(--s3) var(--s4); margin-bottom: var(--s2);
  transition: opacity var(--fast);
}
.card.off { opacity: .5; }
.card-head { display: flex; align-items: center; gap: var(--s2); min-height: 26px; }
.card-head h3 {
  margin: 0; font-size: 16px; font-weight: 600; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.card .meta { margin: var(--s2) 0 0; color: var(--text-2); font-size: 14px; }
.card .meta div + div { margin-top: 2px; }
/* В карточке — только начало объявления. Переносы строк тут схлопываем:
   с pre-wrap пустая строка между абзацами съедала половину трёх видимых
   и вместо текста показывалось одинокое многоточие. */
.card .excerpt {
  margin: var(--s2) 0 0; font-size: 15px; color: var(--text); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;
}
/* Полный текст записи в журнале — со своей прокруткой, а не в двадцать строк. */
.card .excerpt.tall {
  -webkit-line-clamp: unset; display: block; white-space: pre-wrap;
  max-height: 40vh; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent;
}
.card .excerpt.tall::-webkit-scrollbar { width: 5px; }
.card .excerpt.tall::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 999px; }
/* Действия карточки в два яруса: сверху равные по ширине второстепенные,
   снизу — главное действие во всю строку и удаление отдельной кнопкой.
   Раньше всё лежало одним переносящимся рядом, и «Опубликовать» оказывалось
   то в конце первой строки, то в начале второй — попасть в него не глядя
   было невозможно. */
.card-actions {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--s2);
  margin-top: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--line);
}
.card-actions + .card-actions { margin-top: var(--s2); padding-top: 0; border-top: 0; }
.card-actions.main { grid-auto-columns: 1fr auto; }
.card-actions > * { min-width: 0; }

/* Строка «куда и когда пойдёт»: главный ответ на «а что вообще произойдёт». */
.plan-line {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; margin-top: var(--s3); padding: var(--s2) var(--s3);
  background: var(--fill); border: 0; border-radius: var(--radius-sm);
  color: var(--text); font: inherit; text-align: left; cursor: pointer;
  transition: background var(--fast), transform var(--fast);
}
.plan-line:active { background: var(--line); transform: scale(.99); }
.plan-line .grow { flex: 1; min-width: 0; }
.plan-line b {
  display: block; font-size: 14px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Одна строка: подробности всё равно открываются тапом, а рваный перенос
   с «→» на конце строки читается как поломка. */
.plan-line small {
  display: block; color: var(--text-2); font-size: 13px; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.row { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }
.row.nowrap { flex-wrap: nowrap; }
.row > .grow { flex: 1; min-width: 0; }

.list {
  background: var(--bg-elevated); border-radius: var(--radius);
  padding: 0 var(--s4); margin-bottom: var(--s2); overflow: hidden;
}
.list-row {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) 0; border-bottom: 1px solid var(--line);
  animation: row-in .22s var(--ease) both;
}
@keyframes row-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.list-row:last-child { border-bottom: 0; }
.list-row .grow { flex: 1; min-width: 0; }
.list-row .grow b {
  display: block; font-size: 15px; font-weight: 500;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Подпись строки — всегда в одну строчку: иначе на телефоне она разъезжается
   на три и выдавливает название сообщества в узкий столбик. */
.list-row .grow small {
  display: block; color: var(--text-2); font-size: 13px; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.list-row .grow .tags { display: flex; gap: var(--s1); flex-wrap: wrap; margin-top: 6px; }
.list-row.tappable { cursor: pointer; transition: background var(--fast), transform var(--fast); }
.list-row.tappable:active { background: var(--fill); transform: scale(.995); }

.avatar {
  width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: none;
  background: var(--fill); display: grid; place-items: center;
  color: var(--text-3); font-size: 15px; font-weight: 600;
}
.avatar.sm { width: 28px; height: 28px; }

/* Время публикации в плане — моноширинно, чтобы колонка не плясала. */
.list-row .at {
  flex: none; width: 46px; font-size: 15px; font-weight: 600; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.pill {
  font-size: 12px; padding: 3px var(--s2); border-radius: 8px; white-space: nowrap;
  background: var(--fill); color: var(--text-2); font-weight: 500;
}
.pill.ok { color: var(--ok); background: var(--ok-soft); }
.pill.err { color: var(--danger); background: var(--danger-soft); }
.pill.wait { color: var(--accent); background: var(--accent-soft); }
.pill.warn { color: var(--warn); background: var(--warn-soft); }

/* ---------- кнопки ---------- */

.btn, .ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: var(--control-h); padding: 0 var(--s4);
  border: 0; border-radius: var(--radius-sm); cursor: pointer;
  font: inherit; font-size: 15px; font-weight: 500; white-space: nowrap; flex: 0 0 auto;
  transition: transform var(--fast), background var(--fast), opacity var(--fast);
}
.btn { background: var(--accent); color: var(--on-accent); font-weight: 600; }
.btn:active { background: var(--vk-blue-press); transform: scale(.97); }
.ghost { background: var(--fill); color: var(--text); }
.ghost:active { background: var(--line); transform: scale(.97); }
.ghost.danger, .btn.link.danger { color: var(--danger); }
.btn.danger { background: var(--danger); color: #fff; }
.btn.wide, .ghost.wide { width: 100%; }
.btn.sm, .ghost.sm { height: 36px; padding: 0 var(--s3); font-size: 14px; }
.btn.icon, .ghost.icon { width: var(--control-h); padding: 0; }
.ghost.sm.icon { width: 36px; }
.btn.link {
  background: none; color: var(--accent); height: auto; padding: 0; font-weight: 500;
}
.btn.link:active { opacity: .5; transform: none; background: none; }
button:disabled { opacity: .4; pointer-events: none; }

/* ---------- поля ---------- */

input, textarea {
  font: inherit; color: var(--text);
  width: 100%; height: var(--control-h); padding: 0 var(--s3);
  background: var(--fill); border: 1px solid transparent;
  border-radius: var(--radius-sm); appearance: none; outline: none;
  transition: border-color var(--fast), background var(--fast);
}
input:focus, textarea:focus { border-color: var(--accent); background: var(--bg-elevated); }
input::placeholder, textarea::placeholder { color: var(--text-3); }
textarea { height: auto; min-height: 140px; padding: var(--s3); resize: vertical; line-height: 1.45; }
input[type="time"] { padding-right: var(--s2); }
/* стрелки у числовых полей на мобильных бесполезны и ломают высоту */
input[type="number"] { -moz-appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

label.field { display: block; margin-top: var(--s4); }
label.field > span { display: block; font-size: 14px; color: var(--text-2); margin-bottom: 6px; }
label.field .hint { margin-top: 6px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2) var(--s2); }
.grid2 label.field { margin-top: var(--s4); }

/* Флажки: общее `appearance: none` снимает родную галочку, поэтому рисуем свою
   фоновой картинкой — псевдоэлементы на <input> поддерживаются не везде. */
input[type="checkbox"], input[type="radio"] {
  width: 24px; height: 24px; flex: none; margin: 0; padding: 0; cursor: pointer;
  border: 2px solid var(--line-strong); border-radius: 8px; background: transparent;
  background-repeat: no-repeat; background-position: center;
  transition: background-color var(--fast), border-color var(--fast), transform var(--fast);
}
input[type="radio"] { border-radius: 50%; }
input[type="checkbox"]:active, input[type="radio"]:active { transform: scale(.88); }
input[type="checkbox"]:checked, input[type="radio"]:checked {
  background-color: var(--accent); border-color: var(--accent);
}
input[type="checkbox"]:checked {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.5 3.5L13 4.5'/%3E%3C/svg%3E");
  background-size: 16px;
}
input[type="radio"]:checked {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3.5' fill='%23fff'/%3E%3C/svg%3E");
  background-size: 18px;
}
input[type="checkbox"]:disabled, input[type="radio"]:disabled { opacity: .35; cursor: default; }

/* Флажок внутри <label> тапы не ловит — их ловит сам label.
   Иначе в WebKit нажатие по флажку срабатывает дважды: сначала на input,
   потом переброс от label, — галочка ставилась и тут же снималась. Ровно так
   «пропадал» выбор постов рассылки и отмеченные сообщества. Клавиатуре это
   не мешает: фокус и пробел работают как раньше. */
label.option input[type="checkbox"],
label.list-row input[type="checkbox"],
label.check input[type="checkbox"] { pointer-events: none; }

.check {
  display: flex; align-items: flex-start; gap: var(--s3); margin-top: var(--s4);
  cursor: pointer; font-size: 15px;
}
.check span { flex: 1; min-width: 0; padding-top: 2px; }
.check small { display: block; color: var(--text-2); font-size: 13px; margin-top: 3px; line-height: 1.35; }

/* Свой селект: тап открывает лист выбора снизу, как в приложениях ВК. */
.picker {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; height: var(--control-h); padding: 0 var(--s3);
  background: var(--fill); border: 1px solid transparent; border-radius: var(--radius-sm);
  color: var(--text); font: inherit; font-size: 15px; text-align: left; cursor: pointer;
  transition: background var(--fast), transform var(--fast);
}
.picker:active { background: var(--line); transform: scale(.99); }
.picker .val { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker .val.empty { color: var(--text-3); }
.chev {
  width: 10px; height: 10px; flex: none; border: solid var(--text-3);
  border-width: 0 2px 2px 0; transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--slow);
}
/* Строка, которая куда-то ведёт, помечается «птичкой» вправо, а не вниз:
   вниз — это раскрытие на месте, вправо — переход на другой экран. */
.chev.right, .plan-line .chev { transform: rotate(-45deg) translate(-2px, -2px); }

/* Переключатель режимов («Сейчас» / «В назначенное время», вкладки набора) */
.segmented {
  display: flex; gap: 2px; margin-top: var(--s4); padding: 3px;
  background: var(--fill); border-radius: var(--radius-sm);
}
.segmented button {
  flex: 1; min-width: 0; height: 36px; padding: 0 var(--s2);
  border: 0; border-radius: 8px; background: none; color: var(--text-2);
  font: inherit; font-size: 14px; font-weight: 500; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background var(--fast), color var(--fast), transform var(--fast);
}
.segmented button:active { transform: scale(.97); }
.segmented button.on {
  background: var(--bg-elevated); color: var(--text); font-weight: 600;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
}

/* Выбор дня лентой: на телефоне пролистнуть быстрее, чем ткнуть в календарь. */
.chips {
  display: flex; gap: var(--s2); overflow-x: auto; padding-bottom: var(--s1);
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
  scrollbar-width: none; -ms-overflow-style: none;
}
.chips::-webkit-scrollbar { display: none; }
.chip-day {
  flex: none; scroll-snap-align: start;
  height: 38px; padding: 0 var(--s4);
  border: 0; border-radius: 999px; background: var(--fill); color: var(--text);
  font: inherit; font-size: 14px; font-weight: 500; cursor: pointer; white-space: nowrap;
  transition: background var(--fast), color var(--fast), transform var(--fast);
}
.chip-day:active { transform: scale(.94); }
.chip-day.on { background: var(--accent); color: var(--on-accent); font-weight: 600; }

/* Барабаны времени. Родное поле берёт формат у системы и показывает AM/PM,
   который на части прошивок не переключается, — поэтому здесь всегда 24 часа. */
.wheels { display: flex; gap: var(--s3); padding: var(--s2) var(--s2) 0; }
.wheel-col { flex: 1; min-width: 0; }
.wheel-cap {
  display: block; text-align: center; font-size: 13px; color: var(--text-2);
  margin-bottom: 6px;
}
.wheel {
  height: 216px; overflow-y: auto; -webkit-overflow-scrolling: touch;
  scroll-snap-type: y proximity;
  background: var(--fill); border-radius: var(--radius-sm); padding: 84px 0;
  scrollbar-width: none; -ms-overflow-style: none;
}
.wheel::-webkit-scrollbar { width: 0; display: none; }
.wheel-item {
  display: block; width: 100%; scroll-snap-align: center;
  height: 44px; border: 0; background: none; color: var(--text-2);
  font: inherit; font-size: 20px; font-variant-numeric: tabular-nums;
  cursor: pointer; transition: color var(--fast), transform var(--fast);
}
.wheel-item:active { transform: scale(.9); }
.wheel-item.on {
  color: var(--accent); font-weight: 700; font-size: 24px;
}

/* Нижняя строка листа выбора: «Готово» всегда на виду. */
.picker-foot {
  position: sticky; bottom: 0; z-index: 2;
  display: flex; gap: var(--s2); align-items: center;
  padding: var(--s3) var(--s2) var(--s1);
  background: linear-gradient(to bottom, transparent, var(--bg) 30%);
}
.picker-foot .grow { flex: 1; }

/* дни недели — сегментами; подсветка через `+`, а не :has() (старый WebView) */
.days { display: flex; gap: var(--s1); }
.days label { flex: 1; display: block; min-width: 0; }
.days input { display: none; }
.days span {
  display: block; text-align: center; font-size: 14px; padding: var(--s2) 0;
  border-radius: var(--radius-sm); background: var(--fill); color: var(--text);
  cursor: pointer; transition: background var(--fast), color var(--fast), transform var(--fast);
}
.days span:active { transform: scale(.94); }
.days input:checked + span { background: var(--accent); color: var(--on-accent); font-weight: 600; }

/* переключатель «включено» */
.switch { position: relative; width: 46px; height: 28px; flex: none; }
.switch input {
  position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; z-index: 2;
  border: 0; background: none;
}
.switch i {
  position: absolute; inset: 0; border-radius: 999px; background: var(--line-strong);
  transition: background var(--slow);
}
.switch i::after {
  content: ''; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
  border-radius: 50%; background: #fff; transition: transform var(--slow);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
}
.switch input:checked + i { background: var(--ok); }
.switch input:checked + i::after { transform: translateX(18px); }

/* ---------- панель массовых действий ---------- */

.bulkbar {
  position: sticky; bottom: calc(80px + env(safe-area-inset-bottom)); z-index: 10;
  display: flex; gap: var(--s2); align-items: center; flex-wrap: wrap;
  background: var(--bg-elevated); border-radius: var(--radius);
  padding: var(--s2) var(--s3); margin-bottom: var(--s2);
  box-shadow: var(--shadow);
  animation: fade-up .2s var(--ease);
}
.bulkbar .count { font-size: 14px; color: var(--text-2); flex: 1; }

/* ---------- листы снизу: модалка, выбор, подтверждение ---------- */

.sheet {
  position: fixed; inset: 0; z-index: 40; display: flex; align-items: flex-end;
  background: rgba(0, 0, 0, .4);
  opacity: 0; transition: opacity var(--slow);
}
.sheet.open { opacity: 1; }
.sheet.hidden { display: none; }
.sheet-card {
  background: var(--bg); width: 100%; max-height: 92vh;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  display: flex; flex-direction: column;
  transform: translateY(100%);
  transition: transform var(--slow);
}
.sheet.open .sheet-card { transform: none; }
.sheet-grip {
  width: 36px; height: 4px; border-radius: 999px; background: var(--line-strong);
  margin: var(--s2) auto 0; flex: none;
}
.sheet-head {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--s4) var(--s2); flex: none;
}
.sheet-head h2 { font-size: 18px; font-weight: 600; margin: 0; flex: 1; min-width: 0; }
.sheet-body {
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 0 var(--s4) var(--s4);
  overscroll-behavior: contain;      /* прокрутка листа не тянет страницу под ним */
  scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent;
}
.sheet-body::-webkit-scrollbar { width: 5px; }
.sheet-body::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 999px; }
/* Главная кнопка формы всегда на виду, даже если список длинный. */
.sheet-actions {
  position: sticky; bottom: 0; z-index: 2; flex: none;
  padding: var(--s3) var(--s4) calc(var(--s4) + env(safe-area-inset-bottom));
  background: var(--bg); border-top: 1px solid var(--line);
  display: flex; gap: var(--s2);
}
.sheet-actions .btn, .sheet-actions .ghost { flex: 1; }

/* список вариантов выбора */
.options { padding: 0 var(--s2) calc(var(--s3) + env(safe-area-inset-bottom)); }
.option {
  display: flex; align-items: center; gap: var(--s3);
  width: 100%; padding: var(--s3); border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--text); font: inherit; font-size: 16px; text-align: left;
  cursor: pointer; transition: background var(--fast);
}
.option:active { background: var(--fill); }
.option .grow { flex: 1; min-width: 0; }
.option b { display: block; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.option small { display: block; color: var(--text-2); font-size: 13px; margin-top: 2px; }
/* Строки выезжают по очереди — лист чувствуется живым, а не «моргнувшим». */
.option { animation: option-in .26s var(--ease) both; }
@keyframes option-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.check-option { cursor: pointer; }
.option .tick {
  width: 20px; height: 20px; flex: none; opacity: 0;
  background: no-repeat center/20px url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230077ff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.5 3.5L13 4.5'/%3E%3C/svg%3E");
  transition: opacity var(--fast);
}
.option.selected { color: var(--accent); font-weight: 500; }
.option.selected .tick { opacity: 1; }

/* ---------- превью поста как в ВК ---------- */

.vkpost {
  background: var(--bg-elevated); border-radius: var(--radius);
  overflow: hidden; margin-top: var(--s3);
  animation: fade-up .24s var(--ease);
}
.vkpost-head { display: flex; align-items: center; gap: var(--s2); padding: var(--s3) var(--s4); }
.vkpost-head b { display: block; font-size: 15px; font-weight: 600; }
.vkpost-head small { color: var(--text-2); font-size: 13px; }

/* Текст — как в ленте ВК: над вложениями и свёрнутый, если длинный.
   Своей прокрутки у текста нет намеренно: крутить надо саму запись, а не
   окошко внутри неё — иначе палец елозит по тексту, а запись стоит на месте. */
.vkpost-text {
  padding: 0 var(--s4); font-size: 15px; line-height: 1.45;
  white-space: pre-wrap; word-wrap: break-word; overflow-wrap: anywhere;
}
.vkpost-text.clamped {
  display: -webkit-box; -webkit-line-clamp: 8; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Кнопка ВК называется именно так — «Показать полностью…». */
.vkpost-more {
  display: block; margin: 2px 0 0; padding: 0 var(--s4);
  background: none; border: 0; color: var(--accent);
  font: inherit; font-size: 15px; text-align: left; cursor: pointer;
}
.vkpost-more:active { opacity: .5; }
/* Текст идёт под вложениями и отбит от них: без отступа он прилипал
   к нижнему краю фотографии и читался как подпись к ней. */
.vkpost-body { padding: var(--s3) 0; }
.vkpost-head + .vkpost-body { padding-top: 0; }   /* от шапки отступ уже есть */
.vkpost-body:empty { display: none; }

/* Раскладка фотографий как в ВК: одна во всю ширину, две рядом,
   три — крупная и пара, дальше плитка. Показываем все, а не первые четыре. */
.vkpost-photos { display: grid; gap: 2px; }
.vkpost-photos .ph { overflow: hidden; }
.vkpost-photos img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vkpost-photos.one { grid-template-columns: 1fr; }
.vkpost-photos.one img { max-height: 360px; }
.vkpost-photos.two { grid-template-columns: 1fr 1fr; }
.vkpost-photos.two img { height: 170px; }
.vkpost-photos.three { grid-template-columns: 1fr 1fr; }
.vkpost-photos.three .wide { grid-column: 1 / -1; }
.vkpost-photos.three .wide img { height: 220px; }
.vkpost-photos.three .ph:not(.wide) img { height: 130px; }
.vkpost-photos.many { display: block; }
.vkpost-photos.many .row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.vkpost-photos.many .row2 img { height: 170px; }
.vkpost-photos.many .row3 {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; margin-top: 2px;
}
.vkpost-photos.many .row3 img { height: 104px; }

/* Файлы во вложении — как их рисует ВК под текстом. */
.vkpost-docs { padding: 0 var(--s4) var(--s2); display: grid; gap: var(--s1); }
.vkpost-docs .doc {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s3); border-radius: var(--radius-sm);
  background: var(--fill); color: var(--accent); text-decoration: none; font-size: 14px;
}
.vkpost-docs .doc i { font-style: normal; }
.vkpost-docs .doc span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.vkpost-foot {
  display: flex; gap: var(--s4); padding: var(--s2) var(--s4) var(--s3);
  color: var(--text-2); font-size: 14px;
}

.thumbs {
  display: flex; gap: var(--s2); margin-top: var(--s3); overflow-x: auto; padding: 6px 2px 2px;
  scrollbar-width: none; -ms-overflow-style: none;
}
.thumbs::-webkit-scrollbar { display: none; }
.thumbs img { width: 68px; height: 68px; object-fit: cover; border-radius: var(--radius-sm); flex: none; }
.thumb-wrap { position: relative; flex: none; }
/* Файл в списке вложений поста: плитка того же размера, что и фото. */
.thumb-doc {
  width: 68px; height: 68px; border-radius: var(--radius-sm); background: var(--fill);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; font-size: 20px; color: var(--text-2);
}
.thumb-doc small {
  font-size: 10px; line-height: 1.1; max-width: 62px; text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Крестик удаления — внутри плитки, а не свисающий с угла: снаружи его
   подрезала прокрутка ленты вложений, и попасть пальцем в 22 точки, которые
   вдобавок наполовину за краем, было почти невозможно. */
.thumb-wrap button {
  position: absolute; top: 4px; right: 4px;
  width: 26px; height: 26px; padding: 0; border-radius: 50%;
  border: 0; background: rgba(0, 0, 0, .55); color: #fff;
  font-size: 13px; line-height: 1; cursor: pointer;
  display: grid; place-items: center;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  touch-action: manipulation;          /* тап, а не начало прокрутки ленты */
  transition: transform var(--fast), background var(--fast);
}
/* Область попадания больше самой кнопки: палец не обязан быть точным. */
.thumb-wrap button::before {
  content: ''; position: absolute; inset: -9px;
}
.thumb-wrap button:active { transform: scale(.85); background: var(--danger); }

/* ---------- статистика ---------- */

.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s2); margin-top: var(--s3); }
.kpi {
  background: var(--bg-elevated); border-radius: var(--radius-sm);
  padding: var(--s2) var(--s1); text-align: center;
}
.kpi b { display: block; font-size: 18px; font-weight: 600; }
.kpi small { color: var(--text-2); font-size: 11px; }

.chart { width: 100%; height: 170px; margin-top: var(--s4); }
.chart .grid { stroke: var(--line); stroke-width: 1; }
.chart .line {
  fill: none; stroke: var(--accent); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round;
  stroke-dasharray: 1000; stroke-dashoffset: 1000; animation: draw 1s var(--ease) forwards;
}
@keyframes draw { to { stroke-dashoffset: 0; } }
.chart .area { fill: var(--accent); opacity: .12; animation: fade-in .6s .2s var(--ease) both; }
@keyframes fade-in { from { opacity: 0; } to { opacity: .12; } }
.chart .dot { fill: var(--accent); }
.chart text { fill: var(--text-3); font-size: 10px; }

/* ---------- справка ---------- */

.faq { background: var(--bg-elevated); border-radius: var(--radius); overflow: hidden; }
.faq-item + .faq-item { border-top: 1px solid var(--line); }
.faq-q {
  display: flex; align-items: center; gap: var(--s3);
  width: 100%; padding: var(--s3) var(--s4);
  background: none; border: 0; color: var(--text);
  font: inherit; font-size: 15px; font-weight: 500; text-align: left; cursor: pointer;
  transition: background var(--fast);
}
.faq-q:active { background: var(--fill); }
.faq-q .grow { flex: 1; min-width: 0; }
.faq-q .chev { transform: rotate(45deg) translate(-2px, -2px); }
.faq-item.open .faq-q { color: var(--accent); }
.faq-item.open .faq-q .chev { border-color: var(--accent); transform: rotate(-135deg) translate(-2px, -2px); }
.faq-a {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--slow), opacity var(--slow);
  opacity: 0;
}
.faq-item.open .faq-a { grid-template-rows: 1fr; opacity: 1; }
.faq-inner { overflow: hidden; min-height: 0; }
.faq-a p {
  margin: 0 0 var(--s3); padding: 0 var(--s4); font-size: 15px; line-height: 1.45; color: var(--text);
}
.faq-a p:first-child { padding-top: var(--s1); }
.faq-a code {
  background: var(--fill); padding: 1px 6px; border-radius: 6px;
  font-size: 13px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ---------- уведомление ---------- */

.toast {
  position: fixed; left: 50%; bottom: calc(100px + env(safe-area-inset-bottom));
  transform: translate(-50%, 0); z-index: 60;
  background: rgba(0, 0, 0, .88); color: #fff;
  padding: var(--s3) var(--s4); border-radius: var(--radius-sm);
  font-size: 15px; max-width: 90vw; text-align: center;
  animation: toast-in .24s var(--ease);
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 12px); } to { opacity: 1; transform: translate(-50%, 0); } }
.toast.hidden { display: none; }
.toast.err { background: var(--danger); }

/* Полоса режима проверки — намеренно кричащая, чтобы её не забыли выключить */
.mode-bar {
  background: var(--warn); color: #241a00;
  padding: 7px var(--s3); font-size: 13px; font-weight: 600; text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- кнопка темы ---------- */

/* Показываем то, куда нажатие переключит: в светлой теме — луну. */
#btn-theme svg { width: 19px; height: 19px; }
#btn-theme .i-moon { display: block; }
#btn-theme .i-sun { display: none; }
:root[data-theme="dark"] #btn-theme .i-moon { display: none; }
:root[data-theme="dark"] #btn-theme .i-sun { display: block; }

/* ---------- календарь ---------- */

.cal { padding: 0 var(--s1); }
.cal-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--s3);
}
.cal-head b { font-size: 17px; font-weight: 600; }
.cal-head .icon-btn { font-size: 20px; line-height: 1; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cal-week span {
  text-align: center; font-size: 12px; color: var(--text-3); padding-bottom: var(--s1);
}
.cal-cell {
  aspect-ratio: 1; min-height: 40px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%; background: none; color: var(--text);
  font: inherit; font-size: 16px; font-variant-numeric: tabular-nums; cursor: pointer;
  transition: background var(--fast), color var(--fast), transform var(--fast);
}
.cal-cell.empty { pointer-events: none; }
.cal-cell:active { transform: scale(.88); }
.cal-cell:disabled { color: var(--text-3); opacity: .35; pointer-events: none; }
.cal-cell.today { color: var(--accent); font-weight: 700; }
.cal-cell.on {
  background: var(--accent); color: var(--on-accent); font-weight: 600;
}

/* ---------- фильтр постов ---------- */

/* Узкий вариант переключателя: три раздела со счётчиками должны влезать
   в ширину телефона, не переносясь. */
.segmented.tight { margin-top: 0; margin-bottom: var(--s3); }
.segmented.tight button { font-size: 13px; padding: 0 var(--s1); }
.segmented .cnt {
  display: inline-block; margin-left: 5px; padding: 0 5px;
  border-radius: 6px; background: var(--fill); color: var(--text-2);
  font-size: 11px; font-weight: 600; vertical-align: 1px;
}
.segmented button.on .cnt { background: var(--accent-soft); color: var(--accent); }

/* Найденные площадки, куда писать нельзя, — блёклым: видно, что нашлись,
   но брать их нечего. */
.list.muted { opacity: .55; }

/* Кнопки журнала не должны липнуть к плиткам метрик. */
.kpis + .toolbar { margin-top: var(--s4); }

/* Кнопка, отбитая от поля над ней: без отступа «Войти через ВК» слипалась
   с полем названия и читалась как его часть. */
.btn.spaced, .ghost.spaced { margin-top: var(--s5); }

/* Видео во вложении: показываем проигрыватель, как это делает лента ВК. */
.vkvideo {
  display: block; width: 100%; max-height: 340px;
  background: #000; object-fit: contain;
}
.vkpost-videos { display: grid; gap: 2px; }
.vkpost-photos + .vkpost-videos { margin-top: 2px; }

/* ---------- загрузка вложений ---------- */

/* Полоса прогресса: без неё после выбора тяжёлого видео экран просто замирал,
   и было непонятно, идёт загрузка или приложение зависло. */
.uploading {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(100px + env(safe-area-inset-bottom)); z-index: 60;
  width: min(calc(100% - var(--s5)), 420px);
  background: var(--bg-elevated); border-radius: var(--radius);
  padding: var(--s3) var(--s4); box-shadow: var(--shadow);
  animation: fade-up .2s var(--ease);
}
.uploading.hidden { display: none; }
.uploading span {
  display: block; font-size: 14px; color: var(--text-2); margin-bottom: var(--s2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.uploading .bar {
  height: 6px; border-radius: 999px; background: var(--fill); overflow: hidden;
}
.uploading .bar i {
  display: block; height: 100%; width: 0; border-radius: 999px;
  background: var(--accent); transition: width .18s linear;
}
/* Пока сервер принимает и отдаёт ответ, процент стоит на 100 — показываем,
   что работа не кончилась, бегущей заливкой. */
.uploading.waiting .bar i {
  width: 100% !important;
  background: linear-gradient(90deg, var(--accent-soft), var(--accent), var(--accent-soft));
  background-size: 200% 100%;
  animation: bar-slide 1.1s linear infinite;
}
@keyframes bar-slide { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* ---------- отступы формы добавления сообществ ---------- */

/* Подсказка, строка поиска и результаты стояли впритык друг к другу —
   форма читалась как одна сплошная простыня. */
#f-src-hint { margin: var(--s3) 0 var(--s4); }
#f-find + #f-results, #f-paste + #f-results { margin-top: var(--s3); }
#f-results:not(:empty) { margin-bottom: var(--s3); }
#f-paste .btn.spaced { margin-top: var(--s3); }

/* ---------- фильтр по наборам ---------- */

/* Второй ряд фильтров постов: слева «в каком наборе», справа счётчик.
   Отдельной строкой, потому что в один ряд с «Черновики/Вышли/Все»
   на телефоне это уже не влезает. */
.filterbar { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s3); }
.filterbar .picker { height: 36px; font-size: 14px; }

/* Предупреждение: план собран, но кое-что стоит знать. Не отказ — цвет мягкий. */
.warn-note {
  background: var(--warn-soft); border-radius: var(--radius-sm);
  padding: var(--s2) var(--s3); margin-top: var(--s2);
}

/* Поле для вставки списка сообществ: моноширинный, чтобы `[club123|@name]`
   читалось построчно и было видно, где кончается строка. */
#f-list-text {
  min-height: 150px; font-size: 13px; line-height: 1.5;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
