/* ============================================================
   Мост • Bridge — design system
   Два цвета — два человека. Градиент — «мы».
   ============================================================ */

:root {
  --him: #5B6CF0;
  --her: #EE5D83;
  --us: linear-gradient(135deg, #5B6CF0 0%, #A664BF 55%, #EE5D83 100%);
  --him-soft: rgba(91, 108, 240, .12);
  --her-soft: rgba(238, 93, 131, .12);
  --gold: #C99A3F;                                   /* тёплый акцент — «сургуч письма», особые моменты */
  --gold-soft: rgba(201, 154, 63, .12);

  --bg: #FAF6EF;                                     /* тёплая бумага */
  --surface: #FFFDFA;
  --surface-2: #F1EBDF;
  --text: #2A2733;
  --muted: #837f8c;
  --border: #EBE4D6;
  --shadow: 0 6px 22px rgba(74, 56, 30, .08);        /* тёплая мягкая тень (не серая) */
  --shadow-lift: 0 14px 44px rgba(74, 56, 30, .16);

  --ok: #3EC58A;
  --danger: #E25555;

  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-head: "Lora", Georgia, "Times New Roman", serif;   /* тёплый литературный сериф — заголовки */
  --font-accent: "Caveat", "Segoe Script", cursive;         /* рукописный — имя приложения и подписи */

  --r-lg: 20px;
  --r-md: 14px;
  --r-sm: 10px;

  --tab-h: 62px;
  --header-h: 54px;
  --safe-b: env(safe-area-inset-bottom, 0px);
}

[data-theme="dark"] {
  --bg: #14151F;
  --surface: #1D1E2C;
  --surface-2: #262838;
  --text: #EDEDF4;
  --muted: #9c9aae;
  --border: #2D2F42;
  --shadow: 0 6px 24px rgba(0, 0, 0, .35);
  --shadow-lift: 0 12px 40px rgba(0, 0, 0, .5);
  --him-soft: rgba(91, 108, 240, .2);
  --her-soft: rgba(238, 93, 131, .2);
  --gold: #E0B968;
  --gold-soft: rgba(224, 185, 104, .16);
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

html, body { height: 100%; }
body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  font-size: 15px;
  line-height: 1.5;
  overscroll-behavior: none;
}

/* Заголовки экранов и окон — тёплый сериф Lora (мелкие uppercase-лейблы остаются системными) */
.header h1, .sheet h2 {
  font-family: var(--font-head);
  letter-spacing: 0;
  font-weight: 600;
}
/* Рукописный акцент — имя приложения и тёплые подписи */
.script { font-family: var(--font-accent); font-weight: 700; letter-spacing: .01em; line-height: 1.1; }

#app { height: 100dvh; display: flex; flex-direction: column; }

button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
input, textarea, select { font: inherit; color: inherit; }
a { color: var(--him); text-decoration: none; }

/* ---------- shell ---------- */
.header {
  height: calc(var(--header-h) + env(safe-area-inset-top, 0px));
  flex: none;
  display: flex; align-items: center; gap: 10px;
  padding: env(safe-area-inset-top, 0px) 16px 0; /* не наезжать на статус-бар/Dynamic Island в PWA */
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
  position: relative; z-index: 5;
}
.header .h-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; }
/* ЗАГОЛОВОК ЭКРАНА ОБЯЗАН СЖИМАТЬСЯ. По умолчанию у флекс-ребёнка min-width: auto, то есть
   контейнер заголовка раздувается по содержимому — и многоточие в h1 не срабатывает ВООБЩЕ.
   Проверено замером 14.08.2026 на 375 px: в «Дневнике» блок заголовка выходил на 175 px при
   доступных 149 и заезжал под колокольчик; на «Сегодня» ему оставалось 31 px — дата вставала
   столбиком по одной букве и вываливалась из шапки на ленту дней.
   Распорка .spacer при этом не должна съедать свободное место раньше заголовка. */
.header .h-main > * { min-width: 0; }
.header .h-main > :first-child { flex: 1 1 auto; }
.header .h-main .spacer { flex: 0 1 auto; }
/* БЮДЖЕТ ШИРИНЫ ШАПКИ на экране 375 px. Общая ширина 343 (за вычетом полей). Оболочка
   держит в ней колокольчик, ДНК, обновление и переключатель языка — 162 px, а экран
   «Сегодня» добавляет ещё две круглые кнопки по 44. С прежними отступами по 10 px
   заголовку оставался 31 px: дата вставала столбиком по букве. Ужимаем на узких экранах
   отступы и круглые кнопки шапки — 44 px пальцевой цели у них сохраняется невидимой
   областью нажатия (см. .dna-btn::after ниже). */
@media (max-width: 420px) {
  .header { gap: 6px; padding-left: 12px; padding-right: 12px; }
  .header .h-main { gap: 6px; }
  .header .round-btn { width: 38px; height: 38px; font-size: 17px; position: relative; }
  .header .round-btn::after { content: ''; position: absolute; inset: -3px; }
  .view-switch button { padding: 4px 5px; }
}
.dna-btn { flex: none; font-size: 19px; width: 32px; height: 32px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; opacity: .8; transition: all .15s;
  position: relative; }
/* кнопки шапки: вид 32 px, область нажатия 44 — по ним промахивались (см. .rt-check) */
.dna-btn::after { content: ''; position: absolute; inset: -6px; }
.dna-btn:active { transform: scale(.85); }
.view-switch { flex: none; }
.header h1 { font-size: 17px; font-weight: 700; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Подпись под заголовком — в одну строку с многоточием: иначе она переносится и выдавливает
   шапку за её собственную высоту (54 px), наезжая на содержимое экрана. */
.header .sub { font-size: 12px; color: var(--muted); margin-top: -2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.header .spacer { flex: 1; }

.main { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; display: flex; flex-direction: column; }
.page { padding: 16px 16px calc(24px + var(--safe-b)); display: flex; flex-direction: column; gap: 14px; }

/* ---------- tab bar ---------- */
.tabbar {
  flex: none;
  display: flex; align-items: stretch;
  height: calc(var(--tab-h) + var(--safe-b));
  padding-bottom: var(--safe-b);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--border);
  z-index: 5;
}
.tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; color: var(--muted); font-size: 10.5px; font-weight: 600;
  transition: color .15s;
}
.tab svg { width: 23px; height: 23px; }
.tab.active { color: var(--text); }
.tab.active .ico-stroke { stroke: url(#usGrad); }
.tab-wheel .disc {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--us);
  display: flex; align-items: center; justify-content: center;
  margin-top: -18px;
  box-shadow: 0 6px 18px rgba(166, 100, 191, .45);
  border: 3px solid var(--bg);
}
.tab-wheel .disc svg { width: 24px; height: 24px; }
.tab-wheel span { margin-top: 1px; }

/* ---------- primitives ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 16px;
  box-shadow: var(--shadow);
}
.card h3 { font-size: 15px; font-weight: 700; margin-bottom: 4px; }
.hint { color: var(--muted); font-size: 13px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border-radius: var(--r-md);
  padding: 12px 18px;
  font-weight: 700; font-size: 14.5px;
  background: var(--surface-2);
  transition: transform .08s, opacity .15s;
  user-select: none;
}
.btn:active { transform: scale(.97); }
.btn[disabled] { opacity: .45; pointer-events: none; }
.btn-primary { background: var(--us); color: #fff; box-shadow: 0 6px 18px rgba(166, 100, 191, .35); }
.btn-ghost { background: transparent; border: 1px solid var(--border); }
.btn-danger { color: var(--danger); background: transparent; border: 1px solid var(--border); }
.btn-sm { padding: 8px 12px; font-size: 13px; border-radius: var(--r-sm); }
.btn-block { width: 100%; }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 13px; font-weight: 600; color: var(--muted);
  transition: all .15s;
  white-space: nowrap;
}
.chip.active { background: var(--text); color: var(--bg); border-color: var(--text); }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.chip-row.scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 0 16px; }
.chip-row.scroll::-webkit-scrollbar { display: none; }

.seg { display: flex; background: var(--surface-2); border-radius: var(--r-md); padding: 4px; gap: 4px; }
.seg button {
  flex: 1; padding: 9px 8px; border-radius: 10px; font-weight: 700; font-size: 13.5px; color: var(--muted);
  transition: all .15s;
}
.seg button.active { background: var(--surface); color: var(--text); box-shadow: var(--shadow); }

.input, .textarea, select.input {
  width: 100%;
  background: var(--surface-2);
  border: 1.5px solid transparent;
  border-radius: var(--r-md);
  padding: 12px 14px;
  font-size: 16px; /* ≥16px — iOS Safari не делает авто-зум при фокусе */
  outline: none;
  transition: border-color .15s;
}
.input:focus, .textarea:focus { border-color: var(--him); background: var(--surface); }
.textarea { resize: none; min-height: 90px; }
.field label { display: block; font-size: 12.5px; font-weight: 700; color: var(--muted); margin-bottom: 6px; text-transform: uppercase; letter-spacing: .04em; }
.field { display: flex; flex-direction: column; }
.form { display: flex; flex-direction: column; gap: 14px; }

/* person identity */
.avatar {
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 800; font-size: 16px;
  flex: none;
}
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; }

input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 6px; border-radius: 3px;
  background: var(--surface-2); outline: none;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--thumb, var(--him));
  border: 3px solid var(--surface);
  box-shadow: var(--shadow);
  cursor: pointer;
}

