@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap');

/*
 * Оформление: тёплое ночное стекло — флагманский виток.
 *
 * Обновлено по итогам сессии с тремя вариантами дизайна — выбран «Ночной
 * режим» (тёмное стекло + золотое свечение, в духе премиальных
 * health-трекеров вроде Oura/Whoop), со светлым аналогом в том же духе для
 * дня. Исходная причина остаётся той же, что и раньше: этим пользуются в
 * три часа ночи с ребёнком на руках — никакого чистого белого/чёрного,
 * крупные зоны нажатия, спокойные приглушённые тени.
 *
 * Второй виток — «на сколько дороже можно выглядеть, не меняя архитектуру».
 * Три решения дают основной эффект:
 *   1. Пара шрифтов вместо одного. Fraunces (оптический size-axis, тёплая
 *      низкоконтрастная антиква) — на заголовках, датах, крупных цифрах и
 *      названиях карточек; Manrope остаётся текстовым/интерфейсным шрифтом.
 *      Один гротеск на всё — это как раз тот «безопасный», неотличимый от
 *      сотни других приложений выбор; пара с характером стоит дороже и
 *      выглядит дороже.
 *   2. Свой набор линейных иконок (см. ICONS в app.js) вместо эмодзи.
 *      Эмодзи — самый быстрый способ придать интерфейсу вид прототипа:
 *      они не выровнены по сетке, разного визуального веса и рендерятся
 *      по-разному на каждой платформе. Нарисованные вручную обводочные
 *      иконки — то, что отличает «сделали за вечер» от «наняли дизайнера».
 *   3. Более «инженерное» стекло: тонкий внутренний блик сверху карточки
 *      (как настоящее стекло на просвет), а не только внешняя тень.
 *
 * Архитектура не поменялась: те же CSS-переменные, что и раньше, просто с
 * новыми значениями — поэтому все существующие «тёмные» и цветные темы в
 * профиле (мята/сумерки/персик/лес) автоматически наследуют новый шрифт,
 * радиусы и стекло, meняя только акцентный оттенок.
 *
 * Третий виток — «оживить» то, что уже стоит на месте: статика читается
 * дёшево сама по себе, даже с правильными шрифтами и стеклом. Добавлено
 * (логика — в app.js, здесь только раскладка/тайминги):
 *   1. Направленные переходы между экранами: открыли карточку глубже —
 *      экран наезжает справа (push), вернулись к вкладкам — уезжает
 *      обратно слева (pop), переключили соседнюю вкладку — мягко
 *      проявляется (fade). См. .screen-anim--push/--pop и go()/render().
 *   2. Живая «таблетка» под активной вкладкой нижнего меню — едет за
 *      пальцем пружинным cubic-bezier, а не перепрыгивает. См.
 *      .nav-indicator и positionNavIndicator() в app.js.
 *   3. Кольца прогресса дорисовываются при каждом заходе на экран (было:
 *      конечное значение выставлялось сразу, transition не успевал
 *      сыграть). Крупные цифры (.big) считают вверх от нуля тем же
 *      приёмом — см. animateBigNumbers() в app.js, работает для любого
 *      .big в приложении без правок в местах использования.
 * Всё уважает prefers-reduced-motion — как через глобальное отключение
 * анимаций/transition’ов ниже, так и явной проверкой в JS-таймерах.
 */

