/*
 * Оболочка приложения: шапка, содержимое, нижняя панель.
 * Экранные стили сюда не складываем — у каждого экрана свой файл (этап 1).
 */

*,
*::before,
*::after { box-sizing: border-box; }

html {
    /* приложение не должно тянуться, как страница: резинка гасится */
    overscroll-behavior-y: none;
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    background: var(--background);
    color: var(--text);
    font: 16px/1.5 var(--font);
    -webkit-tap-highlight-color: transparent;
}

img,
svg { max-width: 100%; }

a { color: inherit; }

/*
 * Фокус виден всегда — на нём держится работа с клавиатуры (этап 26).
 * :focus-visible, а не :focus: мышью кольцо не мешает.
 */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 20;
    padding: 12px 16px;
    background: var(--surface);
    border-radius: 0 0 var(--radius-s) 0;
}

.skip-link:focus {
    left: 0;
}

/*
 * Десктопной версии в макете нет: та же колонка центрируется на фоне,
 * многоколоночных раскладок не изобретаем (сквозное требование 2).
 */
.app {
    width: 100%;
    max-width: var(--col-max);
    margin: 0 auto;
    background: var(--background);
}

.app__content {
    flex: 1 0 auto;
    width: 100%;
    padding: var(--gap);
    /* место под плавающую панель: её высота, отступ снизу и воздух над ней */
    padding-bottom: calc(var(--tabbar-h) + var(--tabbar-gap) * 2 + env(safe-area-inset-bottom));
}

/*
 * Шапка. Снято с макета: белая плашка во всю ширину экрана, скруглённая
 * снизу на 30, кнопки — овалы 60×40, а не круги.
 */
.app-header {
    position: sticky;
    top: 0;
    z-index: 10;
    display: grid;
    grid-template-columns: 60px 1fr 60px;
    align-items: center;
    gap: var(--gap-xs);
    height: calc(var(--header-h) + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) var(--gap) 0;
    background: var(--surface);
    border-radius: 0 0 30px 30px;
    width: 100%;
}

.app-header__back {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--surface);
    box-shadow: var(--shadow-card);
    cursor: pointer;
}

.app-header__title {
    margin: 0;
    font-size: 17px;
    font-weight: 600;
    text-align: center;
}

.logo {
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--accent);
}

.logo--lg { font-size: 34px; }

/*
 * Нижняя панель. В макете это не полоса во всю ширину, а плашка 340×70 с
 * отступом 20 по бокам и снизу — «плавающая» над содержимым.
 * Отступ снизу складывается с безопасной зоной: на телефонах с домашней
 * полосой панель иначе легла бы прямо на неё.
 */
.tabbar {
    position: fixed;
    left: 50%;
    bottom: calc(var(--tabbar-gap) + env(safe-area-inset-bottom));
    z-index: 10;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    align-items: center;
    width: min(340px, 100% - var(--tabbar-gap) * 2);
    height: var(--tabbar-h);
    transform: translateX(-50%);
    padding: 0 6px;
    background: var(--surface);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-bar);
}

.tabbar__item {
    display: grid;
    place-items: center;
    height: 100%;
    color: var(--c-inactive);
    text-decoration: none;
    transition: color var(--dur) var(--ease);
}

.tabbar__item[aria-current="page"] { color: var(--accent); }

.tabbar__icon {
    width: 30px;
    height: 30px;
}

/*
 * Центральная кнопка со звездой и счётчиком (этап 9). В макете круг вписан
 * в высоту панели, а не выступает над ней.
 */
.tabbar__item--star { color: var(--on-accent); }

.tabbar__star {
    position: relative;
    display: grid;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--on-accent);
}

.tabbar__badge {
    position: absolute;
    top: -2px;
    right: -2px;
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--accent-2);
    color: var(--c-white);
    font-size: 12px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
}


/* карточка — базовая поверхность экранов */
.card {
    padding: var(--gap);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-card);
}

.muted { color: var(--text-muted); }

.center { text-align: center; }

.stack > * + * { margin-top: var(--gap-s); }

/*
 * Текст только для скринридера: подпись у иконки-кнопки или пояснение к числу.
 * display:none не подходит — такой текст скринридер тоже не читает.
 */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/*
 * Экраны входа. Фон ночной — тот же, что у лендинга, чтобы переход
 * «Начать → форма» не выглядел как переход на другой сайт. Сама форма при
 * этом на светлой карточке: она уже часть приложения.
 */
.auth {
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 100%;
    min-height: 100dvh;
    padding: calc(env(safe-area-inset-top) + 24px) var(--gap) calc(env(safe-area-inset-bottom) + 24px);
    background:
        radial-gradient(120% 90% at 50% 0%, var(--sky-2) 0%, var(--sky-1) 45%, var(--sky-0) 100%);
    color: var(--c-paper);
}

.auth__head {
    width: 100%;
    max-width: var(--col);
    margin: 0 auto 20px;
    text-align: center;
}

.auth__logo {
    margin: 0 0 10px;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.auth__title {
    margin: 0 0 6px;
    font-size: 26px;
    letter-spacing: -0.02em;
}

.auth__text {
    margin: 0;
    color: rgba(var(--c-paper-rgb), 0.72);
    font-size: 15px;
}

.auth__card {
    width: 100%;
    max-width: var(--col);
    margin: 0 auto;
    padding: var(--gap);
    border-radius: calc(var(--radius) * 1.2);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-card);
}

.auth__foot {
    width: 100%;
    max-width: var(--col);
    margin: 18px auto 0;
    text-align: center;
    color: rgba(var(--c-paper-rgb), 0.72);
    font-size: 15px;
}

.auth__foot a { color: var(--c-paper); }

.auth__help {
    margin-top: 12px;
    font-size: 14px;
}

.auth__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-xs);
    margin-bottom: var(--gap-s);
}

.auth__submit { margin-top: var(--gap-xs); }

/*
 * Страница без оболочки (вход, регистрация, сторис). В отличие от приложения,
 * колонкой её не ограничиваем: фон должен доходить до краёв экрана на любой
 * ширине, поэтому и body здесь тёмный — иначе при «резинке» прокрутки сверху
 * и снизу белеет.
 */
.plain {
    display: block;
    max-width: none;
    background: var(--sky-0);
    color: var(--c-paper);
}

/*
 * На широком экране колонка 380 посреди пустоты выглядит зажатой: у экранов
 * входа нет нижней панели и оболочки, они ближе к обычной странице, чем к
 * приложению. Само приложение остаётся колонкой (сквозное требование 2) —
 * шире становятся только эти экраны.
 */
@media (min-width: 900px) {
    .auth__head,
    .auth__card,
    .auth__foot { max-width: 460px; }

    .auth__card { padding: 32px; }

    .auth__title { font-size: 30px; }
}

/* ---- лента главной ---------------------------------------------------- */

.feed > * + * { margin-top: var(--gap-s); }

.feed__hello { padding: 4px 4px 8px; }

.feed__greeting {
    margin: 0 0 2px;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.feed__meta {
    margin: 0;
    color: var(--text-muted);
    font-size: 14px;
}

.card__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap-xs);
    margin-bottom: var(--gap-s);
}

.card__head--section { padding: 0 4px; }

.card__title {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.card__aside {
    margin: 0;
    color: var(--text-muted);
    font-size: 15px;
    font-weight: 600;
}

.card--link {
    display: block;
    text-decoration: none;
    border: 1.5px solid var(--accent);
}

.card--muted { box-shadow: none; background: var(--surface-sunken); }

.card--muted .card__title { margin-bottom: 6px; }

/* задания дня */
.tasks {
    margin: 0;
    padding: 0;
    list-style: none;
}

.tasks__item {
    display: flex;
    align-items: flex-start;
    gap: var(--gap-s);
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}

.tasks__item:last-child { border-bottom: 0; }

/*
 * Кружок отметки. Стилистическая галочка и полёт звезды в копилку — этап 9;
 * здесь только состояние «сделано / не сделано».
 */
.tasks__check {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    margin-top: 1px;
    border: 1.5px solid var(--border);
    border-radius: 50%;
}

.tasks__item--done .tasks__check {
    border-color: var(--accent);
    background: var(--accent);
}

.tasks__body { flex: 1 1 auto; }

.tasks__title { display: block; }

.tasks__item--done .tasks__title { color: var(--text-muted); }

.tasks__text {
    display: block;
    color: var(--text-muted);
    font-size: 14px;
}

.tasks__star {
    flex: 0 0 auto;
    color: var(--accent-2);
    font-weight: 700;
}

/* прогресс цели */
.progress {
    height: 8px;
    margin: 10px 0 6px;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    overflow: hidden;
}

.progress__value {
    display: block;
    height: 100%;
    border-radius: var(--radius-pill);
    background: var(--grad-accent);
}

.feed__goal-text { margin: 0; }

/* плитки дневников */
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-xs);
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 14px;
    border-radius: var(--radius-pill);
    background: var(--surface);
    box-shadow: var(--shadow-card);
    font-size: 15px;
    text-decoration: none;
}

