/* Стили экрана дня — ВЕБ-версия (static/web.html).
 *
 * РАБОЧАЯ КОПИЯ: все правки стилей дневного экрана идут сюда.
 * Мини-апп ТГ (static/app.html) держит свою замороженную копию в
 * history-day.css — расхождение между копиями допустимо и ожидаемо.
 */

.sec-head {
  display: flex; align-items: baseline;
  justify-content: space-between;
  margin: 24px 0 10px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 6px;
}
.sec-head h2 {
  font-size: 11px; font-weight: 600; color: var(--ink);
  text-transform: uppercase; letter-spacing: 0.14em;
  margin: 0;
}
.sec-head h2::before { content: "## "; color: var(--ink-3); font-weight: 400; }
.sec-head .cnt {
  font-size: 11px; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.1em;
}

.sessions { display: grid; gap: 14px; }

.session {
  background: var(--paper);
  border: 1px solid var(--ink);
  position: relative;
}
.ses-head {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--ink);
  background: var(--bg-2);
}
.ses-idx {
  font-size: 11px; font-weight: 700;
  background: var(--ink); color: var(--paper);
  padding: 3px 6px; letter-spacing: 0.04em;
}
.ses-title { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ses-name {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 17px; font-weight: 600;
  letter-spacing: -0.01em; line-height: 1.1;
  color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ses-format {
  font-size: 10px; text-transform: uppercase;
  letter-spacing: 0.1em;
  display: inline-flex; align-items: center; gap: 6px;
  align-self: flex-start; padding: 2px 6px;
  background: var(--fmt-bg, var(--bg-2));
  color: var(--fmt-ink, var(--ink));
  border: 1px solid var(--fmt-line, var(--line));
}
.ses-variation {
  font-size: 10px; text-transform: lowercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  align-self: flex-start; padding: 2px 6px;
  border: 1px dashed var(--line);
  font-family: 'JetBrains Mono', monospace;
}
.ses-variation::before { content: "// "; color: var(--ink-4); }
.ses-meta {
  display: grid; grid-template-columns: repeat(2, 1fr);
  border-bottom: 1px solid var(--line);
}
.ses-meta .item {
  padding: 8px 12px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  display: flex; justify-content: space-between;
  align-items: baseline; gap: 8px;
}
.ses-meta .item:nth-child(2n) { border-right: none; }
.ses-meta .item:last-child { border-bottom: none; }
.ses-meta .k {
  color: var(--ink-3); font-size: 10px;
  text-transform: uppercase; letter-spacing: 0.08em;
  white-space: nowrap;
}
.ses-meta .v {
  color: var(--ink); font-weight: 600;
  text-align: right; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.ses-meta .v .u { color: var(--ink-3); font-weight: 400; margin-left: 2px; font-size: 10px; }
.ses-meta:empty { display: none; }

.ses-props {
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 6px;
  font-size: 11px;
}
.ses-props:empty { display: none; }
.chip {
  display: inline-flex; gap: 6px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  background: var(--bg-2);
  align-items: baseline;
}
.chip .k { color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.06em; font-size: 9px; }
.chip .v { color: var(--ink); }

.ses-empty {
  padding: 16px 12px;
  color: var(--ink-3); font-size: 11px;
  text-align: center;
  text-transform: uppercase; letter-spacing: 0.12em;
}
.ses-empty::before { content: "// "; }

.exercises { padding: 0; }
.ex {
  border-bottom: 1px solid var(--line);
  padding: 12px;
  position: relative;
}
.ex:last-child { border-bottom: none; }
.ex-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.ex-body { padding-left: 32px; }
.ex-marker { font-size: 10px; color: var(--ink-3); font-weight: 500; letter-spacing: 0.04em; flex-shrink: 0; }
.ex-name {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 15px; font-weight: 600;
  color: var(--ink); letter-spacing: -0.005em;
  line-height: 1.2; flex: 1; min-width: 0;
  word-break: break-word;
}
.support-flag {
  display: inline-block; font-size: 8px;
  text-transform: uppercase; letter-spacing: 0.12em;
  color: var(--ink-3); border: 1px solid var(--line);
  padding: 1px 4px; margin-left: 6px; vertical-align: 2px;
  font-family: 'JetBrains Mono', monospace; font-weight: 500;
}
.ex-variation {
  display: inline-block; font-size: 9px;
  text-transform: lowercase; letter-spacing: 0.04em;
  color: var(--ink-3); border: 1px dashed var(--line);
  padding: 1px 5px; margin-left: 6px; vertical-align: 2px;
  font-family: 'JetBrains Mono', monospace;
}
.ex-variation::before { content: "// "; color: var(--ink-4); }
.ex-sub { font-size: 11px; color: var(--ink-3); display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-bottom: 8px; }
.ex-sub .tag { color: var(--ink-2); }

.ex-props { margin-bottom: 8px; font-size: 11px; color: var(--ink-3); }
.ex-props .pk { text-transform: uppercase; letter-spacing: 0.06em; font-size: 9px; }
.ex-props .pv { color: var(--ink); }

.ex-totals { display: flex; gap: 14px; margin-bottom: 8px; font-size: 10px; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.08em; }
.ex-totals .v { color: var(--ink); font-weight: 700; font-size: 12px; letter-spacing: 0; }

.sets { display: grid; gap: 4px; }
.set {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  align-items: start;
  gap: 8px;
  padding: 6px 8px;
  background: var(--bg-2);
  font-size: 12px;
  border-left: 2px solid var(--ink);
}
.set.warmup { background: transparent; border-left: 2px dashed var(--ink-4); }
.set.empty { background: transparent; border-left: 2px dotted var(--ink-4); }
.set.empty .set-vals { color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.1em; font-size: 10px; }
.set-n { font-size: 10px; color: var(--ink-3); font-weight: 600; letter-spacing: 0.04em; }
.set-vals { display: flex; flex-wrap: wrap; gap: 4px 12px; min-width: 0; }
.set-vals .pair { display: inline-flex; align-items: baseline; gap: 3px; white-space: nowrap; }
.set-vals .v { font-weight: 600; color: var(--ink); font-size: 13px; }
.set-vals .v.q { color: var(--ink-4); font-weight: 500; }
.set-vals .v.fail { color: var(--warn); }
.set-vals .u { font-size: 10px; color: var(--ink-3); text-transform: lowercase; }
.set-aside { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; flex-shrink: 0; padding-top: 1px; }
.set-tag { font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-3); text-align: right; white-space: nowrap; }
.set-tag.warmup { color: var(--ink-2); }
.set-tag.warmup::before { content: "~ "; }
.set-note { font-size: 10px; line-height: 1.3; color: var(--ink-2); text-align: right; max-width: 220px; white-space: normal; }
.set-note::before { content: "// "; color: var(--ink-4); }
.set-prop { font-size: 10px; color: var(--ink-2); text-align: right; white-space: nowrap; }
.set-prop .pk { color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.06em; font-size: 9px; margin-right: 4px; }

/* ── Тред исходных инпутов + «Нужны правки» (новый флоу) ── */
/* .ent-block — <details>, свёрнут по умолчанию (см. renderEntryBlock). */
.ent-block {
  border-top: 1px dashed var(--line);
  padding: 12px;
}
.ent-summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  -webkit-tap-highlight-color: transparent;
}
.ent-summary::-webkit-details-marker { display: none; }
.ent-summary::after {
  content: "[ + ]";
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; color: var(--ink-3); letter-spacing: 0.04em;
  flex-shrink: 0;
}
.ent-block[open] > .ent-summary::after { content: "[ − ]"; }
.ent-block[open] > .ent-summary { margin-bottom: 10px; }
.ent-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--ink-3);
}
.ent-label::before { content: "// "; color: var(--ink-4); }
.ent-list { display: flex; flex-direction: column; gap: 6px; }
.ent-msg {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px; line-height: 1.4;
  color: var(--ink-2);
  white-space: pre-wrap; word-break: break-word;
  background: var(--bg-2);
  border-left: 2px solid var(--line);
  padding: 6px 8px;
}
.ent-msg.corr {
  border-left-color: var(--ink-4);
  color: var(--ink-2);
}
.ent-msg.corr::before {
  content: "[правка] ";
  color: var(--ink-4);
  text-transform: uppercase; letter-spacing: 0.06em; font-size: 10px;
}
/* Кнопка правки в правом верхнем углу шапки тренировки (line-art карандаш). */
.ent-fix-icon {
  appearance: none; -webkit-appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  flex-shrink: 0;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.12s, color 0.12s;
}
.ent-fix-icon:active { background: var(--ink); color: var(--paper); }
.ent-fix-icon svg { width: 15px; height: 15px; display: block; }