:root {
  /* Поверхности и текст */
  --paper: #f7f4ee;
  --paper-card: rgba(255, 255, 255, .72);
  --paper-sunk: #efe9dd;
  --ink: #211c17;
  --ink-soft: #675c50;
  --ink-faint: #9a8f81;
  --line: rgba(33, 28, 23, .09);
  --line-strong: rgba(33, 28, 23, .17);

  /* Акценты: тёплое золото — основной, шалфей/охра/эмбер — состояния */
  --clay: #b9752a;
  --clay-deep: #8f5a1e;
  --clay-wash: #f5e7d1;
  --sage: #5c8f6e;
  --sage-wash: #e6efe9;
  --ochre: #b8862e;
  --ochre-wash: #f6ecd4;
  --rose: #c05a3e;
  --rose-wash: #f7e1d9;

  --radius: 20px;
  --radius-sm: 14px;
  --blur: 20px;
  --shadow: 0 1px 2px rgba(33, 28, 23, .05), 0 10px 28px rgba(33, 28, 23, .06);
  --shadow-lift: 0 4px 10px rgba(33, 28, 23, .08), 0 20px 44px rgba(33, 28, 23, .10);
  /* Тонкий блик по верхней кромке стеклянной карточки/кнопки — то, что
     отличает по-настоящему «стеклянную» поверхность (свет ловится сверху)
     от плоского полупрозрачного прямоугольника. */
  --card-rim: rgba(255, 255, 255, .6);
  --btn-rim: rgba(255, 255, 255, .35);

  /* Имя переменной осталось от прежней версии (там правда была антиква) —
     не переименовываю, чтобы не трогать полсотни мест, где она уже
     используется для заголовков/дат/крупных цифр. */
  --serif: "Fraunces", "Iowan Old Style", Georgia, serif;
  --sans: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* Ночь — не чёрная, а тёплая почти-чёрная, со стеклянными карточками и
   золотым свечением: это и есть флагманский вид, ради которого затевалось
   обновление (приложение открывают в темноте чаще, чем при свете). */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #15110e;
    --paper-card: rgba(255, 255, 255, .045);
    --paper-sunk: #1f1a15;
    --ink: #f3ece3;
    --ink-soft: #b6a99c;
    --ink-faint: #83766a;
    --line: rgba(255, 255, 255, .09);
    --line-strong: rgba(255, 255, 255, .17);

    --clay: #e8ab5f;
    --clay-deep: #f2c58c;
    --clay-wash: rgba(232, 171, 95, .16);
    --sage: #8fbb9a;
    --sage-wash: rgba(143, 187, 154, .14);
    --ochre: #d9ac5c;
    --ochre-wash: rgba(217, 172, 92, .14);
    --rose: #e2765a;
    --rose-wash: rgba(226, 118, 90, .16);

    --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 10px 26px rgba(0, 0, 0, .3);
    --shadow-lift: 0 6px 16px rgba(0, 0, 0, .45), 0 24px 50px rgba(0, 0, 0, .4);
    --card-rim: rgba(255, 255, 255, .08);
    --btn-rim: rgba(255, 255, 255, .3);
  }
}

/* ---------- темы, которые открываются за очки в играх ----------

   ВАЖНО про порядок правил. Селектор [data-theme] стоит НИЖЕ ночного
   :root и имеет ту же силу, поэтому он побеждает. Если задать здесь
   только светлую бумагу, ночью получится светлый фон и оставшийся от
   тёмной темы светлый текст — то есть невидимый текст. Именно так и
   произошло с мятной темой.
   Поэтому у каждой темы ОБЯЗАТЕЛЬНО два набора: дневной и ночной.
   Контраст пар «бумага/чернила» проверяется тестом.

   Цветные темы намеренно остаются с непрозрачной (не стеклянной)
   карточкой — это более простой, «спокойный» вариант оформления рядом с
   флагманским стеклянным видом по умолчанию, а не недосмотр. */
[data-theme="mint"] {
  --paper: #f2f8f4; --paper-card: #fbfefc; --paper-sunk: #e6f0ea;
  --line: #dfeae3; --line-strong: #cbdcd2;
  --clay: #4f8c6a; --clay-deep: #35664d; --clay-wash: #e2f0e8;
}
[data-theme="dusk"] {
  --paper: #f4f1f8; --paper-card: #fdfcff; --paper-sunk: #eae5f1;
  --line: #e4ddee; --line-strong: #d2c8e0;
  --clay: #6d5c9d; --clay-deep: #52447a; --clay-wash: #e9e3f4;
}
[data-theme="peach"] {
  --paper: #fdf4ef; --paper-card: #fffbf8; --paper-sunk: #f7e8de;
  --line: #f2e2d7; --line-strong: #e6cebd;
  --clay: #c96742; --clay-deep: #a04d2e; --clay-wash: #fae6dc;
}
[data-theme="forest"] {
  --paper: #f1f5f1; --paper-card: #fafcfa; --paper-sunk: #e4ece5;
  --line: #dde7de; --line-strong: #c8d8ca;
  --clay: #416b50; --clay-deep: #2c4c37; --clay-wash: #dfebe2;
}

/* Ночью бумага остаётся тёмной, меняется только оттенок. Иначе тема
   ломает читаемость, а не украшает. */
@media (prefers-color-scheme: dark) {
  [data-theme="mint"] {
    --paper: #101613; --paper-card: #18211c; --paper-sunk: #0c110e;
    --line: #253029; --line-strong: #33443a;
    --clay: #7fc0a0; --clay-deep: #9bd4b8; --clay-wash: #1b2a22;
  }
  [data-theme="dusk"] {
    --paper: #14121a; --paper-card: #1d1a26; --paper-sunk: #100e15;
    --line: #2a2537; --line-strong: #3b3450;
    --clay: #a294dc; --clay-deep: #bcafec; --clay-wash: #241f33;
  }
  [data-theme="peach"] {
    --paper: #191310; --paper-card: #231a15; --paper-sunk: #14100d;
    --line: #33261e; --line-strong: #45332a;
    --clay: #e6a184; --clay-deep: #f2bda6; --clay-wash: #33231b;
  }
  [data-theme="forest"] {
    --paper: #0f1410; --paper-card: #171f18; --paper-sunk: #0b0f0c;
    --line: #232e25; --line-strong: #314030;
    --clay: #7fb694; --clay-deep: #9bcfae; --clay-wash: #1a2620;
  }
}

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

