/* ==========================================================================
   Токены (значения из макета Figma «veasper-workflow»)
   ========================================================================== */

:root {
    --font: "Noto Sans Display", sans-serif;
    --font-text: "Noto Sans", sans-serif;

    --accent: #E60023;
    --accent-hover: #ff3b3b;

    --brand-tg: linear-gradient(180deg, #2AABEE 0%, #229ED9 99.2%);
    --brand-yt: #FF0000;
    --brand-tw: #9146FF;

    --text: #000;
    --muted: rgba(0, 0, 0, 0.5);
    --faint: rgba(0, 0, 0, 0.4);
    --divider: rgba(0, 0, 0, 0.2);

    --page-bg: white;                        /* фон страницы на телефоне */
    --card-glass: rgba(255, 255, 255, 0.5);
    --card-border: rgba(255, 255, 255, 0.71);
    --glass: rgba(255, 255, 255, 0.4);       /* подсветка играющего трека */
    --player-glass: rgba(255, 255, 255, 0.4);
    --chip: rgba(255, 255, 255, 0.5);        /* кнопка «Скачать» */
    --chip-active: white;
    --chip-active-invert: 0;                 /* иконка на активной кнопке: 0 — тёмная, 1 — белая */
    --cover-empty: rgba(0, 0, 0, 0.08);
    --track-bg: rgba(229, 231, 235, 0.44);   /* дорожки прогресса, громкости, скролла */
    --fill: white;                           /* заливка прогресса, громкости, ползунок скролла */
    --play-bg: black;
    --icon-invert: 0;                        /* 1 — перекрасить чёрные иконки в белые */
    --gloss: inset 0 1px 0 rgba(255, 255, 255, 0.5); /* блик сверху у кнопок */

    --theme-fade: 0.45s ease;

    --player-height: 58px;

    --spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

/* Тёмная тема: <html data-theme="dark"> — ставит инлайн-скрипт в index.php (до отрисовки)
   и переключатель в углу (js/theme.js). Меняются только токены. */
html[data-theme="dark"] {
    --text: #f4f4f5;
    --muted: rgba(255, 255, 255, 0.55);
    --faint: rgba(255, 255, 255, 0.45);
    --divider: rgba(255, 255, 255, 0.14);

    --page-bg: #0e0f10;
    --card-glass: rgba(18, 19, 21, 0.55);
    --card-border: rgba(255, 255, 255, 0.12);
    --glass: rgba(255, 255, 255, 0.07);
    --player-glass: rgba(18, 19, 21, 0.5);
    --chip: rgba(255, 255, 255, 0.1);
    --chip-active: rgba(255, 255, 255, 0.24);
    --chip-active-invert: 1;
    --cover-empty: rgba(255, 255, 255, 0.08);
    --track-bg: rgba(255, 255, 255, 0.14);
    --fill: white;
    --play-bg: white;
    --icon-invert: 1;
    --gloss: inset 0 1px 0 rgba(255, 255, 255, 0.25);

    color-scheme: dark;
}

/* ==========================================================================
   Основа
   ========================================================================== */

* {
    margin: 0;
    padding: 0;
    text-decoration: none;
}

/* Кнопки и поля по умолчанию берут системный шрифт — возвращаем шрифт сайта */
button,
input,
textarea {
    font-family: inherit;
}

/* Фон под страницей — по теме: Safari берёт его для своих панелей и «резинового» скролла */
html {
    background-color: var(--page-bg);
    transition: background-color var(--theme-fade);
}

body {
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    width: 100%;
    height: 100vh;
    min-height: 100vh;
    overflow: hidden;
    font-family: var(--font);
    color: var(--text);
    transition: color var(--theme-fade);
}

.bg-video {
    position: fixed;
    top: 0;
    left: 0;
    z-index: -1;
    width: 100vw;
    height: 100vh;
    object-fit: cover;
}

/* ==========================================================================
   Карточка
   ========================================================================== */

.main {
    position: relative;
    isolation: isolate;
    display: flex;
    width: 1080px;
    height: 530px;
    box-sizing: border-box; /* рамка внутри размера, как в Figma */
    overflow: hidden;
    border: 3px solid var(--card-border);
    border-radius: 64px;
    transition: border-color var(--theme-fade);

    /* Окно меньше карточки (iPad в альбомной ориентации, узкое окно, телефон боком) —
       карточка уменьшается целиком, с полями 24px, а не обрезается по краям.
       tan(atan2(a, b)) = a / b: разделить длину на длину CSS напрямую пока не умеет. */
    scale: min(1, tan(atan2(100vw - 48px, 1080px)), tan(atan2(100vh - 48px, 530px)));
}

/* Стекло карточки — отдельным слоем, а не backdrop-filter на самой .main:
   иначе .main становится «корнем» для вложенных блюров, и стекло плеера
   перестаёт размывать список треков под собой. */
.main::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--card-glass);
    backdrop-filter: blur(24.9px);
    -webkit-backdrop-filter: blur(24.9px);
    transition: background-color var(--theme-fade);
}