.chip__pro {
    padding: 2px 6px;
    border-radius: var(--radius-pill);
    background: var(--grad-accent);
    color: var(--c-white);
    font-size: 11px;
    font-weight: 700;
}

.feed__exit {
    padding: 8px 4px 0;
    text-align: center;
}

/* ---- десктоп ----------------------------------------------------------- */

/*
 * На широком экране приложение перестаёт быть колонкой: контейнер расширяется
 * ступенями (как container в бутстрапе), а лента раскладывается в 12 колонок.
 * Одна колонка 380 посреди экрана в 1600 читается как недоделанная страница,
 * а не как приложение.
 *
 * Мобильная раскладка при этом не меняется — она и есть макет.
 */
@media (min-width: 768px) {
    .app { max-width: 720px; }
}

@media (min-width: 992px) {
    .app { max-width: 960px; }

    .app__content { padding: var(--gap) 24px calc(var(--tabbar-h) + var(--tabbar-gap) * 2 + env(safe-area-inset-bottom)); }

    /*
     * 12 колонок и явные ширины блоков. Задания слева и во всю высоту своей
     * пары, копилка и цель — справа друг под другом: список дел длиннее их
     * обоих, и рядом с ним они как раз укладываются.
     */
    .feed {
        display: grid;
        grid-template-columns: repeat(12, 1fr);
        gap: var(--gap);
        align-items: start;
    }

    /* сетка сама расставит по потоку; по умолчанию блок занимает всю ширину */
    .feed > * { grid-column: span 12; }
    .feed > * + * { margin-top: 0; }

    .feed__tasks {
        grid-column: span 7;
        /* задания и два блока справа стоят в одном ряду */
        grid-row: span 2;
    }

    .feed__stars,
    .feed__goal { grid-column: span 5; }

    .feed__soon { grid-column: span 4; }

    .feed__hello { padding-top: var(--gap-xs); }

    .feed__greeting { font-size: 26px; }
}

@media (min-width: 1200px) {
    .app { max-width: 1140px; }

    .feed__tasks { grid-column: span 8; }

    .feed__stars,
    .feed__goal { grid-column: span 4; }
    .feed__dream { grid-column: span 4; }
    .feed__media { grid-column: span 4; }
    .feed__sound { grid-column: span 4; }
}

/*
 * Шапка на широком экране остаётся простой: логотип слева, а не по центру —
 * по центру он выглядел бы потерянным на всю ширину.
 */
@media (min-width: 992px) {
    .app-header {
        grid-template-columns: 60px 1fr 60px;
        padding-inline: 24px;
    }

    .app-header__title { text-align: center; }
}

/* ---- цели -------------------------------------------------------------- */

/*
 * Ползунок. Оформляем нативный range, а не строим свой на div'ах: у нативного
 * уже есть клавиатура, скринридер и точное попадание пальцем.
 */
.range {
    width: 100%;
    margin: 12px 0 4px;
    accent-color: var(--accent-2);
}

.goal__actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-s);
    margin-top: 10px;
}

.goal__actions form { margin: 0; }

.btn--danger { color: var(--c-param); }

@media (min-width: 992px) {
    .feed__wide { grid-column: span 12; }
    .feed__half { grid-column: span 6; }
}

/* ---- главная по макету ------------------------------------------------- */

/*
 * Заголовки разделов в макете — мелкие прописные над карточкой, а не строка
 * внутри неё. Поэтому карточка отвечает за содержимое, а заголовок живёт
 * рядом и одинаков во всех блоках.
 */
.section-title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap-xs);
    margin: 0 4px 8px;
    color: var(--text);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.section-title__aside {
    color: var(--text-muted);
    font-weight: 600;
    letter-spacing: 0;
}

/* ряд кружков: аватар и сторис */
.circles {
    display: flex;
    gap: var(--gap-s);
    overflow-x: auto;
    padding: 4px 4px 2px;
    /* полоса прокрутки внутри ряда, а не у всей страницы */
    scrollbar-width: none;
}

.circles::-webkit-scrollbar { display: none; }

.circle {
    flex: 0 0 auto;
    width: 68px;
    text-align: center;
    text-decoration: none;
}

.circle__ring {
    display: grid;
    place-items: center;
    width: 64px;
    height: 64px;
    margin: 0 auto 6px;
    border-radius: 50%;
    /* непросмотренная серия — кольцо градиентом, как в макете */
    background: var(--grad-accent);
    padding: 3px;
}

.circle__ring--me { background: var(--accent); }

.circle--empty .circle__ring { background: var(--border); }

.circle__photo {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: var(--surface);
    color: var(--accent);
    font-size: 22px;
    font-weight: 700;
}

.circle__label {
    display: block;
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* карточка цели дня */
.goal__badge {
    display: inline-block;
    margin: 0 0 10px;
    padding: 5px 12px;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 12px;
}

.goal__text {
    margin: 0;
    font-size: 15px;
}

.goal__scale {
    display: flex;
    justify-content: space-between;
    margin: 0 0 12px;
    color: var(--text-muted);
    font-size: 12px;
}

.icon-btn {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1.5px solid var(--border);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    font-size: 15px;
    text-decoration: none;
    cursor: pointer;
}

.icon-btn--accent {
    border-color: transparent;
    background: var(--grad-accent);
    color: var(--c-white);
}

.btn--small {
    padding: 11px 20px;
    font-size: 15px;
}

/* ---- шапка и карусель по макету ---------------------------------------- */

/*
 * Шапка: круглая тёмная «назад» слева, крупный заголовок по центру, круглая
 * кнопка действия справа. Пустые слоты по краям остаются всегда — без них
 * заголовок съезжает, как только пропадает одна из кнопок.
 */
.app-header { height: calc(80px + env(safe-area-inset-top)); }

.app-header__title {
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.02em;
}

.round-btn {
    display: grid;
    place-items: center;
    /* овал 60×40 из макета, а не круг */
    width: 60px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-pill);
    text-decoration: none;
    cursor: pointer;
}

.round-btn--dark {
    background: var(--c-dark);
    color: var(--c-paper);
}

.round-btn--accent {
    background: var(--grad-accent);
    color: var(--c-white);
}

/* пустой слот: держит сетку, но невидим и не ловит нажатия */
.round-btn--ghost {
    background: none;
    pointer-events: none;
}

.round-btn__icon {
    width: 26px;
    height: 26px;
}

/*
 * Карусель на scroll-snap. Библиотеки не нужны: горизонтальная прокрутка
 * работает пальцем, колесом и клавиатурой, а карточка сама встаёт по месту.
 */
.slider {
    display: flex;
    gap: var(--gap-s);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    /* тень карточки не должна срезаться краем прокрутки */
    padding: 4px;
    margin: -4px;
}

.slider::-webkit-scrollbar { display: none; }

.slider__item {
    flex: 0 0 100%;
    scroll-snap-align: center;
}

.dots {
    display: flex;
    gap: 6px;
    justify-content: center;
    margin-top: 10px;
}

.dots__item {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--border);
    transition: background var(--dur) var(--ease), width var(--dur) var(--ease);
}

.dots__item.is-active {
    width: 18px;
    border-radius: var(--radius-pill);
    background: var(--accent-2);
}

/* ---- плитка дневников -------------------------------------------------- */

/*
 * Две в ряд, как в макете (160×140 при колонке 380). На широком экране
 * колонок становится больше — плитка задана минимальной шириной, а не числом.
 */
.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: var(--gap-s);
}

.tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 140px;
    padding: var(--gap-s);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-card);
    color: var(--text);
    text-align: center;
    text-decoration: none;
}

.tile__icon {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--surface-sunken);
    color: var(--accent-2);
}

.tile__glyph {
    width: 22px;
    height: 22px;
}

.tile__title { font-size: 15px; }

.tile__badge {
    position: absolute;
    top: 12px;
    right: 12px;
    padding: 3px 8px;
    border-radius: var(--radius-pill);
    background: var(--grad-accent);
    color: var(--c-white);
    font-size: 11px;
    font-weight: 700;
}

/* раздел без экрана: приглушён и не ссылка — иначе в него стучатся впустую */
.tile--soon { opacity: 0.65; }

.tile__soon {
    color: var(--text-muted);
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* ---- карточка цели по макету ------------------------------------------- */

/*
 * Компонент «Цель на день» (300×240, r20). Один шаблон и один набор стилей
 * на все места — на главной в карусели и в списке целей.
 */
.goal {
    padding: var(--gap);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-card);
}

.goal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-xs);
    margin-bottom: 12px;
}