/* Атрибут hidden обязан прятать элемент — всегда.
   Браузер задаёт [hidden] { display: none } в своей таблице стилей, но любое
   наше правило вроде .splash { display: flex } оказывается важнее и
   перебивает его. Из-за этого заставка не исчезала после загрузки и
   накрывала собой работающее приложение: экран был готов, но невидим.
   Правило ниже возвращает hidden обещанное поведение. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.6 var(--sans);
  overscroll-behavior-y: none;
  -webkit-font-smoothing: antialiased;
}

/* Мягкое сияние вместо ровной заливки — то самое «золотое свечение»,
   которое отличает флагманский тёмный вид. Днём тот же приём даёт едва
   заметную тёплую дымку, а не яркое пятно. Строится из градиентов, без
   картинок — лишний файл ради этого грузить не стоит, и оттенок сам
   следует за текущим акцентом темы (в том числе цветных тем профиля). */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: .5;
  background-image:
    radial-gradient(120% 60% at 20% -10%, color-mix(in srgb, var(--clay) 8%, transparent) 0, transparent 55%),
    radial-gradient(100% 55% at 100% 0%, color-mix(in srgb, var(--rose) 6%, transparent) 0, transparent 50%);
}
@media (prefers-color-scheme: dark) {
  body::before {
    opacity: .9;
    background-image:
      radial-gradient(120% 60% at 20% -10%, color-mix(in srgb, var(--clay) 16%, transparent) 0, transparent 60%),
      radial-gradient(100% 55% at 100% 0%, color-mix(in srgb, var(--rose) 13%, transparent) 0, transparent 55%);
  }
}

h1, h2, h3 { margin: 0; font-family: var(--serif); font-weight: 600; font-optical-sizing: auto; letter-spacing: -.01em; text-wrap: balance; }
h1 { font-size: 21px; }
h2 { font-size: 17px; }

/* Видимый фокус — для клавиатуры, переключателей доступности и ревью
   Apple/Google (требование accessibility, не только эстетика). Заметен
   только при навигации с клавиатуры/свитча, не при обычном тапе. */
:focus-visible {
  outline: 2px solid var(--clay);
  outline-offset: 2px;
  border-radius: 8px;
}

/* ---------- заставка ---------- */
.splash {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; background: var(--paper);
}
.splash-face { font-size: 60px; animation: breathe 2.4s ease-in-out infinite; }
.splash-text { color: var(--ink-faint); font-size: 12px; font-family: var(--sans); font-weight: 700; text-transform: uppercase; letter-spacing: .12em; }
@keyframes breathe { 0%,100% { transform: scale(1) } 50% { transform: scale(1.1) } }

/* ---------- шапка ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 6px;
  padding: calc(var(--safe-top) + 12px) 16px 12px;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(var(--blur)) saturate(1.3);
  -webkit-backdrop-filter: blur(var(--blur)) saturate(1.3);
  border-bottom: 1px solid var(--line);
}
.topbar h1 { flex: 1; }
.icon-btn {
  border: 0; background: transparent; color: var(--ink-soft);
  font-size: 21px; line-height: 1; padding: 6px 10px; border-radius: 12px;
  cursor: pointer; min-width: 42px; min-height: 42px;
}
.icon-btn:active { background: var(--clay-wash); color: var(--clay-deep); }

/* Обводочные иконки (см. ICONS/icon() в app.js) — общая база, размер и
   толщина линии задаются на самом <svg> при создании. */
.icon { display: block; flex-shrink: 0; }

/* ---------- контент ---------- */
.screen {
  padding: 16px 16px calc(var(--safe-bottom) + 92px);
  max-width: 640px; margin: 0 auto;
  animation: rise .24s cubic-bezier(.2, .8, .3, 1);
}
@keyframes rise { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: none } }

/* Экран — не просто «сменился», а либо открылся вглубь (пуш), либо
   вернулся наверх (поп), либо это соседняя вкладка (плавное появление).
   Направление задаёт go() в app.js через класс на корневом узле экрана —
   тот же приём, что и с карточками ниже: свежий узел всегда проигрывает
   свою анимацию при вставке, перезапускать её вручную не нужно. */