/* Карточка неразобранного ввода */
.session.unparsed {
  border-color: var(--ink-4);
}
.session.unparsed .ses-head { background: var(--bg-2); border-bottom-color: var(--ink-4); }
.ses-idx.warn { background: var(--warn); color: var(--paper); }
.unparsed-body {
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

@media (max-width: 480px) {
  .ses-head { grid-template-columns: auto 1fr auto; padding: 10px; }
  .ses-meta { grid-template-columns: 1fr; }
  .ses-meta .item { border-right: none !important; }
  .ex { padding: 10px; }
  .ex-body { padding-left: 0; }
}

/* ══════════════════════════════════════════════════════════════════
   Сообщения дня — одно сохранение (web_entries) = одно сообщение. Карточка —
   ТОЛЬКО ПРОСМОТР (текст + время + огонёк + кнопка «⋮»). Меню «⋮»:
   «редактировать» открывает панель #edit-sheet (стили — в web.html, «как
   инбокс»), «удалить» удаляет прямо с экрана дня (confirm).
   См. render-day-web.js / openEditSheet / doDayDelete.
   ══════════════════════════════════════════════════════════════════ */
/* ── Черновики дня (СПИСКОМ над готовыми сообщениями) ──
   Черновик — обычная запись web_entries с is_draft=true, просто свёрнутая:
   тег + кнопка «⋮» (справа вверху, в меню один пункт «удалить») + однострочное
   превью, без времени и огонька. Их в дне может быть сколько угодно. Тап по
   плашке (вне «⋮») открывает ту же панель-редактор, что «редактировать» у
   готового сообщения. Жёлтый тег роднит блок с точкой этого дня в календаре.
   (Локальный несохранённый текст инбокса тут больше не показывается — он
   виден только внутри инбокса, меткой на «+».) */
.day-draft-list { margin-bottom: 4px; }
.day-draft {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  text-align: left;
  /* Серый пунктир — как у заглушки .empty-day: «этого ещё нет в базе». */
  border: 1px dashed var(--ink-4);
  background: var(--paper);
  padding: 9px 12px 10px;
  margin-bottom: 10px;
  cursor: pointer;
  font-family: inherit;
  -webkit-tap-highlight-color: transparent;
}
/* Прижатый фон — только когда жмут САМУ плашку: браузерный :active поднимается
   с нажатого элемента на предков, и без :not(:has(...)) тап по «⋮» или пункту
   его меню («удалить») мигал бы фоном всей плашки. */
.day-draft:active:not(:has(.msg-menu-wrap :active)) { background: var(--bg-2); }
/* Метка блока — жёлтая плашка: единственный акцент в приглушённом блоке
   (пунктир + серый текст), роднит его с меткой на «+» и точкой в календаре —
   это один и тот же черновик. Пробовали серую без плашки — вернули жёлтую. */
.day-draft-tag {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  background: var(--hl-yellow);
  color: var(--ink);
  padding: 2px 5px;
}
/* Текст черновика — ЦЕЛИКОМ и с форматированием: тот же .msg-body + .msg-para
   (renderRich), что у готового сообщения и у карточки-черновика в ленте.
   Однострочного превью с многоточием тут больше нет — черновик выглядит
   одинаково во всех трёх местах. Своё правило оставлено ради приглушённой
   типографики плашки; селектор с предком — чтобы перебить .msg-body ниже в
   файле (у него та же специфичность, но он объявлен позже). */
.day-draft .day-draft-text {
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-3);   /* серый, как текст заглушки пустого дня */
}