/* заголовок внутри карточки и акцентом — так в макете */
.goal__kicker {
    margin: 0;
    color: var(--accent-2);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.goal__status {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0;
    padding: 5px 10px;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 12px;
    white-space: nowrap;
}

.goal__status-icon {
    width: 14px;
    height: 14px;
}

.goal__text {
    margin: 0 0 18px;
    font-size: 15px;
    line-height: 1.35;
}

/* ползунок с подписями по краям — 0 % слева, 100 % справа */
.goal__progress {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 18px;
}

.goal__scale-mark {
    flex: 0 0 auto;
    min-width: 34px;
    color: var(--text-muted);
    font-size: 12px;
}

.goal__progress .range { margin: 0; }

/*
 * Ползунок оформлен вручную: у нативного трек тонкий и серый, а в макете
 * крупная белая ручка с тенью на тонкой линии. Нативный input при этом
 * остаётся — с ним работают клавиатура и скринридер.
 */
.range {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 32px;
    background: none;
    cursor: pointer;
}

.range::-webkit-slider-runnable-track {
    height: 4px;
    border-radius: var(--radius-pill);
    background: var(--border);
}

.range::-moz-range-track {
    height: 4px;
    border-radius: var(--radius-pill);
    background: var(--border);
}

.range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 26px;
    height: 26px;
    margin-top: -11px;
    border: 0;
    border-radius: 50%;
    background: var(--surface);
    box-shadow: 0 2px 10px rgba(var(--c-ink-rgb), 0.25);
}

.range::-moz-range-thumb {
    width: 26px;
    height: 26px;
    border: 0;
    border-radius: 50%;
    background: var(--surface);
    box-shadow: 0 2px 10px rgba(var(--c-ink-rgb), 0.25);
}

/* ряд управления: «i», «Редактировать», переход и корзина */
.goal__actions {
    display: flex;
    align-items: center;
    gap: var(--gap-xs);
}

.goal__actions form { margin: 0; }

.btn-pill {
    flex: 1 1 auto;
    padding: 9px 16px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 14px;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
}

.icon-btn {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1.5px solid var(--border);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    text-decoration: none;
    cursor: pointer;
}

.icon-btn--accent-outline {
    border-color: var(--accent-2);
    color: var(--accent-2);
}

.icon-btn__glyph {
    width: 16px;
    height: 16px;
}

/* точки карусели: активная тёмная и вытянутая — снято с макета */
.dots__item.is-active {
    width: 14px;
    background: var(--c-dark);
}

/* картинка кружка серии: фон, а не <img> — так проще подменить файл на градиент */
.circle__photo--art {
    background-position: center;
    background-size: cover;
}

/* ---- документы --------------------------------------------------------- */

.doc {
    width: 100%;
    max-width: 760px;
    margin: 0 auto;
    padding: var(--gap) var(--gap) 60px;
    background: var(--background);
    color: var(--text);
}

.doc__back { margin: 0 0 16px; }

.doc__back a {
    color: var(--text-muted);
    text-decoration: none;
}

.doc__title {
    margin: 0 0 6px;
    font-size: clamp(26px, 5vw, 34px);
    letter-spacing: -0.02em;
}

.doc__updated {
    margin: 0 0 24px;
    color: var(--text-muted);
    font-size: 14px;
}

.doc__section { margin-bottom: 24px; }

.doc__section h2 {
    margin: 0 0 8px;
    font-size: 18px;
}

.doc__section p,
.doc__section li { line-height: 1.6; }

.doc__section ul {
    margin: 8px 0 0;
    padding-left: 20px;
}

.doc__foot {
    margin-top: 40px;
    color: var(--text-muted);
    font-size: 14px;
}

/* ---- личный кабинет ---------------------------------------------------- */

.profile > * + * { margin-top: var(--gap-s); }

/*
 * Шапка: тёмная карточка со скруглением по всем углам, аватар слева, имя и
 * счётчик дней справа. Бейдж тарифа лежит поверх её нижнего края — поэтому
 * у карточки нижний отступ под него, а сам бейдж вынесен вниз абсолютом.
 */
.phead {
    position: relative;
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 22px 22px 40px;
    border-radius: 26px;
    background: var(--c-dark);
    color: var(--c-paper);
}

.phead__avatar {
    flex: 0 0 auto;
    cursor: pointer;
}

.phead__avatar input { display: none; }

.phead__photo {
    display: grid;
    place-items: center;
    width: 120px;
    height: 120px;
    border-radius: 50%;
    background: var(--surface-sunken) center / cover no-repeat;
    color: var(--accent);
    font-size: 40px;
    font-weight: 700;
}

.phead__text { min-width: 0; }

.phead__name {
    margin: 0 0 4px;
    font-size: clamp(26px, 7vw, 34px);
    font-weight: 700;
    letter-spacing: -0.02em;
    overflow-wrap: anywhere;
}

.phead__days {
    margin: 0;
    color: rgba(var(--c-paper-rgb), 0.6);
    font-size: 15px;
}

.phead__plan {
    position: absolute;
    left: 27px;
    bottom: 16px;
    margin: 0;
    padding: 7px 16px;
    border-radius: var(--radius-pill);
    /* персиковый бейдж бесплатного тарифа — как в макете */
    background: var(--c-gold-bg);
    color: var(--c-gold-ink);
    font-size: 14px;
    font-weight: 600;
}

.phead__plan--pro {
    background: var(--grad-accent);
    color: var(--c-white);
}

/* заголовки разделов профиля — крупные и в обычном регистре */
.profile__heading {
    margin: 22px 4px 10px;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.02em;
}

/* тёмная плашка баланса */
.balance {
    position: relative;
    padding: 20px 22px;
    border-radius: var(--radius);
    background: var(--c-dark);
    color: var(--c-paper);
    overflow: hidden;
}

.balance__label {
    margin: 0 0 6px;
    color: rgba(var(--c-paper-rgb), 0.6);
    font-size: 14px;
}

.balance__value {
    margin: 0;
    font-size: 28px;
    font-weight: 700;
    letter-spacing: -0.02em;
}

/* камень из макета — картинка в media, поверх лёгкое свечение */
.balance__art {
    position: absolute;
    right: 8px;
    top: 50%;
    width: 150px;
    height: 110px;
    transform: translateY(-50%);
    background: url("/media/stone.webp") right center / contain no-repeat;
    pointer-events: none;
}

/* таблица достижений */
.stats__head,
.stats__row {
    display: grid;
    grid-template-columns: 1fr 72px 72px;
    gap: var(--gap-xs);
    align-items: center;
}

.stats__head {
    padding-bottom: 10px;
    color: var(--text-muted);
    font-size: 13px;
    text-align: center;
}

.stats__row {
    padding: 12px 0;
    border-top: 1px solid var(--border);
}

.stats__name {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 15px;
}

.stats__icon {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--surface-sunken);
    color: var(--text-muted);
}

.stats__glyph {
    width: 18px;
    height: 18px;
}

.stats__done {
    color: var(--accent-2);
    font-size: 19px;
    font-weight: 700;
    text-align: center;
}

.stats__total {
    color: var(--text-muted);
    font-size: 19px;
    text-align: center;
}

/* карточка подписки */
.pro {
    padding: 22px;
    border-radius: var(--radius);
    background: var(--grad-accent);
    color: var(--c-ink);
}

.pro__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-xs);
    margin-bottom: 12px;
}

.pro__title {
    margin: 0;
    font-size: 19px;
    font-weight: 700;
    letter-spacing: -0.01em;
    text-transform: uppercase;
}

.pro__price {
    margin: 0;
    padding: 6px 12px;
    border-radius: var(--radius-pill);
    background: var(--surface);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

.pro__text {
    margin: 0 0 18px;
    font-size: 15px;
    line-height: 1.4;
}

.pro--active { background: var(--surface-sunken); }

/* строки данных и документов */
.row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-s);
    padding: 12px 0;
    border-top: 1px solid var(--border);
    color: inherit;
    text-decoration: none;
}

.row:first-of-type { border-top: 0; }

.row__label {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 14px;
}

.row__value {
    flex: 1 1 auto;
    text-align: right;
}

.row--link .row__value { text-align: left; }

.row__arrow-icon {
    width: 18px;
    height: 18px;
    color: var(--text-muted);
}

.row__input {
    flex: 1 1 auto;
    max-width: 60%;
}

.is-editing .row { align-items: flex-start; }

.profile__save { margin-top: var(--gap-s); }

.profile__logout {
    margin: var(--gap) 0 0;
    text-align: center;
}

.btn-pill--danger {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--text-muted);
}

.btn-pill__icon {
    width: 18px;
    height: 18px;
}

/* ---- строки данных по макету ------------------------------------------- */

/*
 * В макете данные идут прямо на фоне, без карточки: подпись слева, значение
 * справа, тонкая линия между строками.
 */
.data { margin: 0 4px; }

.data__row {
    display: flex;
    align-items: center;
    gap: var(--gap-s);
    padding: 14px 0;
    border-bottom: 1px solid var(--border);
    color: inherit;
    text-decoration: none;
}

.data__row:last-child { border-bottom: 0; }

.data__label {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 14px;
}

.data__value {
    flex: 1 1 auto;
    text-align: right;
    overflow-wrap: anywhere;
}

.data__value--left { text-align: left; }

.data__spacer {
    flex: 0 0 auto;
    width: 32px;
}