.screen-anim--push { animation: push-in .34s cubic-bezier(.22, .8, .3, 1); }
.screen-anim--pop { animation: pop-in .34s cubic-bezier(.22, .8, .3, 1); }
@keyframes push-in { from { opacity: 0; transform: translateX(26px) scale(.99) } to { opacity: 1; transform: none } }
@keyframes pop-in { from { opacity: 0; transform: translateX(-26px) scale(.99) } to { opacity: 1; transform: none } }

.card {
  background: var(--paper-card); border-radius: var(--radius);
  padding: 18px; margin-bottom: 14px;
  box-shadow: var(--shadow), inset 0 1px 0 var(--card-rim);
  border: 1px solid var(--line);
  backdrop-filter: blur(var(--blur)) saturate(1.15);
  -webkit-backdrop-filter: blur(var(--blur)) saturate(1.15);
}
.card.flat { box-shadow: none; background: transparent; border-style: dashed; backdrop-filter: none; -webkit-backdrop-filter: none; }
.card.warm { background: var(--clay-wash); border-color: transparent; box-shadow: none; }
.card h2 { margin-bottom: 12px; }

/* Кольцо прогресса — там, где это уместнее плоской полосы: карточка дня
   на «Сегодня». Рисуется как SVG-элемент (см. progressRing() в app.js),
   здесь только его оформление. */
.card.ring-card { display: flex; align-items: center; gap: 14px; }
.ring-wrap { position: relative; flex-shrink: 0; }
.ring-wrap svg { transform: rotate(-90deg); display: block; }
.ring-track { fill: none; stroke: var(--paper-sunk); stroke-width: 5; }
.ring-fill {
  fill: none; stroke: var(--clay); stroke-width: 5; stroke-linecap: round;
  transition: stroke-dashoffset .6s cubic-bezier(.2, .8, .3, 1);
}
.ring-fill.bad { stroke: var(--rose); }
@media (prefers-color-scheme: dark) {
  .ring-fill { filter: drop-shadow(0 0 6px color-mix(in srgb, var(--clay) 55%, transparent)); }
  .ring-fill.bad { filter: drop-shadow(0 0 6px color-mix(in srgb, var(--rose) 55%, transparent)); }
}

/* Карточки появляются по очереди, а не пачкой.
   Разница в 60 миллисекунд между соседями почти не осознаётся, но
   экран перестаёт «выпрыгивать» целиком и начинает собираться —
   а собирающийся экран читают сверху вниз, а не окидывают взглядом.
   Задержки заданы вручную для первых шести: nth-child с формулой
   ставила бы задержку и десятой карточке, а это уже ожидание. */
.screen > div > .card,
.screen > div > .game-card,
.screen > .card {
  animation: rise .32s cubic-bezier(.2, .8, .3, 1) backwards;
}
.screen > div > .card:nth-child(1) { animation-delay: 0ms }
.screen > div > .card:nth-child(2) { animation-delay: 60ms }
.screen > div > .card:nth-child(3) { animation-delay: 120ms }
.screen > div > .card:nth-child(4) { animation-delay: 180ms }
.screen > div > .card:nth-child(5) { animation-delay: 240ms }
.screen > div > .card:nth-child(n+6) { animation-delay: 300ms }

/* Нажатие должно ощущаться пальцем, а не только выглядеть.
   На телефоне нет наведения курсора, и без этого отклика интерфейс
   кажется неживым — «нажал и не понял, сработало ли». */
.card.flat[onclick], .card.ring-card[onclick], .game-card { transition: transform .12s cubic-bezier(.2,.8,.3,1), box-shadow .12s; }
.card.ring-card[onclick]:active, .game-card:active { transform: scale(.98); box-shadow: none; }

.muted { color: var(--ink-soft); font-size: 14px; }
.faint { color: var(--ink-faint); font-size: 13px; }
.serif { font-family: var(--serif); }

/* «Крупная цифра» — фирменный элемент экрана «Сегодня» и статистики:
   лёгкий градиент от чернил к акценту, тот самый штрих, который в
   макете-варианте отличал заголовок карточки дня. На коротких числах
   эффект едва заметен и не мешает, на длинных — читается как решение,
   а не случайность. */
