/* ==========================================================================
   Марго Квиз — Design System v2 «Неон-сцена»
   choreo.css — ХОРЕОГРАФИЯ ЭКРАНОВ. Стадия 05, пара к choreo.js.

   Требует: motion.css (длительности, изинги, библиотека кадров),
   components.css (предметы, которые здесь двигаются).

   ГРАНИЦА С motion.css ПРОВЕДЕНА ТАК: общий кадр — вход, уход, пульс,
   такт — живёт в библиотеке и называется mk-enter-*, mk-exit-*, mk-tick.
   Сюда уезжает только то, что бессмысленно вне своего экрана: как именно
   раскрывается верный ответ, как ведёт себя колонка Марго в паузе, чем
   отличается конфетти подиума от конфетти тоста.

   ГРАНИЦА С components.css: там ВИД предмета во всех состояниях, здесь —
   КОГДА он переходит из состояния в состояние. Правило то же, что и на
   стадии 03: один класс объявляется в одном файле.
   ========================================================================== */

/* ==========================================================================
   Такт — общий (9 · последние секунды, 7 · счётчик, 4 · нажатие)
   ========================================================================== */

/* Однократный такт, который вешает choreo.js. Именно однократный: пульс
   привязан к событию секунды, а не к бесконечному циклу, — иначе за пять
   секунд цикл уезжает от цифры на пол-такта и живёт своей жизнью. */
.mk-tick-now { animation: mk-tick var(--dur-sm) var(--ease-spring) both; }

/* ==========================================================================
   5 · Раскрытие верного ответа
   ========================================================================== */

/* Раскрытие играет ТОЛЬКО когда каскад окончен: пока право хода может уйти
   следующей команде, ответ на экране — подсказка. Движение поэтому не
   «появление», а «признание»: вариант уже стоял в кадре, он вспыхивает
   и остаётся. Вспышка — отдельный слой с opacity, а не анимация тени. */
.mk-reveal { animation: mk-pop var(--dur-md) var(--ease-spring) both; }

.mk-option--correct { position: relative; }

/* Свечение ВНУТРЬ, а не наружу: сам вариант ответа клипует содержимое
   (у него overflow: hidden ради дорожки доли голосов), и внешний ореол
   срезался бы своей же рамкой — плюс два пикселя переполнения, которые
   исправно ловит проверка раскладки. Вариант загорается изнутри, и для
   «правильного ответа» это читается даже лучше внешнего ореола. */
.mk-option--correct::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: inset 0 0 60px var(--ok-glow);
    opacity: 0;
    pointer-events: none;
}

.mk-reveal::after { animation: mk-flash var(--dur-xl) var(--ease-out) both; }

/* ==========================================================================
   8 · Смена лидера
   ========================================================================== */

/* Отдельный момент, а не побочный эффект пересборки. Играет ПОСЛЕ того, как
   строки встали на места: подсветка, едущая вместе со строкой, теряется.
   Золото уже принадлежит первому месту (предмет 6) — здесь только вспышка,
   которая говорит «место сменилось именно сейчас». */
.mk-lead { animation: mk-pop var(--dur-md) var(--ease-spring) both; }

.mk-scoreboard-row { position: relative; }

.mk-scoreboard-row::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: 0 0 60px var(--gold);
    opacity: 0;
    pointer-events: none;
}

.mk-lead::before { animation: mk-flash var(--dur-xl) var(--ease-out) both; }

/* ==========================================================================
   10 · Подиум
   ========================================================================== */

/* Снизу вверх: третье, второе, первое. Порядок задан переменной --i,
   которую ставит choreo.js, — DOM остаётся в порядке мест, а появление
   идёт обратным. Цепочки таймеров нет: лестница считается в CSS. */
.mk-podium--show .mk-podium-place {
    animation: mk-enter-up var(--dur-md) var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 70ms);
}

/* Первое место приходит последним и приходит иначе: не выезжает снизу,
   а вырастает. Разница в движении — это и есть разница в месте. */
.mk-podium--show .mk-podium-place--1 {
    animation-name: mk-pop;
    animation-duration: var(--dur-lg);
    animation-timing-function: var(--ease-spring);
}

/* Корона садится на голову позже самой платформы — иначе она приезжает
   вместе с ней и читается как часть плитки, а не как награда. */
.mk-podium--show .mk-podium-place__crown {
    animation: mk-enter-down var(--dur-md) var(--ease-spring) both;
    animation-delay: calc(var(--i, 0) * 70ms + var(--dur-md));
}

/* Движение выключено: подиум обязан всё равно СТОЯТЬ, а не отсутствовать. */
.mk-podium--shown .mk-podium-place { animation: none; opacity: 1; }

