/* ==========================================================================
   Ponder на вебе — прототип

   Грамматика взята из исходников Create (infrastructure/ponder/scenes):
     showBasePlate()            — клетчатая платформа под сценой
     showSection(sel, UP)       — блоки влетают с направления, тактами
     chaseBoundingBoxOutline()  — цветная рамка вокруг детали
     showText().pointAt()       — подпись с линией-выноской к блоку
     markKeyframe()             — глава, по которой можно листать
   ========================================================================== */

.pd {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 10;
    background:
        radial-gradient(70% 60% at 50% 45%, #1a1626 0%, #0b0910 70%, #07060a 100%);
    border: 1px solid rgba(242, 238, 248, 0.10);
    border-radius: 6px;
    overflow: hidden;
    font-family: 'Space Grotesk', system-ui, sans-serif;
    user-select: none;
}

/* Виньетка — в Ponder сцена всегда «в коробке» */
.pd::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    box-shadow: inset 0 0 120px rgba(0, 0, 0, 0.75);
}

/* --- Заголовок сцены ---------------------------------------------------- */
.pd-head {
    position: absolute;
    top: 18px;
    left: 22px;
    z-index: 8;
}

.pd-kicker {
    font-family: 'Press Start 2P', monospace;
    font-size: 8px;
    letter-spacing: 0.18em;
    color: #7c6bb0;
    display: block;
    margin-bottom: 8px;
}

.pd-title {
    font-family: 'Syne', sans-serif;
    font-weight: 800;
    font-size: clamp(1.1rem, 2vw, 1.75rem);
    letter-spacing: -0.02em;
    color: #fff;
    margin: 0;
    line-height: 1.05;
}

/* --- Сцена -------------------------------------------------------------- */
.pd-stage {
    position: absolute;
    inset: 0;
    perspective: 1400px;
    perspective-origin: 50% 46%;
}

.pd-cam {
    position: absolute;
    inset: 0;
    transform-style: preserve-3d;
    transform:
        scale(var(--zoom, 1))
        rotateX(calc(var(--cx, -24) * 1deg))
        rotateY(calc(var(--cy, 32) * 1deg))
        /* сдвиг сцены, чтобы подвести к камере нужную деталь */
        translate3d(calc(var(--px, 0) * 1px),
                    calc(var(--py, 0) * 1px),
                    calc(var(--pz, 0) * 1px));
    transition: transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* --- Платформа ----------------------------------------------------------
   В Ponder это клетчатая плита, на которой стоит демонстрация.
   Здесь — сетка плоских квадратов в плоскости XZ.                         */
.pd-plate {
    position: absolute;
    top: 50%;
    left: 50%;
    transform-style: preserve-3d;
    transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--plate-y, 130) * -1px));
    opacity: 0;
    transition: opacity 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

.pd.is-plate .pd-plate { opacity: 1; }

.pd-tile {
    position: absolute;
    width: var(--t, 44px);
    height: var(--t, 44px);
    margin: calc(var(--t, 44px) / -2);
    background: #2b2735;
    outline: 1px solid rgba(0, 0, 0, 0.4);
    outline-offset: -1px;
}

.pd-tile.alt { background: #241f2e; }

/* Плитка с текстурой блока: плита рисуется плоской, а не 81 кубом */
.pd-tile--tex {
    background-size: 100% 100%;
    image-rendering: pixelated;
}

/* --- Блок --------------------------------------------------------------- */
.pd-voxel {
    --s: 44px;
    --h: 22px;
    /* Габариты блока. По умолчанию куб, но плита и столб их переопределяют. */
    --sx: var(--s);
    --sy: var(--s);
    --sz: var(--s);
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--s);
    height: var(--s);
    margin: calc(var(--s) / -2);
    transform-style: preserve-3d;
    transform:
        translate3d(calc(var(--x, 0) * 1px), calc(var(--y, 0) * 1px), calc(var(--z, 0) * 1px));
    opacity: 0;
    transition: transform 620ms cubic-bezier(0.22, 1, 0.36, 1),
                opacity 320ms linear;
}

.pd-voxel.is-in { opacity: 1; }

/*
 * Грани считаем от центра блока и размеряем по --sx/--sy/--sz,
 * иначе плита и столб растянулись бы до размеров полного куба.
 */
.pd-face {
    position: absolute;
    left: 50%;
    top: 50%;
    background-image: var(--tex);
    background-size: 100% 100%;
    image-rendering: pixelated;
    outline: 1px solid rgba(0, 0, 0, 0.45);
    outline-offset: -1px;
    /* Грани смотрят наружу, поэтому задние можно не рисовать вовсе:
       на живой странице это ровно вдвое поднимает частоту кадров. */
    backface-visibility: hidden;
}