/* --- Левая половина: арт --- */

.hero-img {
    position: relative;
    flex: 1;
    min-width: 0;
    height: 100%;
    overflow: hidden;
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    outline: none;
}

.hero-img img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    -webkit-user-drag: none;
    user-select: none;
    pointer-events: none;
    transition: opacity 0.5s;
}

/* Смена арта по клику (js/gallery.js): новая картинка раскрывается кругом из точки
   клика (--x, --y), проявляясь из блюра и чуть «оседая», старая уходит вглубь.
   Зум у обеих — из той же точки, что и круг. */
.hero-img img.is-entering,
.hero-img img.is-leaving {
    transform-origin: var(--x) var(--y);
}

.hero-img img.is-entering {
    z-index: 1;
    animation: hero-reveal 0.9s cubic-bezier(0.65, 0, 0.35, 1) both;
}

.hero-img img.is-leaving {
    animation: hero-leave 0.9s cubic-bezier(0.65, 0, 0.35, 1) both;
}

@keyframes hero-reveal {
    from {
        clip-path: circle(0% at var(--x) var(--y));
        filter: blur(16px);
        transform: scale(1.15);
    }
    to {
        clip-path: circle(150% at var(--x) var(--y));
        filter: blur(0);
        transform: scale(1);
    }
}

@keyframes hero-leave {
    to {
        filter: blur(8px) brightness(0.85);
        transform: scale(1.06);
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-img img.is-entering { animation: hero-fade 0.3s ease both; }
    .hero-img img.is-leaving  { animation: none; }
}

@keyframes hero-fade {
    from { opacity: 0; }
}

/* Рамка фокуса для тех, кто ходит по сайту клавишей Tab (мышью и пальцем её не видно) */
.hero-img:focus-visible,
.likes:focus-visible,
.track:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.likes:focus-visible {
    outline-offset: 4px;
    border-radius: 8px;
}

/* --- Правая половина: пост --- */

.content {
    position: relative; /* для мини-плеера внизу */
    display: flex;
    flex-direction: column;
    gap: 16px;
    flex-shrink: 0;
    width: 539px;
    padding: 24px 24px 0;
    box-sizing: border-box;
}

.top-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 24px;
    font-weight: 600;
}

/* ==========================================================================
   Лайк
   ========================================================================== */

/* Пульс и одометр рисует js/likes.js: scale сердца и блока меняется покадрово,
   поэтому своих transition на transform здесь нет. */
.likes {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    outline: none;
}

.heart {
    display: flex;
    align-items: center;
    justify-content: center;
}

.heart svg {
    display: block;
    transform-origin: center;
}

.heart.is-liked svg { fill: var(--accent); }