.data__chevron {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 22px;
    line-height: 1;
}

/* ---- всплывающие окна --------------------------------------------------- */

.sheet {
    position: fixed;
    inset: 0;
    z-index: 30;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.sheet[hidden] { display: none; }

.sheet__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(var(--sky-0-rgb), 0.55);
}

/*
 * Телефон: лист выезжает снизу и занимает почти весь экран, прокручиваясь
 * внутри себя. Широкий экран — модалка по центру (ниже в медиазапросе).
 */
.sheet__box {
    position: relative;
    width: 100%;
    max-height: 92dvh;
    padding: var(--gap) var(--gap) calc(var(--gap) + env(safe-area-inset-bottom));
    border-radius: 26px 26px 0 0;
    background: var(--background);
    overflow-y: auto;
    animation: sheet-up var(--dur-slow) var(--ease);
}

@keyframes sheet-up {
    from { transform: translateY(16px); opacity: 0; }
    to { transform: none; opacity: 1; }
}

.sheet__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-s);
    margin-bottom: var(--gap-s);
}

.sheet__title {
    margin: 0;
    font-size: 19px;
    font-weight: 700;
}

.sheet__close {
    flex: 0 0 auto;
    font-size: 16px;
}

.sheet__text {
    margin: 0 0 16px;
    color: var(--text-muted);
    font-size: 15px;
    line-height: 1.45;
}

.sheet__submit { margin-top: var(--gap); }

/* окно «О подписке» */
.prosheet__card {
    padding: var(--gap);
    border-radius: var(--radius);
    background: var(--surface);
}

.prosheet__facts {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--gap-s);
    margin-bottom: 14px;
    padding: 14px;
    border-radius: var(--radius-s);
    background: var(--surface-sunken);
    text-align: center;
}

.prosheet__facts span {
    display: block;
    color: var(--text-muted);
    font-size: 13px;
}

.prosheet__facts b {
    display: block;
    margin-top: 2px;
    font-size: 15px;
}

.prosheet__note {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 0 0 14px;
    font-size: 14px;
    line-height: 1.35;
}

.prosheet__note-icon {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    margin-top: 1px;
}

.prosheet__note--on .prosheet__note-icon { color: var(--c-conifer); }

.prosheet__note--off .prosheet__note-icon { color: var(--accent-2); }

.prosheet__second { margin-top: var(--gap-xs); }

.prosheet__cancel {
    margin: 14px 0 0;
    text-align: center;
}

.prosheet__cancel a {
    color: var(--text-muted);
    font-size: 14px;
}

.prosheet__subtitle {
    margin: 24px 0 10px;
    font-size: 15px;
    line-height: 1.4;
}

.checklist {
    margin: 0;
    padding: 0;
    list-style: none;
}

.checklist li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 10px;
    font-size: 14px;
    line-height: 1.4;
}

.checklist__icon {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    margin-top: 1px;
    color: var(--c-conifer);
}

/* пока окно открыто, страница под ним не прокручивается */
body.is-locked { overflow: hidden; }

@media (min-width: 768px) {
    .sheet { align-items: center; }

    .sheet__box {
        max-width: 520px;
        max-height: 86dvh;
        border-radius: 26px;
        padding: 26px;
    }
}

/* бейдж «Активно» на карточке подписки */
.pro__badge {
    margin: 0;
    padding: 6px 14px;
    border-radius: var(--radius-pill);
    background: var(--c-dark);
    color: var(--c-paper);
    font-size: 13px;
    font-weight: 600;
}

.balance__unit {
    font-size: 20px;
    font-weight: 600;
}

.profile__logout-icon { display: inline-flex; }

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

.cal { margin-top: var(--gap-s); }

.cal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-xs);
    margin-bottom: 12px;
}

.cal__title {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
}

.icon-btn--off {
    opacity: 0.35;
    cursor: default;
}

/*
 * Семь колонок: день встаёт под свой день недели, поэтому месяц, начавшийся
 * со среды, и рисуется с середины первой строки.
 */
.cal__weekdays,
.cal__grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
}

.cal__weekdays {
    margin-bottom: 6px;
    color: var(--text-muted);
    font-size: 12px;
    text-align: center;
}

.cal__day {
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    padding: 0;
    border: 1.5px solid transparent;
    border-radius: 50%;
    background: var(--surface-sunken);
    color: var(--text);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
}

.cal__day--empty {
    background: none;
    cursor: default;
}

/* день с записью — заполненный кружок, как в трекере из макета */
.cal__day--marked {
    background: var(--accent);
    color: var(--on-accent);
    font-weight: 600;
}

.cal__day--today { border-color: var(--accent-2); }

.cal__day--future {
    background: none;
    color: var(--c-inactive);
    cursor: default;
}

/* ---- вес ---------------------------------------------------------------- */

.weight__form {
    display: flex;
    align-items: center;
    gap: var(--gap-xs);
}

.weight__input {
    flex: 1 1 auto;
    font-size: 20px;
    font-weight: 600;
}

.weight__unit {
    flex: 0 0 auto;
    color: var(--text-muted);
}

/* переключатель периодов графика */
.switch {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
}

.switch__item {
    padding: 6px 12px;
    border-radius: var(--radius-pill);
    color: var(--text-muted);
    font-size: 13px;
    text-decoration: none;
}

.switch__item.is-active {
    background: var(--surface);
    color: var(--text);
    font-weight: 600;
}

.chart {
    position: relative;
    margin-top: var(--gap-xs);
    color: var(--accent-2);
}

.chart svg {
    display: block;
    width: 100%;
    height: auto;
}

/*
 * График веса: холст Chart.js.
 *
 * Высоту держит обёртка, а не сам canvas: библиотека с
 * `maintainAspectRatio: false` растягивает холст по родителю, и без
 * заданной высоты он растёт при каждом пересчёте. Правило идёт после
 * общего `.chart` (там высота 120px под линию состояния в профиле).
 */
/*
 * Двойной класс не украшение: ниже в файле есть второе правило `.chart`
 * (линия состояния в профиле, height 120px), и при равной силе побеждало бы
 * оно — оно идёт позже.
 */
.chart.chart--weight {
    height: 260px;
}

@media (min-width: 720px) {
    .chart.chart--weight { height: 320px; }
}

/*
 * Та же динамика таблицей — под холстом.
 *
 * Содержимое canvas недоступно ни скринридеру, ни агенту (сквозное
 * требование 6), поэтому значения остаются в разметке. Она же единственный
 * график, когда JS выключен, — прятать её насовсем нельзя.
 */
.chart__data {
    width: 100%;
    margin-top: var(--gap-s);
    border-collapse: collapse;
    color: var(--text-muted);
    font-size: 13px;
}

.chart__data th,
.chart__data td {
    padding: 4px 8px;
    text-align: left;
    border-bottom: 1px solid var(--border);
}

.chart__data td:last-child,
.chart__data th:last-child { text-align: right; }

/*
 * Когда график нарисован, таблица — дубль: убираем её с глаз, но оставляем
 * в дереве доступности. Класс ставит сам `weight.js` и только после того,
 * как график создан: по одному лишь `.js` таблица исчезла бы и в тот раз,
 * когда библиотека не загрузилась, — и на экране не осталось бы ничего.
 */
.chart-ready .chart__data {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.sheet__delete { margin-top: var(--gap-s); }

/* ---- воспоминания ------------------------------------------------------ */

.memory__block + .memory__block { margin-top: 14px; }

.memory__label {
    margin: 0 0 4px;
    color: var(--text-muted);
    font-size: 13px;
}

.memory__text {
    margin: 0;
    line-height: 1.45;
    overflow-wrap: anywhere;
}

.memory__actions {
    display: flex;
    align-items: center;
    gap: var(--gap-xs);
    margin-top: 18px;
}

.memory__actions form { margin: 0; }

/* поле-обёртка в окне записи: подпись над полем */
.sheet .field { margin-bottom: var(--gap-s); }

/* ---- стопка карточек дня ----------------------------------------------- */

.deck__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap-xs);
    margin-bottom: 14px;
}

.deck__date {
    margin: 0;
    font-size: 17px;
    font-weight: 600;
}

.deck__counter {
    margin: 0;
    color: var(--text-muted);
    font-size: 14px;
}

/*
 * Стопка: карточки лежат одна на другой, у нижних видны края. Высоту держит
 * верхняя карточка — остальные абсолютные, иначе стопка прыгала бы при
 * листании на карточку другой длины.
 */
.deck__stack {
    position: relative;
    min-height: 260px;
    cursor: pointer;
}