/* ---------- sheet & overlay ---------- */
.overlay {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(15, 14, 22, .45);
  backdrop-filter: blur(2px);
  animation: fadeIn .18s ease;
}
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 41;
  background: var(--surface);
  border-radius: 24px 24px 0 0;
  padding: 10px 18px calc(22px + var(--safe-b));
  max-height: 88dvh; overflow-y: auto;
  box-shadow: var(--shadow-lift);
  animation: slideUp .24s cubic-bezier(.3, 1.1, .4, 1);
}
.sheet .grab { width: 40px; height: 4px; border-radius: 2px; background: var(--border); margin: 2px auto 14px; }
.sheet h2 { font-size: 18px; font-weight: 800; margin-bottom: 12px; letter-spacing: -.01em; }
@keyframes slideUp { from { transform: translateY(60%); opacity: .4; } to { transform: none; opacity: 1; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.toast {
  position: fixed; left: 50%; bottom: calc(var(--tab-h) + var(--safe-b) + 18px);
  transform: translateX(-50%);
  background: var(--text); color: var(--bg);
  padding: 11px 18px; border-radius: 999px;
  font-size: 13.5px; font-weight: 600;
  z-index: 60; box-shadow: var(--shadow-lift);
  animation: fadeIn .2s ease;
  max-width: 86vw; text-align: center;
}

.fab {
  position: fixed; right: 18px; bottom: calc(var(--tab-h) + var(--safe-b) + 18px);
  width: 54px; height: 54px; border-radius: 18px;
  background: var(--us); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 8px 24px rgba(166, 100, 191, .45);
  z-index: 10; font-size: 26px; font-weight: 400;
  transition: transform .1s;
}
.fab:active { transform: scale(.92); }

.empty {
  text-align: center; padding: 36px 24px; color: var(--muted);
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.empty .big { font-size: 40px; }
.empty p { font-size: 14px; max-width: 300px; }

/* ============================================================
   Login / setup
   ============================================================ */
.hero {
  min-height: 100dvh; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 32px 22px calc(32px + var(--safe-b));
  gap: 20px; text-align: center;
}
.hero .logo {
  width: 84px; height: 84px; border-radius: 28px;
  background: var(--us);
  display: flex; align-items: center; justify-content: center;
  font-size: 42px;
  box-shadow: 0 14px 40px rgba(166, 100, 191, .4);
}
.hero h1 { font-family: var(--font-accent); font-size: 44px; font-weight: 700; letter-spacing: .01em; line-height: 1.05; }
.hero .tagline { color: var(--muted); font-size: 15px; max-width: 320px; }
.hero .cards { width: 100%; max-width: 380px; display: flex; flex-direction: column; gap: 12px; }

.person-card {
  display: flex; align-items: center; gap: 14px;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 16px;
  box-shadow: var(--shadow);
  text-align: left;
  transition: transform .1s;
}
.person-card:active { transform: scale(.98); }
.person-card .avatar { width: 52px; height: 52px; font-size: 21px; }
.person-card .name { font-weight: 800; font-size: 17px; }
.person-card .lang { color: var(--muted); font-size: 13px; }
.person-card .arrow { margin-left: auto; color: var(--muted); font-size: 20px; }

.pin-input {
  max-width: 220px; text-align: center;
  font-size: 26px; letter-spacing: .35em; font-weight: 800;
  padding: 14px 10px 14px calc(10px + .35em);
}

.setup-form { width: 100%; max-width: 380px; display: flex; flex-direction: column; gap: 14px; text-align: left; }
.setup-person {
  border-radius: var(--r-lg); padding: 14px 16px 16px;
  border: 1.5px solid var(--border); background: var(--surface);
  display: flex; flex-direction: column; gap: 10px;
}
.setup-person .who { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 14px; }

/* ============================================================
   Chat
   ============================================================ */
.chat-wrap { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.msgs { flex: 1; overflow-y: auto; padding: 14px 14px 8px; display: flex; flex-direction: column; gap: 10px; }

.day-sep { align-self: center; font-size: 11.5px; font-weight: 700; color: var(--muted);
  background: var(--surface-2); padding: 4px 12px; border-radius: 999px; margin: 8px 0 2px; }

.msg { display: flex; flex-direction: column; max-width: 86%; animation: msgIn .18s ease; }
.msg.own { align-self: flex-end; align-items: flex-end; }
.msg.other { align-self: flex-start; align-items: flex-start; }
@keyframes msgIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.bubble {
  /* Точка отсчёта для плашки времени: она лежит абсолютным слоем в правом нижнем углу
     ИМЕННО пузыря. Без этой строки отсчёт уходил к странице, и плашка улетала к краю
     экрана (поймано снимком 14.08.2026). */
  position: relative;
  border-radius: 18px; padding: 10px 14px;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: var(--shadow);
  overflow-wrap: anywhere;
  /* Лёгкий объём: блик по верхней кромке и мягкая тень снизу. Именно лёгкий — сильный
     градиент на пузыре читается как кнопка, а не как реплика. */
  background-image: linear-gradient(180deg, rgba(255,255,255,.10), rgba(0,0,0,.045));
  box-shadow: 0 1px 2px rgba(0,0,0,.10), 0 4px 12px rgba(0,0,0,.05), inset 0 1px 0 rgba(255,255,255,.30);
  /* Пузырь НИКОГДА не шире своего сообщения. Без этой строки цитата с длинным текстом
     (одна строка, nowrap) раздувала его до ширины всей цитаты: замер 14.08.2026 показал
     пузырь 777 px, начинающийся на -416, — своё сообщение уезжало за левый край экрана,
     потому что свои прижаты вправо. max-width у .msg этого не удерживал: он ограничивает
     сообщение, а не пузырь внутри него. */
  max-width: 100%; min-width: 0;
}
.msg.own .bubble { background: var(--bubble-own, var(--him)); border: none; color: #fff; border-bottom-right-radius: 6px; }
.msg.own .msg-meta { color: rgba(255,255,255,.92); opacity: .85; }
.msg.own .msg-meta .act, .msg.own .msg-meta time, .msg.own .msg-meta .ticks { color: inherit; }
.msg.other .bubble { border-bottom-left-radius: 6px; }
/* У своего пузыря фон цветной, поэтому блик слабее: на насыщенном цвете он виден сильнее. */
.msg.own .bubble { background-image: linear-gradient(180deg, rgba(255,255,255,.13), rgba(0,0,0,.07));
  box-shadow: 0 1px 2px rgba(0,0,0,.16), 0 5px 14px rgba(0,0,0,.10), inset 0 1px 0 rgba(255,255,255,.22); }

/* Ряд действий сообщения — за кнопкой «⋯». Постоянно видны только время, галочки и она:
   семь значков под каждым пузырём отвлекают от самой переписки, а нужны изредка. */
.msg-acts { display: none; align-items: center; gap: 2px; }
/* Закрытый ряд не занимает места и не влияет на замер ширины плашки. */
/* Всплывают, а не появляются рывком: короткое движение снизу вверх с лёгким увеличением —
   глаз успевает понять, что это новое, и не теряет строку. */
.msg.acts-open .msg-meta { position: static; margin: 5px -2px -2px auto; background: none;
  backdrop-filter: none; -webkit-backdrop-filter: none; padding: 0; }
.msg.acts-open .meta-gap { display: none; }   /* место в тексте больше не нужно */
.msg.acts-open .msg-acts { display: inline-flex; animation: actsPop .18s cubic-bezier(.2,.9,.3,1.2); transform-origin: right bottom; }
@keyframes actsPop {
  from { opacity: 0; transform: translateY(6px) scale(.88); }
  to   { opacity: 1; transform: none; }
}
.msg-meta .act { padding: 0 1px; }
/* Кнопка «⋯» внутри плашки: у общей .act стоит min-height 30 px, и плашка вырастала до
   32 px — то есть на ДВЕ строки текста, и накрывала строку выше (замер 14.08.2026).
   Здесь она ростом со строку, а 44 px пальцевой цели держит невидимая область ::after. */
/* Селектор с двумя классами намеренно: правило .msg-meta .act стоит НИЖЕ по файлу и при
   равной силе побеждало бы — кнопка снова стала бы 30 px высотой. */
.msg-meta .act.act-more { font-size: 15px; line-height: 1; opacity: .75;
  min-width: 16px; min-height: 16px; padding: 0; }
/* Видимый значок 16 px, а нажимается зона 42×42: рядом только время и галочки, отбирать
   нажатие не у кого. */
.msg-meta .act.act-more::after { content: ''; position: absolute; inset: -13px -12px; }
.msg.acts-open .act.act-more { opacity: 1; color: var(--him); }

/* ---------- статистика ссылки на ролик ---------- */
.ss-sum { font-size: 13px; font-weight: 700; margin-bottom: 10px; }
.ss-map { height: 220px; border-radius: 12px; overflow: hidden; margin-bottom: 12px; }
.ss-list { display: flex; flex-direction: column; gap: 8px; max-height: 42vh; overflow-y: auto; }
.ss-item { padding: 8px 10px; border-radius: 10px; background: var(--surface-2); }
.ss-head { display: flex; align-items: baseline; gap: 8px; }
.ss-head time { margin-left: auto; white-space: nowrap; font-size: 11px; }
.ss-badge { font-size: 12px; font-weight: 700; color: var(--muted); }
.ss-badge.on { color: rgb(30,140,90); }
.ss-where { font-size: 12px; margin-top: 3px; }

/* ---------- «стоп сервиса» и сквозной лог ввода ---------- */
.sb-banner { background: color-mix(in srgb, var(--danger) 16%, transparent);
  color: var(--danger); font-weight: 700; font-size: 13px;
  border-radius: 12px; padding: 9px 12px; margin-bottom: 10px; }
.sb-toggle { display: flex; align-items: center; gap: 10px; cursor: pointer;
  border-radius: 12px; padding: 8px 10px; }
.sb-toggle.on { background: color-mix(in srgb, var(--danger) 9%, transparent); }
.sb-state { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--muted); }
.sb-toggle.on .sb-state { color: var(--danger); }
.sb-out { margin-left: auto; font-size: 11px; font-weight: 700; white-space: nowrap; }
.sb-item.sb-out-ok { border-left: 3px solid var(--ok); }
.sb-item.sb-out-blocked { border-left: 3px solid var(--danger); }
.sb-item.sb-out-empty, .sb-item.sb-out-error { border-left: 3px solid var(--muted); }
.sb-item.sb-out-draft { border-left: 3px solid var(--him); opacity: .92; }
.sb-topbar { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.sb-topbar .seg { flex: 1; }
.sb-refresh { width: 38px; height: 38px; flex: none; font-size: 16px; }
.sb-sum { font-size: 12px; font-weight: 700; color: var(--muted); margin-bottom: 8px; }
.sb-filters { display: flex; gap: 8px; margin-bottom: 10px; }
.sb-filters select { flex: 1; min-width: 0; padding: 7px 9px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text); font: inherit; font-size: 13px; }
.sb-out time { margin-left: 0; }
.sb-list { display: flex; flex-direction: column; gap: 8px; max-height: 44vh; overflow-y: auto; }
.sb-item { padding: 8px 10px; border-radius: 10px; background: var(--surface-2); }
.sb-head { display: flex; align-items: baseline; gap: 8px; font-size: 11.5px; }
.sb-head b { font-size: 12.5px; }
.sb-head time { margin-left: auto; white-space: nowrap; font-size: 10.5px; }
.sb-head { flex-wrap: wrap; }
.sb-text { margin-top: 4px; font-size: 13.5px; line-height: 1.4; overflow-wrap: anywhere; }

/* ---------- чат с разработчиком (админ-панель) ---------- */
/* Лента разговора с фиксированной высотой: панель живёт в шторке, и если ленту не
   ограничить, поле ввода уезжает за нижний край экрана. */
.dev-chat { max-height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: 8px;
  padding: 4px 2px; margin-bottom: 8px; }
.dev-msg { padding: 8px 10px; border-radius: 12px; background: var(--surface-2);
  font-size: 13.5px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.dev-msg.user { background: var(--him-soft); align-self: flex-end; max-width: 88%; }
.dev-msg.system { background: transparent; color: var(--muted); font-size: 12px; text-align: center; }
.dev-msg b { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); margin-bottom: 3px; }
.dev-files { margin-top: 6px; font-family: monospace; font-size: 11px; color: var(--muted);
  overflow-wrap: anywhere; }
.dev-steps { margin-top: 6px; font-size: 11.5px; color: var(--muted); white-space: pre-wrap; }
.dev-steps summary { cursor: pointer; }
.dev-checks { margin-top: 6px; font-size: 11.5px; padding: 5px 8px; border-radius: 8px; }
.dev-checks.ok { background: rgba(62,197,138,.16); color: rgb(30,140,90); }
.dev-checks.bad { background: rgba(239,93,93,.16); color: rgb(190,60,60); }
/* Строка отправки: поле и кнопка в один ряд, поле сжимается — как в обычном чате. */
.dev-say { display: flex; align-items: flex-end; gap: 8px; margin-bottom: 8px; }
.dev-say .textarea { flex: 1; min-width: 0; min-height: 44px; }
.dev-progress { font-size: 12px; color: var(--muted); margin-bottom: 8px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- цитаты ---------- */
/* Цитата внутри пузыря: полоска слева, имя и одна строка текста с многоточием. Именно
   одна строка — цитата не должна перевешивать сам ответ. */
.msg-quote { display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  /* max-width, а не width: ширина пузыря считается по содержимому, и width:100% у цитаты
     означало «сколько попросит текст», то есть раздувало пузырь вместо того, чтобы
     ужаться самой. */
  max-width: 100%; min-width: 0; text-align: left; margin: 0 0 6px; padding: 4px 8px;
  border-left: 3px solid var(--border); border-radius: 6px;
  background: rgba(127,127,127,.10); font-size: 12.5px; line-height: 1.35; }
.msg.own .msg-quote { border-left-color: rgba(255,255,255,.5); background: rgba(255,255,255,.14); }
.msg-quote b { font-weight: 800; font-size: 11.5px; opacity: .9; }
.msg-quote span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: .85; }
.msg-quote.gone span { font-style: italic; opacity: .6; }
/* Подсветка сообщения, к которому увела цитата: короткая вспышка, чтобы глаз нашёл строку. */
.msg.flash .bubble { animation: msgflash 1.2s ease-out; }
@keyframes msgflash { 0% { box-shadow: 0 0 0 3px var(--him); } 100% { box-shadow: var(--shadow); } }
/* Панель «отвечаем на …» над композером. */
.reply-bar { display: flex; align-items: center; gap: 8px; padding: 7px 14px;
  background: var(--surface); border-top: 1px solid var(--border); font-size: 12.5px; }
.reply-bar .rb-ic { flex: none; opacity: .7; }
.reply-bar .rb-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.reply-bar .rb-body b { font-size: 11.5px; font-weight: 800; }
.reply-bar .rb-body span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: .8; }
.reply-bar .rb-cancel { flex: none; width: 24px; height: 24px; border-radius: 50%;
  background: var(--surface-2); color: var(--muted); position: relative; }
.reply-bar .rb-cancel::after { content: ''; position: absolute; inset: -10px; }

/* ---------- вложения чата: фото и файлы ---------- */
/* Картинка живёт ВНУТРИ пузыря и не может быть шире него: иначе одно фото с телефона
   (4032 px) разносит всю переписку вбок. Высота ограничена, чтобы вертикальный снимок
   не занимал экран целиком и рядом было видно время и галочки.
   Размер именно СВОЙ, а не 100%: ширина пузыря считается по содержимому, поэтому проценты
   у картинки упираются в её собственный размер, а маленький снимок ещё и растягивался бы
   в мыло. Большой ужимается по max-width, маленький остаётся собой. */
.msg-img { display: block; max-width: 100%; max-height: 320px; height: auto; width: auto;
  border-radius: 12px; margin: 2px 0 6px; background: var(--surface-2); }
.msg-img-full { display: block; width: 100%; height: auto; border-radius: 12px; }
/* Файл — одна строка: значок, имя с многоточием, размер, стрелка. Именно многоточие:
   длинное имя иначе переносится на три строки и ломает пузырь. */
.msg-file { display: flex; align-items: center; gap: 10px; margin: 2px 0 6px;
  padding: 8px 10px; border-radius: 12px; background: var(--surface-2);
  border: 1px solid var(--border); color: inherit; text-decoration: none; min-width: 0; }
.msg.own .msg-file { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.28); }
.msg-file .mf-ic { flex: none; font-size: 17px; }
.msg-file .mf-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.msg-file .mf-name { font-size: 13.5px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-file .mf-size { font-size: 11px; opacity: .7; }
.msg-file .mf-dl { flex: none; font-size: 15px; opacity: .8; }
/* Полоса загрузки над композером: имя, проценты, отмена и сама полоса. */
.up-row { display: flex; align-items: center; gap: 8px; position: relative;
  padding: 8px 14px 10px; background: var(--surface); border-top: 1px solid var(--border);
  font-size: 12.5px; }
.up-row .up-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.up-row .up-pct { flex: none; font-weight: 800; }
.up-row .up-cancel { flex: none; width: 24px; height: 24px; border-radius: 50%;
  background: var(--surface-2); color: var(--muted); font-size: 12px; position: relative; }
.up-row .up-cancel::after { content: ''; position: absolute; inset: -10px; }
.up-row .up-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: var(--surface-2); }
.up-row .up-bar b { display: block; height: 100%; width: 0; background: var(--us); transition: width .2s; }

.bubble .primary { font-size: 15px; white-space: pre-wrap; }
.bubble .secondary {
  margin-top: 7px; padding-top: 7px;
  border-top: 1px solid rgba(128, 128, 128, .25);
  font-size: 13px; opacity: .78; white-space: pre-wrap;
  display: flex; gap: 6px; align-items: baseline;
}
.msg.own .bubble .secondary { border-top-color: rgba(255, 255, 255, .35); }
.lang-tag {
  font-size: 9.5px; font-weight: 800; letter-spacing: .06em;
  border: 1px solid currentColor; border-radius: 5px; padding: 0 4px;
  opacity: .8; flex: none; transform: translateY(-1px);
}
.bubble .pending { font-size: 12.5px; opacity: .7; font-style: italic; margin-top: 6px; }

.nuance {
  margin-top: 8px; padding: 8px 10px; border-radius: 10px;
  background: var(--gold-soft);
  border: 1px solid color-mix(in srgb, var(--gold) 35%, transparent);
  font-size: 12.5px; line-height: 1.4;
}
.msg.own .nuance { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.3); }

/* один ряд без переноса; если совсем не влезло — горизонтальная прокрутка, а не 2-й ряд */
/* ВРЕМЯ В УГЛУ ПУЗЫРЯ, А НЕ ОТДЕЛЬНОЙ ПОЛОСОЙ.
   Строка времени лежит отдельным слоем в правом нижнем углу, а в конце текста стоит
   невидимая распорка её ширины (.meta-gap). Дальше работает обычный перенос: короткая
   последняя строка — время встаёт рядом с ней; длинная — распорка уезжает вниз и уводит
   время за собой. Пустой полосы не остаётся ни в одном случае.
   --meta-w держит ширину распорки и ширину самого блока в одном месте: разъедутся —
   время наедет на текст. */
.msg-meta { --meta-w: 62px;
  position: absolute; right: 10px; bottom: 7px;
  display: flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .01em;
  padding: 1px 6px; border-radius: 9px;
  background: rgba(127,127,127,.14);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
.msg.own .msg-meta { --meta-w: 78px; }        /* у своих ещё галочки прочтения */
.meta-gap { display: inline-block; width: var(--meta-w, 62px); height: 1px; vertical-align: baseline; }
/* Фото или файл без единой строки текста: отдельная полоса под плашку — это те же
   потерянные 22 px, от которых мы уходим. Плашка ложится поверх нижнего угла снимка,
   её читаемость держат подложка и размытие. */
.meta-gap-solo { display: none; }
.msg-meta { z-index: 2; }
.msg-meta::-webkit-scrollbar { display: none; }
.msg-meta time, .msg-meta .ticks { flex: none; }
.msg-meta time { font-size: 11px; color: var(--muted); }
.msg-meta .act { font-size: 12.5px; font-weight: 700; color: var(--muted); flex: none;
  min-width: 26px; min-height: 30px; display: inline-flex; align-items: center; justify-content: center;
  position: relative; }
/* область нажатия до 44 px, вид прежний (см. .rt-check выше) */
.msg-meta .act::after { content: ''; position: absolute; inset: -7px -4px; }
.msg-meta .act:active { opacity: .6; }

.explain-box {
  margin-top: 6px; padding: 10px 12px; border-radius: 12px;
  background: var(--surface-2); border: 1px dashed var(--border);
  font-size: 13px; line-height: 1.5; max-width: 100%;
}
.explain-box b { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: 4px; }

.voice-row { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.play-btn {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  background: rgba(255,255,255,.22); color: inherit;
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
.msg.other .play-btn { background: var(--surface-2); }
.voice-bar { flex: 1; height: 4px; border-radius: 2px; background: rgba(128,128,128,.3); position: relative; min-width: 90px; }
.voice-bar i { position: absolute; inset: 0 auto 0 0; width: 0; border-radius: 2px; background: currentColor; opacity: .9; }
.voice-len { font-size: 11.5px; opacity: .8; }

.composer {
  flex: none;
  display: flex; align-items: flex-end; gap: 9px;
  /* Безопасную зону снизу (полоска home indicator) держит НИЖНЯЯ ПАНЕЛЬ, которая стоит
     прямо под композером: её высота уже равна tab-h + safe-b. Композер добавлял её второй
     раз, и под строкой ввода получалась пустая полоса в 34 px — она и видна на телефоне
     как «большой отступ до меню» (замер 14.08.2026: композер 101 px вместо 67). */
  padding: 10px 12px;
  background: var(--surface);
  border-top: 1px solid var(--border);
}
.composer textarea {
  flex: 1;
  background: var(--surface-2); border: 1.5px solid transparent; border-radius: 20px;
  padding: 11px 15px; max-height: 120px; resize: none; outline: none;
  font-size: 16px; line-height: 1.4; /* ≥16px — iOS не зумит при фокусе */
}
.composer textarea:focus { border-color: var(--him); }
/* БЮДЖЕТ ШИРИНЫ КОМПОЗЕРА. Кнопок стало четыре (❓ 📎 🎙 ➤), и на 375 px они с отступами
   съедали 236 из 375: полю ввода оставалось 139 при 164, которые нужны его же подсказке.
   Подсказка переносилась на ТРИ строки, и низ чата выглядел сломанным (замер 14.08.2026).
   Ужимаем на узких экранах кнопки и отступы; 44 px пальцевой цели сохраняем невидимой
   областью нажатия, как в шапке. */
@media (max-width: 430px) {
  .composer { gap: 6px; padding-left: 10px; padding-right: 10px; }
  .composer .round-btn { width: 38px; height: 38px; font-size: 17px; position: relative; }
  .composer .round-btn::after { content: ''; position: absolute; inset: -3px; }
  .composer textarea { padding-left: 13px; padding-right: 13px; }
}
.round-btn {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); color: var(--muted); font-size: 18px;
  transition: all .15s;
}
.round-btn.send { background: var(--us); color: #fff; box-shadow: 0 4px 14px rgba(166,100,191,.4); }
.round-btn:active { transform: scale(.92); }

.rec-panel {
  flex: 1; display: flex; align-items: center; gap: 12px;
  background: var(--surface-2); border-radius: 20px; padding: 10px 16px;
}
.rec-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--danger); animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .25; } }
.rec-time { font-weight: 700; font-variant-numeric: tabular-nums; }
.rec-hint { font-size: 12px; color: var(--muted); flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

.presence { display: flex; align-items: center; gap: 5px; }
.presence .dot { background: var(--muted); }
.presence.on .dot { background: var(--ok); }

/* ============================================================
   Wheel
   ============================================================ */
.wheel-card { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 6px 16px; }
.wheel-svg { width: 100%; max-width: 430px; height: auto; }
.wheel-svg .ring { fill: none; stroke: var(--border); stroke-width: 1; }
.wheel-svg .axis { stroke: var(--border); stroke-width: 1; }
.wheel-svg .poly { stroke-width: 2.5; stroke-linejoin: round; fill-opacity: .28; }
.wheel-svg .vertex { stroke: var(--surface); stroke-width: 1.5; }
.wheel-svg .lbl { cursor: pointer; }
.wheel-svg .lbl text { fill: var(--muted); font-size: 10.5px; font-weight: 700; }
.wheel-svg .lbl .em { font-size: 15px; }
.legend { display: flex; gap: 16px; }
.legend span { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; }

.area-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 12px 14px;
  box-shadow: var(--shadow);
}
.area-row .em { font-size: 21px; width: 30px; text-align: center; }
.area-row .nm { flex: 1; font-weight: 700; font-size: 14.5px; }
.area-row .vals { display: flex; gap: 10px; align-items: center; }
.area-row .val { display: flex; align-items: center; gap: 5px; font-weight: 800; font-size: 14px; font-variant-numeric: tabular-nums; }
.area-row .val.zero { opacity: .35; }

.rate-row { display: flex; align-items: center; gap: 14px; margin: 6px 0 2px; }
.rate-row .num { font-size: 26px; font-weight: 800; width: 44px; text-align: center; font-variant-numeric: tabular-nums; }

/* ============================================================
   Goals
   ============================================================ */
.goal-card {
  position: relative;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 14px 16px 14px 20px;
  box-shadow: var(--shadow); overflow: hidden;
}
.goal-card:active { transform: scale(.99); }
.goal-card .stripe { position: absolute; left: 0; top: 0; bottom: 0; width: 5px; }
.goal-card .ttl { font-weight: 700; font-size: 15px; }
.goal-card .ttl-tr { color: var(--muted); font-size: 12.5px; margin-top: 1px; }
.goal-card.done .ttl { text-decoration: line-through; opacity: .55; }
.goal-card .meta { display: flex; align-items: center; gap: 8px; margin-top: 9px; flex-wrap: wrap; }
.goal-card .area-tag { font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px; }
.owner-dots { display: flex; align-items: center; }
.owner-dots .dot { width: 15px; height: 15px; border: 2px solid var(--surface); }
.owner-dots .dot + .dot { margin-left: -5px; }

.progress { height: 5px; border-radius: 3px; background: var(--surface-2); overflow: hidden; flex: 1; min-width: 60px; }
.progress i { display: block; height: 100%; border-radius: 3px; background: var(--us); transition: width .3s; }
.progress-lbl { font-size: 11.5px; color: var(--muted); font-weight: 700; }

.event-badge {
  width: 48px; flex: none; text-align: center;
  border-radius: var(--r-sm); padding: 6px 2px;
  background: var(--surface-2);
}
.event-badge .d { font-size: 19px; font-weight: 800; line-height: 1.1; }
.event-badge .m { font-size: 10.5px; text-transform: uppercase; font-weight: 700; color: var(--muted); }
.event-card { display: flex; align-items: center; gap: 13px; }
.countdown { font-size: 12px; font-weight: 700; }

.step-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--border); }
.step-row:last-child { border-bottom: none; }
.step-check {
  width: 22px; height: 22px; border-radius: 7px; flex: none; margin-top: 1px;
  border: 2px solid var(--border); background: var(--surface);
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 13px; transition: all .15s;
}
.step-row.done .step-check { background: var(--ok); border-color: var(--ok); }
.step-row .tx { flex: 1; font-size: 14px; }
.step-row.done .tx { opacity: .5; text-decoration: line-through; }
.step-row .tx small { display: block; color: var(--muted); font-size: 12px; }
.step-row .del { color: var(--muted); font-size: 15px; padding: 2px 6px; }

.ai-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700;
  background: linear-gradient(135deg, var(--him-soft), var(--her-soft));
  border: 1px solid var(--border);
  padding: 9px 14px; border-radius: var(--r-md);
}
.ai-btn .spark { font-size: 14px; }

/* ============================================================
   Journal
   ============================================================ */
.j-card { display: flex; flex-direction: column; gap: 8px; }
.j-head { display: flex; align-items: center; gap: 9px; }
.j-head .avatar { width: 30px; height: 30px; font-size: 12px; }
.j-head .who { font-weight: 800; font-size: 13.5px; }
.j-head time { color: var(--muted); font-size: 11.5px; }
.j-head .mood { margin-left: auto; font-size: 20px; }
.j-text { font-size: 14.5px; white-space: pre-wrap; }
.j-orig { color: var(--muted); font-size: 13px; white-space: pre-wrap; border-left: 2.5px solid var(--border); padding-left: 10px; }
.j-toggle { font-size: 12px; font-weight: 700; color: var(--muted); align-self: flex-start; }
.priv-tag { font-size: 10.5px; font-weight: 800; letter-spacing: .04em; color: var(--muted);
  border: 1px solid var(--border); padding: 2px 8px; border-radius: 999px; }
.mood-row { display: flex; gap: 6px; flex-wrap: wrap; }
.mood-row button { font-size: 24px; padding: 6px; border-radius: 10px; transition: all .12s; opacity: .55; }
.mood-row button.active { background: var(--surface-2); opacity: 1; transform: scale(1.15); }
.prompt-chips { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; }
.prompt-chips::-webkit-scrollbar { display: none; }

.switch { position: relative; width: 48px; height: 28px; flex: none; }
.switch input { opacity: 0; width: 100%; height: 100%; position: absolute; cursor: pointer; z-index: 1; }
.switch i {
  position: absolute; inset: 0; border-radius: 999px; background: var(--surface-2);
  border: 1px solid var(--border); transition: background .18s;
}
.switch i::after {
  content: ""; position: absolute; width: 22px; height: 22px; border-radius: 50%;
  background: #fff; top: 2px; left: 2px; transition: transform .18s;
  box-shadow: 0 2px 6px rgba(0,0,0,.25);
}
.switch input:checked + i { background: var(--us); border-color: transparent; }
.switch input:checked + i::after { transform: translateX(20px); }

/* ============================================================
   Today: week strip, routines, vocab, quick add
   ============================================================ */
.week-strip {
  display: flex; gap: 6px; justify-content: space-between;
}
.day-pill {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 0 9px; border-radius: 14px;
  background: var(--surface); border: 1px solid var(--border);
  transition: all .15s;
}
.day-pill .dw { font-size: 10px; font-weight: 800; text-transform: uppercase; color: var(--muted); }
.day-pill .dn { font-size: 15px; font-weight: 800; }
.day-pill.today .dn { color: var(--her); }
.day-pill.active { background: var(--text); border-color: var(--text); }
.day-pill.active .dw, .day-pill.active .dn { color: var(--bg); }

.sec-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: -4px; }

.routine-row {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 11px 14px;
  box-shadow: var(--shadow);
}
.routine-row.done { opacity: .72; }
.routine-row.done .r-title { text-decoration: line-through; }
.r-check {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  border: 2px solid var(--border); background: var(--surface);
  color: #fff; font-size: 14px; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  transition: all .15s;
}
.r-check[disabled] { opacity: .3; }
.r-body { flex: 1; min-width: 0; }
.r-title { font-weight: 700; font-size: 14.5px; }
.r-sub { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); margin-top: 1px; }
.r-partner {
  width: 14px; height: 14px; border-radius: 50%; flex: none;
  border: 2px solid var(--pc); background: transparent;
}
.r-partner.on { background: var(--pc); }

.days-row { display: flex; gap: 6px; }
.day-toggle {
  flex: 1; padding: 9px 0; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-size: 12px; font-weight: 800; color: var(--muted);
  transition: all .12s;
}
.day-toggle.on { background: var(--us); border-color: transparent; color: #fff; }

.focus-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 11px 14px 11px 0;
  box-shadow: var(--shadow); overflow: hidden;
}
.focus-card:active { transform: scale(.995); }
.focus-card .fc-head { display: flex; align-items: flex-start; gap: 10px; }
.focus-card .stripe { width: 4px; align-self: stretch; border-radius: 3px; flex: none; min-height: 20px; }
.focus-card .ttl { flex: 1; font-weight: 700; font-size: 14.5px; min-width: 0; }
.fc-toggle { flex: none; color: var(--muted); font-size: 13px; padding: 0 4px; }
.focus-card .fc-meta { display: flex; align-items: center; gap: 8px; margin-top: 8px; padding-left: 14px; flex-wrap: wrap; }
.fc-steps { padding: 8px 0 2px 14px; display: flex; flex-direction: column; gap: 5px; }
.fc-step { display: flex; gap: 7px; font-size: 13px; align-items: flex-start; }
.fc-step.done { opacity: .55; text-decoration: line-through; }

.vocab-card { border: 1.5px solid transparent;
  background: linear-gradient(var(--surface), var(--surface)) padding-box,
              var(--us) border-box; }