.big {
  font-family: var(--serif); font-size: 34px; font-weight: 600;
  font-optical-sizing: auto; letter-spacing: -.015em; line-height: 1.12;
  font-variant-numeric: tabular-nums; /* цифры не «гуляют» по ширине, пока считают вверх */
  color: var(--ink);
  background: linear-gradient(135deg, var(--ink) 30%, var(--clay-deep) 80%, var(--ink) 130%);
  background-size: 220% 220%;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  /* Медленный, малозаметный блик по градиенту — читаемость не страдает
     (стопы близки по тону), но цифра не стоит совсем неподвижно, пока
     остальной экран уже живёт переходами и частицами. */
  animation: big-shimmer 8s ease-in-out infinite;
}
@keyframes big-shimmer {
  0%, 100% { background-position: 20% 50%; }
  50% { background-position: 80% 50%; }
}
.row { display: flex; align-items: center; gap: 12px; }
.row.between { justify-content: space-between; }
.row.top { align-items: flex-start; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* Тонкая линия-разделитель */
.rule { height: 1px; background: var(--line); margin: 14px 0; border: 0; }

/* ---------- кнопки ---------- */
button, .btn { font: inherit; border-radius: 14px; border: 0; cursor: pointer; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 18px; min-height: 52px; width: 100%;
  background: linear-gradient(135deg, var(--clay), var(--clay-deep));
  color: #fff; font-weight: 700;
  text-decoration: none;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--clay-deep) 35%, transparent), inset 0 1px 0 var(--btn-rim);
  transition: transform .1s cubic-bezier(.2, .8, .3, 1), filter .15s;
}
.btn:active { transform: scale(.975); filter: brightness(.95); }
.btn.ghost { background: var(--paper-card); color: var(--clay-deep); border: 1px solid var(--line-strong); box-shadow: none; backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur)); }
.btn.quiet { background: transparent; color: var(--ink-soft); box-shadow: none; font-weight: 500; }
.btn.small { padding: 9px 14px; min-height: 38px; font-size: 13px; width: auto; border-radius: 11px; }
.btn[disabled] { opacity: .45; pointer-events: none; }

/* На золотом фоне тёмный текст читается лучше белого — но только у
   фирменной темы по умолчанию: у цветных тем профиля акцент темнее и
   белый текст на нём по-прежнему контрастнее, менять не нужно. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="paper"] .btn:not(.ghost):not(.quiet) { color: #241a0d; }
}

/* ---------- нижняя навигация ---------- */
.nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  /* 4 вкладки, не 5 — раздел «Игры» убрали, а сетку под него не обновили.
     С repeat(5,...) четыре кнопки занимали только левые 4/5 строки и
     съезжали влево, оставляя пустой столбец справа. */
  display: grid; grid-template-columns: repeat(4, 1fr);
  padding: 8px 4px calc(var(--safe-bottom) + 8px);
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(var(--blur)) saturate(1.3);
  -webkit-backdrop-filter: blur(var(--blur)) saturate(1.3);
  border-top: 1px solid var(--line);
}
/* Живая «таблетка» под активной вкладкой — едет за пальцем, а не
   перепрыгивает. Позицию и размер считает positionNavIndicator() в
   app.js по факту раскладки: так она не разъезжается с текстом кнопок
   ни на одном экране и языке. Пружинный cubic-bezier с небольшим
   перелётом — тот самый штрих, который отличает вкладки уровня
   iOS/Arc от плоского «просто подсветили новую». */
.nav-indicator {
  position: absolute; left: 0; top: 0; width: 0; height: 0;
  border-radius: 12px; background: var(--clay-wash);
  transition: transform .34s cubic-bezier(.34, 1.56, .4, 1), width .34s cubic-bezier(.34, 1.56, .4, 1);
  pointer-events: none; z-index: 0;
}
.nav button {
  position: relative; z-index: 1;
  background: none; color: var(--ink-faint);
  font-size: 10.5px; font-weight: 700; font-family: var(--sans);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 2px; border-radius: 12px;
  transition: color .18s;
}
.nav button span { font-size: 20px; line-height: 1; transition: transform .2s cubic-bezier(.2,.8,.3,1); }
.nav button.active { color: var(--clay-deep); }
.nav button.active span { transform: translateY(-2px) scale(1.08); }

/* ---------- списки ---------- */
.item {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px 0; border-bottom: 1px solid var(--line);
}
.item:last-child { border-bottom: 0; }
.item .dot { font-size: 19px; line-height: 1.25; flex-shrink: 0; }
.item .body { flex: 1; min-width: 0; }
.item .name { font-weight: 700; font-size: 15px; }
.item .sub { font-size: 13px; color: var(--ink-soft); margin-top: 2px; }
.item.done .name { opacity: .5; text-decoration: line-through; text-decoration-thickness: 1px; }

.pill {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 700; white-space: nowrap;
  background: var(--clay-wash); color: var(--clay-deep);
}
.pill.ok { background: var(--sage-wash); color: var(--sage); }
.pill.warn { background: var(--ochre-wash); color: var(--ochre); }
.pill.bad { background: var(--rose-wash); color: var(--rose); }