/* Под последним сообщением — «воздух» высотой в 1.5 плавающей кнопки «+»
   (.cal-fab = 52px). При длинном списке даёт проскроллить так, чтобы «+» (fixed,
   в правом нижнем углу) висела над пустотой, а не над последней карточкой. */
.msg-list { display: flex; flex-direction: column; gap: 10px; padding-bottom: calc(52px * 1.5); }

.msg {
  border: 1px solid var(--line);
  background: var(--paper);
  padding: 10px 12px;
}

.msg-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;   /* база; поверхности задают свой отбив, см. ниже */
}
/* Отбив шапки от текста задаёт КАЖДАЯ поверхность отдельно (база выше —
   на случай новой): в дне 1.5×, в ленте 2× — там карточки стоят реже и
   шапке нужно больше воздуха, чтобы не липнуть к тексту. */
.msg-list .msg-head,
.day-draft .msg-head { margin-bottom: 9px; }
/* Левая группа шапки — ЕДИНАЯ для всех мест, где показывается сообщение
   (карточка дня, плашка черновика, карточка ленты): [ЧЕРНОВИК] · огонёк ·
   время. Собирает её messageHead в render-day-web.js. Справа в шапке остаются
   только действия («⋮»), поэтому space-between у .msg-head разводит их по краям
   даже когда действий нет (одна группа = прижата влево). */