.vocab-word { padding: 10px 0; border-bottom: 1px solid var(--border); }
.vocab-word:last-child { border-bottom: none; }
.vocab-word .w { font-size: 14.5px; }
.vocab-word .ex { font-size: 12.5px; color: var(--muted); margin-top: 3px; font-style: italic; }
.vocab-word .ex span { font-style: normal; opacity: .8; }
.vocab-body { margin-top: 8px; }

.plan-preview {
  margin-top: 4px; padding: 14px;
  border-radius: var(--r-md);
  background: var(--surface-2); border: 1px dashed var(--border);
}

.seg-mini { padding: 3px; gap: 3px; }
.seg-mini button { padding: 6px 9px; font-size: 11px; border-radius: 8px; white-space: nowrap; }

/* ============================================================
   Journal v2: reactions, comments, read receipts
   ============================================================ */
/* Подвал записи — один ряд: реакции и отметка «прочитано» рядом, а не друг под другом.
   Раньше .react-row { flex: 1 } растягивал ряд эмодзи на всю ширину (309 px), и отметка
   «✓ не прочитано» физически не помещалась — уезжала на вторую строку. */
.j-foot { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; }
/* Шесть кнопок реакций (242 px) и отметка прочтения (90) вместе шире экрана. Уменьшать
   кнопки нельзя — они и так меньше пальцевой цели, — поэтому ряд листается вбок и остаётся
   ОДНИМ рядом, а не переносится. */
.react-row { display: flex; gap: 4px; flex: 0 1 auto; min-width: 0; flex-wrap: nowrap;
  overflow-x: auto; scrollbar-width: none;
  /* overflow-x: auto обрезает и по вертикали (так работает CSS), а вместе с ним —
     невидимую область нажатия кнопок. Поле внутрь и отрицательный отступ наружу
     возвращают её, не сдвигая вёрстку. */
  padding: 6px 0; margin: -6px 0; }
.react-row::-webkit-scrollbar { display: none; }
.react-row > * { flex: none; }
.react {
  font-size: 15px; padding: 4px 8px; border-radius: 999px;
  border: 1px solid transparent; opacity: .55; transition: all .12s;
  display: inline-flex; align-items: center; gap: 3px;
  position: relative;
}
.react::after { content: ''; position: absolute; inset: -6px -2px; }   /* область нажатия 44 px */
.react i { font-style: normal; font-size: 11px; font-weight: 800; color: var(--muted); }
.react.on { opacity: 1; background: var(--surface-2); border-color: var(--border); }
.read-mark { font-size: 11.5px; font-weight: 700; color: var(--muted);
  flex: none; white-space: nowrap; margin-left: auto; }
.read-mark.on { color: var(--ok); }

.j-comments { border-top: 1px solid var(--border); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.j-comment { display: flex; gap: 9px; }
.j-c-text { font-size: 13.5px; }
.j-c-orig { font-size: 12px; color: var(--muted); }
.j-c-input { display: flex; gap: 8px; }
.j-c-input .input { flex: 1; }

/* ============================================================
   v4: темы чата, реакции, прочтения
   ============================================================ */
.topics-row {
  flex: none; display: flex; gap: 7px; overflow-x: auto; scrollbar-width: none;
  padding: 8px 12px; border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
}
.topics-row::-webkit-scrollbar { display: none; }
.topics-row .chip { padding: 5px 11px; font-size: 12.5px; }

.react-bar {
  display: flex; gap: 2px; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; padding: 4px 8px; box-shadow: var(--shadow-lift);
  margin-top: 6px;
}
.react-bar button { font-size: 19px; padding: 4px 5px; border-radius: 8px; transition: transform .1s; }
.react-bar button:active { transform: scale(1.3); }
.msg-reacts { display: flex; gap: 4px; margin-top: 4px; flex-wrap: wrap; }
.msg-reacts .rc {
  display: inline-flex; align-items: center; gap: 3px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; padding: 2px 8px; font-size: 13px;
}
.msg-reacts .rc .dot { width: 7px; height: 7px; }
.ticks { font-size: 11px; font-weight: 700; color: var(--muted); }
.ticks.on { color: var(--ok); }

.c-meta { display: flex; align-items: baseline; gap: 7px; font-size: 11.5px; color: var(--muted); }
.c-meta b { font-size: 12px; color: var(--text); }
.c-quote {
  border-left: 3px solid var(--him); background: var(--him-soft);
  border-radius: 0 8px 8px 0; padding: 5px 9px; margin: 4px 0;
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.c-quote-active { white-space: normal; }

/* ============================================================
   v4: компактные рутины (3 в ряд) и события
   ============================================================ */
.r-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.r-chip {
  position: relative;
  background: var(--surface); border: 1.5px solid var(--border);
  border-radius: var(--r-md); padding: 9px 7px 8px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  text-align: center; min-height: 74px;
  transition: all .15s;
}
.r-chip .em { font-size: 19px; line-height: 1; }
.r-chip .tt { font-size: 11.5px; font-weight: 700; line-height: 1.15; max-height: 27px; overflow: hidden; }
.r-chip.done-me { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, var(--surface)); }
.r-chip .who-row { display: flex; gap: 5px; font-size: 9px; font-weight: 800; margin-top: auto; }
.r-chip .who-row span { display: inline-flex; align-items: center; gap: 2px; color: var(--muted); }
.r-chip .who-row i { font-style: normal; width: 12px; height: 12px; border-radius: 50%; color: #fff;
  display: inline-flex; align-items: center; justify-content: center; font-size: 8px; }
.r-chip .new-dot { position: absolute; top: 6px; right: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--her); }
.r-chip .time-tag { position: absolute; top: 5px; left: 7px; font-size: 8.5px; color: var(--muted); font-weight: 700; }

.ev-row {
  display: flex; align-items: center; gap: 9px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 7px 11px;
  box-shadow: var(--shadow); width: 100%; text-align: left;
}
.ev-row .d { font-size: 12px; font-weight: 800; color: var(--her); white-space: nowrap; }
.ev-row .tt { flex: 1; font-size: 13px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-row .cd { font-size: 11px; font-weight: 700; color: var(--muted); white-space: nowrap; }

/* ============================================================
   v4: игра слов
   ============================================================ */
.game-word { font-size: 30px; font-weight: 800; text-align: center; margin: 14px 0 4px; letter-spacing: -.01em; }
.game-sub { text-align: center; color: var(--muted); font-size: 13px; margin-bottom: 14px; }
.game-opts { display: flex; flex-direction: column; gap: 9px; }
.game-opts button {
  padding: 13px 16px; border-radius: var(--r-md); font-size: 15px; font-weight: 600;
  background: var(--surface-2); border: 1.5px solid transparent; text-align: left;
  transition: all .12s;
}
.game-opts button.right { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, var(--surface-2)); }
.game-opts button.wrong { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, var(--surface-2)); }
.game-ex { margin-top: 12px; padding: 10px 12px; border-radius: var(--r-sm); background: var(--surface-2);
  font-size: 13px; font-style: italic; }
.game-ex span { display: block; font-style: normal; color: var(--muted); margin-top: 2px; }
.streak-badge {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--us); color: #fff; border-radius: 999px;
  padding: 4px 12px; font-size: 12px; font-weight: 800;
}
.vocab-status { font-size: 12px; font-weight: 800; }
.vocab-status.ok { color: var(--ok); }
.vocab-status.todo { color: var(--danger); }

/* ============================================================
   v4: дневник по датам, колесо, мечты, идеи
   ============================================================ */
.date-head {
  font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); margin: 8px 2px -6px;
  display: flex; align-items: center; gap: 8px;
}
.date-head::after { content: ""; flex: 1; height: 1px; background: var(--border); }

.wheel-switch { display: flex; gap: 8px; }
.area-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.area-cell {
  display: flex; align-items: center; gap: 7px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 9px 10px;
  box-shadow: var(--shadow);
}
.area-cell .em { font-size: 17px; }
.area-cell .nm { flex: 1; font-size: 12px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.area-cell .vals { display: flex; gap: 5px; font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; }
.area-cell .vals span { display: flex; align-items: center; gap: 3px; }
.area-cell .plus {
  width: 24px; height: 24px; border-radius: 8px; flex: none;
  background: var(--surface-2); color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 800;
}

.dream-card { position: relative; }
.dream-card .em { font-size: 22px; }
.dream-head { display: flex; align-items: center; gap: 10px; }
.dream-text { font-size: 14.5px; margin-top: 6px; white-space: pre-wrap; }
.dream-tr { color: var(--muted); font-size: 12.5px; margin-top: 3px; }

.idea-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.idea-row:last-child { border-bottom: none; }
.idea-row .tx { flex: 1; font-size: 13.5px; }
.idea-row.done .tx { opacity: .5; text-decoration: line-through; }

/* ============================================================
   Profile
   ============================================================ */
.set-row {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 2px;
  border-bottom: 1px solid var(--border);
}
.set-row:last-child { border-bottom: none; }
.set-row .lbl { flex: 1; font-weight: 600; font-size: 14.5px; }
.set-row .lbl small { display: block; font-weight: 500; color: var(--muted); font-size: 12px; margin-top: 1px; }
.section-title { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); margin: 6px 2px -6px; }
.kbd-ok { color: var(--ok); font-weight: 700; font-size: 13px; }

@media (min-width: 760px) {
  .page, .msgs, .composer { max-width: 680px; width: 100%; margin-left: auto; margin-right: auto; }
  .tabbar, .header { padding-left: calc(50vw - 340px); padding-right: calc(50vw - 340px); }
}

/* ============================================================
   v7: слова дня 2.0 — письмо, озвучка, история слов
   ============================================================ */
.spin {
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid var(--surface-2); border-top-color: var(--us);
  animation: spinRot .8s linear infinite;
}
@keyframes spinRot { to { transform: rotate(360deg); } }
.speak-btn { border: none; background: none; font-size: 17px; padding: 2px 4px; cursor: pointer;
  position: relative; }
.speak-btn::after { content: ''; position: absolute; inset: -6px; }   /* область нажатия 44 px */
.game-type-input { margin-top: 12px; text-align: center; font-size: 17px; font-weight: 700; }
.game-type-input.type-right { border-color: var(--ok); }
.game-type-input.type-wrong { border-color: var(--danger); }
.vh-stats { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.vh-stat {
  background: var(--surface-2); border-radius: 999px;
  padding: 5px 11px; font-size: 12px; font-weight: 700;
}
.vh-row {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 2px; border-bottom: 1px solid var(--border);
}
.vh-row:last-child { border-bottom: none; }
.vh-word { flex: 1; min-width: 0; font-size: 14.5px; }
.vh-chip {
  flex: none; font-size: 10.5px; font-weight: 800;
  border-radius: 999px; padding: 3px 8px; white-space: nowrap;
  background: var(--surface-2); color: var(--muted);
}
.vh-chip.mastered { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.vh-chip.due { background: color-mix(in srgb, var(--danger) 13%, transparent); color: var(--danger); }
.vh-chip.new { background: color-mix(in srgb, var(--us) 14%, transparent); color: var(--us); }

/* ============================================================
   v9: рутины-строки с фото, вопросы, вкладка «Учёба»
   ============================================================ */
.rt-list { display: flex; flex-direction: column; gap: 5px; }
.rt-row {
  display: flex; align-items: center; gap: 7px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm);
  padding: 6px 9px; min-height: 38px;
}
.rt-row.done-me { opacity: .78; }
.rt-check {
  flex: none; width: 23px; height: 23px; border-radius: 50%;
  border: 2px solid var(--border); background: var(--surface-2);
  font-size: 12px; font-weight: 800; color: #fff; line-height: 1; padding: 0;
  position: relative;
}
/* ПАЛЬЦЕВАЯ ЦЕЛЬ. Кружок отметки — главное действие раздела «Рутины», и он 23 px при
   рекомендованных 44. Увеличивать сам кружок нельзя: он держит ритм строки. Поэтому
   растягиваем НЕВИДИМУЮ область нажатия поверх пустого места вокруг — вид не меняется,
   промахнуться перестаёт. Тот же приём ниже для остальных мелких кнопок. */
.rt-check::after { content: ''; position: absolute; inset: -11px; border-radius: 50%; }
.rt-check.on { background: var(--ok); border-color: var(--ok); }
.rt-check.ghost { border: none; background: none; width: 23px; }
.rt-row .em { flex: none; font-size: 15px; }
.rt-row .tt {
  flex: 1; min-width: 0; font-size: 13px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rt-row .rt-t { color: var(--muted); font-weight: 700; font-size: 11px; }
.rt-status { flex: none; display: inline-flex; gap: 6px; }
.rt-u {
  display: inline-flex; align-items: center; gap: 2px;
  font-size: 9.5px; font-weight: 700; color: var(--muted);
}
.rt-u i {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--uc); color: #fff; font-style: normal; font-size: 8px; font-weight: 800;
  opacity: .4;
}
.rt-u.on { color: var(--ok); }
.rt-u.on i { opacity: 1; }
.rt-thumb {
  flex: none; width: 24px; height: 24px; border-radius: 6px; object-fit: cover;
  border: 1px solid var(--border); cursor: pointer;
}
.rt-cam { flex: none; border: none; background: none; font-size: 14px; padding: 2px; opacity: .65; }

.q-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 19px; height: 19px; border-radius: 999px; padding: 0 5px;
  background: var(--her); color: #fff; font-size: 11.5px; font-weight: 800; vertical-align: 2px;
}
.q-row {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 10px 2px; border-bottom: 1px solid var(--border);
}
.q-row:last-child { border-bottom: none; }
.q-row .q-text { font-size: 14px; font-weight: 600; }
.q-row.q-done .q-text { color: var(--muted); font-weight: 500; }
.q-toggle { font-size: 15px; }
.q-toggle.on { background: var(--her); color: #fff; }

/* v10: присутствие и метки «увидел» */
.rt-seen { font-size: 9px; font-weight: 800; color: var(--muted); margin-left: 5px; white-space: nowrap; }
.rt-seen.on { color: var(--ok); }

/* v11: календарь пары + пульс кнопки игры */
.cal-nav { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.cal-month { flex: 1; text-align: center; font-weight: 800; font-size: 15px; text-transform: capitalize; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow { text-align: center; font-size: 10px; color: var(--muted); font-weight: 800; padding: 2px 0; }
.cal-day {
  position: relative; min-height: 46px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--border);
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding: 5px 0 4px; gap: 3px;
}
.cal-day .n { font-size: 11.5px; font-weight: 700; line-height: 1; }
.cal-day.out { visibility: hidden; }
.cal-day.today { border-color: var(--us); border-width: 1.5px; }
.cal-day.future { opacity: .72; }
.cal-day.perfect { background: color-mix(in srgb, var(--ok) 11%, var(--surface)); border-color: color-mix(in srgb, var(--ok) 35%, var(--border)); }
.rings { display: flex; gap: 3px; min-height: 10px; align-items: center; }
.ring { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.ring.big { width: 15px; height: 15px; }
.ring.hollow { width: 8px; height: 8px; background: none; border: 1.5px dashed var(--muted); opacity: .5; }
.cal-ev { position: absolute; top: 2px; right: 4px; font-size: 7px; color: var(--her); }
.cal-j { position: absolute; top: 1px; left: 4px; font-size: 8px; color: var(--muted); }
.pulse { animation: pulseGlow 1.9s ease-in-out infinite; }
@keyframes pulseGlow {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 color-mix(in srgb, var(--us) 45%, transparent); }
  50% { transform: scale(1.05); box-shadow: 0 0 0 9px transparent; }
}

/* v11.1: управление личными записями */
/* автору закрытой записки: видел ли партнёр сам факт её существования */
.priv-seen { font-size: 11.5px; color: var(--muted); margin-top: 8px; font-weight: 600; }
.priv-seen.on { color: var(--her); }
/* Кнопка «Отправить партнёру» и дата автораскрытия — в один ряд. Поле даты просило
   145 px под свой формат, кнопка — 179, вместе 324 при доступных 307, и ряд ломался
   пополам. Теперь поле сжимается: перенос запрещён, ширина не фиксирована. */
.priv-controls {
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap;
  margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border);
}
.priv-controls > * { min-width: 0; }
.priv-controls label { flex: 1 1 auto; display: flex; align-items: center; gap: 4px; }
.priv-controls input[type="date"] { flex: 1 1 auto; min-width: 0; width: 100%; }

/* v11.2: запечатанные записки 💌 */
.sealed-note { text-align: center; padding: 20px 16px; border-style: dashed; }
.sealed-note time { color: var(--muted); font-size: 11.5px; }

/* v11.4: структурированный «Что нового» + IP-гео на карте */
.cl-wrap { display: flex; flex-direction: column; gap: 14px; margin: 12px 0; max-height: 62vh; overflow-y: auto; }
.cl-item { border-left: 3px solid var(--us); padding: 2px 0 2px 12px; }
.cl-ver { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.cl-ver b { font-size: 14px; color: var(--us); }
.cl-ver span { font-size: 11px; color: var(--muted); }
.cl-lead { font-size: 13.5px; font-weight: 600; margin: 4px 0 2px; }
.cl-list { margin: 2px 0 0; padding-left: 18px; }
.cl-list li { font-size: 13px; line-height: 1.5; margin: 3px 0; }
.geo-ip { font-family: ui-monospace, monospace; font-size: 12.5px; }
.geo-map { width: 100%; height: 300px; border: none; border-radius: 12px; background: var(--surface-2); }

/* v11.5: разделы чата, дискуссии, навигатор папок */
.chat-top { display: flex; align-items: center; gap: 8px; padding: 6px 12px 2px; }
.kind-seg { flex: 1; }
.kind-seg button { font-size: 12.5px; white-space: nowrap; }
.chip-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; padding: 0 4px; margin-left: 4px;
  border-radius: 999px; background: var(--her); color: #fff;
  font-size: 10px; font-weight: 800; font-style: normal; vertical-align: 1px;
}
.chip-add { border-style: dashed; opacity: .85; }
.disc-head {
  margin: 4px 12px 0; padding: 8px 12px; border-radius: 12px;
  background: color-mix(in srgb, var(--us) 9%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--us) 25%, var(--border));
}
.disc-title { font-size: 13.5px; font-weight: 800; }
.disc-actions { display: flex; gap: 8px; margin-top: 6px; }
.nav-folder { margin-bottom: 12px; }
.nav-folder-head { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); padding: 4px 2px; }
.nav-topic {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 10px 12px; margin: 3px 0; border-radius: 10px;
  background: var(--surface-2); border: 1.5px solid transparent;
  font-size: 14px; font-weight: 600; text-align: left;
}
.nav-topic.active { border-color: var(--us); background: color-mix(in srgb, var(--us) 10%, var(--surface-2)); }
.nav-topic span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* v11.6: вкладка дискуссий + календарь-спойлер в дневнике */
.disc-card { display: block; padding: 12px 14px; margin-bottom: 8px; }
.disc-q { font-size: 14.5px; font-weight: 700; line-height: 1.35; }
.disc-msgs {
  display: flex; flex-direction: column; gap: 2px;
  min-height: 120px; max-height: 56vh; overflow-y: auto;
  padding: 6px 2px; margin: 4px 0;
}
.disc-msgs .msg { max-width: 100%; }
.cal-spoiler { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 14px; }
.cal-spoiler .cal-grid { gap: 3px; }

/* v11.7: кнопка экспресс-обновления в шапке */
#refreshbtn.spinning { animation: spinRot .5s linear; }