/* Цифра-одометр: меняющийся разряд уезжает вверх (лайк) или вниз (снятие) */
#like-count {
    display: inline-block;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.like-slot {
    display: inline-block;
    height: 1.2em;
    overflow: hidden;
    vertical-align: top;
}

.like-roll {
    display: flex;
    flex-direction: column;
}

.like-roll > span              { height: 1.2em; }
.like-roll.is-down             { transform: translateY(-1.2em); }
.like-roll.is-rolling          { transform: translateY(-1.2em); transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1); }
.like-roll.is-down.is-rolling  { transform: translateY(0); }

/* ==========================================================================
   Кнопка «Сохранить»
   ========================================================================== */

.save-btn {
    padding: 18px 30px;
    border: none;
    border-radius: 100px;
    background: var(--accent);
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.5);
    color: white;
    font-size: 20px;
    font-weight: 700;
    cursor: pointer;
    transition: 0.3s ease;
}

.save-btn:hover {
    background: var(--accent-hover);
    transform: scale(1.05);
}

.save-btn:active {
    transform: scale(0.9);
}

/* ==========================================================================
   Автор, статус, просмотры
   ========================================================================== */

.post-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.author-info {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-text);
    font-size: 20px;
    font-weight: 600;
}

.author-info img {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    object-fit: cover;
}

/* Имя — главный заголовок страницы (для поисковиков), но выглядит как в макете */
.author-text {
    font: inherit;
}

.description {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    font-size: 20px;
}

/* Статус «печатается» как в текстовом редакторе (js/status.js + js/typewriter.js):
   текст набирается по буквам, стирается, набирается следующий. Курсор мигает,
   пока текст стоит, и горит ровно, пока печатается — как в настоящем редакторе.
   Мигание (--caret-blink) и сам курсор (no-caret) — из настроек печати в админке. */
.status {
    min-height: 1.35em; /* строка не схлопывается, когда текст стёрт до конца */
}

.status__caret {
    display: inline-block;
    width: 2px;
    height: 1.1em;
    margin-left: 2px;
    border-radius: 1px;
    background: currentColor;
    vertical-align: -0.18em;
    animation: caret-blink var(--caret-blink, 1s) steps(1) infinite;
}

.status.is-typing .status__caret {
    animation: none;
}

.status.no-caret .status__caret {
    display: none;
}

@keyframes caret-blink {
    50% { opacity: 0; }
}

.views {
    flex-shrink: 0; /* длинный статус не сжимает счётчик */
    display: flex;
    align-items: center;
    gap: 3px;
    color: var(--muted);
    font-size: 15px;
    font-weight: 600;
}

.views .icon-views {
    fill: var(--muted);
}

/* ==========================================================================
   «Прям ща слушаю» — плашка Spotify на месте статуса (js/status.js), макет Figma 3199:11920.
   Пока у меня играет Spotify, статус стирается и на его месте появляется плашка,
   трек в ней печатается. На паузе плашка уходит, статус печатается обратно.
   ========================================================================== */

/* С плашкой просмотры прижаты к её низу, как в макете */
.description.is-now {
    align-items: flex-end;
}

.now {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 10px;
    border-radius: 15px;
    background: linear-gradient(180deg, #1ED760 0%, #107132 315%);
    box-shadow: var(--gloss);
    color: #000;
    font-family: var(--font);
    font-size: 14px;
    line-height: normal;
    transition: filter 0.2s ease;
}

.now[hidden] {
    display: none;
}

.now:hover {
    filter: brightness(1.05);
}

.now:focus-visible {
    outline: 2px solid #000;
    outline-offset: -4px;
}

/* Появление и уход (классы ставит js/status.js) */
.now.is-entering { animation: now-in 0.45s var(--spring) both; }
.now.is-leaving  { animation: now-out 0.25s ease both; }

@keyframes now-in {
    from { opacity: 0; transform: translateY(6px) scale(0.94); }
}

@keyframes now-out {
    to { opacity: 0; transform: translateY(4px) scale(0.96); }
}

/* Обложка под зелёной дымкой, по центру — значок Spotify */
.now__art {
    position: relative;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    overflow: hidden;
    border-radius: 4px;
    background: #121212;
}

.now__art::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(30, 215, 96, 0.38);
}

