/* ── конверт: шесть граней ────────────────────────────────────── */

.vinyl {
    user-select: none;

    width: var(--vinyl-size);
    height: var(--vinyl-thickness);

    position: relative;

    transform-style: preserve-3d;
    transition: transform var(--dur-base) var(--ease-out);
}

/* общее для всех граней. preserve-3d нужен WebKit:
   без него грань рисуется плоской картинкой, без перспективы.

   Грань, повёрнутая от камеры, у закрытой коробки всегда заслонена —
   не рисуем её вовсе. Это не мелочь: у конверта ниже центра его низ,
   у конверта выше — верх, это две обложки на каждый конверт, и с
   фильтрами (свет, размытие) они стоили треть кадра впустую. */
.vinyl__box > * {
    position: absolute;
    left: 50%;
    top: 50%;

    transform-style: preserve-3d;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    transition: opacity 520ms var(--ease-out);
}

.vinyl__frontside,
.vinyl__backside {
    width: var(--vinyl-size);
    aspect-ratio: 1;
    object-fit: cover;
    background: var(--edge);
}

.vinyl__frontside {
    transform: translate(-50%, -50%)
               rotateX(90deg)
               translateZ(var(--vinyl-half-thickness));
}

.vinyl__backside {
    transform: translate(-50%, -50%)
               rotateX(-90deg)
               translateZ(var(--vinyl-half-thickness));
}

/* Свет от лампы в камере и размытие по граням: насколько притушить и
   размыть грань, считает ShelfScroller (lighting.js) и пишет в
   переменные слота. Фильтр — на плоских гранях: на слоте или коробке
   он сделал бы transform-style: flat и схлопнул бы 3D. На обложку
   (<img>) псевдоэлемент-затемнение не повесить — поэтому brightness. */
.vinyl__frontside { filter: brightness(var(--lit-front, 1)) var(--face-blur,); }
.vinyl__backside  { filter: brightness(var(--lit-back, 1)) var(--face-blur,); }
.vinyl__side      { filter: brightness(var(--lit-side, 1)) var(--face-blur,); }

.vinyl__side {
    width: var(--vinyl-size);
    height: var(--vinyl-thickness);
    /* без этого флекс-детей нельзя ужать меньше их содержимого */
    min-width: 0;

    display: flex;
    justify-content: center;
    align-items: center;
    gap: calc(var(--vinyl-thickness) * 0.8);
    padding-inline: calc(var(--vinyl-thickness) * 0.6);

    /* Подпись привязана к ТОЛЩИНЕ корешка, а не к размеру страницы:
       корешок тонкий по определению, и текст в 16px вылезал из него. */
    font-size: calc(var(--vinyl-thickness) * 0.78);
    line-height: 1;

    transform: translate(-50%, -50%)
               translateZ(calc(var(--vinyl-size) / 2));

    /* Цвет приходит из обложки; откат — нейтральный из темы. Поверх —
       картон под лампой (сила — от настройки «Освещение»):
        - концы корешка дальше от лампы, чем середина, — темнее;
        - ребро, обращённое к свету, светлее, дальнее — темнее;
        - на самих рёбрах — блик в 1px и тень: так край ловит свет.
       Это не padding: padding прозрачный и залит тем же фоном. */
    --shade: calc(var(--lighting, .7) * .32);
    --glow: calc(var(--lighting, .7) * .16);
    background:
        linear-gradient(to right, rgb(0 0 0 / var(--shade)), transparent 22% 78%, rgb(0 0 0 / var(--shade))),
        linear-gradient(to bottom, rgb(255 255 255 / var(--glow)), transparent 45%, rgb(0 0 0 / var(--shade))),
        var(--spine, var(--spine-fallback));
    box-shadow:
        inset 0 1px rgb(255 255 255 / calc(var(--glow) * 1.6)),
        inset 0 -1px rgb(0 0 0 / calc(var(--shade) * 1.4));
    color: var(--spine-text, var(--spine-text-fallback));
}

/* Конверт выше центра: лампа под ним — свет приходит на нижнее ребро */
.slot--above .vinyl__side {
    background:
        linear-gradient(to right, rgb(0 0 0 / var(--shade)), transparent 22% 78%, rgb(0 0 0 / var(--shade))),
        linear-gradient(to top, rgb(255 255 255 / var(--glow)), transparent 45%, rgb(0 0 0 / var(--shade))),
        var(--spine, var(--spine-fallback));
    box-shadow:
        inset 0 -1px rgb(255 255 255 / calc(var(--glow) * 1.6)),
        inset 0 1px rgb(0 0 0 / calc(var(--shade) * 1.4));
}