/* v11.9: топбар ветки дискуссии (кнопка назад + вопрос + озвучка) */
.disc-topbar {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: 8px 10px 4px; border-bottom: 1px solid var(--border);
}
.disc-topbar .disc-title { font-size: 13.5px; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act-speak { font-size: 13px; }

/* ============================================================
   v12: рутины-раздел, объяснение 2.0, уведомления, компактное меню
   ============================================================ */
/* язык одним эмодзи */
.view-switch button { display: flex; align-items: center; gap: 3px; padding: 4px 7px; }
.vs-emoji { font-size: 15px; }
.vs-code { font-size: 9px; font-weight: 800; color: var(--muted); }
/* колокольчик + бейджи */
.bell-btn { position: relative; }
.bell-badge, .tab-badge {
  position: absolute; top: -3px; right: -3px; min-width: 15px; height: 15px;
  padding: 0 3px; border-radius: 999px; background: var(--her); color: #fff;
  font-size: 9px; font-weight: 800; font-style: normal; line-height: 15px; text-align: center;
}
.tab-ico { position: relative; display: inline-flex; }
.tab-badge { top: -5px; right: -8px; }
/* компактное нижнее меню (7 вкладок) */
.tab { gap: 2px; font-size: 9.5px; }
.tab svg { width: 21px; height: 21px; }
.tab span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* уведомления */
.notif-row { display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left;
  padding: 10px 4px; border-bottom: 1px solid var(--border); }
.notif-ico { font-size: 18px; flex: none; }
.notif-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.notif-title { font-size: 12px; font-weight: 800; color: var(--muted); }
.notif-text { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notif-row time { font-size: 11px; color: var(--muted); flex: none; }
/* объяснение смысла — спойлер */
/* «Смысл и оттенки» — изящная заметка на полях в тёплом золотом акценте (не отдельная карточка) */
/* блок «смысла»: без заголовка-текста — только 💡 инлайн перед текстом, компактно */
.explain-note {
  margin-top: 4px; max-width: 100%;
  background: var(--gold-soft);
  border: 1px solid color-mix(in srgb, var(--gold) 28%, transparent);
  border-left: 2.5px solid var(--gold);
  border-radius: 4px 12px 12px 4px;
  padding: 6px 10px;
}
.msg.own .explain-note { /* у своих сообщений акцент справа — «указывает» на пузырь */
  border-left: 1px solid color-mix(in srgb, var(--gold) 28%, transparent);
  border-right: 2.5px solid var(--gold);
  border-radius: 12px 4px 4px 12px;
}
.explain-title { font-size: 13px; } /* 💡 инлайн-маркер вместо длинного «Смысл и оттенки» */
.explain-body { font-size: 13px; line-height: 1.42; color: var(--text); }
.explain-body.clamp { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* футер: «показать всё» слева, автор + 🔊 прижаты вправо — одной компактной строкой */
.explain-foot { display: flex; align-items: center; gap: 8px; margin-top: 3px; }
.explain-more { font-size: 11px; font-weight: 700; color: var(--gold); padding: 0; line-height: 1.3; opacity: .9; }
.explain-by { font-size: 10.5px; color: var(--muted); margin-left: auto; }
.explain-ic { font-size: 13px; padding: 2px 4px; border-radius: 6px; opacity: .45; line-height: 1; transition: opacity .15s, transform .1s; }
.explain-ic:active { transform: scale(.85); }
/* привычки: карточки прогресса */
.hab-card { padding: 12px 14px; }
.hab-head { display: flex; align-items: center; gap: 8px; }
.hab-head .em { font-size: 18px; }
.hab-title { font-weight: 800; font-size: 14.5px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hab-user { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 12.5px; }
.hab-u-name { display: flex; align-items: center; gap: 5px; font-weight: 700; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hab-u-name i { width: 9px; height: 9px; border-radius: 50%; }
.hab-streak { font-weight: 800; }
.hab-pct { color: var(--muted); font-size: 11.5px; }
.hab-strip { display: flex; gap: 3px; margin-top: 4px; flex-wrap: wrap; }
.hab-dot { width: 11px; height: 11px; border-radius: 3px; background: var(--surface-2); }
.hab-dot.done { background: var(--uc); }
.hab-dot.miss { background: color-mix(in srgb, var(--danger) 30%, var(--surface-2)); }
.hab-dot.off { opacity: .4; }
/* контейнер дней в редакторе рутин — тэг-квалификация div, чтобы не задевать
   КНОПКУ .day-toggle из старого редактора на «Сегодня» (другой виджет с тем же классом) */
div.day-toggle { display: flex; gap: 5px; }
div.day-toggle button { flex: 1; padding: 8px 0; border-radius: 8px; background: var(--surface-2);
  border: 1.5px solid transparent; font-size: 12px; font-weight: 700; }
div.day-toggle button.on { background: color-mix(in srgb, var(--us) 14%, var(--surface-2)); border-color: var(--us); color: var(--us); }

/* v12.1: история смен IP в присутствии (только Денис) */
.ip-change { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-bottom: 1px solid var(--border); }
.ip-change:last-child { border-bottom: none; }
.ip-change.current { font-weight: 700; }

/* v12.2: виджет привычек в одну строку, важное, корзина */
.hab-widget-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
.hab-w-name { display: flex; align-items: center; gap: 5px; font-weight: 700; font-size: 12.5px; width: 78px; flex: none; }
.hab-w-name i { width: 9px; height: 9px; border-radius: 50%; }
.hab-w-pct { font-size: 12.5px; font-weight: 800; width: 38px; text-align: right; }
.hab-line { display: flex; align-items: center; gap: 7px; margin-top: 6px; font-size: 12px; }
.hab-line .hab-u-name { width: 66px; flex: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hab-line .hab-streak { flex: none; font-weight: 800; }
/* Полоса привычки — РОВНО ОДИН ряд. Базовое правило .hab-strip разрешает перенос, и на
   узком экране 21 день (231 px) не влезал в 170 px: половина точек уезжала на вторую
   строку внутрь overflow: hidden и виднелась обрезанной полоской. Точки теперь делят
   ширину между собой (6-9 px вместо жёстких 9), поэтому в ряд помещается вся история. */
.hab-line .hab-strip { flex: 1; display: flex; gap: 2px; overflow: hidden; flex-wrap: nowrap; }
.hab-line .hab-dot { flex: 1 1 0; min-width: 0; max-width: 9px; height: 9px; border-radius: 2px; }
.hab-line .hab-pct { flex: none; width: 34px; text-align: right; font-weight: 700; color: var(--muted); }
.rt-spoiler { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 14px; }
.trash-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.trash-row:last-child { border-bottom: none; }

/* v12.3: пикер эмодзи, выбор языка, «в дискуссию» из дневника */
.emoji-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px; max-height: 60vh; overflow-y: auto; }
.emoji-grid button { font-size: 22px; padding: 6px 0; border-radius: 8px; }
.emoji-grid button:active { background: var(--surface-2); }
.lang-choices { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.lang-choice { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1.5px solid transparent; font-size: 15px; font-weight: 700; text-align: left; }
.lang-choice span:nth-child(2) { flex: 1; }
.lang-choice.active { border-color: var(--us); background: color-mix(in srgb, var(--us) 10%, var(--surface-2)); }
.j-disc-line { margin-top: 8px; }
.j-disc-link { font-size: 12.5px; font-weight: 700; color: var(--us); background: color-mix(in srgb, var(--us) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--us) 25%, transparent); border-radius: 999px; padding: 5px 12px; }

/* v12.4: спойлер комментариев под шагом цели + «в дискуссию» */
.step-block { border-bottom: 1px solid var(--border); padding-bottom: 4px; margin-bottom: 4px; }
.step-block:last-child { border-bottom: none; }
.step-comments { margin: 2px 0 4px 30px; }
.step-comments > summary {
  list-style: none; cursor: pointer; font-size: 12px; color: var(--muted);
  padding: 4px 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.step-comments > summary::-webkit-details-marker { display: none; }
.step-comments > summary b { color: var(--text); font-weight: 700; }
.step-comments[open] > summary { white-space: normal; color: var(--muted); }
.step-comments > [data-thread] { margin-top: 4px; }

/* v12.5: вложенные ответы + маленькие значки цитаты/удаления в комментариях */
/* компактный ВЕРТИКАЛЬНЫЙ столбик иконок у комментария — не забирает ширину у текста.
   Иконки прижаты друг к другу: перебиваем общий тач-таргет min-height:34 из блока v32. */
.c-icons { flex: none; display: flex; flex-direction: column; gap: 0; align-self: flex-start; margin-top: 0; }
.c-icons .c-ic { min-width: auto; min-height: auto; font-size: 15px; line-height: 1; padding: 3px 5px;
  border-radius: 8px; opacity: .4; transition: opacity .15s, background .15s; }
.c-icons .c-ic:active { opacity: 1; background: var(--surface-2); }
.j-comment.c-reply { position: relative; }
.j-comment.c-reply::before {
  content: ""; position: absolute; left: -9px; top: 4px; bottom: 8px;
  width: 2px; border-radius: 2px; background: var(--border);
}

/* v12.6: превью комментария прячется, когда спойлер шага открыт */
.step-comments:not([open]) .c-sum-open { display: none; }
.step-comments[open] .c-sum-preview { display: none; }
.step-comments[open] > summary { font-size: 11.5px; padding-bottom: 2px; }

/* v12.7: отметка прочтения шага партнёром */
.step-read { display: inline-block; font-size: 10px; font-weight: 700; color: var(--ok); margin-left: 6px; vertical-align: 1px; }

/* v12.8: быстрые реплики к секретной записке */
/* Подсказки «попросить открыть» — одна листаемая полоса вместо трёх этажей. По-английски
   фразы длиннее («👀 What's there? Show me» — 184 px), и на 309 px каждая занимала свою
   строку: три ряда вместо одного. */
.priv-quick { display: flex; gap: 6px; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
  justify-content: flex-start; margin: 4px 0 2px; padding-bottom: 2px; }
.priv-quick::-webkit-scrollbar { display: none; }
.priv-quick .chip { flex: none; }
.priv-quick .chip { font-size: 12.5px; padding: 6px 11px; }

/* v72: «стук» в закрытую записку — знак без сообщения */
.priv-quick .chip.knocked { border-color: var(--her); }
.nudge-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 16px; height: 16px; margin-left: 5px; padding: 0 4px;
  border-radius: 8px; background: var(--her); color: #fff;
  font-size: 10.5px; font-weight: 800; font-style: normal; font-variant-numeric: tabular-nums;
  vertical-align: 1px;
}
/* после первого стука появляется приглашение постучать ещё (пояснений к кнопкам нет) */
.nudge-again { margin: 7px 0 2px; text-align: center; }
.nudge-again-t { font-size: 12.5px; font-weight: 700; color: var(--her); }
/* сводка для автора записки: кто стучался и сколько раз (текста нажатия не существует) */
.nudge-box {
  margin: 10px 0 2px; padding: 9px 12px; border-radius: 12px; text-align: left;
  background: color-mix(in srgb, var(--her) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--her) 26%, transparent);
}
.nudge-who { font-size: 12.5px; font-weight: 800; margin-bottom: 5px; }
.nudge-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 12.5px; padding: 2px 0; }
.nudge-row b { font-variant-numeric: tabular-nums; color: var(--her); }
.nudge-last { font-size: 11px; margin-top: 4px; }

/* v12.9: непрочитанные комментарии — мягкое живое свечение, приглашающее зайти прочитать */
@keyframes unreadGlow {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--her) 42%, transparent); }
  50%      { box-shadow: 0 0 10px 1px color-mix(in srgb, var(--her) 42%, transparent); }
}
@keyframes unreadPulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .8;  transform: scale(1.06); }
}
/* пилюля со счётчиком новых комментариев */
.c-unread-pill {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 10.5px; font-weight: 800; color: #fff; background: var(--her);
  padding: 2px 8px; border-radius: 999px; line-height: 1.55; white-space: nowrap;
  animation: unreadPulse 1.8s ease-in-out infinite;
}
/* карточка цели/события/мечты с непрочитанным — тёплая рамка + пульс */
.goal-card.has-unread,
.dream-card.has-unread {
  border-color: color-mix(in srgb, var(--her) 55%, var(--border));
  animation: unreadGlow 2.1s ease-in-out infinite;
}
/* спойлер комментариев к шагу с непрочитанным — подсвеченная строка */
.step-comments.has-unread > summary { color: var(--her); font-weight: 700; }
.step-comments.has-unread:not([open]) > summary { animation: unreadPulse 1.8s ease-in-out infinite; }
/* сам новый комментарий внутри треда «светится» */
.j-comment.c-new .j-c-text {
  background: color-mix(in srgb, var(--her) 13%, transparent);
  border-radius: 9px; padding: 5px 9px; animation: unreadPulse 1.9s ease-in-out infinite;
}
/* колокольчик со свежими уведомлениями: непрерывно светится + периодически звенит.
   Идёт всё время, пока есть НЕПРОЧИТАННОЕ (total>0) — даже если панель открывали, но не прочли */
.bell-btn.has-unread {
  animation: bellRing 2.4s ease-in-out infinite, bellGlow 1.7s ease-in-out infinite;
  transform-origin: 50% 3px; border-radius: 999px;
}
@keyframes bellRing {
  0%, 82%, 100% { transform: rotate(0); }
  85% { transform: rotate(12deg); }  88% { transform: rotate(-10deg); }
  91% { transform: rotate(7deg); }   94% { transform: rotate(-4deg); }  97% { transform: rotate(1deg); }
}
@keyframes bellGlow {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--her) 60%, transparent); filter: none; }
  50% { box-shadow: 0 0 13px 4px color-mix(in srgb, var(--her) 50%, transparent);
        filter: drop-shadow(0 0 4px color-mix(in srgb, var(--her) 70%, transparent)); }
}
/* счётчик тоже мягко пульсирует — притягивает взгляд */
.bell-btn.has-unread .bell-badge { animation: badgePulse 1.3s ease-in-out infinite; }
@keyframes badgePulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.18); } }
@media (prefers-reduced-motion: reduce) {
  .c-unread-pill, .goal-card.has-unread, .dream-card.has-unread,
  .step-comments.has-unread:not([open]) > summary, .j-comment.c-new .j-c-text,
  .bell-btn.has-unread, .bell-btn.has-unread .bell-badge { animation: none; }
}
/* ============================================================
   v13: тренажёр глаголов — таблица «3 времени × 3 формы» и игры
   ============================================================ */
.vt-table { display: grid; grid-template-columns: 22px repeat(3, 1fr); gap: 5px; align-items: stretch; }
.vt-h { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); text-align: center; align-self: end; padding-bottom: 2px; }
.vt-rowlbl {
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); text-align: center; justify-self: center;
}
.vt-cell {
  background: var(--surface-2); border: 1.5px solid var(--border); border-radius: var(--r-sm);
  padding: 9px 5px; min-height: 62px; font-size: 12.5px; line-height: 1.45; color: var(--text);
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  font-family: var(--font-body); cursor: pointer; text-align: center; word-break: break-word;
}
.vt-cell:active { transform: scale(.98); }
.vt-cell.veiled { font-size: 20px; }
.vt-veil { opacity: .5; }
.vt-line.one { font-size: 15px; font-weight: 600; }
.vt-prons { font-style: normal; font-size: 10.5px; color: var(--muted); display: block; }
.vt-aux { color: var(--him); font-weight: 800; }
.vt-end { color: var(--her); font-weight: 800; }
.vt-irr { color: var(--gold); font-weight: 800; }
.vt-irr-mark { font-size: 11px; }
.vt-verb-btn {
  flex: 1; text-align: left; background: var(--surface-2); border: 1.5px solid var(--border);
  border-radius: var(--r-sm); padding: 8px 10px; font-size: 15px; color: var(--text); cursor: pointer;
}
/* Семь местоимений — один ряд. Просили 343 px при 309: «she» оставалась одна на второй
   строке. Ужимаем поля кнопок и разрешаем им сжиматься — набор виден целиком, как и
   задумано: это переключатель, а не список. */
.vt-pron-row { display: flex; gap: 4px; flex-wrap: nowrap; margin-bottom: 10px; }
.vt-pron {
  border: 1.5px solid var(--border); background: var(--surface-2); color: var(--text);
  border-radius: 999px; padding: 5px 8px; font-size: 12.5px; font-weight: 700; cursor: pointer;
  flex: 0 1 auto; min-width: 0; white-space: nowrap;
}
.vt-pron.active { border-color: var(--him); background: var(--him-soft); color: var(--him); }

/* тепловая карта прогресса и мини-таблица игры «найди клетку» */
.vt-table.heat .vt-cell { min-height: 44px; font-size: 13px; font-weight: 800; cursor: default; }
.vt-lvl { display: block; font-style: normal; font-size: 7px; letter-spacing: 2px; color: var(--muted); }
.vt-table.mini { margin-top: 4px; }
.vt-table.mini .vt-cell { min-height: 46px; }
.vt-cell.pickable { background: var(--surface); }
.vt-cell.right { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, var(--surface-2)); }
.vt-cell.wrong { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, var(--surface-2)); }

/* игры: цель задания, сборка из слов, пары */
.vg-target { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin: 6px 0 4px; }
.vg-tag {
  font-size: 12px; font-weight: 800; padding: 4px 10px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
}
.vg-tag.tense { background: var(--him-soft); color: var(--him); border-color: transparent; }
.vg-tag.form { background: var(--her-soft); color: var(--her); border-color: transparent; }
.vg-answer {
  min-height: 52px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  border-bottom: 2px dashed var(--border); padding: 8px 2px; margin-bottom: 12px;
}
.vg-answer.right { border-color: var(--ok); }
.vg-answer.wrong { border-color: var(--danger); }
.vg-q { font-size: 18px; font-weight: 800; color: var(--muted); }
.vg-chips, .vg-pairs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.vg-pairs { display: grid; grid-template-columns: 1fr 1fr; }
.vg-chip {
  border: 1.5px solid var(--border); background: var(--surface-2); color: var(--text);
  border-radius: var(--r-sm); padding: 9px 14px; font-size: 15px; font-weight: 700; cursor: pointer;
}
.vg-chip:active { transform: scale(.97); }
.vg-chip.used { opacity: .25; pointer-events: none; }
.vg-chip.in { padding: 6px 10px; font-size: 14px; }
.vg-chip.pair { text-align: center; }
.vg-chip.sel { border-color: var(--him); background: var(--him-soft); color: var(--him); }
.vg-chip.done { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, var(--surface-2)); opacity: .55; pointer-events: none; }
.vg-chip.shake { animation: vgShake .35s; border-color: var(--danger); }
@keyframes vgShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce) { .vg-chip.shake { animation: none; } }

/* ============================================================
   v13: раздел «Фильм» — плеер + двуязычные субтитры + транскрипт
   ============================================================ */
/* вход с «Сегодня» */
.film-entry { width: 100%; display: flex; align-items: center; gap: 12px; text-align: left;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 13px 16px; box-shadow: var(--shadow); }
.film-entry:active { transform: scale(.99); }
.film-entry-ic { font-size: 26px; }
.film-entry-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.film-entry-tx b { font-size: 15px; }
.film-entry-tx small { color: var(--muted); font-size: 12px; }
.film-entry-arrow { color: var(--muted); font-size: 20px; }

/* добавление ссылки */
.film-add { display: flex; gap: 8px; }
.film-add .input { flex: 1; }
/* Блок озвучки: ярусами, а не кашей. Общий флекс с переносом раскидывал подпись и три
   группы кнопок по четырём рваным рядам, причём две группы вставали в одну строку, а
   подпись — в другую. Теперь каждая группа занимает свой ряд целиком и листается вбок,
   если не помещается: порядок читается сверху вниз, а не угадывается. */
.film-dubpick { display: flex; flex-direction: column; align-items: stretch; gap: 6px; margin-top: 10px; }
.film-dubpick .chip-row { display: flex; gap: 6px; flex-wrap: nowrap; overflow-x: auto;
  scrollbar-width: none; }
.film-dubpick .chip-row::-webkit-scrollbar { display: none; }
.film-dubpick .chip-row > * { flex: none; }
.film-dubpick .chip { padding: 4px 10px; font-size: 12.5px; }
.film-dubnote { flex-basis: 100%; font-size: 11.5px; line-height: 1.4; opacity: .75; }