.pd-face.f, .pd-face.bk {
    width: var(--sx); height: var(--sy);
    margin: calc(var(--sy) / -2) 0 0 calc(var(--sx) / -2);
}
.pd-face.r, .pd-face.l {
    width: var(--sz); height: var(--sy);
    margin: calc(var(--sy) / -2) 0 0 calc(var(--sz) / -2);
}
.pd-face.t, .pd-face.bt {
    width: var(--sx); height: var(--sz);
    margin: calc(var(--sz) / -2) 0 0 calc(var(--sx) / -2);
}

.pd-face.f  { transform: translateZ(calc(var(--sz) / 2)); background-image: linear-gradient(rgba(0, 0, 0, 0.258), rgba(0, 0, 0, 0.258)), var(--tex); }
.pd-face.bk { transform: rotateY(180deg) translateZ(calc(var(--sz) / 2)); background-image: linear-gradient(rgba(0, 0, 0, 0.484), rgba(0, 0, 0, 0.484)), var(--tex); }
.pd-face.r  { transform: rotateY(90deg)  translateZ(calc(var(--sx) / 2)); background-image: linear-gradient(rgba(0, 0, 0, 0.371), rgba(0, 0, 0, 0.371)), var(--tex); }
.pd-face.l  { transform: rotateY(-90deg) translateZ(calc(var(--sx) / 2)); background-image: linear-gradient(rgba(0, 0, 0, 0.371), rgba(0, 0, 0, 0.371)), var(--tex); }
.pd-face.t  { transform: rotateX(90deg)  translateZ(calc(var(--sy) / 2));  }
.pd-face.bt { transform: rotateX(-90deg) translateZ(calc(var(--sy) / 2)); background-image: linear-gradient(rgba(0, 0, 0, 0.661), rgba(0, 0, 0, 0.661)), var(--tex); }

/* Коробка модели: точка без размеров, грани разбегаются от её центра */
.pd-el, .pd-turn {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 0;
    height: 0;
    transform-style: preserve-3d;
}

/* У мелких деталей модели контур съедает саму деталь */
.pd-face--el {
    outline: none;
    background-repeat: no-repeat;
}

/* Пропеллер крутится вокруг вала — отдельная обёртка, чтобы не спорить
   с translate3d самого вокселя. */
.pd-spin {
    position: absolute;
    inset: 0;
    transform-style: preserve-3d;
}
/* Ось вращения задаёт сама деталь: она крутится вокруг оси СВОЕЙ модели,
   уже после доворота под ориентацию блока. */
.pd-voxel.is-in .pd-spin[data-axis="x"] { animation: pdSpinX 900ms linear infinite; }
.pd-voxel.is-in .pd-spin[data-axis="y"] { animation: pdSpinY 900ms linear infinite; }
.pd-voxel.is-in .pd-spin[data-axis="z"] { animation: pdSpinZ 900ms linear infinite; }

@keyframes pdSpinX { to { transform: rotateX(360deg); } }
@keyframes pdSpinY { to { transform: rotateY(360deg); } }
@keyframes pdSpinZ { to { transform: rotateZ(360deg); } }