/* ---------- прогресс (линейный, там где кольцо избыточно) ---------- */
.bar { height: 9px; background: var(--paper-sunk); border-radius: 999px; overflow: hidden; }
.bar > i { display: block; height: 100%; border-radius: 999px; transition: width .5s cubic-bezier(.2,.8,.3,1); background: linear-gradient(90deg, var(--clay), var(--clay-deep)); }
.bar.sage > i { background: linear-gradient(90deg, var(--sage), color-mix(in srgb, var(--sage) 70%, black)); }
@media (prefers-color-scheme: dark) {
  .bar > i { box-shadow: 0 0 10px color-mix(in srgb, var(--clay) 45%, transparent); }
  .bar.sage > i { box-shadow: 0 0 10px color-mix(in srgb, var(--sage) 40%, transparent); }
}

/* ---------- поля ввода ---------- */
label { display: block; font-size: 13px; color: var(--ink-soft); margin: 0 0 6px 2px; }
input, select, textarea {
  width: 100%; font: inherit; font-size: 16px; color: var(--ink);
  padding: 13px 15px; border-radius: 14px;
  border: 1px solid var(--line-strong); background: var(--paper-card);
  min-height: 52px;
}
textarea { min-height: 88px; resize: vertical; line-height: 1.5; }
input:focus, select:focus, textarea:focus {
  outline: 0; border-color: var(--clay); box-shadow: 0 0 0 3px var(--clay-wash);
}

/* ---------- дневник ---------- */
.day-head {
  display: flex; align-items: baseline; gap: 10px;
  margin: 22px 2px 10px;
}
.day-head .d { font-family: var(--serif); font-size: 17px; font-weight: 700; }
.day-head .w { font-size: 12px; color: var(--ink-faint); }
.day-head .ln { flex: 1; height: 1px; background: var(--line); }

.event { display: flex; gap: 12px; padding: 11px 0; }
.event .t { font-size: 12px; color: var(--ink-faint); width: 40px; flex-shrink: 0; padding-top: 2px; font-variant-numeric: tabular-nums; }
.event .i { font-size: 17px; flex-shrink: 0; }
.event .c { flex: 1; min-width: 0; }
.event .c b { font-weight: 700; font-size: 14.5px; }
.event .c .m { font-size: 13px; color: var(--ink-soft); }

/* ---------- график ---------- */
.chart-wrap { margin: 6px -4px 0; }
.chart-tabs { display: flex; gap: 6px; margin-bottom: 12px; }
.chart-tabs button {
  flex: 1; padding: 9px; border-radius: 11px; font-size: 13px; font-weight: 700;
  background: var(--paper-sunk); color: var(--ink-soft);
}
.chart-tabs button.on { background: linear-gradient(135deg, var(--clay), var(--clay-deep)); color: #fff; }
@media (prefers-color-scheme: dark) {
  :root[data-theme="paper"] .chart-tabs button.on { color: #241a0d; }
}

/* ---------- игры ---------- */
.game-card {
  background: var(--paper-card); border-radius: var(--radius); padding: 16px;
  box-shadow: var(--shadow), inset 0 1px 0 var(--card-rim); border: 1px solid var(--line);
  backdrop-filter: blur(var(--blur)) saturate(1.15);
  -webkit-backdrop-filter: blur(var(--blur)) saturate(1.15);
  display: flex; gap: 14px; align-items: center; margin-bottom: 10px; cursor: pointer;
  transition: transform .12s cubic-bezier(.2,.8,.3,1);
}
.game-card:active { transform: scale(.985); }
.game-card .emo {
  font-size: 30px; flex-shrink: 0;
  width: 44px; height: 44px; border-radius: 13px;
  display: flex; align-items: center; justify-content: center;
  background: var(--clay-wash); color: var(--clay-deep);
}
.game-card .emo .icon { width: 22px; height: 22px; }
.game-card .t { font-weight: 700; font-family: var(--serif); font-size: 16px; }
.game-card .d { font-size: 13px; color: var(--ink-soft); margin-top: 1px; }

.board { display: grid; gap: 10px; margin: 16px 0; }
.tile {
  aspect-ratio: 1; border-radius: 16px; background: var(--paper-sunk);
  display: flex; align-items: center; justify-content: center;
  font-size: 34px; cursor: pointer; user-select: none;
  transition: transform .13s cubic-bezier(.2,.8,.3,1), background .25s;
}
.tile:active { transform: scale(.93); }
.tile.hit { background: var(--clay-wash); }
.tile.good { background: var(--sage-wash); }
.tile.flat { background: var(--paper-card); border: 1px solid var(--line); }

/* ---------- живые фоны ----------
   Всё движение только через transform и opacity: такие анимации целиком
   уходят на видеокарту и не заставляют браузер пересчитывать вёрстку.
   Это принципиально — приложением пользуются подолгу и часто ночью, а
   анимация, дёргающая процессор, съедает батарею.

   Никаких резких движений: цикл 24–40 секунд, цель — ощущение дыхания,
   а не спецэффект. Слои за контентом и не перехватывают нажатия. */
.living {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  isolation: isolate;
}
.living > *:not(.fx) { position: relative; z-index: 1; }
.living .fx {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
  border-radius: inherit;
}
.living .blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(40px);
  opacity: .5;
  will-change: transform;
}

/* --- 1. Пятна: мягко перетекающие круги (по умолчанию) --- */
.fx-blobs .b1 { width: 210px; height: 210px; background: var(--clay); top: -80px; left: -60px; animation: drift1 26s ease-in-out infinite; }
.fx-blobs .b2 { width: 180px; height: 180px; background: var(--sage); bottom: -80px; right: -50px; animation: drift2 32s ease-in-out infinite; }
.fx-blobs .b3 { width: 140px; height: 140px; background: var(--ochre); top: 40%; right: 18%; animation: drift3 38s ease-in-out infinite; }

@keyframes drift1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33% { transform: translate(32px, 24px) scale(1.12); }
  66% { transform: translate(-18px, 32px) scale(.94); }
}
@keyframes drift2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  40% { transform: translate(-30px, -22px) scale(1.15); }
  70% { transform: translate(20px, -30px) scale(.9); }
}
@keyframes drift3 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-36px, 28px) scale(1.2); }
}