/* карточка ролика в списке */
.film-card { width: 100%; display: flex; gap: 12px; align-items: stretch; text-align: left;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 10px; box-shadow: var(--shadow); margin-bottom: 10px; }
.film-card:active { transform: scale(.995); }
.film-thumb { flex: none; width: 108px; height: 68px; border-radius: 10px; background: #000 center/cover no-repeat;
  display: flex; align-items: center; justify-content: center; color: #fff; font-size: 20px; position: relative; overflow: hidden; }
.film-play { width: 30px; height: 30px; border-radius: 50%; background: rgba(0,0,0,.5);
  display: flex; align-items: center; justify-content: center; font-size: 13px; padding-left: 2px; }
.film-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; justify-content: center; }
.film-ttl { font-weight: 700; font-size: 14px; line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.film-sub2 { color: var(--muted); font-size: 11.5px; }
/* «о чём ролик» в списке — две строки максимум, чтобы карточки не разъезжались */
.film-gist {
  color: var(--text); opacity: .78; font-size: 12px; line-height: 1.3; margin: 1px 0 2px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.film-badge-proc { color: var(--him); border-color: var(--him); font-size: 11px; }
.film-badge-err { color: var(--danger); border-color: var(--danger); font-size: 11px; }
/* «где провёл время сегодня»: полоски по экранам вместо простыни переходов */
.act-bar-row { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 12.5px; }
.act-bar-name { width: 82px; flex: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.act-bar { flex: 1; height: 8px; border-radius: 4px; background: var(--surface-2); overflow: hidden; }
.act-bar i { display: block; height: 100%; border-radius: 4px; background: var(--him); }
.act-bar-val { width: 58px; flex: none; text-align: right; font-size: 11px; }

/* «смотрим вместе»: непросмотренное, лайки и строка «кто сколько посмотрел» */
.film-badge-new { color: var(--her); border-color: var(--her); font-size: 11px; font-weight: 800; }
/* Ссылка на оригинал ролика. Обёртка нужна не для отступа: без неё ссылка становится прямым
   ребёнком флекс-колонки .page, блокифицируется и разрастается на всю свободную высоту —
   получалась кликабельная полоса рядом с плеером, уводившая в инстаграм при попытке
   запустить видео (2026-08-07). Кликабельно должно быть РОВНО столько, сколько занял текст. */
.film-src-row { margin: 2px 0 6px; line-height: 1.3; }
.film-src {
  display: inline-block; max-width: 100%;
  padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-2);
  font-size: 12px; color: var(--him); text-decoration: none;
  overflow-wrap: anywhere;
}
.film-src:active { opacity: .6; }
.film-reacts { margin: 8px 0 2px; flex-wrap: wrap; }
.film-views { margin: 4px 0 10px; display: flex; flex-direction: column; gap: 4px; }
.film-view-row {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-size: 12.5px; padding: 5px 10px; border-radius: 10px; background: var(--surface-2);
}
.film-view-row .dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.film-view-row.w-none { opacity: .6; }
.film-view-row.w-done { background: color-mix(in srgb, var(--ok) 14%, transparent); }
/* архив удалённых роликов */
.film-arc-row { display: flex; align-items: center; gap: 8px; padding: 6px 2px; border-bottom: 1px solid var(--border); }
.film-arc-ttl { flex: 1; min-width: 0; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.film-view-row .hint { font-size: 11.5px; }

/* верхняя строка деталки */
.film-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }

/* плеер + оверлей субтитров */
.film-player { position: relative; border-radius: var(--r-md); overflow: hidden; background: #000; }
.film-player video { display: block; width: 100%; max-height: 70vh; background: #000; }
.film-subs { position: absolute; left: 0; right: 0; bottom: 9%; text-align: center; pointer-events: none;
  padding: 0 10px; display: flex; flex-direction: column; gap: 2px; }
.film-sub-1 { display: inline-block; margin: 0 auto; font-size: 16px; font-weight: 700; color: #fff; line-height: 1.28;
  text-shadow: 0 1px 3px rgba(0,0,0,.9), 0 0 6px rgba(0,0,0,.7); }
.film-sub-2 { display: inline-block; margin: 0 auto; font-size: 13.5px; font-weight: 600; color: #ffe9b8; line-height: 1.25;
  text-shadow: 0 1px 3px rgba(0,0,0,.9); }

/* переключатель субтитров */
.film-subs-ctl { display: flex; align-items: center; gap: 6px; margin: 10px 0 4px; flex-wrap: wrap; }
.chip.film-sm { padding: 5px 11px; font-size: 12px; }
.film-ttl-full { font-weight: 700; font-size: 15px; margin: 8px 2px 4px; }
.film-explain { margin: 8px 0 4px; border-left: 2.5px solid var(--gold); }

/* транскрипт: тап по строке — перемотка; активная строка подсвечена */
.film-transcript { margin-top: 10px; border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; }
.film-transcript > summary { cursor: pointer; padding: 10px 12px; font-size: 13px; font-weight: 700; color: var(--muted); list-style: none; }
.film-transcript > summary::-webkit-details-marker { display: none; }
.film-transcript[open] > summary { border-bottom: 1px solid var(--border); }
.film-transcript > div { max-height: 44vh; overflow-y: auto; }
.film-tline { display: flex; gap: 9px; padding: 7px 12px; cursor: pointer; border-bottom: 1px solid var(--border); transition: background .15s; }
.film-tline:active { background: var(--surface-2); }
.film-tline.on { background: color-mix(in srgb, var(--him) 12%, transparent); }
.film-tt { flex: none; width: 40px; font-size: 11px; color: var(--him); font-weight: 700; padding-top: 2px; font-variant-numeric: tabular-nums; }
.film-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.film-tx-1 { font-size: 13.5px; line-height: 1.3; }
.film-tx-2 { font-size: 12px; color: var(--muted); line-height: 1.25; margin-top: 1px; }

/* v13.1 → v25: секретная записка (любая, что была секретной: private/sealed/was_secret) =
   запечатанное белое письмо с замочком и сердечком. Локально переопределяем структурные
   токены → ВСЯ начинка карточки становится «бумагой» в ЛЮБОЙ теме (в тёмной светлые чернила
   превращаются в тёмные на белом письме; фон заметно-белый, а не бледно-розовый как раньше). */
.j-card.j-secret {
  --surface: #FFF8F4;
  --surface-2: #F8EAE4;
  --text: #40303A;
  --muted: #A2888F;
  --border: #EAD3CD;
  --bg: #FFF8F4; /* элементы с color:var(--bg) (напр. .chip.active) читаемы на бумаге и в тёмной теме */
  position: relative;
  color: var(--text);
  border: 1px solid #E7C9C2;
  border-left: 3px solid var(--her);
  /* тёплая бумага письма (заметно отличается от обычной белой карточки) + линии листа */
  background:
    repeating-linear-gradient(180deg, transparent 0, transparent 26px, rgba(238, 93, 131, .06) 27px, rgba(238, 93, 131, .06) 28px),
    linear-gradient(180deg, #FFF7F2 0%, #FBE7E0 100%);
  box-shadow: 0 6px 20px -10px color-mix(in srgb, var(--her) 45%, transparent), 0 6px 22px rgba(74, 56, 30, .08);
  overflow: hidden;
  padding-top: 20px;
}
/* клапан конверта сверху */
.j-card.j-secret::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 30px;
  background: linear-gradient(180deg, rgba(238, 93, 131, .18), transparent);
  clip-path: polygon(0 0, 100% 0, 50% 100%); opacity: .85; pointer-events: none;
}
/* печать секретной записки — замок + письмо с сердечком, по центру верхнего края конверта.
   Эмодзи (не CSS-круг), мягкая «наклейка»: не мешает кнопкам ✎/✕ и mood справа. */
.j-card.j-secret::after {
  content: '🔒💌';
  position: absolute; top: 1px; left: 50%; transform: translateX(-50%);
  font-size: 13px; letter-spacing: -1px; line-height: 1;
  padding: 3px 8px 4px; border-radius: 0 0 10px 10px;
  background: color-mix(in srgb, var(--her) 14%, #fff);
  box-shadow: 0 1px 4px rgba(150, 30, 66, .22);
  z-index: 3; pointer-events: none;
}
.j-card.j-secret .j-head, .j-card.j-secret .j-text { position: relative; }
/* запечатанная (партнёром ещё не открытая) записка — тот же образ письма (усиленная тень);
   у неё своя крупная иконка 🔒/💌, поэтому мелкую печать-сургуч не дублируем */
.j-card.sealed-note.j-secret {
  border-left-width: 1px;
  box-shadow: 0 6px 20px -10px color-mix(in srgb, var(--her) 55%, transparent), 0 6px 22px rgba(74, 56, 30, .08);
}
.j-card.sealed-note.j-secret::after { display: none; }
/* стрелка направления на маршруте дня (Leaflet divIcon): треугольник смотрит вверх,
   поворачивается по азимуту отрезка. Белая обводка — чтобы читалась на любых тайлах. */
.geo-arrow { background: none; border: none; }
.geo-arrow span {
  font-size: 15px; line-height: 1; text-align: center;
  text-shadow: 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff;
}
/* строка ленты точек кликабельна — уводит карту на эту точку */
.ip-change[data-geo-pt] { cursor: pointer; }

/* нарисованный конверт секретной записки: сердце-сургуч + марка с эмодзи автора.
   Цвета бумаги заданы явно (не токенами темы) — письмо белое и в тёмной теме тоже. */
.env-wrap { position: relative; margin: 0 auto 2px; line-height: 0; max-width: 100%; }
.env-art { display: block; width: 100%; height: auto; overflow: visible; }
.env-body { fill: #FFFDFB; stroke: #E8A6B7; stroke-width: 2.4; }
.env-fold { fill: none; stroke: #F3CCD5; stroke-width: 1.8; stroke-linecap: round; }
.env-flap { fill: none; stroke: #E8A6B7; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.env-heart { fill: var(--her); stroke: #FFFDFB; stroke-width: 2; }
.env-key { fill: #FFF3F6; }                      /* замочная скважина = записка ещё закрыта */
.env-stamp {
  position: absolute; right: 6%; bottom: 9%;
  width: 27px; height: 27px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; border-radius: 7px;
  background: #FFFDFB; border: 1.5px dashed #E8A6B7;
  box-shadow: 0 1px 3px rgba(150, 30, 66, .18);
}
.read-mark.secret { color: var(--her); font-weight: 700; }
.read-mark.secret.on { color: var(--her); }
/* поле ввода комментария на бумаге письма — тёмные чернила (перебиваем color:inherit) */
.j-card.j-secret .input, .j-card.j-secret .textarea { color: var(--text); }
.j-card.j-secret .input::placeholder, .j-card.j-secret .textarea::placeholder { color: var(--muted); }

/* образ письма прямо при создании: пометил «секретная» → бумага запечатывается */
.letter-wrap { position: relative; transition: all .2s; }
.letter-seal {
  position: absolute; top: 9px; right: 11px; z-index: 2;
  font-size: 18px; letter-spacing: -1px; line-height: 1;
  padding: 4px 9px 5px; border-radius: 999px;
  background: color-mix(in srgb, var(--her) 16%, #fff);
  box-shadow: 0 2px 6px rgba(150, 30, 66, .28);
  opacity: 0; transform: scale(.6) rotate(-14deg);
  transition: all .25s cubic-bezier(.34, 1.56, .64, 1); pointer-events: none;
}
.letter-seal::before { content: '🔒💌'; }
.letter-wrap.on .letter-seal { opacity: 1; transform: scale(1) rotate(-6deg); }
.letter-wrap.on .textarea {
  background: linear-gradient(180deg, #fffdfb, #fbf1ee);
  color: #40303a; border-color: color-mix(in srgb, var(--her) 45%, var(--border));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--her) 20%, transparent);
}
.letter-wrap.on .textarea::placeholder { color: #b9a2aa; }
/* полный текст исходной темы дискуссии сверху ветки */
.disc-origin {
  margin: 0 12px 8px; padding: 10px 13px;
  background: var(--surface-2); border-radius: var(--r-md);
  border-left: 3px solid var(--him);
}
.disc-origin-text { font-size: 14px; line-height: 1.45; white-space: pre-wrap; }
.disc-origin-tr { font-size: 12.5px; color: var(--muted); line-height: 1.4; margin-top: 4px; white-space: pre-wrap; }

/* v13.2: черновик целей из дискуссии — тема-цель + цели-дети + двойное утверждение */
.goal-group { border: 1px solid var(--border); border-radius: var(--r-lg); padding: 6px; margin-bottom: 10px; background: color-mix(in srgb, var(--gold) 4%, var(--surface)); }
.goal-group.draft { border-color: color-mix(in srgb, var(--gold) 45%, var(--border)); }
.goal-group > .goal-card { margin-bottom: 6px; }
.goal-children { padding-left: 12px; border-left: 2px solid color-mix(in srgb, var(--gold) 35%, var(--border)); margin-left: 8px; display: flex; flex-direction: column; gap: 8px; }
.goal-card.goal-draft { position: relative; border: 1px dashed color-mix(in srgb, var(--gold) 55%, var(--border)); background: color-mix(in srgb, var(--gold) 7%, var(--surface)); }
.draft-badge { font-size: 10px; font-weight: 800; color: var(--gold); background: var(--gold-soft); padding: 1px 7px; border-radius: 999px; vertical-align: 2px; }
.goal-approve-row { display: flex; align-items: center; gap: 8px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }
.appr-dots { display: inline-flex; gap: 4px; }
.appr-dot { width: 12px; height: 12px; border-radius: 50%; border: 1.5px solid; background: transparent; transition: all .15s; }
.appr-dot.on { box-shadow: 0 0 0 2px color-mix(in srgb, var(--ok) 30%, transparent); }

/* v13.4: плитка выпуска в колокольчике — «обновление применилось + что сделано» */
.rel-card {
  margin-bottom: 12px; padding: 11px 13px; border-radius: var(--r-md);
  background: color-mix(in srgb, var(--gold) 7%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--gold) 32%, var(--border));
}
.rel-card.unseen { box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--gold) 45%, transparent); }
.rel-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.rel-badge { font-weight: 800; font-size: 13px; color: var(--gold); }
.rel-when { font-size: 11px; color: var(--muted); }
.rel-lead { font-size: 13px; line-height: 1.4; margin-top: 5px; }
.rel-list { margin: 5px 0 0; padding-left: 18px; }
.rel-list li { font-size: 12.5px; line-height: 1.5; color: var(--text); }

/* v30: блок «Ждут твоего ответа» в колокольчике — мягкий акцент, отделён от ленты */
.await-block { margin-bottom: 10px; padding-bottom: 6px; border-bottom: 1px dashed var(--border); }
.await-row { background: color-mix(in srgb, var(--her) 5%, transparent); border-radius: var(--r-md); }
/* v31: зеркало партнёра «У Мии/Дениса в ожидании» — нейтральный (его цвет) оттенок */
.await-block.partner .await-row { background: color-mix(in srgb, var(--him) 5%, transparent); }

/* v35: ручное напоминание партнёру — «🔔» рядом с пунктом зеркала */
.await-row-wrap { display: flex; align-items: center; gap: 6px; }
.await-row-wrap .await-row { flex: 1; }
.notif-nudge { flex: none; font-size: 17px; padding: 6px 8px; border-radius: 10px;
  background: var(--gold-soft); min-width: 40px; min-height: 40px; }
.notif-nudge:active { transform: scale(.9); }

/* v35: эмодзи-реакции на комментарии + «любой эмодзи» в пикере */
.c-reacts { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.c-react { font-size: 14px; padding: 1px 7px; border-radius: 999px; line-height: 1.5;
  background: var(--surface-2); border: 1px solid var(--border); }
.c-react.mine { border-color: var(--him); background: color-mix(in srgb, var(--him) 12%, var(--surface-2)); }
.emoji-any { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
/* «＋» произвольного настроения в композере записи */
.mood-row [data-m-any] { font-weight: 800; }

/* v35: единый Админ-центр в профиле (только Денис) — визуально отделён */
.admin-center {
  margin: 6px 0; padding: 12px 13px; border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--gold) 5%, var(--surface-2));
  border: 1px solid color-mix(in srgb, var(--gold) 28%, var(--border));
}
.admin-head { font-weight: 800; font-size: 14px; color: var(--gold); margin-bottom: 2px; }
/* Красный маркер: функции, которые видит ТОЛЬКО Денис-админ (Мия их не видит — гейты на
   клиенте и сервере 403). Красный = «это скрытое, не для неё». */
.admin-only,
.admin-only .hint,
.admin-only .admin-head,
.admin-only h2,
.admin-only summary,
.admin-only .lbl,
.admin-only b { color: var(--danger); }

/* v32: тач-таргеты — мелкие иконки-кнопки до комфортных размеров (iPhone, Apple HIG) */
.del, .c-ic, .explain-ic, .speak-btn, .rt-cam {
  min-width: 34px; min-height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
}
.j-toggle { min-height: 32px; display: inline-flex; align-items: center; }
/* точки согласования: видимая рамка по умолчанию (цвет задаёт JS, но fallback нужен) */
.appr-dot { border-color: var(--muted); }
/* длинные названия целей/имена не рвут карточки */
.goal-card .ttl { overflow-wrap: anywhere; }
.j-head .who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 40vw; }

/* ===================== Раздел «Игры» + игра «Ближе» (v37) ===================== */
.game-card { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px; }
.game-ico { font-size: 30px; flex: none; }
.game-name { font-weight: 800; font-size: 16px; }

.closer-stats { display: flex; gap: 8px; margin-bottom: 10px; }
.cs-item { flex: 1; background: var(--surface-2); border-radius: var(--r-md); padding: 8px 6px; text-align: center; }
.cs-item b { display: block; font-size: 17px; font-weight: 800; }
.cs-item span { font-size: 10.5px; color: var(--muted); }
.closer-tabs { display: flex; gap: 4px; margin-bottom: 12px; }
.closer-tabs button { flex: 1; padding: 8px; border-radius: var(--r-md); font-weight: 700; font-size: 13px; color: var(--muted); background: var(--surface-2); }
.closer-tabs button.on { background: var(--him); color: #fff; }

.cl-qcard { padding: 16px; }
.cl-src { font-size: 11.5px; color: var(--muted); font-weight: 700; margin-bottom: 8px; }
.cl-qtext { font-size: 18px; font-weight: 700; line-height: 1.35; }
.cl-opts { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.cl-opt { text-align: left; padding: 13px 15px; border-radius: var(--r-md); background: var(--surface-2);
  border: 1.5px solid transparent; font-size: 15px; font-weight: 600; transition: all .12s; }
.cl-opt:active { transform: scale(.98); }
.cl-opt.on { border-color: var(--him); background: color-mix(in srgb, var(--him) 12%, var(--surface-2)); }
.cl-opt.cl-own { color: var(--him); font-weight: 700; }
.cl-mini { display: inline-block; width: auto; padding: 8px 12px; margin: 0 6px 6px 0; font-size: 13px; }

.cl-reveal { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.cl-ans { display: flex; gap: 8px; align-items: baseline; padding: 10px 13px; border-radius: var(--r-md); background: var(--surface-2); font-size: 15px; }
.cl-ans .cl-who { font-weight: 800; font-size: 12px; color: var(--muted); flex: none; min-width: 54px; }
.cl-ans.mine { background: color-mix(in srgb, var(--us) 10%, var(--surface-2)); }
.cl-ans.partner { background: color-mix(in srgb, var(--him) 10%, var(--surface-2)); }
.cl-ans.waiting { color: var(--muted); font-size: 13px; justify-content: center; font-style: italic; }
.cl-match { align-self: center; font-weight: 800; font-size: 13px; padding: 4px 12px; border-radius: 999px; margin-top: 2px; }
.cl-match.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, transparent); }
.cl-match.diff { color: var(--gold); background: var(--gold-soft); }
.cl-hist { padding: 14px; margin-bottom: 10px; }

/* управление вопросами: свои + от ИИ, правка/удаление */
.cl-manage { padding: 13px 14px; margin-bottom: 10px; }
.cl-mrow { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.cl-tag { font-size: 11px; font-weight: 800; padding: 3px 9px; border-radius: 999px; letter-spacing: .2px; }
.cl-tag.mine { color: var(--us); background: color-mix(in srgb, var(--us) 12%, transparent); }
.cl-tag.ai { color: var(--gold); background: var(--gold-soft); }
.cl-mbtns { display: flex; gap: 4px; }
.cl-mbtns .c-ic { min-width: auto; min-height: auto; font-size: 15px; line-height: 1; padding: 4px 7px; }
.cl-mopts { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; }
.cl-mopt { font-size: 12px; font-weight: 600; color: var(--muted); background: var(--surface-2);
  padding: 4px 10px; border-radius: 999px; }

/* ===================== Лента фото рутин в уведомлениях (v38) ===================== */
.photo-block { margin-bottom: 12px; }
/* дата — разделителем на ВСЮ ширину сетки, чтобы фото шли плотно по 5 в ряд */
.photo-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; margin-bottom: 4px; }
.photo-date { grid-column: 1 / -1; font-size: 11px; font-weight: 700; color: var(--muted); margin: 4px 2px 0; }
.photo-cell { position: relative; aspect-ratio: 1; border-radius: 8px; overflow: hidden; background: var(--surface-2); }
.photo-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-cell:active { transform: scale(.95); }
.photo-badge { position: absolute; bottom: 2px; right: 2px; font-size: 9px;
  background: rgba(0,0,0,.4); padding: 0 3px; border-radius: 999px; letter-spacing: -1px; }
.photo-more > summary { list-style: none; cursor: pointer; font-size: 12px; font-weight: 700; color: var(--gold); padding: 6px 2px; }
.photo-more > summary::-webkit-details-marker { display: none; }
/* просмотр фото: инфо + реакции-эмодзи на выбор */
.photo-info { margin-top: 12px; }
.photo-info b { font-size: 15px; }
.photo-reacts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 12px; }
.photo-react { font-size: 22px; padding: 5px 8px; border-radius: 12px; background: var(--surface-2);
  border: 1.5px solid transparent; line-height: 1; transition: transform .1s; }
.photo-react.on { border-color: var(--her); background: color-mix(in srgb, var(--her) 14%, var(--surface-2)); }
.photo-react.more { font-weight: 800; color: var(--muted); }
.photo-react:active { transform: scale(1.15); }
.photo-react-sum { margin-left: auto; font-size: 18px; letter-spacing: -2px; }

/* v40: кнопка «напомнить» (🔔) рядом с топиком — цели/дневник/дискуссии (только Денис) */
.topic-row-wrap { display: flex; align-items: stretch; gap: 6px; margin-bottom: 8px; }
.topic-row-wrap > .card, .topic-row-wrap > .goal-card, .topic-row-wrap > .disc-card { margin-bottom: 0; }
.nudge-topic { flex: none; align-self: center; font-size: 17px; padding: 0 11px; min-height: 40px;
  border-radius: 12px; background: var(--gold-soft); display: inline-flex; align-items: center; }
.nudge-topic:active { transform: scale(.9); }

/* v42: эмодзи рутины на фото-ячейке + история апгрейдов под спойлером */
.photo-rt-emoji { position: absolute; top: 2px; left: 2px; font-size: 12px; line-height: 1;
  filter: drop-shadow(0 1px 1.5px rgba(0,0,0,.6)); }
/* дата — поверх фото снизу, компактно */
.photo-day { position: absolute; bottom: 0; left: 0; right: 0; font-size: 8px; font-weight: 700;
  color: #fff; background: linear-gradient(transparent, rgba(0,0,0,.55)); padding: 6px 3px 2px;
  text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.1; }
.rel-history { margin-top: 8px; }
.rel-history > summary { list-style: none; cursor: pointer; font-size: 12px; font-weight: 700; color: var(--gold); padding: 2px 0; }
.rel-history > summary::-webkit-details-marker { display: none; }
.rel-hist-item { margin-top: 10px; padding-top: 8px; border-top: 1px dashed color-mix(in srgb, var(--gold) 25%, var(--border)); }
.rel-hist-item > b { font-size: 12.5px; }
.rel-hist-item .rel-when { margin-left: 6px; }

/* v45: счётчик новых сообщений в одной теме — «Тема · 3 новых» */
.notif-count { color: var(--her); font-weight: 800; font-size: 12px; white-space: nowrap; }

/* крошечный, еле заметный «уведомить партнёра» — только у Дэни (см. notifybell.js).
   На фоне почти незаметен (серый, opacity .25), проявляется при наведении/тапе. */
.mini-bell { background: none; border: none; cursor: pointer; font: inherit; font-size: 10.5px;
  line-height: 1; padding: 2px 3px; color: inherit; opacity: .22; filter: grayscale(1);
  transition: opacity .15s, filter .15s, transform .1s; -webkit-tap-highlight-color: transparent;
  vertical-align: middle; }
.mini-bell:hover, .mini-bell:focus-visible { opacity: .9; filter: none; }
.mini-bell:active { transform: scale(.88); }
.mini-bell.sent { opacity: 1; filter: none; }
.mini-bell:disabled { cursor: default; }

/* карточка видео + колонка действий (🔔/🗑) справа — только у Дэни */
.film-row { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.film-row .film-card { flex: 1; min-width: 0; margin-bottom: 0; }
.film-row-acts { flex: none; display: flex; flex-direction: column; gap: 6px; align-items: center; }
.mini-del { background: none; border: none; cursor: pointer; font-size: 14px; line-height: 1;
  padding: 3px 5px; opacity: .4; transition: opacity .15s, transform .1s; -webkit-tap-highlight-color: transparent; }
.mini-del:hover, .mini-del:focus-visible { opacity: 1; }
.mini-del:active { transform: scale(.88); }

/* прогресс загрузки файла (МБ + проценты) */
.up-progress { margin: 8px 2px 2px; }
.up-bar { height: 7px; border-radius: 5px; background: var(--surface-2, rgba(127,127,127,.2)); overflow: hidden; }
.up-bar > i { display: block; height: 100%; width: 0; border-radius: 5px;
  background: linear-gradient(90deg, #5b6cf0, #7d8bff); transition: width .2s ease; }
.up-text { margin-top: 5px; font-size: 12px; font-weight: 600; color: var(--muted); text-align: center; }

/* ============ СЛОЙ ПОЛИРОВКИ: единое качество на всех экранах ======================
   Принцип: НЕ переписываем разметку живых экранов (это риск сломать рабочее приложение),
   а поднимаем базовые примитивы — тени, типографику, границы, состояния. Меняется ощущение
   везде сразу, поведение — нигде. Всё уважает prefers-reduced-motion и тёмную тему.        */

:root {
  /* Многослойные тени вместо одиночной плоской: слабый общий ореол + направленная тень.
     Плоская тень читается как «шаблон», слоистая — как продуманный материал. */
  --shadow: 0 1px 2px rgba(74, 56, 30, .05), 0 4px 14px rgba(74, 56, 30, .07);
  --shadow-lift: 0 2px 6px rgba(74, 56, 30, .07), 0 16px 40px rgba(74, 56, 30, .14);
  --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, .6);
  /* вертикальный ритм: единая шкала отступов вместо произвольных чисел */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px; --sp-6: 32px;
}
[data-theme="dark"] {
  --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 16px rgba(0, 0, 0, .34);
  --shadow-lift: 0 2px 8px rgba(0, 0, 0, .4), 0 18px 44px rgba(0, 0, 0, .5);
  --shadow-inset: inset 0 1px 0 rgba(255, 255, 255, .04);
}

/* Типографика: спокойный ритм и переносы, чтобы заголовки не рвались некрасиво */
body { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; }
h1, h2, h3, .section-title { text-wrap: balance; }
p, .hint, .notif-text, .cap-text, .ar-block p { text-wrap: pretty; }
/* цифры в статистике не «прыгают» при обновлении — табличные знаки */
.pulse-score, .syn-score, .pm-score, .cs-item b, .ap-cell b, time { font-variant-numeric: tabular-nums; }

/* Карточки: тонкий внутренний блик сверху — поверхность читается как материал, а не заливка */
.card, .film-card, .goal-card, .game-card, .cap-card, .astro-person, .astro-syn, .pulse-tip {
  box-shadow: var(--shadow), var(--shadow-inset);
}

/* Границы-волосинки: на плотных экранах 1px выглядит грубо */
@media (min-resolution: 2dppx) {
  .pulse-list, .ap-grid { border-width: .5px; }
  .syn-rows > div + div, .cap-mem-row + .cap-mem-row, .astro-advice li + li { border-top-width: .5px; }
}

/* Единые состояния для всего интерактивного — предсказуемость важнее эффектности */
button, .chip, .tab, [role="button"] { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
button:disabled { opacity: .55; cursor: default; }
/* Зону нажатия иконок увеличиваем ТОЛЬКО отступом внутри самой кнопки. Накладку-псевдоэлемент
   на 44px здесь применять нельзя: иконки в рядах стоят вплотную, и невидимая накладка
   перекрывала бы соседнюю кнопку, воруя нажатия. Отступ безопасен — он раздвигает соседей. */
.act, .c-ic, .mini-bell, .mini-del, .explain-ic { min-height: 32px; }

/* Плавное появление списков — по одному, а не «вспышкой всего сразу» */
.pulse-row, .cap-card, .astro-person { animation: riseIn .34s cubic-bezier(.22, 1, .36, 1) both; }
.pulse-row:nth-child(2) { animation-delay: .03s } .pulse-row:nth-child(3) { animation-delay: .06s }
.pulse-row:nth-child(4) { animation-delay: .09s } .pulse-row:nth-child(5) { animation-delay: .12s }
.pulse-row:nth-child(6) { animation-delay: .15s }
@keyframes riseIn { from { opacity: 0; transform: translateY(8px); } }

/* Скролл: инерция на iOS и отсутствие «прилипания» к краям */
.msgs, #main, .sheet { -webkit-overflow-scrolling: touch; }
/* Полоса прокрутки на десктопе — тонкая и в тон, а не системная серая */
* { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-thumb { background: var(--border); border-radius: 8px; }
*::-webkit-scrollbar-track { background: transparent; }

/* Выделение текста — в фирменном цвете, мелочь, которую замечают */
::selection { background: color-mix(in srgb, var(--him) 26%, transparent); }

@media (prefers-reduced-motion: reduce) {
  .pulse-row, .cap-card, .astro-person { animation: none; }
}

/* ============ «Капсула времени» =================================================== */
.cap-page { padding-bottom: 26px; }
.cap-new { margin-bottom: 6px; }
.cap-card { display: flex; gap: 12px; align-items: flex-start; padding: 14px 15px; margin-bottom: 10px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--shadow); position: relative; overflow: hidden; }
.cap-card.sealed { background: linear-gradient(150deg, color-mix(in srgb, var(--gold) 8%, var(--surface)), var(--surface) 62%); }
.cap-card.fresh { border-color: color-mix(in srgb, var(--gold) 60%, var(--border));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold) 30%, transparent), var(--shadow-lift);
  animation: capGlow 2.6s ease-in-out infinite; }
@keyframes capGlow { 0%,100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold) 22%, transparent), var(--shadow); }
  50% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 26%, transparent), var(--shadow-lift); } }
.cap-wax { flex: none; width: 38px; height: 38px; display: grid; place-items: center; font-size: 18px;
  border-radius: 50%; background: color-mix(in srgb, var(--gold) 14%, var(--surface-2));
  border: 1px solid color-mix(in srgb, var(--gold) 34%, var(--border)); }
.cap-wax.open { background: color-mix(in srgb, var(--him) 12%, var(--surface-2));
  border-color: color-mix(in srgb, var(--him) 32%, var(--border)); }
.cap-body { flex: 1; min-width: 0; }
.cap-head { display: flex; align-items: baseline; gap: 8px; }
.cap-head b { flex: 1; min-width: 0; font-size: 15px; font-weight: 700; overflow-wrap: anywhere; }
.cap-meta { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.cap-until { margin-top: 8px; font-family: var(--font-head), serif; font-size: 16px; font-weight: 700; color: var(--gold); }
.cap-bar { height: 5px; border-radius: 4px; background: var(--surface-2); overflow: hidden; margin: 7px 0 5px; }
.cap-bar > i { display: block; height: 100%; border-radius: 4px;
  background: linear-gradient(90deg, var(--gold), color-mix(in srgb, var(--gold) 50%, var(--him)));
  animation: pmGrow .8s cubic-bezier(.22,1,.36,1) both; }
.cap-date { font-size: 11px; color: var(--muted); opacity: .8; }
.cap-text { margin-top: 9px; font-size: 14.6px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.cap-text.alt { margin-top: 6px; font-size: 13px; color: var(--muted); padding-top: 6px; border-top: 1px dashed var(--border); }
.cap-lbl { display: block; font-size: 10.5px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted); margin: 10px 0 4px; }
.cap-presets { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.cap-mem { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 12px 14px; margin-bottom: 10px; }
.cap-mem-head { font-size: 11.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 8px; }
.cap-mem-row { display: flex; gap: 10px; padding: 7px 0; align-items: flex-start; }
.cap-mem-row + .cap-mem-row { border-top: 1px dashed var(--border); }
.cap-mem-ico { flex: none; font-size: 13px; line-height: 1.5; }
.cap-mem-txt { font-size: 13.6px; line-height: 1.5; }
.cap-mem-meta { font-size: 11px; color: var(--muted); margin-top: 2px; }
.cap-note { font-size: 11.5px; line-height: 1.5; text-align: center; margin: 14px 8px 0; opacity: .72; }

/* ============ глобальная полировка: единый визуальный язык ========================= */
/* мягкая, «дорогая» кривая для всех переходов + отклик на тап */
.btn, .card, .chip, .game-card, .film-card, .goal-card, .notif-row, .cap-card, .astro-person, .pulse-row {
  transition: transform .16s cubic-bezier(.22,1,.36,1), box-shadow .2s ease, border-color .2s ease, background-color .2s ease;
}
.btn:active, .chip:active, .game-card:active, .film-card:active, .goal-card:active { transform: scale(.982); }
.card:hover, .game-card:hover, .film-card:hover { box-shadow: var(--shadow-lift); }
/* плавное появление экрана — убирает ощущение «перескока» между разделами */
#main > .page { animation: pageIn .26s cubic-bezier(.22,1,.36,1) both; }
@keyframes pageIn { from { opacity: 0; transform: translateY(6px); } }
/* заголовки разделов — единый ритм и «воздух» */
.section-title { letter-spacing: .04em; }
/* аккуратный фокус для доступности (виден только с клавиатуры) */
:focus-visible { outline: 2px solid color-mix(in srgb, var(--gold) 70%, transparent); outline-offset: 2px; border-radius: 8px; }
/* мягкий скролл и отсутствие «резинового» горизонтального сдвига */
#main { scroll-behavior: smooth; overscroll-behavior-y: contain; }
body { overflow-x: hidden; }
@media (prefers-reduced-motion: reduce) {
  #main > .page, .cap-card.fresh, .cap-bar > i { animation: none; }
  #main { scroll-behavior: auto; }
  .btn:active, .chip:active, .game-card:active, .film-card:active, .goal-card:active { transform: none; }
}

/* ============ «Пульс пары» — индекс близости ====================================== */
.pulse-page { padding-bottom: 26px; }
.pulse-hero { position: relative; text-align: center; padding: 22px 16px 18px; border-radius: var(--r-lg);
  background: linear-gradient(170deg, color-mix(in srgb, var(--her) 12%, var(--surface)), var(--surface) 66%);
  border: 1px solid var(--border); overflow: hidden; margin-bottom: 14px; }

/* кольцо-индикатор: conic-gradient по значению --p (0..100) */
.pulse-ring { --p: 0; width: 168px; height: 168px; margin: 0 auto; border-radius: 50%; display: grid;
  place-items: center; position: relative;
  background: conic-gradient(var(--ring, var(--her)) calc(var(--p) * 1%), var(--surface-2) 0);
  animation: ringIn .95s cubic-bezier(.22,1,.36,1) both; }
@keyframes ringIn { from { --p: 0; opacity: .4; } }
.pulse-ring::after { content: ''; position: absolute; inset: 9px; border-radius: 50%; background: var(--surface); }
.pulse-ring-in { position: relative; z-index: 1; }
.pulse-hero.high { --ring: var(--ok); } .pulse-hero.good { --ring: var(--him); }
.pulse-hero.mid  { --ring: var(--gold); } .pulse-hero.low { --ring: var(--her); }
.pulse-heart { font-size: 21px; line-height: 1; animation: beat 1.9s ease-in-out infinite; }
.pulse-heart.big { font-size: 40px; }
@keyframes beat { 0%,100% { transform: scale(1); } 14% { transform: scale(1.17); } 28% { transform: scale(1); } 42% { transform: scale(1.11); } }
.pulse-score { font-family: var(--font-head), serif; font-size: 46px; font-weight: 700; line-height: 1.05; margin-top: 2px; }
.pulse-band { font-size: 11.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin-top: 1px; }
.pulse-meta { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 13px; flex-wrap: wrap; }
.pulse-trend { font-size: 13px; font-weight: 800; padding: 3px 9px; border-radius: 999px; }
.pulse-trend.up { color: var(--ok); background: color-mix(in srgb, var(--ok) 13%, transparent); }
.pulse-trend.down { color: var(--her); background: color-mix(in srgb, var(--her) 13%, transparent); }
.pulse-trend.flat { color: var(--muted); background: var(--surface-2); }
.pulse-vs { font-size: 12px; color: var(--muted); }
.pulse-spark-wrap { margin-top: 12px; color: var(--him); opacity: .85; }
.pulse-spark { width: 100%; height: 26px; display: block; }
.pulse-spark-wrap span { display: block; font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); margin-top: 3px; }

.pulse-tip { display: flex; gap: 12px; align-items: flex-start; padding: 14px 15px; margin-bottom: 4px;
  border: 1px solid color-mix(in srgb, var(--gold) 42%, var(--border)); }
.pt-ico { flex: none; font-size: 18px; width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: 10px; background: color-mix(in srgb, var(--gold) 12%, var(--surface-2)); }
.pulse-tip b { display: block; font-size: 11.5px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 3px; }
.pulse-tip p { margin: 0; font-size: 14.5px; line-height: 1.5; }

.pulse-list { display: flex; flex-direction: column; gap: 1px; background: var(--border);
  border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; }
.pulse-row { display: flex; gap: 11px; padding: 12px 14px; background: var(--surface); align-items: flex-start; }
.pulse-row.weak { background: color-mix(in srgb, var(--gold) 6%, var(--surface)); }
.pm-ico { flex: none; font-size: 15px; line-height: 1.5; }
.pm-body { flex: 1; min-width: 0; }
.pm-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.pm-top b { font-size: 14px; font-weight: 700; }
.pm-score { font-family: var(--font-head), serif; font-size: 17px; font-weight: 700; }
.pulse-row.high .pm-score { color: var(--ok); } .pulse-row.good .pm-score { color: var(--him); }
.pulse-row.mid .pm-score { color: var(--gold); } .pulse-row.low .pm-score { color: var(--her); }
.pulse-row.none .pm-score { color: var(--muted); opacity: .6; }
.pm-bar { height: 5px; border-radius: 4px; background: var(--surface-2); overflow: hidden; margin: 6px 0 5px; }
.pm-bar > i { display: block; height: 100%; border-radius: 4px; background: var(--muted);
  animation: pmGrow .8s cubic-bezier(.22,1,.36,1) both; }
@keyframes pmGrow { from { width: 0 !important; } }
.pulse-row.high .pm-bar > i { background: var(--ok); } .pulse-row.good .pm-bar > i { background: var(--him); }
.pulse-row.mid .pm-bar > i { background: var(--gold); } .pulse-row.low .pm-bar > i { background: var(--her); }
.pm-detail { font-size: 11.8px; color: var(--muted); line-height: 1.45; }
.pulse-note, .pulse-days { font-size: 11.5px; line-height: 1.5; text-align: center; margin: 13px 8px 0; opacity: .72; }
.pulse-loading { text-align: center; padding: 54px 20px; }
@media (prefers-reduced-motion: reduce) {
  .pulse-heart, .pulse-ring, .pm-bar > i { animation: none; }
}

/* ============ «Расклад» — премиальный космический блок ============================ */
.astro-page { padding-bottom: 26px; }
.astro-day { text-align: center; font-size: 11.5px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); opacity: .75; margin: 2px 0 14px; }

/* заголовок-толкование: крупная «обложка» дня */
.astro-headline { font-family: var(--font-head), serif; font-size: clamp(21px, 6.2vw, 27px);
  line-height: 1.22; font-weight: 700; text-align: center; margin: 0 6px 16px;
  background: linear-gradient(102deg, var(--him) 0%, var(--gold) 52%, var(--her) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  text-wrap: balance; }

/* карточка толкования */
.astro-read { padding: 4px 0; overflow: hidden; }
.ar-block { display: flex; gap: 12px; padding: 14px 15px; align-items: flex-start; }
.ar-block + .ar-block { border-top: 1px solid var(--border); }
.ar-ico { flex: none; font-size: 17px; line-height: 1.35; width: 26px; height: 26px; display: grid;
  place-items: center; border-radius: 9px; background: var(--surface-2); }
.ar-block b { display: block; font-size: 11.5px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 3px; }
.ar-block p { margin: 0; font-size: 14.5px; line-height: 1.55; }

.astro-two { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
.ar-person { padding: 13px 14px; position: relative; overflow: hidden; }
.ar-person::before { content: ''; position: absolute; inset: 0 auto 0 0; width: 3px; }
.ar-person.him::before { background: var(--him); }
.ar-person.her::before { background: var(--her); }
.ar-person b { display: block; font-size: 13px; font-weight: 800; margin-bottom: 5px; }
.ar-person p { margin: 0; font-size: 13.2px; line-height: 1.5; color: var(--text); opacity: .92; }
@media (max-width: 430px) { .astro-two { grid-template-columns: 1fr; } }

.astro-advice { margin-top: 10px; padding: 14px 15px; }
.astro-advice b { font-size: 11.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.astro-advice ul { margin: 8px 0 0; padding-left: 0; list-style: none; }
.astro-advice li { position: relative; padding: 7px 0 7px 24px; font-size: 14px; line-height: 1.5; }
.astro-advice li + li { border-top: 1px dashed var(--border); }
.astro-advice li::before { content: '\2726'; position: absolute; left: 4px; top: 7px; color: var(--gold); font-size: 12px; }

.astro-disclaimer, .astro-note { font-size: 11.5px; line-height: 1.5; text-align: center;
  margin: 14px 8px 0; opacity: .7; }

/* синастрия */
.astro-syn { margin-top: 14px; padding: 15px; }
.syn-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.syn-head > span:first-child { font-size: 11.5px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); }
.syn-score { font-family: var(--font-head), serif; font-size: 27px; font-weight: 700; line-height: 1;
  background: linear-gradient(96deg, var(--him), var(--her)); -webkit-background-clip: text;
  background-clip: text; color: transparent; }
.syn-score small { font-size: 12px; opacity: .5; -webkit-text-fill-color: var(--muted); }
.syn-bar { height: 7px; border-radius: 6px; background: var(--surface-2); overflow: hidden; margin: 10px 0 13px; }
.syn-bar > i { display: block; height: 100%; border-radius: 6px;
  background: linear-gradient(90deg, var(--him), var(--gold), var(--her));
  animation: synGrow .9s cubic-bezier(.22,1,.36,1) both; }
@keyframes synGrow { from { width: 0 !important; } }
.syn-rows > div { display: flex; align-items: baseline; gap: 8px; padding: 7px 0; font-size: 13.5px; }
.syn-rows > div + div { border-top: 1px solid var(--border); }
.syn-rows b { font-weight: 700; }
.syn-rows i { margin-left: auto; font-style: normal; font-size: 12px; color: var(--muted); text-align: right; }
.syn-note { margin: 11px 0 0; font-size: 11px; line-height: 1.5; opacity: .68; }

/* карта человека */
.astro-person { margin-top: 10px; padding: 14px 15px; position: relative; overflow: hidden; }
.astro-person::after { content: ''; position: absolute; top: -46px; right: -46px; width: 128px; height: 128px;
  border-radius: 50%; opacity: .11; pointer-events: none; }
.astro-person.him::after { background: radial-gradient(circle, var(--him), transparent 70%); }
.astro-person.her::after { background: radial-gradient(circle, var(--her), transparent 70%); }
.ap-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 11px; }
.ap-name { font-family: var(--font-head), serif; font-size: 17px; font-weight: 700; }
.ap-sun { font-size: 13.5px; font-weight: 700; color: var(--gold); }
.ap-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--border);
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
.ap-cell { background: var(--surface); padding: 9px 11px; min-width: 0; }
.ap-k { display: block; font-size: 9.8px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); opacity: .8; margin-bottom: 2px; }
.ap-cell b { font-size: 13.2px; font-weight: 700; overflow-wrap: anywhere; }
.ap-sm { font-weight: 500; font-size: 11.5px; color: var(--muted); }
.ap-matrix { margin-top: 12px; }
.ap-arc { display: flex; gap: 7px; margin-top: 6px; flex-wrap: wrap; }
.arc { flex: 1 1 0; min-width: 62px; text-align: center; padding: 8px 5px; border-radius: 11px;
  background: var(--surface-2); border: 1px solid var(--border);
  font-family: var(--font-head), serif; font-size: 19px; font-weight: 700; line-height: 1.05; }
.arc i { display: block; font-style: normal; font-family: var(--font-body), sans-serif;
  font-size: 9.5px; font-weight: 600; color: var(--muted); margin-top: 3px; line-height: 1.25; }
.arc.center { border-color: color-mix(in srgb, var(--gold) 55%, var(--border)); color: var(--gold);
  background: color-mix(in srgb, var(--gold) 9%, var(--surface-2)); }
.arc.money { border-color: color-mix(in srgb, var(--ok) 45%, var(--border)); }
.ap-today { margin-top: 11px; padding-top: 10px; border-top: 1px dashed var(--border); font-size: 12.8px; color: var(--muted); }
.ap-today b { color: var(--text); }
.empty-person { opacity: .6; }

/* форма данных рождения + «геройский» блок */
.astro-hero { position: relative; border-radius: var(--r-lg); overflow: hidden; margin-bottom: 14px;
  background: linear-gradient(168deg, color-mix(in srgb, var(--him) 16%, var(--surface)), var(--surface) 62%); }
.astro-hero-glow { position: absolute; inset: -60% -10% auto -10%; height: 220px;
  background: radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--gold) 40%, transparent), transparent 68%);
  pointer-events: none; }
