/* shared/runtime/progress.css
 *
 * Единый вид полос прогресса: заполненность профиля компании, прогресс
 * уровня участника, награда за серию, надёжность пароля.
 *
 * ── Что было ──────────────────────────────────────────────────────────────
 * Каждая полоса красилась по-своему: пустая дорожка — rgba(0,0,0,.05) или
 * rgba(148,163,184,.18) (на тёмном фоне не видно вообще, полоса выглядела
 * как «прогресса нет»), заливка — то золото с #FFD700, то радужный
 * linear-gradient(plum → blue → green), собранный из фирменных цветов.
 * Ни то, ни другое не читалось как прогресс.
 *
 * ── Как сделано ───────────────────────────────────────────────────────────
 * Одна шкала на всё: нейтральный тон → золото → зелёный успех. Смысл
 * читается без подписи: начал, идёт, почти готово.
 *
 * Главное — градиент растянут на ВСЮ ширину дорожки, а не на ширину
 * заливки. Поэтому при 15% пользователь видит только начало шкалы, а
 * зелёный конец достаётся тому, кто действительно дозаполнил. Если
 * растянуть градиент по самой заливке (как делают обычно), «успешный»
 * зелёный появляется уже при 5% и мотивировать перестаёт.
 *
 * Технически: дорожка объявлена контейнером (`container-type: inline-size`),
 * и слой с градиентом внутри заливки имеет ширину `100cqw` — ровно ширину
 * дорожки. Заливка обрезает его по себе. JS для этого не нужен, ширину
 * заливки по-прежнему ставит тот код, который её и ставил.
 *
 * Фолбэк для движков без контейнерных единиц — сплошная заливка
 * серединой шкалы; проверяется через @supports.
 */

.ws-progress,
.progress-track,
.progress-bar-container,
.claim-progress-bar-bg,
.cdb-progress,
.cp-progress,
body.user-dashboard .up-xp-progress {
    position: relative;
    overflow: hidden;
    border-radius: var(--ws-radius-full);
    background: var(--ws-progress-track);
    container-type: inline-size;
}

.ws-progress > .ws-progress__fill,
.progress-track > .progress-fill,
.progress-bar-container > .progress-bar-fill,
.claim-progress-bar-bg > .claim-progress-bar-fill,
.cdb-progress > i,
.cp-progress > i,
body.user-dashboard .up-xp-progress > i {
    position: relative;
    display: block;
    height: 100%;
    min-width: 0;
    overflow: hidden;
    border-radius: inherit;
    background: var(--ws-canon-progress-mid);
    transition: width .9s cubic-bezier(.4, 0, .2, 1);
}

@supports (width: 100cqw) {
    .ws-progress > .ws-progress__fill,
    .progress-track > .progress-fill,
    .progress-bar-container > .progress-bar-fill,
    .claim-progress-bar-bg > .claim-progress-bar-fill,
    .cdb-progress > i,
    .cp-progress > i,
    body.user-dashboard .up-xp-progress > i {
        background: transparent;
    }

    .ws-progress > .ws-progress__fill::before,
    .progress-track > .progress-fill::before,
    .progress-bar-container > .progress-bar-fill::before,
    .claim-progress-bar-bg > .claim-progress-bar-fill::before,
    .cdb-progress > i::before,
    .cp-progress > i::before,
    body.user-dashboard .up-xp-progress > i::before {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        /* Ровно ширина дорожки, а не заливки — в этом весь смысл. */
        width: 100cqw;
        border-radius: inherit;
        /* Два слоя: сверху редкий блик, под ним сама шкала.

           Блик — это и есть «полоса живая». Статичная заливка сообщает
           только факт: столько-то процентов. Медленная волна раз в
           несколько секунд говорит, что за полосой что-то происходит и её
           стоит доводить до конца. Пауза в кадрах длинная (движение
           занимает меньше половины цикла) — блик должен попадаться на
           глаза, а не мельтешить. */
        background-image:
            linear-gradient(100deg,
                transparent 42%,
                rgba(255, 255, 255, 0.20) 50%,
                transparent 58%),
            var(--ws-progress-ramp);
        background-size: 260% 100%, 100% 100%;
        background-position: 200% 0, 0 0;
        background-repeat: no-repeat;
        animation: ws-progress-sheen 5s ease-in-out infinite;
    }

    @keyframes ws-progress-sheen {
        0%, 58%  { background-position: 200% 0, 0 0; }
        100%     { background-position: -60% 0, 0 0; }
    }
}