/* --- 2. Звёздная ночь: редкие мерцающие точки --- */
.fx-stars { background: linear-gradient(160deg, transparent, color-mix(in srgb, var(--clay) 8%, transparent)); }
.fx-stars .star {
  position: absolute;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--clay-deep);
  animation: twinkle 5s ease-in-out infinite;
}
@keyframes twinkle {
  0%, 100% { opacity: .15; transform: scale(.7); }
  50% { opacity: .8; transform: scale(1.25); }
}

/* --- 3. Волны: медленно поднимающиеся полосы --- */
.fx-waves .wave {
  position: absolute;
  left: -25%; right: -25%;
  height: 150px;
  border-radius: 45%;
  background: var(--clay);
  opacity: .16;
  will-change: transform;
}
.fx-waves .w1 { bottom: -90px; animation: swell 20s ease-in-out infinite; }
.fx-waves .w2 { bottom: -110px; background: var(--sage); animation: swell 27s ease-in-out infinite reverse; }
.fx-waves .w3 { bottom: -130px; background: var(--ochre); animation: swell 34s ease-in-out infinite; }
@keyframes swell {
  0%, 100% { transform: translateX(-18px) rotate(-2deg); }
  50% { transform: translateX(18px) rotate(2deg); }
}

/* --- 4. Пузырьки: всплывают снизу вверх --- */
.fx-bubbles .bubble {
  position: absolute;
  bottom: -40px;
  border-radius: 50%;
  background: var(--clay);
  opacity: .18;
  animation: rise-up 18s linear infinite;
}
@keyframes rise-up {
  0% { transform: translateY(0) scale(.6); opacity: 0; }
  15% { opacity: .22; }
  85% { opacity: .18; }
  100% { transform: translateY(-260px) scale(1.15); opacity: 0; }
}

/* --- 5. Рассвет: тёплое свечение, которое медленно разгорается --- */
.fx-dawn { background: radial-gradient(120% 80% at 50% 120%, color-mix(in srgb, var(--ochre) 26%, transparent), transparent 70%); }
.fx-dawn .sun {
  position: absolute;
  left: 50%; bottom: -110px;
  width: 220px; height: 220px;
  margin-left: -110px;
  border-radius: 50%;
  background: var(--ochre);
  filter: blur(46px);
  opacity: .35;
  animation: glow 22s ease-in-out infinite;
}
@keyframes glow {
  0%, 100% { transform: translateY(0) scale(1); opacity: .3; }
  50% { transform: translateY(-26px) scale(1.15); opacity: .5; }
}

/* ---------- прочее ---------- */
.center { text-align: center; }
.empty { text-align: center; padding: 44px 22px; color: var(--ink-soft); }
.empty .emo { font-size: 46px; display: block; margin-bottom: 12px; opacity: .9; }
.empty .h { font-family: var(--serif); font-size: 19px; font-weight: 700; color: var(--ink); margin-bottom: 8px; }