.astro-hero-in { position: relative; padding: 26px 20px 22px; text-align: center; }
.astro-sym { font-size: 30px; color: var(--gold); line-height: 1; margin-bottom: 8px;
  animation: astroPulse 3.4s ease-in-out infinite; }
@keyframes astroPulse { 0%,100% { opacity: .75; transform: scale(1); } 50% { opacity: 1; transform: scale(1.09); } }
.astro-hero-in h2 { font-family: var(--font-head), serif; font-size: 20px; margin: 0 0 6px; }
.astro-hero-in .hint { margin: 0 auto; max-width: 300px; font-size: 12.5px; line-height: 1.5; }
.astro-birth { margin-bottom: 10px; padding: 14px 15px; }
.astro-birth-head { font-family: var(--font-head), serif; font-size: 16px; font-weight: 700; margin-bottom: 10px; }
.astro-fields { display: flex; gap: 9px; margin-bottom: 9px; }
.astro-fields label { flex: 1; min-width: 0; display: block; font-size: 10.5px; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.astro-fields .input { margin-top: 4px; width: 100%; padding: 9px 11px; }
/* Полное имя при рождении — своей строкой во всю ширину: ФИО длиннее места и рядом с
   часовым поясом не помещается. */
.astro-fullname { display: block; margin-bottom: 9px; font-size: 10.5px; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.astro-fullname .input { margin-top: 4px; width: 100%; padding: 9px 11px; }
.astro-fullname .hint { display: block; margin-top: 4px; font-size: 11px; font-weight: 500;
  letter-spacing: 0; text-transform: none; line-height: 1.4; }
.astro-reading-off { padding: 14px 15px; margin-bottom: 12px; }

/* загрузка — вращающаяся орбита */
.astro-loading { text-align: center; padding: 48px 20px; }
.astro-orb { width: 54px; height: 54px; margin: 0 auto 14px; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--gold); border-right-color: var(--him);
  animation: astroSpin 1.05s linear infinite; }
@keyframes astroSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .astro-orb, .astro-sym, .syn-bar > i { animation: none; }
}