.msg-head-left { display: flex; align-items: center; gap: 7px; min-width: 0; }
/* Огонёк рядом с временем — без собственных полей (интерактивный вариант в
   инбоксе/редакторе живёт со своим паддингом-хит-зоной, тут кликать нечего). */
.msg-head-left .intensity.int-ro { padding: 0; }
/* Оптическое центрирование огонька по времени. align-items: center равняет
   БОКСЫ, а краска внутри них лежит несимметрично, и огонёк уезжал вниз:
   • ink огонька на 0.5/24 viewBox ниже центра своего бокса (у пути низ —
     дуга радиусом 7 от y=15, т.е. до y=22, а верх — только y=3) = 0.31px
     при иконке 15px;
   • ink цифр, наоборот, на ~0.28px ВЫШЕ центра строчного бокса (в line-box
     заложен descender, а в «08:02» его нет).
   Суммарно 0.59px — замерено в браузере и для JetBrains Mono, и для
   системного mono-фолбэка (значения совпали до сотых), поэтому правим
   константой, а не подгонкой под шрифт. */
.msg-head-left .int-flame { transform: translateY(-0.6px); }
.msg-time {
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
/* Пометка «не отправлено»: запись сохранена локально, но до сервера ещё не
   доехала (офлайн-очередь, см. docs/web-frontend.md § «Локальное зеркало»).
   Появляется редко — только пока нет связи, — поэтому места в шапке занимает
   минимум: значок в размер строки времени, тем же приглушённым цветом. */
.msg-unsent {
  display: inline-flex;
  align-items: center;
  color: var(--ink-3);
}
.msg-unsent svg { width: 12px; height: 12px; display: block; }

/* Кнопка «⋮» (меню действий) в шапке карточки сообщения и на плашке черновика.
   БЕЗ рамки и фона — только сами точки: квадратик вокруг них читался как ещё
   один бордюр внутри и без того обведённой карточки. Габарит 26×26 при этом
   СОХРАНЁН (у нас глобальный box-sizing: border-box, снятый 1px-бордюр размер
   не менял) — область тапа осталась прежней, не ужимать до размера иконки.
   Прижатие и открытое меню ([aria-expanded=true]) отзываются цветом точек, а не
   инверсией фона: заливка вернула бы ровно тот квадрат, который убирали. */
.msg-more {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: none;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.msg-more:active,
.msg-more[aria-expanded="true"] { color: var(--ink); }
.msg-more svg { width: 14px; height: 14px; display: block; }

/* Выпадающее меню «⋮»: прямоугольник в стайлгайде (рамка --ink, без скруглений),
   выпадает под кнопкой, прижат к правому краю. Пункты — иконка слева + UPPERCASE-
   текст; «удалить» подсвечивается --warn. Обёртка позиционирования — .msg-menu-wrap
   (position:relative вокруг кнопки), логика открытия/закрытия — render-day-web.js. */
.msg-menu-wrap { position: relative; display: inline-flex; }
.msg-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 30;
  min-width: 172px;
  border: 1px solid var(--ink);
  background: var(--paper);
}
.msg-menu-item {
  appearance: none;
  -webkit-appearance: none;
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 9px 12px;
  border: none;
  background: transparent;
  color: var(--ink-2);
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.msg-menu-item + .msg-menu-item { border-top: 1px solid var(--line-2); }
.msg-menu-item:hover { background: var(--bg-2); color: var(--ink); }
.msg-menu-item:active { background: var(--ink); color: var(--paper); }
.msg-menu-item .mi-ico { display: inline-flex; flex: none; }
.msg-menu-item .mi-ico svg { width: 14px; height: 14px; display: block; }
.msg-menu-item.mi-del:hover { color: var(--warn); }
.msg-menu-item.mi-del:active { background: var(--warn); color: var(--paper); }

.msg-body {
  font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-wrap;
  overflow-wrap: break-word;
  word-break: break-word;
  /* ПРОБЕЛ В ПРОСМОТРЕ — 2× натурального (просьба юзера 2026-09-05). word-spacing
     ДОБАВЛЯЕТСЯ к собственной ширине пробела шрифта, поэтому «в два раза» = +1
     ширина пробела. Просмотр везде тёмный и рисуется Manrope (--d-ui), у него
     пробел ровно 0.2em (замерено в chromium на 13/16/100px) → +0.2em.
     ⚠️ Значение ЗАВЯЗАНО НА ШРИФТ: меняешь семейство текста просмотра —
     перемеряй ширину пробела (span 'aa' против 'a a') и пересчитывай.
     Правило живёт в БАЗОВОМ .msg-body намеренно, без скоупа поверхности: один
     renderRich рисует карточку дня, плашку черновика и карточку ленты — им
     нельзя разъезжаться (см. предупреждение у .msg-tok.is-activity ниже).
     В режиме ПРАВКИ пробел свой, 1.5× (.cal-sheet .tag-field в web.html). */
  word-spacing: 0.2em;
}
/* Абзац просмотра — блок по '\n'-границе (renderRich в render-day-web.js): каждая
   строка/пункт списка. Отступ МЕЖДУ абзацами в 1.5× больше строки: блочная
   раскладка уже даёт 1 line-height (1.5em) между абзацами, +0.75em margin =
   2.25em = 1.5× обычной строки. Переносы ВНУТРИ абзаца (мягкий wrap) остаются на
   line-height 1.5 и отступа не получают. Первый абзац сверху без margin. */
.msg-para { margin: 0; }
.msg-para + .msg-para { margin-top: 0.75em; }
/* Пункт словаря в РЕЖИМЕ ПРОСМОТРА — обычный текст, без рамки тега. Рамки/×
   появляются только в режиме правки (поле .tag-field, теги .tok). */
.msg-tok { display: inline; }
/* Пункт-активность (dictionary.is_activity) — жирный текст (иконки в просмотре нет). */
.msg-tok.is-activity { font-weight: 700; }
/* Иконка слева от текста токена (сейчас тег — хештег, локация — пин, тренер —
   человек; те же SVG, что в тегах инбокса).

   ⚠️ ПРАВИЛО ПРОСМОТРА (на ВСЕ иконки токена, включая будущие): между иконкой
   и следующим за ней словом ЗАЗОРА НЕТ — ни пробельного узла в разметке (его и
   не было, поэтому перенос между ними не случится), ни margin. Просьба юзера
   2026-09-02: иконка читается как часть слова, а не как отдельный значок перед
   ним. Правило только для ПРОСМОТРА (день и ленты) — в редакторе (.tok-ic в
   web.html) зазор остаётся, там иконка живёт внутри пилюли-тега. */
.msg-tok-ic {
  display: inline-flex;
  align-items: center;
  vertical-align: -2px;
  margin-right: 0;
  color: var(--ink-3);
}
.msg-tok-ic svg { width: 13px; height: 13px; display: block; }

/* Тег / локация / тренер в ПРОСМОТРЕ — ССЫЛКА-ФИЛЬТР (класс ставит renderRich,
   когда web.html дал opts.onTokenClick): клик включает чип этой сущности в
   общем фильтре. Правила общие для дня и лент — как и остальные .msg-tok*,
   БЕЗ скоупа поверхности (см. предупреждение в тёмной секции ниже).

   • ЦВЕТ ТЕКСТА = цвету иконки (.msg-tok-ic выше) — ссылка читается одной
     краской «значок + слово», а не «серый значок + чёрное слово».
   • ПОДЧЁРКИВАНИЕ по ховеру — НА ВЕСЬ токен: линия, заданная на .msg-tok-link,
     проходит и под атомарной inline-flex иконкой, поэтому «иконка + слово»
     подчёркиваются одной непрерывной чертой. Ставить её на вложенный текст
     нельзя — иконка осталась бы без линии.
   • Outline на :focus НЕ снимаем — клавиатурная навигация по ссылкам должна
     быть видна; :focus-visible дополнительно подчёркиваем, как на ховере.

   ⚠️ В РЕЖИМЕ ПРАВКИ этого класса не бывает: там пункты словаря рисуются
   пилюлями .tok (makeTag в web.html), и ссылок в них нет. */
.msg-tok-link {
  color: var(--ink-3);
  cursor: pointer;
  text-decoration: none;
}
.msg-tok-link:hover,
.msg-tok-link:focus-visible {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ══════════════════════════════════════════════════════════════════
   ЭКРАН ДНЯ — ТЁМНЫЙ (design_handoff_day_dark, экраны 13–14)
   ─────────────────────────────────────────────────────────────────
   Применён 2026-08-13: день догнал остальные экраны дневника (календарь,
   ленты, инбокс). Всё выше в файле — прежняя СВЕТЛАЯ база; она осталась
   потому, что теми же классами (.msg*, .day-draft*) можно нарисовать
   сообщение вне тёмного дневника, и разъезжаться такая поверхность не должна.

   Скоуп двойной: `body.theme-dark` (тема) + `.msg-list` / `.day-draft-list`
   (сам день). Карточки ЛЕНТЫ (.feed-msg) держат СВОИ правила в конце
   history-cal-web.css — метрика у них чуть другая (шапка отбита 11px против
   10px, текст 1.9 против 1.85), поэтому селекторы намеренно не общие.
   ══════════════════════════════════════════════════════════════════ */

/* Черновики — та же карточка, что и сообщения, но пунктиром на полупрозрачной
   подложке и с приглушённым текстом. Шаг между карточками 10px во всём
   списке, включая стык «последний черновик → первое сообщение». */
body.theme-dark .day-draft-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 10px;
}
body.theme-dark .day-draft {
  margin-bottom: 0;
  padding: 12px 14px;
  border: 1px dashed #2b4a59;
  border-radius: 16px;
  background: rgba(18, 38, 49, 0.5);
}
/* Прижатая плашка — тот же приподнятый градиент, что у карточки-черновика в
   ленте. Guard :not(:has(...)) прежний: :active всплывает с «⋮» на предка. */
body.theme-dark .day-draft:active:not(:has(.msg-menu-wrap :active)) {
  background: var(--d-raise);
}
/* Текст черновика — та же метрика, что у сообщения дня (Manrope 13/1.85), но
   приглушённый, как у карточки-черновика в ленте (.feed-msg.is-draft
   .msg-body). Показывается ЦЕЛИКОМ, с абзацами и токенами: превью в одну
   строку тут больше нет. */
body.theme-dark .day-draft .day-draft-text {
  font-family: var(--d-ui);
  font-size: 13px;
  line-height: 1.85;
  color: var(--ink-3);
}
/* Метка «черновик» — циановая пилюля со СПЛОШНОЙ рамкой (жёлтая плашка светлой
   темы в тёмной гамме не используется), строчными, как в макете. Пунктир носит
   только сама плашка-карточка: два пунктира вложенно читались грязно. */
body.theme-dark .day-draft .day-draft-tag {
  padding: 2px 8px;
  border: 1px solid #2a86a5;
  border-radius: 999px;
  background: none;
  color: var(--d-accent);
  font-family: var(--d-mono);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.06em;
  text-transform: none;
}

/* Карточка сообщения — скруглённая (r16) карточка-градиент с рамкой. */
body.theme-dark .msg-list .msg {
  padding: 12px 14px;
  border: 1px solid var(--d-border);
  border-radius: 16px;
  background: var(--d-card);
}

/* Шапка: огонёк 14px цианом + время моно-подписью, отбив от текста 10px. */
body.theme-dark .msg-list .msg-head,
body.theme-dark .day-draft .msg-head { margin-bottom: 10px; }
body.theme-dark .msg-list .msg-head-left,
body.theme-dark .day-draft .msg-head-left { gap: 8px; }
body.theme-dark .msg-list .msg-time,
body.theme-dark .day-draft .msg-time {
  font-family: var(--d-mono);
  font-size: 11px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--d-label);
}
body.theme-dark .msg-list .msg-unsent,
body.theme-dark .day-draft .msg-unsent { color: var(--d-label); }
body.theme-dark .msg-list .msg-unsent svg,
body.theme-dark .day-draft .msg-unsent svg { width: 13px; height: 13px; }

/* Оптическое центрирование огонька по времени — та же поправка, что в светлой
   базе (см. её длинный комментарий выше), но пересчитанная под ТЁМНУЮ метрику:
   огонёк 14px вместо 15px, время — IBM Plex Mono 11px вместо JetBrains Mono 9px
   капсом. Суммарная разница краски там 0.12px, а не 0.6px — со старой поправкой
   огонёк уезжал ВВЕРХ почти на полпикселя (test_flame_and_time_optically_centered).
   ⚠️ Обе константы завязаны на ФОРМУ значка: под молнию (проба 2026-09-03,
   откачена) знак поправки переворачивался. Меняешь путь — перемеряй тестом.
   Скоуп — вся тёмная тема: у карточек ленты метрика шапки ровно такая же. */
body.theme-dark .msg-head-left .int-flame { transform: translateY(-0.12px); }

/* Огонёк в шапке сообщения/черновика — шкала = степень заливки силуэта
   (пусто → чуть меньше половины → целиком, клипы .int-stop.lN из базы web.html),
   контур у всех трёх уровней одного цвета и размера. Гашение «1» и «2» группой
   до --fire-mid откатили — обоснование в комментарии у .cal-cell .fire в
   history-cal-web.css. */
body.theme-dark .msg-list .int-flame,
body.theme-dark .msg-list .int-flame svg,
body.theme-dark .day-draft .int-flame,
body.theme-dark .day-draft .int-flame svg { width: 14px; height: 14px; }
body.theme-dark .msg-list .int-stop.on,
body.theme-dark .day-draft .int-stop.on { color: var(--d-accent); }

/* Текст — пропорциональный (Manrope) вместо моноширинного, интерлиньяж макета.
   Теги-пилюли тут, как и в ленте, НЕ рисуются: активность жирным, локация и
   тренер — иконкой слева обычным весом, остальное обычным текстом. */
body.theme-dark .msg-list .msg-body {
  font-family: var(--d-ui);
  font-size: 13px;
  line-height: 1.85;
  color: var(--ink-2);
}
/* Токены — ОДИН вид на ВСЕХ тёмных поверхностях просмотра: карточка дня,
   плашка черновика в дне и карточка ленты (в т.ч. черновик в ней). Текст всем
   троим рисует один renderRich, и разъезжаться им нельзя.
   ⚠️ Скоуп НАМЕРЕННО без поверхности (`body.theme-dark`, а не `.msg-list` /
   `.day-draft` / `.feed-msg`): пока правила были заскоплены днём, лента
   молча падала на СВЕТЛУЮ базу — активность 700 в цвет тела вместо 800
   белым, пин 13px серый вместо 12px цианового. Именно так черновик в ленте и
   разошёлся с черновиком в дне (правка 2026-09-02 по жалобе пользователя).
   Не возвращать префикс поверхности: `.msg-tok` живёт только в просмотре
   (renderRich), а весь просмотр тёмный. Метрика карточек у ленты и дня
   по-прежнему СВОЯ (шапка 11 против 10px, текст 1.9 против 1.85) — это макет,
   а не расхождение. */
body.theme-dark .msg-tok.is-activity {
  font-weight: 800;
  color: var(--ink);
}
/* ⚠️ `vertical-align: middle` ставит центр иконки на СЕРЕДИНУ x-height (у
   Manrope 13px это baseline − 3.61px), а слово рядом — локация или тренер, т.е.
   имя собственное с ЗАГЛАВНОЙ: его краска идёт от cap-height (9.36px) до
   baseline, центр — baseline − 4.68px. Разница 1.07px и есть та «спущенная»
   иконка; снимаем её подъёмом на 1px (transform не трогает поток — строка не
   разъезжается). Меняешь кегль текста / размер иконки — перемеряй:
   сдвиг = (cap − x-height) / 2 у шрифта строки.
   `margin-right: 0` — общее правило просмотра «иконка приклеена к слову», см.
   светлую базу .msg-tok-ic выше. */
body.theme-dark .msg-tok-ic {
  margin-right: 0;
  vertical-align: middle;
  transform: translateY(-1px);
  /* Тот же циан, что у иконок тегов в РЕЖИМЕ ПРАВКИ (`.cal-sheet .tok-ic`,
     web.html) — просмотр и редактор рисуют одну и ту же иконку и расходиться
     по цвету не должны (просьба юзера 2026-09-03: в просмотре было темнее,
     #2a86a5 — это приглушённый оттенок из состояния «поле под дейт-пикером»). */
  color: var(--d-accent);
}
/* Исключение из подъёма выше: у ТЕГА слово всегда строчное (правило «тег — это
   нижний регистр»), его краска идёт от x-height, и центр совпадает с тем, куда
   `vertical-align: middle` иконку и ставит. Поправка на cap-height тут лишняя —
   она задрала бы иконку на тот самый 1px. */
body.theme-dark .msg-tok.is-tag .msg-tok-ic { transform: none; }
body.theme-dark .msg-tok-ic svg { width: 12px; height: 12px; }
/* Ссылка-фильтр в тёмной теме — текст В ЦВЕТ ИКОНКИ (--d-accent, тот же циан,
   что у .msg-tok-ic выше и у иконок тегов в редакторе).
   ⚠️ Селектор намеренно `.msg-tok.msg-tok-link` (0,3,1), а не голый
   `.msg-tok-link` (0,2,1): пункт, помеченный И активностью, И тегом, красится
   выше правилом `body.theme-dark .msg-tok.is-activity` (0,3,1) в --ink. При
   равной специфичности выигрывает то, что НИЖЕ по файлу, — поэтому ссылка и
   стоит здесь, после активности: жирность от активности остаётся, цвет
   становится ссылочным. */
body.theme-dark .msg-tok.msg-tok-link { color: var(--d-accent); }

/* «⋮» — кнопка В РАМКЕ (26×26, r8): на карточке-градиенте голые точки
   светлой темы терялись. Отрицательные margin — чтобы 26px кнопки не
   растягивали шапку выше строки времени (макет 13). Активное состояние —
   заливка акцентом (в ленте там только цвет: у дня макет 14 явно рисует
   залитую кнопку под открытым меню). */
body.theme-dark .msg-list .msg-more,
body.theme-dark .day-draft .msg-more {
  margin: -6px -6px -6px 0;
  border: 1px solid var(--d-border-2);
  border-radius: 8px;
  background: var(--d-neutral);
  color: var(--ink-3);
}
body.theme-dark .msg-list .msg-more svg,
body.theme-dark .day-draft .msg-more svg { width: 15px; height: 15px; }
body.theme-dark .msg-list .msg-more:active,
body.theme-dark .msg-list .msg-more[aria-expanded="true"],
body.theme-dark .day-draft .msg-more:active,
body.theme-dark .day-draft .msg-more[aria-expanded="true"] {
  border-color: var(--d-accent);
  background: var(--d-accent);
  color: var(--d-on-accent);
}

/* Меню «⋮» — попап r12 на тёмной поверхности, выровнен по правому краю
   карточки (right: -6px компенсирует отрицательный margin кнопки).
   «удалить» сразу в danger-цвете, разделитель — линия с боковыми отбивами
   (в макете это отдельный div, у нас псевдоэлемент второго пункта). */
body.theme-dark .msg-list .msg-menu,
body.theme-dark .day-draft .msg-menu {
  top: calc(100% + 2px);
  right: -6px;
  min-width: 0;
  padding: 4px;
  border: 1px solid var(--d-border-2);
  border-radius: 12px;
  background: #10222d;
  box-shadow: 0 12px 28px rgba(4, 10, 14, 0.6);
}
body.theme-dark .msg-list .msg-menu-item,
body.theme-dark .day-draft .msg-menu-item {
  gap: 8px;
  padding: 9px 20px 9px 11px;
  border-radius: 9px;
  font-family: var(--d-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  color: var(--ink-2);
}
body.theme-dark .msg-list .msg-menu-item .mi-ico,
body.theme-dark .day-draft .msg-menu-item .mi-ico { color: var(--ink-3); }
body.theme-dark .msg-list .msg-menu-item + .msg-menu-item,
body.theme-dark .day-draft .msg-menu-item + .msg-menu-item {
  position: relative;
  margin-top: 7px;               /* 3px воздуха + линия + 3px */
  border-top: none;
}
body.theme-dark .msg-list .msg-menu-item + .msg-menu-item::before,
body.theme-dark .day-draft .msg-menu-item + .msg-menu-item::before {
  content: "";
  position: absolute;
  top: -4px;
  left: 8px;
  right: 8px;
  height: 1px;
  background: #1d3a48;
}
body.theme-dark .msg-list .msg-menu-item.mi-del,
body.theme-dark .msg-list .msg-menu-item.mi-del:hover,
body.theme-dark .day-draft .msg-menu-item.mi-del,
body.theme-dark .day-draft .msg-menu-item.mi-del:hover { color: #ff8a7a; }
body.theme-dark .msg-list .msg-menu-item.mi-del .mi-ico,
body.theme-dark .day-draft .msg-menu-item.mi-del .mi-ico { color: inherit; }
/* Прижатие/ховер — подложка, а не инверсия светлой базы. */
body.theme-dark .msg-list .msg-menu-item:hover,
body.theme-dark .msg-list .msg-menu-item:active,
body.theme-dark .day-draft .msg-menu-item:hover,
body.theme-dark .day-draft .msg-menu-item:active {
  background: var(--d-neutral);
  color: var(--ink);
}
body.theme-dark .msg-list .msg-menu-item.mi-del:active,
body.theme-dark .day-draft .msg-menu-item.mi-del:active {
  background: var(--d-neutral);
  color: #ff8a7a;
}