/* Блик по верхней кромке заливки: полоса перестаёт быть плоской заливкой
   и читается как налитая капсула. Блик рисуется поверх шкалы и обрезается
   вместе с ней, поэтому пустая часть дорожки остаётся матовой. */
.ws-progress > .ws-progress__fill::after,
.progress-track > .progress-fill::after,
.progress-bar-container > .progress-bar-fill::after,
.claim-progress-bar-bg > .claim-progress-bar-fill::after,
.cdb-progress > i::after,
.cp-progress > i::after,
body.user-dashboard .up-xp-progress > i::after {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 45%;
    border-radius: inherit;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.26), rgba(255, 255, 255, 0));
    pointer-events: none;
}

/* Полностью заполненная полоса получает мягкое свечение зелёным концом
   шкалы — маленькая награда за доведённое до конца действие. */
.ws-progress[data-complete="1"],
.cdb-progress[data-complete="1"],
.cp-progress[data-complete="1"] {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--ws-canon-progress-end) 45%, transparent);
}

@media (prefers-reduced-motion: reduce) {
    .ws-progress > .ws-progress__fill,
    .progress-track > .progress-fill,
    .progress-bar-container > .progress-bar-fill,
    .claim-progress-bar-bg > .claim-progress-bar-fill,
    .cdb-progress > i,
    .cp-progress > i,
    body.user-dashboard .up-xp-progress > i {
        transition: none;
    }

    /* Волна выключается вместе с остальным движением; шкала и её цвет
       остаются — они и несут смысл. */
    .ws-progress > .ws-progress__fill::before,
    .progress-track > .progress-fill::before,
    .progress-bar-container > .progress-bar-fill::before,
    .claim-progress-bar-bg > .claim-progress-bar-fill::before,
    .cdb-progress > i::before,
    .cp-progress > i::before,
    body.user-dashboard .up-xp-progress > i::before {
        animation: none;
        background-position: 200% 0, 0 0;
    }
}


/* ==========================================================================
   ШАГИ ПРОЦЕССА (.ws-stepper)
   ==========================================================================
   Второй вид прогресса на платформе: не «сколько заполнено», а «на каком шаге
   находимся». Раньше такой индикатор рисовали трижды и по-разному: мастер
   публикации на лендинге (.pland-wizard__progress), этапы задачи в кабинете
   компании (.ctc-lifecycle) и хронология платежа (.cb-timeline). У всех трёх
   отличались размеры точек, толщина дорожки и логика соединительной линии.

   За образец взят индикатор мастера с лендинга: сплошная дорожка на всю
   ширину, поверх неё залитая часть до текущего шага и круглые точки. Здесь он
   собран как общий компонент и дополнен подписями — в кабинете шаг без
   подписи не читается.

   Разметка:
     <ol class="ws-stepper" style="--ws-stepper-progress: 66%">
       <li class="ws-stepper__step is-done">
         <span class="ws-stepper__dot"></span>
         <span class="ws-stepper__label">Оплата</span>
         <span class="ws-stepper__note">Награда внесена</span>
       </li>
       …
     </ol>

   Состояния шага: is-done | is-current | is-pending | is-danger.
   --ws-stepper-progress — доля залитой дорожки, её считает вызывающий код:
   позиция последнего пройденного шага между центрами первой и последней точки.
   ========================================================================== */