.mcard {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: var(--gap-s);
    padding: 24px;
    border-radius: calc(var(--radius) * 1.2);
    background: var(--accent);
    color: var(--accent-2);
    box-shadow: 0 12px 30px rgba(var(--c-conifer-rgb), 0.28);
    overflow-y: auto;

    /*
     * Глубина в стопке приходит из скрипта: каждая следующая карточка ниже,
     * мельче и чуть повёрнута — так видно, что за верхней есть ещё.
     */
    transform:
        translateY(calc(var(--depth, 0) * 10px))
        scale(calc(1 - var(--depth, 0) * 0.04))
        rotate(calc(var(--depth, 0) * -1.2deg));
    transform-origin: bottom center;
    opacity: 1;
    transition:
        transform var(--dur-slow) var(--ease),
        opacity var(--dur) var(--ease);
    z-index: 1;
}

/* верхняя карточка выше по слою и без наклона */
.mcard.is-active {
    z-index: 5;
    transform: none;
}

/* пролистанная уезжает в сторону и не мешает нажатиям */
.mcard.is-gone {
    transform: translateX(-120%) rotate(-8deg);
    opacity: 0;
    pointer-events: none;
}

/* глубже третьей карточки стопку не показываем — иначе каша */
.mcard[style*="--depth: 3"],
.mcard[style*="--depth: 4"],
.mcard[style*="--depth: 5"] { opacity: 0; }

/*
 * Заголовок собран приёмом из сторис: мелкая строка прижата вправо над
 * крупным разреженным словом.
 */
.mcard__head { margin-bottom: 18px; }

.mcard__kicker {
    margin: 0 2px 2px 0;
    color: rgba(var(--c-paper-rgb), 0.72);
    font-size: 13px;
    letter-spacing: 0.14em;
    text-align: right;
    text-transform: uppercase;
}

.mcard__title {
    margin: 0;
    color: var(--c-paper);
    font-size: clamp(30px, 9vw, 44px);
    font-weight: 700;
    letter-spacing: 0.12em;
    line-height: 1;
    text-transform: uppercase;
}

.mcard__text {
    flex: 1 1 auto;
    margin: 0;
    overflow-wrap: anywhere;
    font-size: 17px;
    line-height: 1.5;
    letter-spacing: -0.01em;
}

.mcard__actions {
    display: flex;
    align-items: center;
    gap: var(--gap-xs);
}

.mcard__actions form { margin: 0; }

.deck__nav {
    display: flex;
    justify-content: center;
    gap: var(--gap-s);
    margin-top: 16px;
}

.deck__add { margin-top: var(--gap-s); }

@media (prefers-reduced-motion: reduce) {
    .mcard { transition: none; }
}

/* ---- окно со стопкой: без подложки, карточка 9:16 ---------------------- */

/*
 * Полноэкранный режим окна: подложки нет вовсе, карточки лежат прямо на
 * затемнении. Так стопка читается как колода, а не как содержимое диалога.
 */
.sheet--full { align-items: center; }

.sheet--full .sheet__box {
    max-width: none;
    max-height: none;
    width: 100%;
    height: 100dvh;
    padding: calc(env(safe-area-inset-top) + 14px) 16px calc(env(safe-area-inset-bottom) + 16px);
    border-radius: 0;
    background: none;
    box-shadow: none;
    overflow: visible;
    display: flex;
    flex-direction: column;
    animation: none;
}

.sheet--full .sheet__head {
    justify-content: flex-end;
    margin-bottom: 10px;
}

.sheet--full .sheet__body {
    flex: 1 1 auto;
    display: flex;
    min-height: 0;
}

.sheet--full .deck {
    display: flex;
    flex-direction: column;
    width: 100%;
}

.deck__counter {
    margin: 0 0 10px;
    color: rgba(var(--c-paper-rgb), 0.8);
    font-size: 14px;
    text-align: center;
}

/*
 * Карточка 9:16, как сторис.
 *
 * Задаём высоту, а ширину считает aspect-ratio: если брать наоборот, на
 * невысоком телефоне карточка вылезает за нижний край. Высота — меньшее из
 * «сколько осталось на экране» и «сколько влезает по ширине».
 */
.sheet--full .deck__stack {
    position: relative;
    flex: 0 0 auto;
    align-self: center;
    width: auto;
    height: min(calc(100dvh - 170px), calc((100vw - 32px) * 16 / 9));
    min-height: 0;
    margin: 0 auto;
    aspect-ratio: 9 / 16;
}

.sheet--full .mcard {
    padding: 26px 24px;
    border-radius: 26px;
}

.mcard__date {
    margin: 0 0 auto;
    color: rgba(var(--c-paper-rgb), 0.55);
    font-size: 13px;
    letter-spacing: 0.06em;
}

/* заголовок прижат к низу верхней половины — как в сторис макета */
.sheet--full .mcard__head {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    margin-bottom: 16px;
}

.sheet--full .mcard__text {
    flex: 0 1 auto;
    overflow-y: auto;
}

.sheet--full .deck__nav { margin-top: 14px; }

/* кнопка добавления: заливка хвойная, текст фуксией */
.btn-add {
    padding: 9px 18px;
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--c-conifer);
    color: var(--accent-2);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

@media (min-width: 768px) {
    /* на десктопе карточка не на весь экран, а по центру в тех же пропорциях */
    .sheet--full .sheet__box {
        width: min(520px, 100%);
        height: min(92dvh, 820px);
        padding: 16px;
    }
}

/*
 * Карточка занимает стопку целиком. Размер держит .deck__stack, поэтому у
 * самой карточки только inset: без этого они схлопывались по содержимому.
 */
.sheet--full .mcard {
    position: absolute;
    inset: 0;
    justify-content: flex-start;
    padding: 28px 24px;
    border-radius: 26px;
}

/* текст занимает остаток карточки и прокручивается внутри неё */
.sheet--full .mcard__text {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* на десктопе высота считается от окна, а не от экрана */
@media (min-width: 768px) {
    .sheet--full .deck__stack {
        height: min(calc(92dvh - 120px), 700px);
    }
}
/* ---- задания: выполнено, звезда, анимация ------------------------------ */

/*
 * Выполненное задание зачёркнуто, но звезда за него ещё не взята — её
 * забирают кнопкой. Пока не взята, строка остаётся заметной.
 */
.tasks__item--done .tasks__title {
    color: var(--text-muted);
    text-decoration: line-through;
    text-decoration-thickness: 1.5px;
}

.tasks__item--done .tasks__check {
    border-color: var(--accent);
    background: var(--accent);
    color: var(--on-accent);
}

.tasks__check svg {
    width: 14px;
    height: 14px;
}

/* галочка дорисовывается штрихом, а не появляется целиком */
.tasks__tick {
    stroke-dasharray: 24;
    stroke-dashoffset: 24;
    animation: tick var(--dur-slow) var(--ease) forwards;
}

@keyframes tick {
    to { stroke-dashoffset: 0; }
}

.tasks__item:not(.tasks__item--done) .tasks__check svg { opacity: 0; }

.tasks__note {
    display: block;
    margin-top: 2px;
    color: var(--accent-2);
    font-size: 13px;
}

.tasks__claim,
.tasks__do {
    flex: 0 0 auto;
    white-space: nowrap;
}

.tasks__do {
    padding: 8px 14px;
    font-size: 13px;
}

/*
 * Звезда, летящая в копилку. Живёт поверх всего и не ловит нажатия: это
 * украшение поверх интерфейса, а не элемент.
 */
.flying-star {
    position: fixed;
    z-index: 40;
    margin: -14px 0 0 -14px;
    color: var(--accent-2);
    /* глифа ✦ в Gilroy нет — держим системный запас, иначе вместо звезды квадрат */
    font-family: "Segoe UI Symbol", "Apple Symbols", "Noto Sans Symbols 2", sans-serif;
    font-size: 28px;
    line-height: 1;
    /* свечение вокруг символа заменяет фон: сама звезда — глиф ✦ */
    text-shadow: 0 0 14px rgba(var(--c-fuchsia-rgb), 0.8);
    pointer-events: none;
    animation: fly 700ms cubic-bezier(0.5, 0, 0.35, 1) forwards;
}

/*
 * Дуга собирается из двух шагов: сначала звезда подскакивает, потом уходит
 * в копилку и гаснет. Прямая линия читается как «улетело в никуда».
 */
@keyframes fly {
    0% { transform: translate(0, 0) scale(1); opacity: 1; }
    35% { transform: translate(calc(var(--dx) * 0.35), calc(var(--dy) * 0.2 - 60px)) scale(1.25); opacity: 1; }
    100% { transform: translate(var(--dx), var(--dy)) scale(0.4); opacity: 0.2; }
}

/* копилка коротко подпрыгивает, когда звезда долетела */
.tabbar__star.is-hit { animation: pocket-hit 400ms var(--ease); }

@keyframes pocket-hit {
    0%, 100% { transform: scale(1); }
    45% { transform: scale(1.16); }
}

@media (prefers-reduced-motion: reduce) {
    .tasks__tick { animation: none; stroke-dashoffset: 0; }
    .flying-star { display: none; }
    .tabbar__star.is-hit { animation: none; }
}

/* пустая копилка бейдж не показывает, но он есть в разметке — для счётчика */
.tabbar__badge.is-empty { display: none; }

/*
 * Аватар в ряду кружков. Картинка кадрируется по кружку: снимки приходят
 * любых пропорций, и без object-fit портрет растянулся бы в блин.
 */
.circle__photo--img {
    object-fit: cover;
}

/* ---- состояние дня «тревога — счастлив» (этап 14) ---------------------- */

.mood__title {
    margin: 0 0 var(--gap-s);
    font-size: 17px;
    font-weight: 600;
}

/*
 * Шкала без делений и без числа: точка стоит между двумя краями, и этого
 * достаточно. Деления читались бы как измерение, а показатель — оценка.
 */
.mood__scale {
    position: relative;
    height: 8px;
    border-radius: var(--radius-pill);
    background: linear-gradient(90deg, var(--c-inactive), var(--c-lilac-pale), var(--c-fuchsia));
}

.mood__dot {
    position: absolute;
    top: 50%;
    left: calc(var(--mood, 0.5) * 100%);
    width: 16px;
    height: 16px;
    border: 3px solid var(--surface);
    border-radius: 50%;
    background: var(--accent);
    transform: translate(-50%, -50%);
    box-shadow: var(--shadow-card);
}

.mood__ends {
    display: flex;
    justify-content: space-between;
    margin: var(--gap-xs) 0 var(--gap-s);
    color: var(--text-muted);
    font-size: 12px;
}

/* ---- приложение на главном экране (этап 24) ---------------------------- */

/*
 * Плашка обновления и предложение установки стоят над нижней панелью, а не
 * поверх неё: перекрыть вкладки ради подсказки — плохая сделка.
 */
.update-bar,
.install {
    position: fixed;
    left: 50%;
    bottom: calc(var(--tabbar-h) + var(--tabbar-gap) * 2 + env(safe-area-inset-bottom, 0px));
    z-index: 40;
    width: min(var(--col), calc(100vw - var(--gap) * 2));
    padding: var(--gap-s) var(--gap);
    border-radius: var(--radius);
    background: var(--c-dark);
    color: var(--c-paper);
    box-shadow: var(--shadow-card);
    transform: translateX(-50%);
}

.update-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-s);
    font-size: 14px;
}