.vinyl__side__album,
.vinyl__side__title {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.vinyl__side__album { font-weight: var(--font-weight-bold); flex: 0 1 auto; }
.vinyl__side__title { font-style: italic; font-weight: var(--font-weight-light); flex: 1 1 auto; }

/* ── коробка целиком ─────────────────────────────────────────── */
.vinyl__box {
    position: absolute;
    inset: 0;

    /* нулевая трансформация не бесполезна: она удерживает элемент
       полноценным участником 3D-контекста. Без неё грани появлялись
       только после того, как translateX им его возвращал. */
    transform: translateX(0);

    transform-style: preserve-3d;
    transition: transform var(--dur-base) var(--ease-out);
}

/* Текущий — конверт отъезжает вбок и открывает пластинку.
   0.72, а не «полностью»: при 0.92 правый край конверта оказывался
   в 1.42 ширины обложки от центра — на телефоне конверт уезжал за экран.
   Меньше 0.67 тоже нельзя: конверт начинает закрывать этикетку,
   а по этикетке и читается вращение. */
.slot--current .vinyl__box {
    transform: translateX(calc(var(--vinyl-size) * 0.72));
}

/* три недостающих ребра: дальнее и два боковых */
.vinyl__edge {
    background: var(--edge);
    transform-style: preserve-3d;
}

.vinyl__edge--far {
    width: var(--vinyl-size);
    height: var(--vinyl-thickness);
    transform: translate(-50%, -50%)
               rotateY(180deg)
               translateZ(calc(var(--vinyl-size) / 2));
}

.vinyl__edge--left,
.vinyl__edge--right {
    width: var(--vinyl-size);          /* по глубине коробки */
    height: var(--vinyl-thickness);
}
.vinyl__edge--left {
    transform: translate(-50%, -50%)
               rotateY(-90deg)
               translateZ(calc(var(--vinyl-size) / 2));
}
.vinyl__edge--right {
    transform: translate(-50%, -50%)
               rotateY(90deg)
               translateZ(calc(var(--vinyl-size) / 2));
}

/* ── пластинка ─────────────────────────────────────────────── */
.disc {
    --disc-size: calc(var(--vinyl-size) * 0.94);

    /* Пластинку рисуем ТОЛЬКО у текущего трека и у прежнего, пока он
       доигрывает уход. У остальных её нет в отрисовке вообще: браузер
       не декодирует этикетку на каждом конверте полки. */
    display: none;

    /* Пока конверт закрыт, пластинка внутри — значит её не видно.
       visibility, а не opacity: opacity меньше единицы принудительно
       делает transform-style: flat и убило бы 3D у диска. */
    visibility: hidden;
    transition: visibility 0s var(--dur-base);

    width: var(--disc-size);
    height: var(--disc-size);

    position: absolute;
    left: 50%;
    top: 50%;

    border-radius: 50%;

    /* лежит в той же плоскости, что и обложка, чуть ниже неё по толщине;
       rotateZ в конце — то есть уже в плоскости лежащей пластинки */
    transform: translate(-50%, -50%)
               rotateX(90deg)
               translateZ(calc(var(--vinyl-half-thickness) * -0.2))
               rotateZ(var(--disc-spin, 0deg));

    /* Сплошной чёрный, тонкая обводка — как палочка прогресса. */
    background: var(--disc);
    border: 1px solid var(--disc-line);

    transform-style: preserve-3d;
}

.slot--current .disc,
.slot--recent .disc { display: block; }

/* Пластинку показываем сразу, а прячем — только когда конверт доехал,
   то есть при СМЕНЕ трека; на паузе она так и остаётся снаружи.

   visibility: visible у потомка перебивает hidden родителя. Раньше это
   правило не знало ни про поиск, ни про отсечение за экраном — и диск
   играющего трека висел поверх полки, даже когда сам слот был скрыт:
   не уходил при поиске и торчал «квадратиком в углу». Теперь такие
   состояния исключены явно, и ещё — пока конверт проявляется: иначе
   при запуске пластинка «продолжить с места» висела без конверта. */
.slot--current:not(.slot--gone, .slot--hidden, .slot--culled, .slot--loading) .disc {
    visibility: visible;
    transition: visibility 0s;
}

/* этикетка по центру и отверстие */
.disc__label {
    width: 34%;
    height: 34%;

    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);

    border-radius: 50%;
    background: var(--disc-art, var(--label-fallback)) center / cover;

    /* по этикетке и читается вращение: у сплошного диска
       других подвижных деталей нет */
    box-shadow: 0 0 0 1px var(--label-line);
}
.disc__label::after {
    content: '';

    width: 9%;
    height: 9%;

    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);

    border-radius: 50%;
    background: var(--disc);
    box-shadow: 0 0 0 1px var(--label-line);
}