.now__cover {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.now__cover:not([src]) {
    visibility: hidden; /* обложки нет — остаётся тёмная плитка со значком */
}

.now__icon {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 1;
}

.now__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.now__label {
    color: rgba(0, 0, 0, 0.5);
    white-space: nowrap;
}

/* Трек печатается; не влезает — многоточие (целиком — в подсказке и по ссылке) */
.now__track {
    overflow: hidden;
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.now__eq {
    flex-shrink: 0;
}

/* Палочки растут снизу вверх: видна часть линии длиной с «высоту» (dasharray),
   так круглые концы остаются круглыми. В покое — высоты из макета: 12, 7.2 и 10.2. */
.now__bar {
    animation: now-bar 0.9s ease-in-out infinite alternate;
}

.now__bar:nth-child(1) { stroke-dasharray: 12 24;  animation-duration: 0.9s;  animation-delay: -0.2s; }
.now__bar:nth-child(2) { stroke-dasharray: 7.2 24; animation-duration: 0.7s;  animation-delay: -0.5s; }
.now__bar:nth-child(3) { stroke-dasharray: 10.2 24; animation-duration: 1.1s; animation-delay: -0.8s; }

@keyframes now-bar {
    from { stroke-dasharray: 2.5 24; }
    to   { stroke-dasharray: 12 24; }
}

@media (prefers-reduced-motion: reduce) {
    .now.is-entering { animation-name: now-fade-in; }
    .now.is-leaving  { animation-name: now-fade-out; }
    .now__bar        { animation: none; }
}

@keyframes now-fade-in  { from { opacity: 0; } }
@keyframes now-fade-out { to   { opacity: 0; } }

/* ==========================================================================
   Ссылки на соцсети
   ========================================================================== */

.links {
    display: flex;
    gap: 6px;
}

.link {
    display: flex;
    flex: 1 0 0;
    min-width: 0;
    justify-content: center;
    align-items: center;
    gap: 8px;
    height: 45px;
    padding: 9px 17px;
    box-sizing: border-box;
    border-radius: 21px;
    box-shadow: var(--gloss);
    color: white;
    font-size: 20px;
    white-space: nowrap;
    transition: filter 0.2s ease;
}

.link:hover { filter: brightness(1.15); }

.link--tg { background: var(--brand-tg); }
.link--yt { background: var(--brand-yt); }
.link--tw { background: var(--brand-tw); }

.link__icon {
    display: flex;
    align-items: center;
}

.link--yt .link__icon {
    width: 17px;
    height: 20px;
}

.divider {
    flex-shrink: 0;
    height: 1px;
    border: none;
    background: var(--divider);
}

/* ==========================================================================
   Аудиозаписи
   ========================================================================== */

.tracks {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    font-family: var(--font-text);
}

.tracks__title {
    padding-bottom: 12px;
    font-size: 20px;
    font-weight: 700;
}

.tracks__list {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-right: 16px;
    padding-bottom: calc(var(--player-height) + 12px); /* последний трек докручивается из-под плеера с запасом */
    list-style: none;
}

/* Скроллбар 4px: белый ползунок на полупрозрачной дорожке.
   Chrome/Safari — через ::-webkit-scrollbar; Firefox умеет только thin + цвета. */
@supports (-moz-appearance: none) {
    .tracks__list {
        scrollbar-width: thin;
        scrollbar-color: var(--fill) var(--track-bg);
    }
}

.tracks__list::-webkit-scrollbar       { width: 4px; }
.tracks__list::-webkit-scrollbar-track { margin: 8px 0 calc(var(--player-height) + 8px); border-radius: 999px; background: var(--track-bg); }
.tracks__list::-webkit-scrollbar-thumb { border-radius: 999px; background: var(--fill); }

/* Как в макете: у обычных треков отступов нет, а играющий «въезжает» внутрь
   подсветки — содержимое сдвигается на 10px с обеих сторон. */
.track {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 0;
    border-radius: 10px;
    cursor: pointer;
    transition: padding 0.3s var(--spring), background-color 0.3s ease;
}

.track.is-active {
    padding: 7px 10px;
    background: var(--glass);
}

.track__cover {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    border-radius: 4px;
    object-fit: cover;
    background: var(--cover-empty);
}

.track__cover--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--faint);
    font-size: 20px;
}