.ws-stepper {
    --ws-stepper-dot: 28px;
    --ws-stepper-track: 3px;
    --ws-stepper-progress: 0%;

    position: relative;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Дорожка идёт от центра первой точки до центра последней, а не от края до
   края: иначе по бокам торчат хвосты, которым нечего обозначать. */
.ws-stepper::before,
.ws-stepper::after {
    content: "";
    position: absolute;
    top: calc(var(--ws-stepper-dot) / 2 - var(--ws-stepper-track) / 2);
    height: var(--ws-stepper-track);
    border-radius: var(--ws-radius-full);
    pointer-events: none;
}

.ws-stepper::before {
    left: calc(100% / var(--ws-stepper-count, 4) / 2);
    right: calc(100% / var(--ws-stepper-count, 4) / 2);
    background: var(--ws-progress-track);
}

/* Залитая часть. Ширина считается от той же базы, что и дорожка, поэтому
   заливка всегда заканчивается ровно в центре нужной точки. */
.ws-stepper::after {
    left: calc(100% / var(--ws-stepper-count, 4) / 2);
    width: calc((100% - 100% / var(--ws-stepper-count, 4)) * var(--ws-stepper-progress) / 100%);
    background: var(--ws-primary);
    transition: width .45s cubic-bezier(.4, 0, .2, 1);
}

.ws-stepper__step {
    position: relative;
    z-index: 1;
    display: grid;
    justify-items: center;
    align-content: start;
    gap: 3px;
    padding: 0 6px;
    text-align: center;
}

.ws-stepper__dot {
    display: grid;
    place-items: center;
    width: var(--ws-stepper-dot);
    height: var(--ws-stepper-dot);
    margin-bottom: 8px;
    border: 2px solid var(--ws-line);
    border-radius: var(--ws-radius-full);
    background: var(--ws-surface);
    color: var(--ws-fg-soft);
    font: 800 11px/1 var(--ws-font-heading);
}

.ws-stepper__dot svg {
    width: 13px;
    height: 13px;
}

.ws-stepper__label {
    color: var(--ws-fg-muted);
    font: 700 13px/1.25 var(--ws-font-sans);
}

.ws-stepper__note {
    color: var(--ws-fg-soft);
    font: 500 12px/1.35 var(--ws-font-sans);
}

.ws-stepper__step.is-done .ws-stepper__dot {
    border-color: var(--ws-primary);
    background: var(--ws-primary);
    color: var(--ws-primary-fg);
}

.ws-stepper__step.is-done .ws-stepper__label {
    color: var(--ws-fg);
}

/* Текущий шаг — кольцо акцента с мягким ореолом: он должен читаться первым,
   но не выглядеть завершённым. */
.ws-stepper__step.is-current .ws-stepper__dot {
    border-color: var(--ws-primary);
    background: var(--ws-surface);
    color: var(--ws-primary);
    box-shadow: 0 0 0 4px var(--ws-primary-soft);
}

.ws-stepper__step.is-current .ws-stepper__label {
    color: var(--ws-fg);
    font-weight: 800;
}

.ws-stepper__step.is-danger .ws-stepper__dot {
    border-color: var(--ws-error);
    background: var(--ws-error);
    color: var(--ws-on-scrim);
}

.ws-stepper__step.is-danger .ws-stepper__label,
.ws-stepper__step.is-danger .ws-stepper__note {
    color: var(--ws-error);
}

.ws-stepper__step.is-pending .ws-stepper__label,
.ws-stepper__step.is-pending .ws-stepper__note {
    opacity: .7;
}

/* В колонку — на узком экране подписи в четыре столбца нечитаемы. */
@media (max-width: 720px) {
    .ws-stepper {
        grid-auto-flow: row;
        grid-auto-columns: auto;
        gap: 14px;
    }

    .ws-stepper::before,
    .ws-stepper::after {
        top: calc(var(--ws-stepper-dot) / 2);
        bottom: calc(var(--ws-stepper-dot) / 2);
        left: calc(var(--ws-stepper-dot) / 2 - var(--ws-stepper-track) / 2);
        right: auto;
        width: var(--ws-stepper-track);
        height: auto;
    }

    .ws-stepper::after {
        height: calc((100% - var(--ws-stepper-dot)) * var(--ws-stepper-progress) / 100%);
        bottom: auto;
        transition: height .45s cubic-bezier(.4, 0, .2, 1);
    }

    .ws-stepper__step {
        grid-template-columns: var(--ws-stepper-dot) minmax(0, 1fr);
        justify-items: start;
        align-items: center;
        gap: 2px 12px;
        padding: 0;
        text-align: left;
    }

    .ws-stepper__dot {
        grid-row: span 2;
        margin-bottom: 0;
    }
}

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