.update-bar button {
    padding: 8px 16px;
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--c-paper);
    color: var(--c-dark);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.install__text {
    margin: 0 0 var(--gap-s);
    font-size: 14px;
    line-height: 1.45;
}

/* показывается ровно одна половина — какая, решает скрипт */
.install:not([data-install-mode="prompt"]) .install__text--prompt,
.install:not([data-install-mode="ios"]) .install__text--ios,
.install:not([data-install-mode="prompt"]) .install__go {
    display: none;
}

.install__actions {
    display: flex;
    align-items: center;
    gap: var(--gap-s);
}

/* «не сейчас» в предложении установить приложение — обычная ссылка,
   и красить её в серый значило бы прятать единственный отказ */
.install .btn--link { color: var(--accent); }

/*
 * Ощущение приложения, а не страницы: по элементам управления не выделяется
 * текст (долгий тап по кнопке в standalone иначе показывает лупу и «копировать»),
 * и браузер не ждёт двойного тапа перед нажатием.
 */
.btn,
.icon-btn,
.round-btn,
.tabbar__link,
.cal__day,
.track__mark,
.circle,
.tile {
    -webkit-user-select: none;
    user-select: none;
    touch-action: manipulation;
}

/* ---- значки достижений (этап 22) --------------------------------------- */

.badges__list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--gap-s);
}

.badge {
    display: flex;
    align-items: flex-start;
    gap: var(--gap-s);
}

/*
 * Незакрытый значок приглушён, но читается: он показывает, что впереди, а не
 * прячет цель до момента получения.
 */
.badge:not(.badge--done) .badge__title {
    color: var(--text-muted);
}

.badge__mark {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 15px;
}

.badge--done .badge__mark {
    background: var(--grad-accent);
    color: var(--on-accent);
}

.badge__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.badge__title {
    font-weight: 600;
    font-size: 14px;
}

.badge__text,
.badge__count {
    color: var(--text-muted);
    font-size: 12px;
}

.badge__bar {
    display: block;
    height: 4px;
    margin-top: 4px;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
}

.badge__fill {
    display: block;
    height: 100%;
    width: calc(var(--done, 0) * 100%);
    border-radius: inherit;
    background: var(--accent);
}

/* линия состояния: высоту задаёт CSS, точки считает сервер */
.chart {
    display: block;
    width: 100%;
    height: 120px;
    color: var(--accent);
}

/*
 * Удаление аккаунта: ссылка внизу профиля, приглушённая. Единственное
 * необратимое действие в приложении не должно выглядеть как обычная кнопка,
 * но и прятать его нельзя — это право человека на свои данные.
 */
.profile__erase {
    margin: var(--gap-s) 0 var(--gap);
    text-align: center;
}

.profile__erase .btn--link {
    color: var(--text-muted);
    font-size: 13px;
}

.btn--block.btn--danger {
    background: var(--c-dark);
    color: var(--c-paper);
}

/* ---- плашка уведомления (этап 23) -------------------------------------- */

/*
 * Стоит в ленте, а не поверх неё: перекрывать содержимое ради сообщения о
 * готовой расшифровке незачем — человек и так пришёл смотреть.
 */
.notice {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap-s);
    padding: var(--gap-s) var(--gap);
    border-radius: var(--radius);
    background: var(--c-dark);
    color: var(--c-paper);
}

.notice__body {
    min-width: 0;
}

.notice__title {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
}

.notice__text {
    margin: 2px 0 0;
    color: var(--c-inactive);
    font-size: 13px;
    line-height: 1.4;
}

.notice__actions {
    display: flex;
    align-items: center;
    gap: var(--gap-xs);
}

.notice .btn {
    padding: 8px 16px;
    background: var(--c-paper);
    color: var(--c-dark);
}

.notice .btn--link {
    padding: 8px;
    background: none;
    color: var(--accent);
}

/* ---- закрытые задания (этап 30) ---------------------------------------- */

/*
 * Закрытая строка приглушена, но читается: она показывает ритм дня, а не
 * прячет задание. Полностью серой её делать нельзя — тогда человек решит,
 * что задание уже выполнено.
 */
.tasks__item--locked .tasks__title {
    color: var(--text-muted);
}

.tasks__item--locked .tasks__check {
    opacity: 0.4;
}

.tasks__when {
    display: block;
    color: var(--accent-2);
    font-size: 12px;
}

.tasks__lock {
    flex: 0 0 auto;
    font-size: 14px;
    opacity: 0.5;
}

/* ---- значок непрочитанного на вкладке (этап 30) ------------------------- */

.tabbar__slot {
    position: relative;
    display: inline-flex;
}

/*
 * Цифра сидит на иконке, а не рядом: панель узкая, и сдвигать вкладку ради
 * счётчика — значит двигать все остальные.
 */
.tabbar__count {
    position: absolute;
    top: -6px;
    right: -10px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: var(--radius-pill);
    background: var(--grad-accent);
    color: var(--on-accent);
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
}

/* та же цифра у плитки раздела в «Моей жизни» */
.tile__count {
    position: absolute;
    top: 10px;
    right: 10px;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--grad-accent);
    color: var(--on-accent);
    font-size: 11px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
}

/* ---- мечта, слайдер разделов и живой счётчик (этап 30) ------------------ */

/*
 * Карточка мечты: фото во всю ширину, подпись на тёмной подложке снизу — как
 * в макете. Текст лежит под фотографией, а не поверх неё: поверх он читается
 * только на удачном снимке, а сюда люди ставят что угодно.
 */
/*
 * «Моя мечта». Была тёмной плашкой под фотографией — на светлой ленте
 * это читалось как акцент, а на ночном небе тёмная карточка среди белых
 * стала выглядеть выключенной. Теперь она такая же карточка, как
 * остальные, и фотография в ней работает сама по себе.
 */
.dream-card {
    display: block;
    overflow: hidden;
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-card);
    text-decoration: none;
}

.dream-card__photo {
    display: block;
    width: 100%;
    height: 180px;
    object-fit: cover;
}

.dream-card__body {
    display: block;
    padding: var(--gap-s) var(--gap);
}

.dream-card__title {
    display: block;
    font-size: 16px;
    font-weight: 600;
}

.dream-card__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-s);
    margin-top: 4px;
    color: var(--text-muted);
    font-size: 12px;
}

/* тёмный конец градиента, а не сама фуксия: на белом она даёт 2.28 */
.dream-card__progress {
    margin-left: auto;
    color: var(--c-fuchsia-deep);
    font-weight: 600;
}

/*
 * Полоса разделов. Прокручивается внутри себя и «вылезает» за поля колонки
 * отрицательными отступами: в макете кружки уходят под край экрана, показывая,
 * что список продолжается.
 */
.rail {
    display: flex;
    gap: var(--gap-s);
    overflow-x: auto;
    margin: 0 calc(-1 * var(--gap));
    padding: 4px var(--gap);
    scroll-snap-type: x proximity;
    scrollbar-width: none;
}