.track__title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    font-size: 14px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.track__duration {
    flex-shrink: 0;
    color: var(--muted);
    font-size: 13px;
}

.track__download {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding: 5.75px;      /* макет × 1.15 */
    border-radius: 4.6px;
    background: var(--chip);
    transition: background-color 0.2s ease, transform 0.15s ease;
}

.track__download img              { display: block; width: 9.2px; height: 11.5px; filter: invert(var(--icon-invert)); }
.track__download:hover,
.track.is-active .track__download { background: var(--chip-active); }
.track__download:hover img,
.track.is-active .track__download img { filter: invert(var(--chip-active-invert)); }
.track__download:active           { transform: scale(0.9); }

.tracks__empty {
    padding: 7px 0;
    color: var(--muted);
    font-size: 14px;
}

/* ==========================================================================
   Мини-плеер (стеклянная полоса внизу правой колонки)
   ========================================================================== */

.player {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 16px;
    height: var(--player-height);
    padding: 8px 37px;
    box-sizing: border-box;
    background: var(--player-glass);
    backdrop-filter: blur(40px) saturate(1.4);
    -webkit-backdrop-filter: blur(40px) saturate(1.4);
    font-family: var(--font-text);
}

.player[hidden] {
    display: none;
}

.player__play {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 16px;
    background: var(--play-bg);
    cursor: pointer;
    transition: transform 0.15s ease;
}

.player__play:active { transform: scale(0.9); }

.player__play img,
.player__play svg { filter: invert(var(--icon-invert)); } /* белые иконки на белой кнопке в тёмной теме */

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

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