.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--safe-bottom) + 96px); z-index: 60;
  background: var(--ink); color: var(--paper);
  display: flex; align-items: center; gap: 8px;
  padding: 12px 20px; border-radius: 14px; font-size: 14px; font-weight: 700;
  max-width: 92vw; text-align: left; box-shadow: var(--shadow-lift);
  /* Небольшой перелёт при появлении — тост «выскакивает», а не просто
     проявляется, под стать остальным подтверждениям действия на экране. */
  animation: toast-pop .4s cubic-bezier(.34, 1.5, .4, 1);
}
.toast .icon { flex-shrink: 0; color: var(--sage); }
.toast.bad { background: var(--rose); color: #fff; }
.toast.bad .icon { color: #fff; }
@keyframes toast-pop {
  from { opacity: 0; transform: translate(-50%, 14px) scale(.92); }
  to { opacity: 1; transform: translate(-50%, 0) scale(1); }
}

/* ---------- частицы-«поздравление» (celebrate() в app.js) ---------- */
.confetti-particle {
  position: fixed; top: 0; left: 0; width: 7px; height: 7px; z-index: 9999;
  border-radius: 2px; pointer-events: none; will-change: transform, opacity;
  animation: confetti-burst .7s cubic-bezier(.2, .7, .3, 1) forwards;
}
@keyframes confetti-burst {
  0% { transform: translate(var(--x), var(--y)) rotate(0deg) scale(1); opacity: 1; }
  100% {
    transform: translate(calc(var(--x) + var(--dx)), calc(var(--y) + var(--dy))) rotate(var(--rot)) scale(.35);
    opacity: 0;
  }
}

/* ---------- всплеск из точки нажатия (attachRippleEffect() в app.js) ----------
   Цветной, не белый: белый блик на светлой .ghost-кнопке или .game-card
   почти не виден в дневной теме. На сплошной клеевой кнопке, наоборот,
   светлый блик читается лучше, чем ещё один слой того же оттенка —
   для неё отдельный модификатор .ripple--light. */
.ripple {
  position: absolute; border-radius: 50%; pointer-events: none; z-index: 5;
  background: radial-gradient(circle, color-mix(in srgb, var(--clay) 45%, transparent), transparent 70%);
  transform: scale(0); animation: ripple-pop .5s ease-out forwards;
}
.ripple--light { background: radial-gradient(circle, rgba(255,255,255,.6), transparent 70%); }
@keyframes ripple-pop { to { transform: scale(1); opacity: 0; } }

.code-box {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  background: var(--paper-sunk); border-radius: var(--radius-sm);
  padding: 14px; text-align: center; font-size: 14px;
  word-break: break-all; user-select: all; border: 1px dashed var(--line-strong);
}

/* ---------- чат с близкими ---------- */
.chat-list {
  display: flex; flex-direction: column; gap: 10px;
  padding: 4px 2px 10px;
}
.chat-bubble { display: flex; flex-direction: column; max-width: 78%; }
.chat-bubble.me { align-self: flex-end; align-items: flex-end; }
.chat-bubble.them { align-self: flex-start; align-items: flex-start; }
.chat-bubble .author {
  font-size: 11.5px; color: var(--ink-faint); margin: 0 4px 3px; font-weight: 700;
}
.chat-bubble .bubble-body {
  padding: 9px 13px; border-radius: 16px; font-size: 14.5px; line-height: 1.4;
  word-break: break-word; white-space: pre-wrap;
}
.chat-bubble.me .bubble-body { background: var(--clay-wash); color: var(--ink); border-bottom-right-radius: 5px; }
.chat-bubble.them .bubble-body { background: var(--paper-sunk); color: var(--ink); border-bottom-left-radius: 5px; }
.chat-bubble .time { font-size: 10.5px; color: var(--ink-faint); margin: 3px 4px 0; }

.chat-empty { text-align: center; padding: 30px 16px; color: var(--ink-soft); }
.chat-empty .emo { font-size: 40px; display: block; margin-bottom: 10px; }

.chat-input-row {
  display: flex; gap: 8px; align-items: flex-end;
  margin-top: 12px; padding-bottom: var(--safe-bottom);
}
.chat-input-row textarea {
  flex: 1; resize: none; max-height: 96px;
}
.chat-input-row .btn.small { flex: none; padding: 0 16px; min-height: 44px; }

/* Значок непрочитанного на карточке «Чат с близкими» в разделе «Малыш» */
.badge-dot {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 99px;
  background: var(--rose); color: #fff; font-size: 11px; font-weight: 700;
  margin-left: 6px;
}

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