/* Пламя горелки */
.pd-flame {
    position: absolute;
    left: 50%; top: 50%;
    width: calc(var(--s) * 0.34);
    height: calc(var(--s) * 0.7);
    margin: calc(var(--s) * -0.9) 0 0 calc(var(--s) * -0.17);
    border-radius: 50% 50% 46% 46%;
    background: linear-gradient(to top, #ffd700, #ff8a3d 55%, rgba(255, 120, 60, 0));
    filter: blur(0.5px);
    animation: pdFlame 620ms cubic-bezier(0.45, 0, 0.55, 1) infinite alternate;
}
@keyframes pdFlame {
    from { transform: scaleY(0.72) scaleX(1.05); opacity: 0.75; }
    to   { transform: scaleY(1.12) scaleX(0.9);  opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .pd-voxel.is-in .pd-spin, .pd-flame { animation: none; }
}

/* --- Рамка выделения ----------------------------------------------------
   chaseBoundingBoxOutline: каркас вокруг детали, о которой идёт речь.     */
.pd-outline {
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--s, 52px);
    height: var(--s, 52px);
    margin: calc(var(--s, 52px) / -2);
    transform-style: preserve-3d;
    transform: translate3d(calc(var(--x, 0) * 1px), calc(var(--y, 0) * 1px), calc(var(--z, 0) * 1px));
    opacity: 0;
    transition: opacity 300ms linear;
    pointer-events: none;
}

.pd-outline.is-on { opacity: 1; }

.pd-outline > i {
    position: absolute;
    inset: 0;
    border: 2px solid var(--oc, #6ee7a8);
    box-shadow: 0 0 14px var(--oc, #6ee7a8);
}

.pd-outline > i.f  { transform: translateZ(calc(var(--s, 52px) / 2)); }
.pd-outline > i.bk { transform: rotateY(180deg) translateZ(calc(var(--s, 52px) / 2)); }
.pd-outline > i.r  { transform: rotateY(90deg)  translateZ(calc(var(--s, 52px) / 2)); }
.pd-outline > i.l  { transform: rotateY(-90deg) translateZ(calc(var(--s, 52px) / 2)); }

/* --- Подпись с выноской -------------------------------------------------- */
.pd-caption {
    position: absolute;
    z-index: 9;
    max-width: 290px;
    padding: 12px 14px;
    background: rgba(14, 12, 20, 0.95);
    border: 1px solid rgba(242, 238, 248, 0.14);
    border-left: 3px solid var(--cc, #6ee7a8);
    border-radius: 3px;
    color: #efeaf5;
    font-size: 0.9rem;
    line-height: 1.45;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 420ms cubic-bezier(0.22, 1, 0.36, 1),
                transform 420ms cubic-bezier(0.22, 1, 0.36, 1);
    pointer-events: none;
}

.pd-caption.is-on { opacity: 1; transform: none; }

/* Заголовок главы. Свой класс, иначе <b> внутри текста ловит этот же
   стиль и акцент выпадает отдельной строкой. */
/* Не пиксельным шрифтом: в Press Start 2P нет кириллицы, и «ОБОЛОЧКА»
   вываливалась в засечный фолбэк. */
.pd-caption .pd-ch {
    display: block;
    font-family: 'Space Grotesk', system-ui, sans-serif;
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--cc, #6ee7a8);
    margin-bottom: 9px;
}

.pd-caption b { font-weight: 600; color: #fff; }

/* Линия-выноска рисуется в SVG поверх сцены */
.pd-leader {
    position: absolute;
    inset: 0;
    z-index: 8;
    pointer-events: none;
}

.pd-leader line {
    stroke: var(--cc, #6ee7a8);
    stroke-width: 1.5;
    stroke-dasharray: 4 3;
    opacity: 0;
    transition: opacity 320ms linear;
}

.pd-leader.is-on line { opacity: 0.8; }

.pd-leader circle {
    fill: var(--cc, #6ee7a8);
    opacity: 0;
    transition: opacity 320ms linear;
}

.pd-leader.is-on circle { opacity: 1; }

/* --- Панель глав --------------------------------------------------------- */
.pd-bar {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 18px;
    background: linear-gradient(180deg, transparent, rgba(7, 6, 10, 0.92) 46%);
}

.pd-btn {
    flex: none;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border: 1px solid rgba(242, 238, 248, 0.18);
    border-radius: 3px;
    background: rgba(20, 17, 28, 0.9);
    color: #efeaf5;
    font-size: 12px;
    cursor: pointer;
    transition: all 180ms cubic-bezier(0.25, 1, 0.5, 1);
}

.pd-btn:hover { border-color: #ffd700; color: #ffd700; }

.pd-track {
    position: relative;
    flex: 1;
    height: 3px;
    background: rgba(242, 238, 248, 0.12);
}

.pd-fill {
    position: absolute;
    inset: 0 auto 0 0;
    width: 0;
    background: #ffd700;
    transition: width 200ms linear;
}

/* Ромбы-главы, как в шкале Ponder */
.pd-key {
    position: absolute;
    top: 50%;
    width: 9px;
    height: 9px;
    margin: -4.5px 0 0 -4.5px;
    background: #4a4360;
    rotate: 45deg;
    cursor: pointer;
    transition: background 220ms linear, scale 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.pd-key:hover { scale: 1.25; }
.pd-key.is-done { background: #ffd700; }
.pd-key.is-now { background: #fff; scale: 1.3; }

.pd-chapter {
    flex: none;
    font-family: 'Press Start 2P', monospace;
    font-size: 8px;
    letter-spacing: 0.1em;
    color: #8f83b8;
    min-width: 54px;
    text-align: right;
}

@media (prefers-reduced-motion: reduce) {
    .pd-cam, .pd-voxel, .pd-caption { transition: none; }
}


/* ==========================================================================
   Режим прокрутки на сайте

   Секция выше окна на несколько экранов, сцена внутри липкая: пока
   секция проходит мимо, главы сменяют друг друга. Кнопки в этом
   режиме лишние — шкала работает указателем.
   ========================================================================== */
.pd-scroll {
    --pd-steps: 6;
    position: relative;
    height: calc(100vh + var(--pd-steps) * 62vh);
}

.pd-sticky {
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    align-items: center;
}

/* Ширину ведём от доступной высоты, чтобы сцена целиком влезала в экран */
.pd-sticky .pd-hold {
    width: min(1160px, calc(78vh * 1.6));
    margin-inline: auto;
    padding-inline: 16px;
}

.pd.is-scroll .pd-btn { display: none; }
.pd.is-scroll .pd-key { pointer-events: none; }
.pd.is-scroll .pd-bar { gap: 18px; }

@media (max-width: 767px) {
    .pd-scroll { height: calc(100vh + var(--pd-steps) * 48vh); }
    .pd-sticky .pd-hold { width: 100%; }

    /* Кадр 16:10 на телефоне слишком низкий: постройка в него не влезает */
    .pd { aspect-ratio: 3 / 4; }
    .pd-caption { max-width: none; }
    .pd-head { top: 12px; left: 14px; }
}