.player__title {
    overflow: hidden;
    font-family: var(--font);
    font-size: 14px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.player__row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.player__time {
    flex-shrink: 0;
    color: var(--faint);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

/* Дорожка 4px, но зона клика больше — удобно попадать */
.player__progress {
    position: relative;
    flex: 1;
    height: 4px;
    border-radius: 999px;
    background: var(--track-bg);
    cursor: pointer;
    touch-action: none;
}

.player__progress::before {
    content: "";
    position: absolute;
    inset: -8px 0;
}

.player__progress-fill {
    width: 0;
    height: 100%;
    border-radius: 999px;
    background: var(--fill);
}

/* Громкость: вертикальная «таблетка», заполнение снизу.
   Уровень (0..1) задаёт скрипт через --volume. Белая заливка поднимается снизу и работает
   как маска для иконки: под уровнем иконка чёрная, выше — светлая. На 100% — вся чёрная. */
.player__volume {
    --volume: 0.22;

    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    flex-shrink: 0;
    width: 43px;
    height: 100%;
    overflow: hidden;
    border-radius: 20px;
    background: var(--track-bg);
    cursor: ns-resize;
    touch-action: none;
}

.player__volume-fill {
    height: calc(var(--volume) * 100%);
    background: var(--fill);
}

/* Две копии иконки: светлая снизу и чёрная сверху, обрезанная по уровню громкости */
.player__volume-icon {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
}

.player__volume-icon img {
    position: absolute;
    top: 13px;
    left: 13px;
}

.player__volume-icon--base {
    opacity: 0.3;
}

.player__volume-icon--base img { filter: invert(var(--icon-invert)); }
html[data-theme="dark"] .player__volume-icon--base { opacity: 0.5; }

.player__volume-mask {
    clip-path: inset(calc((1 - var(--volume)) * 100%) 0 0 0);
}

/* ==========================================================================
   Тёмная тема: фон и переключатель
   ========================================================================== */

/* Ночное видео лежит поверх дневного и проявляется при тёмной теме.
   Пока оно грузится, за ним тёмный фон, а не вспышка дня. */
.bg-video--night {
    background: #151617;
    opacity: 0;
    transition: opacity 0.8s ease;
}

html[data-theme="dark"] .bg-video--night {
    opacity: 1;
}

/* Переключатель (порт SquishSwitch): ползунок едет на пружине, растягивается по ходу
   движения и чуть раздувается под курсором — transform ставит js/theme.js покадрово. */
.theme-switch {
    /* В тон теме: светлая тема — светлая дорожка, тёмная тема — тёмная */
    --ss-track: #f5f5f5;
    --ss-track-on: #27272a;
    --ss-thumb: #27272a;
    --ss-thumb-on: #f5f5f5;

    position: fixed;
    right: 30px;
    bottom: 30px;
    z-index: 20;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
}

.theme-switch__track {
    position: relative;
    display: block;
    width: 76px;
    height: 38px;
    border-radius: 19px;
    background: var(--ss-track);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18), inset 0 0 0 1px rgba(0, 0, 0, 0.06);
    transition: background-color 320ms ease, box-shadow 320ms ease;
}

.theme-switch__thumb {
    position: absolute;
    top: 4px;
    left: 0;
    width: 30px;
    height: 30px;
    border-radius: 15px;
    background: var(--ss-thumb);
    transform: translateX(4px);
    will-change: transform;
    transition: background-color 320ms ease;
}

.theme-switch[aria-checked="true"] .theme-switch__track { background: var(--ss-track-on); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35), inset 0 0 0 1px rgba(255, 255, 255, 0.14); }
.theme-switch[aria-checked="true"] .theme-switch__thumb { background: var(--ss-thumb-on); }