/* ---------- невидимый наблюдатель ---------- */
/* Полоса-напоминание: вкладка показывает приложение ЧУЖИМИ глазами и ничего не записывает.
   Без неё легко забыть, в чьей сессии находишься, и пытаться что-то ответить «за партнёра». */
.observer-bar {
  flex: none;
  display: flex; align-items: center; gap: 8px;
  padding: calc(env(safe-area-inset-top, 0px) + 6px) 14px 6px;
  font-size: 12.5px; line-height: 1.25;
  color: #fff;
  background: linear-gradient(90deg, #4A3F8F, #7A4E96);
  box-shadow: 0 1px 0 rgba(0, 0, 0, .18);
}
.observer-bar .ob-eye { font-size: 14px; }
.observer-bar .ob-txt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.observer-bar .ob-txt b { font-weight: 700; }
.observer-bar .ob-exit {
  flex: none; padding: 3px 10px; border-radius: 999px;
  font-size: 12px; color: #fff;
  background: rgba(255, 255, 255, .18);
  border: 1px solid rgba(255, 255, 255, .3);
}
.observer-bar .ob-exit:active { background: rgba(255, 255, 255, .3); }
/* отступ под чёлку/Dynamic Island уже взяла полоса — шапка его не дублирует */
html.is-observer .header { height: var(--header-h); padding-top: 0; }

/* пометка на чужой закрытой записке, открытой в админ-режиме: чтобы ни на секунду не
   спутать её с обычной записью, которой с тобой поделились */
.admin-peek {
  font-size: 11px; font-weight: 800; color: var(--danger);
  border: 1px dashed var(--danger); border-radius: 8px;
  padding: 3px 8px; margin-bottom: 6px; align-self: flex-start;
}

/* ключик входа в админ-режим: только у Дениса, в шапке «Сегодня» и «Ещё».
   В обычном состоянии приглушён, чтобы не тянуть на себя внимание; в админ-режиме — заметен. */
.admin-key { opacity: .45; font-size: 15px; }
.admin-key.on { opacity: 1; background: color-mix(in srgb, var(--danger) 16%, transparent); }

/* Плавающая кнопка входа в админ-режим. Место выбирается случайно при запуске приложения,
   поэтому она не примелькается в одном углу. Полупрозрачная, поверх всего, но ниже шторок.
   У Мии этот элемент вообще не создаётся — см. adminlock.js. */
.admin-float {
  position: fixed; z-index: 30;
  width: 30px; height: 30px; padding: 0;
  border: none; border-radius: 50%;
  background: color-mix(in srgb, var(--surface-2) 70%, transparent);
  font-size: 14px; line-height: 1; opacity: .28;
  transition: opacity .15s, transform .15s;
}
.admin-float:active { opacity: 1; transform: scale(1.15); }
.admin-float.on {
  opacity: 1; background: color-mix(in srgb, var(--danger) 22%, transparent);
}

/* скачивание, публичная ссылка и комментарии гостей под роликом */
.film-share { margin: 6px 0 4px; }
.film-share-row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.film-share-row .btn { text-decoration: none; }
.film-share-link { font-size: 11.5px; margin-top: 6px; overflow-wrap: anywhere; }
.film-guests { margin-top: 10px; }
.film-guest {
  border-left: 2px solid var(--border); padding: 4px 0 4px 9px;
  margin-bottom: 6px; font-size: 13px;
}
.film-guest b { font-size: 13px; }

/* галочка «оригинальная озвучка»: перевод глушится, звучит исходная дорожка ролика */
.film-origsnd {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 8px 0 2px; font-size: 13px; cursor: pointer;
}
.film-origsnd input { width: 17px; height: 17px; accent-color: var(--him); }

/* строка транскрипта, помеченная «не переводим»: кусок звучит в оригинале */
.film-tline.skip { opacity: .62; }
.film-tline.skip .film-tx-1 { text-decoration: line-through; text-decoration-thickness: 1px; }
.film-tskip { background: none; border: 0; color: var(--muted); font-size: 13px;
              padding: 0 4px; cursor: pointer; align-self: flex-start; }

/* просмотр фото рутины: место и действия под снимком */
.photo-place { display: block; text-align: center; margin-top: 8px; font-size: 13px; }
.photo-acts { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 10px; }
.photo-acts .danger { color: var(--bad, #e5534b); }

/* блок «свой текст для озвучки» на странице ролика */
.film-script { margin-top: 12px; }
.film-script summary { cursor: pointer; font-weight: 600; font-size: 14px; padding: 4px 0; }
.film-script textarea { min-height: 110px; resize: vertical; line-height: 1.5; }

/* архив роликов: карточка с заставкой вместо голой строки */
.film-arc-row { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0;
                border-top: 1px solid var(--border); }
.film-arc-thumb { flex: none; width: 54px; height: 72px; border-radius: 8px;
                  background-size: cover; background-position: center; background-color: #0002;
                  display: grid; place-items: center; font-size: 18px; }
.film-arc-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.film-arc-ttl { font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.film-arc-acts { flex: none; display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }

/* строка «партнёр уведомлён» под списком просмотров */
.film-notif { font-size: 12px; margin-top: 6px; opacity: .8; }

.bd-page { --bd-accent: var(--him); }
.bd-page.for-her { --bd-accent: var(--her); }

/* ---- «Разбор по дате» -------------------------------------------------------
   Верстка под телефон в одну колонку: вкладки и чипы-переходы липнут к верху,
   разделы свёрнуты, цели под палец не меньше 44 px. */
.bd-tabs { display: flex; gap: 6px; position: sticky; top: 0; z-index: 5;
  background: var(--bg); padding: 6px 0 8px; }
.bd-tabs button { flex: 1; padding: 11px 8px; border: 1px solid var(--border); background: transparent;
  color: var(--muted); border-radius: 12px; font: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer; }
.bd-tabs button.active { background: var(--surface); color: var(--text); border-color: var(--bd-accent); }
.bd-who { font-size: 12px; color: var(--muted); text-align: center; margin: 2px 0 10px; }
/* «Чей разбор» — над вкладками. Цвет активной кнопки берётся от человека (--uc), как везде
   в приложении: цвет здесь всегда означает конкретного человека, а не состояние. */
.bd-whoswitch { display: flex; gap: 6px; margin: 0 0 10px; }
.bd-whoswitch button {
  flex: 1; min-width: 0; min-height: 44px; padding: 9px 10px;
  border: 1px solid var(--border); border-radius: 12px; background: transparent;
  color: var(--muted); font-size: 13.5px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bd-whoswitch button.active {
  color: var(--text); border-color: var(--uc); background: var(--surface);
  box-shadow: inset 0 -2px 0 var(--uc);
}
/* Третья кнопка — связь двоих. Цвета человека у неё нет намеренно: она не про одного из
   них, поэтому подсвечивается общим цветом пары. */
.bd-whoswitch button.pair { --uc: var(--text); }
.bd-whoswitch button.pair.active { background: var(--surface); }
/* Канал связи: пара «ворота — название» и владелец, если канал целиком у одного. */
.pair-link { padding: 8px 0; border-bottom: 1px solid var(--border); }
.pair-link:last-child { border-bottom: none; }
.pair-link-top { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; font-size: 13.5px; }
.pair-link-top b { font-weight: 800; }
.pair-owner { margin-left: auto; font-style: normal; font-size: 11.5px; font-weight: 700;
  color: var(--muted); white-space: nowrap; }
.bd-hero { background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  padding: 16px 14px; text-align: center; margin-bottom: 10px; }
.bd-hero-main { font-size: 26px; font-weight: 800; line-height: 1.15; }
.bd-hero-sub { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.bd-hero-grid { display: flex; gap: 8px; margin-top: 12px; }
.bd-hero-grid > div { flex: 1; background: var(--bg); border-radius: 10px; padding: 8px 6px; }
.bd-hero-grid span { display: block; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted); }
.bd-hero-grid b { display: block; font-size: 12.5px; margin-top: 3px; }
/* Чипы-переходы: один ряд с прокруткой вбок, как и вкладки над ними. Семь чипов просят
   384 px при 343 — седьмой уезжал на вторую строку и вставал под первым. */
.bd-jump { position: sticky; top: 52px; z-index: 4; background: var(--bg); padding: 4px 0 8px;
  flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.bd-jump::-webkit-scrollbar { display: none; }
.bd-jump > * { flex: none; }
.bd-jump .chip { min-width: 44px; text-align: center; font-size: 16px; }
.bd-sec { background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  margin-bottom: 8px; overflow: hidden; }
.bd-sec > summary { list-style: none; cursor: pointer; display: flex; align-items: center;
  gap: 10px; padding: 13px 14px; font-size: 14.5px; }
.bd-sec > summary::-webkit-details-marker { display: none; }
.bd-ic { font-size: 17px; }
.bd-sec > summary b { flex: 1; }
.bd-chev { color: var(--muted); transition: transform .15s; }
.bd-sec[open] .bd-chev { transform: rotate(180deg); }
.bd-body { padding: 0 14px 12px; }
.bd-row { padding: 9px 0; border-top: 1px solid var(--border); }
.bd-row:first-child { border-top: 0; }
.bd-row.has-why { cursor: pointer; }
.bd-row-top { display: flex; align-items: baseline; gap: 10px; }
.bd-label { flex: 1; font-size: 13.5px; color: var(--muted); }
.bd-value { font-size: 14.5px; font-weight: 700; text-align: right; }
.bd-row.has-why .bd-value::after { content: ' ⓘ'; font-size: 11px; opacity: .5; font-weight: 400; }
.bd-note { font-size: 11.5px; color: var(--muted); margin-top: 5px; line-height: 1.45; }
.bd-why { font-size: 12px; margin-top: 7px; padding: 8px 10px; background: var(--bg);
  border-radius: 9px; line-height: 1.5; }
.bd-warn { font-size: 11.5px; margin-top: 8px; padding: 8px 10px; border-radius: 9px;
  background: rgba(240,160,60,.12); line-height: 1.45; }
.bd-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.bd-chip { border: 1px solid var(--border); border-radius: 999px; padding: 6px 12px; font-size: 13px; }
.bd-chip.sm { padding: 4px 9px; font-size: 12px; }
.bd-chip.warn { background: rgba(240,160,60,.14); border-color: transparent; font-weight: 700; }
.bd-centers { display: flex; flex-direction: column; gap: 5px; }
.bd-center { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 10px;
  background: var(--bg); font-size: 13.5px; }
.bd-center i { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.bd-center.on i { background: var(--bd-accent); }
.bd-center.off i { border: 1.5px solid var(--border); }
.bd-center span { flex: 1; }
.bd-center b { font-size: 11px; color: var(--muted); font-weight: 600; }
.bd-center.on b { color: var(--bd-accent); }
.bd-filter { margin-bottom: 8px; }
.bd-act-head, .bd-act { display: flex; align-items: center; gap: 8px; }
.bd-act-head { font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); padding-bottom: 5px; }
.bd-act-head span:first-child, .bd-act-name { flex: 1; }
.bd-act-head span:not(:first-child), .bd-act-v { width: 58px; text-align: right; }
.bd-act { padding: 7px 0; border-top: 1px solid var(--border); font-size: 13.5px; }
.bd-act-v { font-weight: 700; font-variant-numeric: tabular-nums; }
.bd-act-v.d { color: var(--muted); }
.bd-name-card { background: var(--bg); border-radius: 12px; padding: 10px 12px; margin-bottom: 8px; }
.bd-name-head { font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--muted); }
.bd-letters { font-size: 12.5px; margin: 6px 0 2px; font-variant-numeric: tabular-nums; }
.bd-pinn { display: flex; flex-direction: column; gap: 5px; }
.bd-pinn-row { display: flex; align-items: center; gap: 10px; padding: 9px 11px;
  background: var(--bg); border-radius: 10px; }
.bd-pinn-row b { font-size: 18px; width: 26px; }
.bd-pinn-row span { flex: 1; font-size: 13px; }
.bd-pinn-row i { font-size: 11.5px; color: var(--muted); font-style: normal; }
.bd-name-head em { font-style: normal; font-weight: 600; font-size: 10px; margin-left: 6px;
  padding: 2px 7px; border-radius: 999px; background: var(--border); color: var(--muted); }
.bd-chan, .bd-gates { display: flex; flex-direction: column; gap: 5px; }
.bd-chan-row, .bd-gate { display: flex; align-items: baseline; gap: 10px; padding: 8px 11px;
  background: var(--bg); border-radius: 10px; }
.bd-chan-row b, .bd-gate b { font-variant-numeric: tabular-nums; min-width: 46px; font-size: 13.5px; }
.bd-gate b { min-width: 26px; }
.bd-chan-row span, .bd-gate span { flex: 1; font-size: 13px; color: var(--muted); }

/* Пальцевые цели в «Разборе» — не меньше 44 px по высоте (стандарт iOS).
   Прогон на 414×896 показал вкладки по 42 px и чипы по 36–40: мимо таких промахиваешься. */
.bd-page .bd-tabs button { min-height: 44px; }
.bd-page .chip { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.bd-page .bd-sec > summary { min-height: 48px; }

/* ---- бодиграф ---------------------------------------------------------------
   Схема рисуется SVG и тянется по ширине колонки. Определённое — сплошное и ярче,
   остальная система — бледным скелетом: видно и своё, и на фоне чего оно стоит. */
.bg-wrap { display: flex; justify-content: center; padding: 4px 0 2px; }
.bodygraph { width: 100%; max-width: 300px; height: auto; }
.bg-ch { stroke-linecap: round; }
.bg-ch.off { stroke: var(--border); stroke-width: 1.5; }
.bg-ch.half { stroke: var(--muted); stroke-width: 2; stroke-dasharray: 4 4; opacity: .55; }
.bg-ch.on { stroke: var(--bd-accent); stroke-width: 5; }
.bg-c { stroke: var(--border); stroke-width: 1.6; }
.bg-c.off { fill: var(--bg); }
.bg-c.on { fill: var(--bd-accent); stroke: var(--bd-accent); }
.bd-hero-sub2 { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
/* Толкование — визуально отдельно от расчёта: другая заливка и подпись.
   Это учение системы, а не измерение, и путать их на экране нельзя. */
.bd-say { background: color-mix(in srgb, var(--him) 7%, transparent);
  border-left: 2.5px solid color-mix(in srgb, var(--bd-accent) 45%, transparent);
  border-radius: 0 10px 10px 0; padding: 9px 12px; margin: 6px 0 10px;
  font-size: 12.5px; line-height: 1.55; }
.bd-say-h { font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); margin-bottom: 4px; font-weight: 700; }
.bd-gate em { display: block; width: 100%; font-style: normal; font-size: 11.5px;
  color: var(--muted); margin-top: 2px; }
.bd-gate { flex-wrap: wrap; }
.bd-cross-name { font-size: 15px; font-weight: 800; margin-bottom: 2px; }
/* Первоисточник — третья рамка, визуально отличная и от расчёта, и от толкования школы. */
.bd-src { background: color-mix(in srgb, var(--gold, #C8A24A) 8%, transparent);
  border-left: 2.5px solid color-mix(in srgb, var(--gold, #C8A24A) 55%, transparent);
  border-radius: 0 10px 10px 0; padding: 9px 12px; margin: 4px 0 10px;
  font-size: 12px; line-height: 1.6; }
.bd-src-h { font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); margin-bottom: 4px; font-weight: 700; }
.bd-act-say { font-size: 12px; line-height: 1.55; color: var(--text);
  background: color-mix(in srgb, var(--him) 6%, transparent); border-radius: 10px;
  padding: 8px 11px; margin: 2px 0 10px; }
.bd-act-say.d { background: color-mix(in srgb, var(--muted) 8%, transparent); }
.bd-act-say b { font-weight: 700; }
/* линия после точки в активации: своя строка, приглушённая — это уточнение, а не заголовок */
.bd-act-say em { display: block; margin-top: 5px; padding-top: 5px; font-style: normal;
  border-top: 1px solid var(--border); color: var(--muted); font-size: 11.5px; }
.bd-sources { background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 12px 14px; margin-top: 10px; }
.bd-sources-h { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 700; margin-bottom: 8px; }
.bd-sources a { display: block; font-size: 12.5px; padding: 7px 0; min-height: 44px;
  display: flex; align-items: center; border-top: 1px solid var(--border); }
.bd-sources a:first-of-type { border-top: 0; }
.bd-sign { font-size: 11.5px; color: var(--muted); line-height: 1.5; margin-top: 8px;
  padding-top: 9px; border-top: 1px solid var(--border); }
.bd-natal { display: flex; flex-direction: column; gap: 4px; }
.bd-natal-row { display: flex; align-items: baseline; gap: 10px; padding: 8px 11px;
  background: var(--bg); border-radius: 10px; font-size: 13.5px; }
.bd-natal-row span { flex: 1; color: var(--muted); }
.bd-natal-row b { font-weight: 700; }
.bd-natal-row i { font-style: normal; font-size: 12px; color: var(--muted);
  font-variant-numeric: tabular-nums; min-width: 42px; text-align: right; }
.bd-combo-title { font-size: 17px; font-weight: 800; line-height: 1.25; }
.bd-combo-rare { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin: 6px 0 12px; }
.bd-combo-b { margin-top: 14px; }
.bd-combo-b h4 { font-size: 13.5px; font-weight: 800; margin: 0 0 6px; }
.bd-combo-b p { font-size: 13.5px; line-height: 1.62; margin: 0 0 9px; }
.bd-phase { display: flex; flex-direction: column; gap: 4px; margin: 10px 0 4px; }
.bd-phase-h { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 700; margin-bottom: 3px; }
.bd-phase-row { display: flex; align-items: center; gap: 10px; padding: 9px 11px;
  background: var(--bg); border-radius: 10px; font-size: 13px; opacity: .55; }
.bd-phase-row.on { opacity: 1; background: color-mix(in srgb, var(--bd-accent) 12%, transparent);
  font-weight: 700; }
.bd-phase-row b { width: 18px; }
.bd-phase-row span { flex: 1; }
.bd-phase-row i { font-style: normal; font-size: 11.5px; color: var(--muted); }

/* ---- «Разбор по дате»: три новые системы ------------------------------------
   Пять вкладок в ряд на телефон не помещаются: flex:1 сжимал бы подписи до
   нечитаемых огрызков. Поэтому ряд едет вбок, а кнопки держат свою ширину.
   Полоса прокрутки убрана — на телефоне её всё равно нет, а на десктопе она
   уродует липкую шапку. */
.bd-tabs.five { overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; }
.bd-tabs.five::-webkit-scrollbar { display: none; }
.bd-tabs.five button { flex: 0 0 auto; padding: 11px 13px; font-size: 13px; white-space: nowrap; }

/* Пометка о надёжности слоя. Стоит НАД разделом, а не мелким шрифтом внизу:
   читатель должен знать, чему он сейчас верит, ДО того как прочтёт, а не после. */
.bd-trust { font-size: 11.5px; line-height: 1.5; padding: 10px 12px; border-radius: 12px;
  margin-bottom: 10px; border: 1px solid var(--border); }
.bd-trust b { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  margin-bottom: 4px; }
.bd-trust.solid { background: color-mix(in srgb, var(--bd-accent) 7%, transparent); }
.bd-trust.solid b { color: var(--bd-accent); }
.bd-trust.modern { background: rgba(240,160,60,.1); border-color: rgba(240,160,60,.35); }
.bd-trust.modern b { color: rgb(200,130,40); }

/* Карточка аркана: номер, позиция, имя — и четыре абзаца разбора. */
.bd-arc { background: var(--bg); border-radius: 12px; padding: 11px 12px; margin-top: 8px; }
.bd-arc-h { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.bd-arc-h b { font-size: 20px; font-weight: 800; color: var(--bd-accent); min-width: 24px; }
.bd-arc-h span { font-size: 12.5px; font-weight: 700; flex: 1; min-width: 120px; }
.bd-arc-h i { font-style: normal; font-size: 12px; color: var(--muted); }
.bd-arc-b { margin-top: 7px; }
.bd-arc-b p { font-size: 13px; line-height: 1.55; margin: 6px 0 0; }
.bd-arc-b em { font-style: normal; font-weight: 700; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted); margin-right: 5px; }
.bd-arc-b p.task { border-top: 1px solid var(--border); padding-top: 7px; margin-top: 8px; }

/* Возрастная линия: 16 отрезков по пять лет. Крупные точки — углы матрицы. */
.bd-ages { display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); gap: 5px; }
.bd-age { background: var(--bg); border-radius: 10px; padding: 7px 6px; text-align: center;
  border: 1px solid transparent; }
.bd-age.main { background: color-mix(in srgb, var(--bd-accent) 8%, var(--bg)); }
.bd-age.now { border-color: var(--bd-accent); }
.bd-age i { display: block; font-style: normal; font-size: 10px; color: var(--muted); }
.bd-age b { display: block; font-size: 17px; font-weight: 800; line-height: 1.3; }
.bd-age span { display: block; font-size: 10px; color: var(--muted); line-height: 1.25; }
.bd-age u { display: block; text-decoration: none; font-size: 9.5px; font-weight: 700;
  color: var(--bd-accent); margin-top: 2px; }
.bd-age-now { margin-top: 12px; }
.bd-age-now-h, .bd-dasha-now-h, .bd-dasha-line-h, .bd-line-h { font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin: 12px 0 6px; }
.bd-line-card { background: var(--bg); border-radius: 12px; padding: 4px 12px 10px; margin-top: 8px; }
.bd-line-card .bd-line-h { margin-top: 8px; }

/* Граха: планета, знак, достоинство. Рамка слева окрашена по достоинству —
   экзальтация и падение видны, не читая подписи. */
.bd-graha { background: var(--bg); border-radius: 12px; padding: 10px 12px; margin-top: 8px;
  border-left: 3px solid transparent; }
.bd-graha.exalted { border-left-color: rgb(70,170,110); }
.bd-graha.own { border-left-color: var(--bd-accent); }
.bd-graha.debilitated { border-left-color: rgb(210,130,60); }
/* Строка планеты — один ряд. Раньше имя требовало 130 px минимума, и пометка достоинства
   («экзальтация», «падение») уезжала на вторую строку у трёх планет из девяти. Теперь имя
   сжимается с многоточием, а градус показан целым числом: сотые доли на телефоне не читают,
   а место занимают. */
.bd-graha-h { display: flex; align-items: baseline; gap: 8px; flex-wrap: nowrap; }
.bd-graha-h b { font-size: 14px; flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bd-graha-h span { flex: none; }
.bd-graha-h u { flex: none; }
.bd-graha-h span { font-size: 13px; font-weight: 700; }
.bd-graha-h u { text-decoration: none; font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; padding: 2px 7px; border-radius: 999px; background: var(--surface); }
.bd-graha-h u.exalted { color: rgb(70,170,110); }
.bd-graha-h u.debilitated { color: rgb(200,120,50); }
.bd-graha-sub { font-size: 11.5px; color: var(--muted); margin-top: 4px; line-height: 1.45; }

/* Даши: текущий период крупно, вся линейка — списком. */
.bd-dasha-cur { background: var(--bg); border-radius: 12px; padding: 10px 12px; margin-top: 7px;
  border-left: 3px solid var(--bd-accent); }
.bd-dasha-cur.antar { border-left-color: color-mix(in srgb, var(--bd-accent) 55%, transparent); margin-left: 10px; }
.bd-dasha-cur.pratyantar { border-left-color: color-mix(in srgb, var(--bd-accent) 30%, transparent); margin-left: 20px; }
.bd-dasha-h { display: flex; align-items: baseline; gap: 10px; }
.bd-dasha-h b { font-size: 15px; flex: 1; }
.bd-dasha-h i { font-style: normal; font-size: 11.5px; color: var(--muted); }
.bd-dasha-line { display: flex; flex-direction: column; gap: 4px; }
.bd-dasha-row { display: flex; align-items: baseline; gap: 9px; padding: 8px 11px; border-radius: 10px;
  background: var(--bg); font-size: 13px; opacity: .62; }
.bd-dasha-row.on { opacity: 1; font-weight: 700;
  background: color-mix(in srgb, var(--bd-accent) 12%, transparent); }
.bd-dasha-row b { min-width: 78px; }
.bd-dasha-row span { flex: 1; font-size: 11.5px; color: var(--muted); }
.bd-dasha-row i { font-style: normal; font-size: 11px; color: var(--muted); }

/* Долгий счёт: пять разрядов в ряд, как разряды числа — потому что это они и есть. */
.bd-longcount { display: flex; gap: 5px; margin-top: 9px; }
.bd-longcount .bd-lc { flex: 1; background: var(--bg); border-radius: 10px; padding: 8px 4px;
  text-align: center; min-width: 0; }
.bd-lc b { display: block; font-size: 18px; font-weight: 800; }
.bd-lc span { display: block; font-size: 10px; margin-top: 1px; }
.bd-lc i { display: block; font-style: normal; font-size: 9.5px; color: var(--muted); }

/* ---- тихий режим партнёра ----------------------------------------------------
   Когда выключен — обычная строка настройки, не мозолит глаз. Когда ВКЛЮЧЁН —
   карточка краснеет целиком. Это состояние, о котором нельзя забыть: человек
   в это время не получает вообще ничего, и напоминать об этом должен интерфейс,
   а не память. Полоса слева видна и в свёрнутом списке, при беглом взгляде. */
.mute-box { margin: 4px 0 10px; padding: 8px 10px; border-radius: 12px;
  border: 1px solid transparent; transition: background .18s, border-color .18s; }
.mute-box.on { background: color-mix(in srgb, var(--danger) 12%, transparent);
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  border-left-width: 3px; border-left-color: var(--danger); }
.mute-box .lbl { font-weight: 700; }
.mute-box.on .lbl { color: var(--danger); }
.mute-box .lbl small { display: block; font-weight: 400; font-size: 11.5px;
  line-height: 1.45; color: var(--muted); margin-top: 2px; }
.mute-box.on .lbl small { color: color-mix(in srgb, var(--danger) 78%, var(--text)); }
.mute-box.on .switch input:checked + i { background: var(--danger); }


/* ================================================================================
   BRIDGE 2.0 — ДИЗАЙН-СКИН (docs/DESIGN-PLAYBOOK.md)
   Отдельный слой в конце файла: переопределяет токены и добивает пять разрывов
   playbook (⚑): шрифт Golos, reduced-motion, tabular-nums, motion-система,
   направленный вход экрана. Компоненты выше по файлу не правились.
   ================================================================================ */
:root {
  --bg: #FAF6EF; --surface: #FFFDFA; --surface-2: #F1EBDF;
  --text: #2A2733; --muted: #837F8C; --border: #EBE4D6;
  --him-soft: color-mix(in oklab, var(--him) 12%, transparent);
  --her-soft: color-mix(in oklab, var(--her) 12%, transparent);
  --shadow: 0 1px 2px rgba(74,56,30,.05), 0 6px 22px rgba(74,56,30,.08);
  --shadow-lift: 0 2px 6px rgba(74,56,30,.07), 0 14px 44px rgba(74,56,30,.16);
  --t-fast: 120ms; --t-base: 200ms; --t-sheet: 340ms;
  --ease-out: cubic-bezier(0.165, 0.84, 0.44, 1);
  --ease-spring: cubic-bezier(0.3, 1.25, 0.4, 1);
}
html.dark {
  --him: #8E9AF5; --her: #F58BA6;
  --bg: #161320; --surface: #1E1B2A; --surface-2: #282436;
  --text: #EDEDF4; --muted: #9C9AAE; --border: #2F2B40;
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 6px 24px rgba(0,0,0,.35);
  --shadow-lift: 0 2px 6px rgba(0,0,0,.4), 0 12px 40px rgba(0,0,0,.5);
}
/* ⚑ Golos Text (кириллица-first) — главный шаг «сайт → продукт» */
body { font-family: 'Golos Text', -apple-system, system-ui, 'Segoe UI', sans-serif; }
/* ⚑ цифры не прыгают: счётчики, время, статистика */
time, .ticks, .bd-value, .hab-pct, .hab-streak, .chip-badge, .bell-badge, .tab-badge,
.sb-sum, .ss-sum, .voice-len, .streak-num { font-variant-numeric: tabular-nums; }
/* ⚑ направленный вход экрана: содержимое въезжает снизу с fade (200ms quart-out) */
.main > .page, .main > .chat-wrap { animation: pageIn var(--t-base) var(--ease-out); }
@keyframes pageIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
/* шторки: вход spring, ручка сверху; выход быстрее входа делает close() мгновенно — ок */
.sheet { animation: sheetIn var(--t-sheet) var(--ease-spring); }
@keyframes sheetIn { from { transform: translateY(28px); opacity: .4; } to { transform: none; opacity: 1; } }
/* фокус видимый, но свой (запрет №10) */
:focus-visible { outline: 2px solid var(--him); outline-offset: 2px; border-radius: 4px; }
* { -webkit-tap-highlight-color: transparent; }
textarea { resize: none; }
/* ⚑ уважение к reduced-motion — обязателен */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- 2.0: «Вопрос дня» на главном ---------- */
.daily-card { position: relative; overflow: hidden; border-radius: 20px; padding: 18px 16px;
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow); }
.daily-card::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--us); }
.daily-kicker { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 800;
  letter-spacing: .07em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.daily-streak { margin-left: auto; display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--gold, #C99A3F); letter-spacing: 0; text-transform: none; }
.daily-q { font-family: Lora, Georgia, serif; font-size: 19px; line-height: 1.35; letter-spacing: -0.01em; }
.daily-input { display: flex; gap: 8px; margin-top: 12px; }
.daily-input textarea { flex: 1; min-width: 0; min-height: 44px; background: var(--surface-2);
  border: 1.5px solid transparent; border-radius: 14px; padding: 11px 14px; font-size: 16px; outline: none; }
.daily-input textarea:focus { border-color: var(--him); }
.daily-wait { margin-top: 12px; font-size: 13px; color: var(--muted); }
.daily-answers { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.daily-ans { padding: 10px 12px; border-radius: 14px; font-size: 14.5px; line-height: 1.45; }
.daily-ans.me { background: var(--him-soft); }
.daily-ans.them { background: var(--her-soft); }
.daily-ans b { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); margin-bottom: 2px; }

/* ---------- 2.0: «Совпадения» ---------- */
.match-decks { display: flex; flex-direction: column; gap: 12px; }
.deck-card { display: flex; align-items: center; gap: 14px; text-align: left; width: 100%;
  padding: 16px; border-radius: 20px; background: var(--surface); border: 1px solid var(--border);
  box-shadow: var(--shadow); transition: transform var(--t-fast) ease; }
.deck-card:active { transform: scale(.97); }
.deck-card.locked { opacity: .55; }
.deck-ico { font-size: 28px; flex: none; }
.deck-name { font-weight: 800; font-size: 16px; }
.deck-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.deck-meta { margin-left: auto; text-align: right; flex: none; }
.deck-matches { font-size: 15px; font-weight: 800; color: var(--her); font-variant-numeric: tabular-nums; }
.deck-progress { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* стек карточек */
.match-stage { position: relative; height: 340px; margin: 12px 0; }
.match-card { position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center; padding: 28px 22px;
  border-radius: 24px; background: var(--surface); border: 1px solid var(--border);
  box-shadow: var(--shadow-lift); will-change: transform;
  transition: transform var(--t-base) var(--ease-out), opacity var(--t-base) ease; }
.match-card.under { transform: scale(.94) translateY(12px); opacity: .6; pointer-events: none; }
.match-card .mc-text { font-family: Lora, Georgia, serif; font-size: 21px; line-height: 1.35; letter-spacing: -0.01em; }
.match-card .mc-tr { margin-top: 10px; font-size: 14px; color: var(--muted); }
.match-card.fly-right { transform: translateX(120%) rotate(10deg); opacity: 0; }
.match-card.fly-left { transform: translateX(-120%) rotate(-10deg); opacity: 0; }
.match-btns { display: flex; justify-content: center; gap: 22px; }
.match-btn { width: 64px; height: 64px; border-radius: 50%; font-size: 26px;
  background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow);
  transition: transform var(--t-fast) ease; }
.match-btn:active { transform: scale(.9); }
.match-btn.yes { color: #fff; background: var(--us); border: none;
  box-shadow: 0 6px 18px color-mix(in oklab, #A664BF 35%, transparent); }
/* delight-момент совпадения — редкий, поэтому богатый (600ms spring) */
.match-pop { position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 10px; background: color-mix(in oklab, var(--bg) 55%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); z-index: 90;
  animation: fadeIn 200ms ease; }
.match-pop .mp-heart { font-size: 64px; animation: heartPop 700ms var(--ease-spring); }
.match-pop .mp-title { font-family: Caveat, cursive; font-size: 34px; background: var(--us);
  -webkit-background-clip: text; background-clip: text; color: transparent; }
.match-pop .mp-text { font-size: 16px; max-width: 300px; text-align: center; line-height: 1.4; }
@keyframes heartPop { 0% { transform: scale(.2); } 60% { transform: scale(1.15); } 100% { transform: none; } }
@keyframes fadeIn { from { opacity: 0; } }
.match-list { display: flex; flex-direction: column; gap: 8px; }
.match-item { display: flex; align-items: center; gap: 10px; padding: 12px 14px;
  border-radius: 14px; background: var(--surface); border: 1px solid var(--border); }
.match-item .mi-ico { flex: none; }
.match-empty { text-align: center; padding: 28px 16px; color: var(--muted); }
.match-empty .big { font-size: 44px; margin-bottom: 6px; }
.match-empty .cav { font-family: Caveat, cursive; font-size: 22px; color: var(--text); }

/* ==== 2.0: «Квиз недели» — знаешь ли ты партнёра ================================ */
.quiz-q { background: var(--surface); border: 1px solid var(--border); border-radius: 16px; padding: 14px 14px 12px; margin: 10px 0; box-shadow: var(--shadow); }
.quiz-qt { font-weight: 600; font-size: 16px; line-height: 1.35; margin-bottom: 6px; text-wrap: balance; }
.quiz-n { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; margin-right: 8px; }
.quiz-role { font-size: 11.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); margin: 10px 0 6px; font-weight: 600; }
.quiz-opts { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.quiz-opt { min-height: 44px; border: 1px solid var(--border); background: var(--surface-2, transparent); color: var(--text); border-radius: 12px; padding: 8px 10px; font: inherit; font-size: 14px; line-height: 1.25; text-align: left; transition: border-color var(--t-fast), background var(--t-fast), transform var(--t-fast); }
.quiz-opt:active { transform: scale(.98); }
.quiz-opt.sel { border-color: var(--her); background: var(--her-soft); font-weight: 600; }
.quiz-res { font-size: 14px; margin: 6px 0; color: var(--muted); line-height: 1.4; }
.quiz-res b { color: var(--text); }
.quiz-res .ok { color: #3f8f4f; font-weight: 700; } .quiz-res .no { color: #c84c3c; font-weight: 700; }
.quiz-score { text-align: center; padding: 14px 0 6px; }
.qs-big { font-size: 46px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1; background: var(--us); -webkit-background-clip: text; background-clip: text; color: transparent; display: inline-block; }
.qs-sub { font-size: 14px; color: var(--muted); margin-top: 8px; }
.quiz-hist-row { display: flex; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 14px; font-variant-numeric: tabular-nums; }
.quiz-hist-row:last-child { border-bottom: none; }
.quiz-card { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; background: var(--surface); border: 1px solid var(--border); border-radius: 16px; padding: 12px 14px; margin: 10px 0 0; font: inherit; color: var(--text); min-height: 56px; box-shadow: var(--shadow); cursor: pointer; }
.quiz-card .qc-ic { font-size: 22px; } .quiz-card .qc-tx { flex: 1; min-width: 0; }
.quiz-card b { display: block; font-size: 15px; } .quiz-card small { color: var(--muted); font-size: 13px; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.quiz-card .qc-arrow { color: var(--muted); font-size: 20px; }

/* ==== 2.0: «Живой разговор» — переводчик вживую ================================= */
.live-stage { min-height: 38vh; display: flex; flex-direction: column; justify-content: center; gap: 10px; padding: 8px 4px; }
.live-empty { text-align: center; color: var(--muted); font-size: 15px; line-height: 1.5; padding: 20px 10px; text-wrap: balance; }
.live-tr { font-size: clamp(24px, 6.5vw, 32px); font-weight: 700; line-height: 1.25; text-align: center; padding: 14px 8px; text-wrap: balance; transition: transform var(--t-base) var(--ease-out); }
.live-tr.flip { transform: rotate(180deg); }
.live-src { text-align: center; color: var(--muted); font-size: 15px; line-height: 1.4; }
.live-log { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 6px; }
.live-log-row { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 5px 0; color: var(--muted); }
.live-log-row b { color: var(--text); font-weight: 500; text-align: right; }
.live-controls { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-top: 14px; }
.live-btn { width: 96px; height: 96px; border-radius: 50%; border: none; font-size: 40px; color: #fff; background: var(--us); box-shadow: var(--shadow-lift); touch-action: none; -webkit-user-select: none; user-select: none; transition: transform var(--t-fast) var(--ease-spring), box-shadow var(--t-fast); }
.live-btn.rec { transform: scale(1.12); box-shadow: 0 0 0 12px var(--her-soft), var(--shadow-lift); }
.live-hint { font-size: 13px; color: var(--muted); min-height: 18px; }
.live-type { display: flex; gap: 8px; width: 100%; align-items: center; }
.live-type input { flex: 1; min-width: 0; min-height: 44px; border: 1px solid var(--border); border-radius: 14px; padding: 8px 12px; font: inherit; background: var(--surface); color: var(--text); }
.tools-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tools-row .quiz-card { margin: 10px 0 0; padding: 12px; }