.rail::-webkit-scrollbar {
    display: none;
}

.rail__item {
    flex: 0 0 auto;
    width: 72px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    text-align: center;
    text-decoration: none;
    scroll-snap-align: start;
}

.rail__circle {
    position: relative;
    display: grid;
    place-items: center;
    width: 60px;
    height: 60px;
    border-radius: 50%;
    background: var(--surface);
    box-shadow: var(--shadow-card);
}

.rail__glyph {
    width: 26px;
    height: 26px;
    color: var(--accent-2);
}

.rail__pro {
    position: absolute;
    top: -4px;
    right: -6px;
    padding: 1px 6px;
    border-radius: var(--radius-pill);
    background: var(--grad-accent);
    color: var(--on-accent);
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.04em;
}

.rail__title {
    font-size: 11px;
    line-height: 1.25;
    color: var(--text-muted);
}

/* строка «сейчас медитирует N человек»: живая, поэтому с точкой-пульсом */
.feed__live {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--gap-xs);
    margin: 0;
    color: var(--text-muted);
    font-size: 13px;
}

.feed__live-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent-2);
    animation: live-pulse 2s var(--ease) infinite;
}

@keyframes live-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.4; transform: scale(0.8); }
}

@media (prefers-reduced-motion: reduce) {
    .feed__live-dot { animation: none; }
}


/* ======================================================== плеер (этап 16) */

/*
 * Плеер живёт в оболочке: мини-полоса висит над нижней панелью на всех
 * экранах, разворот накрывает приложение целиком. Стили поэтому здесь, а не
 * в sound.css — тот подключается только на каталоге.
 */
.player[hidden] { display: none; }

.player__bar {
    position: fixed;
    left: 50%;
    /* над панелью вкладок: её высота, её отступ и воздух между ними */
    bottom: calc(var(--tabbar-gap) * 2 + var(--tabbar-h) + env(safe-area-inset-bottom));
    z-index: 9;
    display: flex;
    align-items: center;
    gap: var(--gap-xs);
    width: min(340px, 100% - var(--tabbar-gap) * 2);
    height: 60px;
    transform: translateX(-50%);
    padding: 0 10px 0 8px;
    background: var(--surface);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-bar);
}

/* содержимое не должно прятаться под полосой, когда она появилась */
.has-player .app__content {
    padding-bottom: calc(var(--tabbar-h) + 60px + var(--tabbar-gap) * 3 + env(safe-area-inset-bottom));
}

/*
 * Полоса прогресса мини-плеера — тонкая линия по нижнему краю плашки.
 * Показывает, сколько осталось, и не занимает ни строки: места в полосе нет.
 */
.player__line {
    position: absolute;
    left: 16px;
    right: 16px;
    bottom: 8px;
    height: 2px;
    border-radius: 2px;
    background: var(--border);
    overflow: hidden;
}

.player__line-fill {
    display: block;
    width: 0;
    height: 100%;
    background: var(--accent);
    transition: width var(--dur-fast) linear;
}

.player__open {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.player__cover {
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    overflow: hidden;
    background: var(--surface-sunken);
}

.player__cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* обложки может не быть — тогда на её месте фирменное пятно, а не дыра */
.player__cover--empty { background: var(--grad-accent); }

.player__cover--mini {
    width: 44px;
    height: 44px;
    border-radius: 14px;
}

.player__meta {
    display: grid;
    min-width: 0;
}

.player__title,
.player__sub {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.player__title { font-weight: 600; }

.player__sub {
    color: var(--text-muted);
    font-size: 13px;
}

.player__btn {
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--text);
    cursor: pointer;
}

.player__btn:disabled {
    color: var(--c-inactive);
    cursor: default;
}

.player__btn--close {
    color: var(--text-muted);
    font-size: 18px;
    line-height: 1;
}

.player__glyph {
    width: 30px;
    height: 30px;
}

/* пауза и воспроизведение — одна кнопка: показывается то, что сейчас можно */
.player__icon--pause,
.player.is-playing .player__icon--play { display: none; }

.player.is-playing .player__icon--pause { display: block; }

/* ------------------------------------------------------------- разворот */

.player__screen {
    position: fixed;
    inset: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: calc(var(--gap) + env(safe-area-inset-top)) var(--gap)
             calc(var(--gap) + env(safe-area-inset-bottom));
    background: var(--background);
    overflow-y: auto;
}

.player__screen[hidden] { display: none; }

.player__head {
    display: grid;
    grid-template-columns: 44px 1fr 44px;
    align-items: center;
    width: 100%;
    max-width: var(--col);
    margin-bottom: var(--gap);
}

.player__kicker {
    margin: 0;
    color: var(--text-muted);
    text-align: center;
}

.player__art {
    display: grid;
    place-items: center;
    width: 100%;
    max-width: var(--col);
    margin-bottom: var(--gap);
}

/*
 * Обложка квадратная и тянется по ширине колонки, но не выше половины
 * экрана: на низком экране иначе она выдавливает кнопки за край.
 */
.player__cover--big {
    width: min(100%, 50vh);
    aspect-ratio: 1;
    border-radius: var(--radius);
}

.player__name {
    width: 100%;
    max-width: var(--col);
    margin: 0 0 var(--gap);
    font-size: 22px;
    font-weight: 700;
    text-align: center;
}

.player__seek {
    width: 100%;
    max-width: var(--col);
    accent-color: var(--accent);
}

.player__times {
    display: flex;
    justify-content: space-between;
    width: 100%;
    max-width: var(--col);
    margin: 4px 0 var(--gap);
    color: var(--text-muted);
    font-size: 13px;
}

.player__controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--gap);
}

.player__btn--main {
    width: 72px;
    height: 72px;
    background: var(--accent);
    color: var(--on-accent);
}

.player__btn--main .player__glyph {
    width: 36px;
    height: 36px;
}

.player__btn--step {
    width: 56px;
    height: 56px;
    background: var(--surface);
    box-shadow: var(--shadow-card);
}

.player__note {
    max-width: var(--col);
    margin: var(--gap) 0 0;
    text-align: center;
}

/* пока плеер развёрнут, страница под ним не прокручивается */
.is-player-open { overflow: hidden; }


/* ============================ карточка медиатеки и медитация дня (этап 16) */

/*
 * Карточка каталога. Живёт в app.css, а не в sound.css: те же карточки
 * стоят в «Гармонии звука» на главной, а второй копии правил быть не должно.
 *
 * Ширина фиксированная — иначе карточки в карусели сжимаются друг под друга
 * и обложки перестают быть квадратными.
 */
.mtile {
    display: grid;
    flex: 0 0 auto;
    gap: 8px;
    width: 140px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    text-decoration: none;
    scroll-snap-align: start;
    cursor: pointer;
}

.mtile__cover {
    position: relative;
    display: block;
    width: 140px;
    height: 140px;
    border-radius: var(--radius);
    /* обложки может не быть — тогда на её месте фирменное пятно, а не дыра */
    background: var(--grad-accent);
    overflow: hidden;
}

.mtile__photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* длительность поверх обложки: в макете она в углу карточки, а не строкой */
.mtile__time {
    position: absolute;
    right: 8px;
    bottom: 8px;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: rgba(var(--c-ink-rgb), 0.62);
    color: var(--c-white);
    font-size: 12px;
    line-height: 18px;
}

.mtile__badge {
    position: absolute;
    top: 8px;
    left: 8px;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: var(--c-white);
    color: var(--accent);
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
}

.mtile__title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    font-size: 15px;
}

/*
 * Закрытая подпиской карточка приглушена, но остаётся ссылкой на тариф:
 * непонятно погашенная карточка заставляет стучаться в неё повторно.
 */
.mtile--locked .mtile__cover { filter: saturate(0.35); }

.mtile--locked .mtile__title { color: var(--text-muted); }

/*
 * Медитация дня — широкая строка, а не плитка: она одна на день, и полоса
 * с крупной кнопкой читается как приглашение, а не как ещё одна карточка
 * каталога.
 */
.media-day {
    display: flex;
    align-items: center;
    gap: var(--gap-s);
    width: 100%;
    padding: var(--gap-s);
    border: 0;
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-card);
    color: inherit;
    font: inherit;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.media-day__cover {
    position: relative;
    flex: 0 0 auto;
    width: 64px;
    height: 64px;
    border-radius: var(--radius-s);
    background: var(--grad-accent);
    overflow: hidden;
}

.media-day__photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.media-day__body {
    flex: 1 1 auto;
    min-width: 0;
}

.media-day__title {
    display: block;
    font-weight: 600;
}

.media-day__meta {
    display: block;
    color: var(--text-muted);
    font-size: 13px;
}

.media-day__play {
    display: grid;
    flex: 0 0 auto;
    place-items: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--on-accent);
}

.media-day__play svg {
    width: 30px;
    height: 30px;
}


/* ============================================ прочитанные сторис (этап 17) */