.theme-switch:focus-visible .theme-switch__track {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* ==========================================================================
   404 (404.php + js/notfound.js)
   Видео-фон ужат до квадрата по центру, карточка спрятана.
   Клик по квадрату: .nf-open — вырез раскрывается на весь экран, надписи тают;
   .nf-revealed — проявляется карточка. Потом классы снимаются и это обычная главная.
   ========================================================================== */

:root {
    --nf-bg: #eaeaea;
    --nf-title: #272727;
    --nf-code: rgba(0, 0, 0, 0.4);
    --nf-muted: rgba(0, 0, 0, 0.5);
    --nf-border: rgba(255, 255, 255, 0.5);

    --nf-head: 158px;  /* «404» + подпись + отступ до квадрата */
    --nf-radius: 64px;
    --nf-size: min(540px, calc(100vw - 32px), calc(100vh - var(--nf-head) - 48px));
    --nf-top: calc(50vh - (var(--nf-head) + var(--nf-size)) / 2 + var(--nf-head)); /* верх квадрата */
    --nf-left: calc(50vw - var(--nf-size) / 2);
    --nf-ease: cubic-bezier(0.65, 0, 0.35, 1);
}

html[data-theme="dark"] {
    --nf-bg: #161616;
    --nf-title: #c7c7c7;
    --nf-code: rgba(255, 255, 255, 0.4);
    --nf-muted: rgba(255, 255, 255, 0.5);
    --nf-border: rgba(0, 0, 0, 0.5);
}

/* Фон 404 — на <html>, а не на <body>: фон body рисуется поверх видео с z-index: -1,
   а фон корня — под ним */
html:has(body.is-404) {
    background-color: var(--nf-bg);
}

/* Видео само размером с квадрат (кадр вписан целиком, как в макете) и при раскрытии
   растягивается до экрана. Конечные значения = обычные у .bg-video — после снятия
   режима 404 ничего не прыгает. */
body.is-404 .bg-video {
    top: var(--nf-top);
    left: var(--nf-left);
    width: var(--nf-size);
    height: var(--nf-size);
    border-radius: var(--nf-radius);
    transition:
        top 0.9s var(--nf-ease),
        left 0.9s var(--nf-ease),
        width 0.9s var(--nf-ease),
        height 0.9s var(--nf-ease),
        border-radius 0.9s var(--nf-ease),
        transform 0.5s var(--spring),
        opacity 0.8s ease;
}

body.is-404.nf-open .bg-video {
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    border-radius: 0;
}

.nf {
    position: fixed;
    top: calc(var(--nf-top) - var(--nf-head));
    left: var(--nf-left);
    z-index: 5;
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: var(--nf-size);
    transition: opacity 0.5s ease, filter 0.5s ease, transform 0.5s ease;
}

.nf__head {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 16px;
    height: calc(var(--nf-head) - 16px);
}

.nf__title {
    color: var(--nf-title);
    font-family: var(--font-text);
    font-size: 128px;
    font-weight: 500;
    line-height: 0.77;
    transition: color var(--theme-fade);
}

.nf__code {
    color: var(--nf-code);
    font-family: var(--font);
    font-size: 20px;
    font-weight: 400;
}

.nf__text {
    color: var(--nf-muted);
    font-family: var(--font-text);
    font-size: 20px;
    font-weight: 500;
}

.nf__window {
    width: var(--nf-size);
    height: var(--nf-size);
    padding: 0;
    border: 3px solid var(--nf-border);
    border-radius: var(--nf-radius);
    background: transparent;
    cursor: pointer;
    outline: none;
    transition: transform 0.5s var(--spring);
    -webkit-tap-highlight-color: transparent;
}

/* Наведение: квадрат вместе с видео чуть «подаётся» навстречу — без обводок и теней,
   одинаково хорошо в обеих темах. Видео — отдельный слой, поэтому масштабируем оба. */
.nf__window:hover,
.nf__window:focus-visible,
body.is-404:not(.nf-open):has(.nf__window:hover) .bg-video,
body.is-404:not(.nf-open):has(.nf__window:focus-visible) .bg-video {
    transform: scale(1.02);
}

/* Пока 404 — карточки и переключателя темы не видно */
body.is-404 .main {
    opacity: 0;
    filter: blur(14px);
    transform: translateY(16px) scale(0.94);
    pointer-events: none;
    transition:
        opacity 0.8s ease,
        filter 0.8s ease,
        transform 0.9s var(--spring);
}

body.is-404 .theme-switch {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.6s ease;
}

/* Раскрытие: надписи тают, квадрат-рамка уходит вместе с ними */
body.nf-open .nf {
    opacity: 0;
    filter: blur(10px);
    transform: scale(0.98);
    pointer-events: none;
}

/* Карточка проявляется из блюра и «всплывает» */
body.nf-revealed .main {
    opacity: 1;
    filter: none;
    transform: none;
    pointer-events: auto;
}

body.nf-revealed .theme-switch {
    opacity: 1;
    pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
    body.is-404 .bg-video,
    body.is-404 .main,
    .nf {
        transition: opacity 0.3s ease;
    }
}

/* ==========================================================================
   Пасхалка для экранов шире 4320px (8K)
   ========================================================================== */

.sosal {
    display: none;
    flex-direction: column;
    padding: 100px 200px;
    border: 16px solid rgba(255, 255, 255, 0.2);
    border-radius: 100px;
    background-color: rgba(255, 255, 255, 0.226);
    backdrop-filter: blur(50px);
    -webkit-backdrop-filter: blur(50px);
    color: white;
    text-align: center;
    font-weight: 600;
}

.sosal .top    { font-size: 350px; }
.sosal .bottom { font-size: 80px; font-weight: 300; }

@media screen and (min-width: 4320px) {
    .main  { display: none; }
    .sosal { display: flex; }
}