/* ==========================================================================
   10 · 11 · Конфетти
   ========================================================================== */

/* Слой поверх кадра, не перехватывает клики и не участвует в раскладке.
   Частица — один <i> с тремя переменными; кадр один на всех (mk-confetti
   в motion.css). Только transform и opacity: частиц на подиуме до сотни,
   и рисует их тот же ноутбук, на котором крутится админка. */
.mk-confetti {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 4;
}

.mk-confetti i {
    --mk-conf: 14px;
    position: absolute;
    top: -40px;
    width: var(--mk-conf);
    height: calc(var(--mk-conf) * 0.42);
    border-radius: 2px;
    background: var(--emotion-soft);
    animation: mk-confetti 2.4s var(--ease-in) both;
    will-change: transform;
}

/* Три цвета вместо одного: одноцветное конфетти читается как помеха,
   а не как праздник. Цвета не новые — золото, серебро, бронза подиума. */
.mk-confetti i:nth-child(3n)   { background: var(--gold); }
.mk-confetti i:nth-child(3n+1) { background: var(--silver); }

/* Тост: то же конфетти, но редкое и медленное, бесконечным циклом.
   Финал держит внимание минуту — эффект входа здесь мёртв через десять
   секунд, а медленный цикл живёт столько, сколько говорит Марго. */
.mk-confetti--slow i {
    --mk-conf: 10px;
    opacity: 0.75;
    animation-timing-function: linear;
}

/* ==========================================================================
   11 · Тост
   ========================================================================== */

/* Лучи занавеса уже описаны в hall.css (решение владельца 23.08, вариант C).
   Здесь только то, что превращает их из фона в живой кадр: медленное
   парение всей группы. Период намеренно не совпадает с периодом лучей —
   совпадающие периоды складываются в один пульс, и кадр начинает мигать. */
.mk-toast-view--live .mk-toast-view__bg {
    animation: mk-float 11s var(--ease-inout) infinite;
}

.mk-toast-view--live .mk-toast-view__text {
    animation: mk-enter-up var(--dur-xl) var(--ease-out) both;
}

/* ==========================================================================
   13 · Марго думает
   ========================================================================== */

/* Пауза между «оператор нажал» и «Марго заговорила» реальная. Движение
   живёт В КОЛОНКЕ, а не в слоте экрана: вопрос в этот момент читают,
   и отнимать у него внимание нельзя. Орб дышит вдвое чаще обычного —
   этого достаточно, чтобы кадр не выглядел зависшим. */
.mk-margo--thinking .mk-orb { animation-duration: 2.2s; }
.mk-margo--thinking .mk-orb::after { animation-duration: 2.2s; }

/* Субтитр в паузе не пустой: три точки на месте будущей реплики. Пустая
   панель в кадре читается как «связь отвалилась», а не как «идёт работа». */
.mk-margo--thinking .mk-margo-sub { color: var(--text-dim); }

/* Озвучка не сработала — остаётся субтитр. Отдельного движения здесь нет
   намеренно: зал не должен понять, что это отказ. Панель просто живёт
   дольше обычного, а хореография отрабатывает ровно так же. */

/* МАРГО ГОВОРИТ — добавлено переносом зала 24.08. Приём тот же, что у «думает»,
   и стоит здесь по той же причине: когда виземы или анализатор звука
   не поднялись — а в зале это происходит регулярно, — зал обязан всё равно
   видеть, что говорит ОНА, а не колонки. В старом зале эту роль играл пульс
   box-shadow на всей колонке (viewer/style.css, .margo-column.speaking);
   переносить его нельзя: анимация тени перерисовывает размытое пятно каждый
   кадр. Здесь учащается такт того же свечения, то есть opacity. */
.mk-margo--speaking .mk-margo-glow { animation-duration: 2.4s; }
.mk-margo--speaking .mk-orb { animation-duration: 2.4s; }
.mk-margo--speaking .mk-orb::after { animation-duration: 2.4s; }

/* ==========================================================================
   Выключенное движение
   ========================================================================== */

/* Блок [data-motion="off"] в motion.css гасит CSS-анимации; скриптовые
   шаги хореографии спрашивают motionOff() сами. Здесь — то, что должно
   остаться ВИДИМЫМ при выключенном движении: элементы, у которых
   единственное состояние «после анимации» задаётся самой анимацией. */
[data-motion="off"] .mk-confetti { display: none; }
[data-motion="off"] .mk-podium--show .mk-podium-place,
[data-motion="off"] .mk-podium--show .mk-podium-place__crown { opacity: 1; }