/*
 * Непрочитанная серия обведена фуксией — это кольцо у `.circle__ring` выше.
 * Прочитанная остаётся без рамки, но того же размера: фон убираем, а отступ
 * оставляем, иначе фотография прыгала бы на три пикселя после каждого
 * просмотра, и лента дёргалась бы на глазах.
 */
.circle--seen .circle__ring {
    background: none;
    box-shadow: 0 0 0 1px var(--border) inset;
}

/* подпись прочитанной серии приглушена — так видно, что уже смотрели */
.circle--seen .circle__label { color: var(--text-muted); }


/* ================================================ планы и разбор (этап 17) */

.plans > * + * { margin-top: var(--gap-s); }

.plans__period { margin: -4px 0 12px; font-size: 13px; }

/*
 * Поле плана намеренно просторное: человек пишет несколько строк о жизни, и
 * однострочный ввод подталкивал бы к отписке в три слова.
 */
.plans__field {
    width: 100%;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-s);
    background: var(--surface-sunken);
    color: var(--text);
    font: inherit;
    resize: vertical;
}

.plans__submit { margin-top: var(--gap-s); }

/* плашка-подтверждение без карточки: она живёт секунду и не должна тяжелить экран */
.notice--flat {
    padding: 12px 16px;
    background: var(--surface-sunken);
    box-shadow: none;
    color: var(--text-muted);
}

/* вопрос недели: ответ пишется прямо в плашке, без перехода на отдельный экран */
.review__field {
    width: 100%;
    margin-top: var(--gap-s);
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-s);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    resize: vertical;
}

/* строка «расскажите, что вас ждёт завтра» над плитками «Моей жизни» */
.diary__plans {
    display: grid;
    gap: 4px;
    margin-bottom: var(--gap-s);
}


/* ============================== приложение на звёздном небе (этапы 1 и 22) */

/*
 * Тёмная тема целиком живёт в токенах — здесь только то, что нельзя выразить
 * переменной: слои, прозрачности и размытие.
 *
 * html красится отдельно от body: колонка приложения уже 480 пикселей, и на
 * широком экране за её краями иначе осталась бы белая полоса.
 */
.is-night { background: var(--background); }

html:has(.is-night) { background: var(--sky-0); }

/*
 * Колонка не закрашивается: под ней должно просвечивать небо. Именно из-за
 * этой строки звёзды видно не только по краям экрана.
 */
.is-night.app { background: transparent; }

/*
 * Содержимое над звёздами.
 *
 * **Без z-index.** Достаточно `position: relative`: слои поля стоят на
 * z-index 0 и идут в разметке раньше, поэтому позиционированное
 * содержимое рисуется поверх них само.
 *
 * Ставить сюда z-index нельзя: он создаёт контекст наложения, и всё
 * внутри — включая всплывающие окна с их z-index 30 — оказывается
 * запертым на этом уровне. Панель вкладок живёт снаружи на z-index 10 и
 * начинает рисоваться поверх открытого окна. Ровно это и случилось.
 *
 * Шапке правило не нужно вовсе: у неё своя позиция sticky и свой слой.
 */
.is-night .app__content { position: relative; }

/*
 * Шапка и панель — стекло, а не заливка: сквозь них видно небо, а текст
 * остаётся читаемым за счёт размытия. Без размытия звезда, попавшая под
 * подпись вкладки, спорит с ней за внимание.
 */
.is-night .app-header,
.is-night .tabbar {
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

/*
 * Кружок вокруг аватара и заглушки фотографий: на светлой стороне это белая
 * подложка, на тёмной она превратилась бы в яркое пятно.
 */
/*
.is-night .circle__photo,
.is-night .rank__avatar,
.is-night .phead__photo--art { background: var(--surface-sunken); }*/К

/* центральная кнопка панели: на тёмном хвойный не виден, роль берёт градиент */
.is-night .tabbar__star { background: var(--grad-accent); }

.is-night .tabbar__item--star { color: var(--on-accent); }

/* прочитанная сторис: тонкая светлая обводка вместо тени */
.is-night .circle--seen .circle__ring {
    box-shadow: 0 0 0 1px rgba(var(--c-paper-rgb), 0.22) inset;
}


/* календарь и графики: линии на тёмном тоньше не становятся, а вот цвет — да */
.is-night .cal__day--empty { background: transparent; }


/*
 * Бейдж PRO: на светлой стороне это белая плашка с хвойной надписью. На
 * тёмной хвойный на белом почти не виден, поэтому надпись становится цвета
 * ночи — плашка остаётся белой, читается так же.
 */
.is-night .mtile__badge,
.is-night .tile__badge,
.is-night .rail__pro { color: var(--sky-0); }

/* ссылка на все значки под коротким списком в профиле */
.badges__all {
    display: block;
    margin-top: var(--gap-s);
}

/* кнопка «получить звезду» у значка: своя строка, не в потоке текста */
.badge__claim { margin-top: 8px; }


/* ========================================= календарь: дневник по датам */

.calendar > * + * { margin-top: var(--gap-s); }

/*
 * Точки под числом. Число остаётся главным, точки — тонкая подпись под ним,
 * поэтому день становится колонкой, а не строкой.
 */
.cal__day { flex-direction: column; gap: 3px; }

.cal__dots {
    display: flex;
    gap: 2px;
    height: 4px;
}

.cal__dot {
    width: 4px;
    height: 4px;
    border-radius: 50%;
}

.cal__dot--dream { background: var(--c-fuchsia-deep); }

.cal__dot--memory { background: var(--c-conifer); }

.cal__dot--weight { background: var(--c-param); }

.cal__dot--task { background: var(--c-gold-ink); }

/*
 * Легенда обязательна: без неё точки — украшение. Человек видит, что в дне
 * «что-то было», и не понимает что.
 */
.legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-s);
    margin: var(--gap-s) 0 0;
    padding: 0;
    list-style: none;
    font-size: 12px;
    color: var(--text-muted);
}

.legend__item {
    display: flex;
    align-items: center;
    gap: 5px;
}

.legend__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
}

.legend__dot--dream { background: var(--c-fuchsia-deep); }

.legend__dot--memory { background: var(--c-conifer); }

.legend__dot--weight { background: var(--c-param); }

.legend__dot--task { background: var(--c-gold-ink); }

/* ----------------------------------------------------- разбор дня */

.day__mood {
    margin: 0 0 var(--gap-s);
    font-size: 17px;
    font-weight: 600;
}

.day__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gap-s);
    padding: 10px 0;
    border-top: 1px solid var(--border);
    color: inherit;
    text-decoration: none;
}

.day__label {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 14px;
}

.day__value {
    text-align: right;
    overflow-wrap: anywhere;
}

/* выполненные задания перечисляются подряд, а не столбиком по одному */
.day__row--tasks .day__value {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 4px 8px;
}

.day__task {
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: var(--surface-sunken);
    font-size: 13px;
}

/*
 * Круглые кнопки в шапке развёрнутого плеера: свернуть и поделиться.
 *
 * Свой класс, а не `.round-btn--ghost`: тот модификатор в проекте означает
 * пустую распорку в шапке приложения — она держит заголовок по центру, когда
 * кнопки с одной стороны нет, и потому у неё `pointer-events: none`. Живая
 * кнопка с этим классом выглядит отсутствующей и не нажимается.
 *
 * Экран плеера тёмный, поэтому кнопка — светлое стекло, а не тёмная плашка.
 */
.player__round {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--glass-light);
    color: var(--c-paper);
    cursor: pointer;
    transition: background var(--dur-fast) var(--ease);
}

.player__round:active { background: rgba(var(--c-paper-rgb), 0.3); }

.player__round-icon {
    width: 26px;
    height: 26px;
}

/* стрелка «свернуть» смотрит вниз — туда, куда уезжает плеер */
.player__collapse { justify-self: start; }

/*
 * Кнопка «назад» на звёздном небе.
 *
 * По макету это тёмная плашка на светлой ленте. На ночном фоне тёмное по
 * тёмному пропадает совсем, поэтому она меняется местами с содержимым:
 * светлый круг с тёмной стрелкой. Тот же приём, что у кнопок в плеере.
 */
.is-night .round-btn--dark {
    background: var(--surface-solid);
    color: var(--on-surface-solid);
}

/*
 * Полоса плеера и панель вкладок — стекло, но не прозрачность.
 *
 * Семь процентов белого поверх неба читались как «полоса не догрузилась»:
 * сквозь неё видно звёзды, а название трека спорит с ними за внимание.
 * Плотная подложка ночного тона плюс светлая линия по краю: панель видно как
 * панель, и небо за ней всё ещё угадывается.
 */
.is-night .player__bar,
.is-night .tabbar {
    background: rgba(var(--sky-1-rgb), 0.86);
    box-shadow: 0 0 0 1px rgba(var(--c-paper-rgb), 0.1), var(--shadow-bar);
}

/* развёрнутый плеер — сплошной, он и должен закрывать всё под собой */
.is-night .player__screen { background: var(--sky-0); }
