/*
 * components.css — повторяющиеся элементы: кнопки, бейджи, плитки, врезки.
 *
 * Семейства из раздела «СТИЛИСТИКА» CLAUDE.md: кнопки — pill 52px (компакт 44px),
 * карточки — bento без рамок с мягкой тенью и радиусом 18px, градиентов нет.
 * Ни один цвет и ни один отступ не пишется числом — только переменной из tokens.css.
 */

/* --- Кнопки --- */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-8);
    min-height: var(--control-height);
    padding: 0 var(--space-24);
    border: 0;
    border-radius: var(--radius-pill);
    font-family: var(--font-family-text);
    font-size: var(--font-size-body);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: transform var(--duration-fast) var(--ease-out),
        background-color var(--duration-fast) var(--ease-out),
        color var(--duration-fast) var(--ease-out);
}

.button--compact {
    min-height: var(--control-height-compact);
    padding: 0 var(--space-16);
    font-size: var(--font-size-small);
}

.button--wide {
    width: 100%;
}

.button--primary {
    background-color: var(--brand);
    color: var(--surface);
}

.button--primary:hover {
    background-color: var(--brand-hover);
    color: var(--surface);
    transform: translateY(-2px);
}

.button--secondary {
    background-color: var(--brand-soft);
    color: var(--brand);
    /* Рамка интерактивного элемента рисуется контрастным цветом — WCAG 1.4.11. */
    box-shadow: inset 0 0 0 1px var(--text-secondary);
}

.button--secondary:hover {
    color: var(--brand-hover);
    transform: translateY(-2px);
}

/* Кнопка на кобальтовой плашке: цвета меняются местами, иначе она сливается с фоном. */
.button--onbrand {
    background-color: var(--surface);
    color: var(--brand);
}

.button--onbrand:hover {
    color: var(--brand-hover);
    transform: translateY(-2px);
}

/* Третичная кнопка — обычная текстовая ссылка, без подложки. */
.button--tertiary {
    min-height: var(--control-height-compact);
    padding: 0;
    background-color: transparent;
    color: var(--brand);
    text-decoration: underline;
}

.button--tertiary:hover {
    color: var(--brand-hover);
}

/*
 * Недоступное действие. Это не «серая кнопка на всякий случай»: она появляется там,
 * где факта о файле нет, и всегда сопровождается текстовой причиной рядом —
 * состояние не передаётся одним цветом.
 */
.button--pending {
    background-color: var(--surface-secondary);
    color: var(--warning);
    box-shadow: inset 0 0 0 1px var(--text-secondary);
    cursor: default;
}

/*
 * Кнопка загрузки вместе с подписью. Подпись обязательна: состояние кнопки
 * (готова, готовится, ведёт через партнёрский переход) читается словами, а не цветом.
 */
.download-cta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-12);
}

.download-cta__note {
    margin: 0;
}

/* Тихая строка-примечание: сноска под блоком, пояснение служебного характера. */
.note {
    color: var(--text-secondary);
    font-size: var(--font-size-small);
}

/* --- Бейджи и чипы --- */

.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    background-color: var(--brand-soft);
    color: var(--brand);
    border-radius: var(--radius-pill);
    padding: var(--space-8) var(--space-16);
    font-size: var(--font-size-small);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
}

/* В вертикальной стопке бейдж не растягивается на всю ширину колонки. */
.stack > .badge {
    align-self: flex-start;
}

.badge--muted {
    background-color: var(--surface-secondary);
    color: var(--text-secondary);
}

.badge--warning {
    background-color: var(--surface-secondary);
    color: var(--warning);
}

.badge--success {
    background-color: var(--surface-secondary);
    color: var(--success);
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    min-height: var(--control-height-compact);
    padding: 0 var(--space-16);
    border-radius: var(--radius-pill);
    background-color: var(--surface);
    color: var(--text-primary);
    box-shadow: var(--shadow-card);
    font-size: var(--font-size-small);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    transition: transform var(--duration-fast) var(--ease-out);
}

.chip:hover {
    color: var(--text-primary);
    transform: translateY(-2px);
}

/* Ряд чипов — оглавление страницы вопросов: переносится по строкам,
   горизонтальной прокрутки внутри страницы на сайте нет. */
.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-8);
}

/* --- Bento: плитки разного размера, без рамок, мягкая тень --- */

.bento {
    display: grid;
    gap: var(--space-16);
    grid-template-columns: 1fr;
}

.tile {
    background-color: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    padding: var(--space-24);
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
}

.tile--soft {
    background-color: var(--brand-soft);
    box-shadow: none;
}

.tile--paper {
    background-color: var(--surface-secondary);
    box-shadow: none;
}

.tile__title {
    font-size: var(--font-size-h4);
    font-weight: var(--font-weight-semibold);
}

.tile__text {
    color: var(--text-secondary);
}

.tile__foot {
    margin-top: auto;
    padding-top: var(--space-8);
}

.tile__number {
    font-family: var(--font-family-display);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-h2);
    line-height: var(--line-height-tight);
    color: var(--brand);
}

@media (min-width: 768px) {
    .bento {
        grid-template-columns: repeat(6, 1fr);
        gap: var(--space-24);
    }

    .tile {
        grid-column: span 2;
        padding: var(--space-40);
    }

    .tile--wide {
        grid-column: span 4;
    }

    /* Половина ряда — пара «иллюстрация + текст»: .figure тоже занимает три колонки. */
    .tile--half {
        grid-column: span 3;
    }

    .tile--full {
        grid-column: span 6;
    }
}

/* --- Лента платформ ---
   Крупная карточка своей системы собирается из bento-плиток, а остальные платформы
   идут короткой лентой рядом (CLAUDE.md, download_family). На мобильном лента
   становится столбиком: горизонтальной прокрутки внутри страницы на сайте нет. */
.platform-strip {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-12);
}

.platform-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
    background-color: var(--surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    padding: var(--space-24);
}

.platform-card__title {
    font-weight: var(--font-weight-semibold);
}

.platform-card__note {
    margin: 0;
}

.platform-card__text {
    color: var(--text-secondary);
    font-size: var(--font-size-small);
}

@media (min-width: 768px) {
    .platform-strip {
        grid-template-columns: repeat(auto-fit, minmax(var(--space-96), 1fr));
        gap: var(--space-16);
    }
}

/* --- Вопросы и ответы ---
   Ответ лежит в HTML целиком и находится поиском по странице даже в свёрнутом виде:
   текст не подгружается скриптом (ТЗ ч. 2 разд. 77). */
.faq {
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
}

/* Отступы карточки живут на самом вопросе, а не на её оболочке: нажатие тогда работает
   по всей верхней части плитки, а не по двум строчкам текста внутри неё. Внешне карточка
   от этого не меняется — те же 24px по кругу. */
.faq__item {
    background-color: var(--surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}

.faq__question {
    padding: var(--space-24);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-16);
    font-size: var(--font-size-h4);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    cursor: pointer;
    list-style: none;
}

.faq__question::-webkit-details-marker {
    display: none;
}

/* Знак раскрытия — не единственный признак состояния: атрибут open читают
   скринридеры, а знак помогает всем остальным. */
.faq__question::after {
    content: "+";
    color: var(--brand);
    font-family: var(--font-family-display);
    flex: 0 0 auto;
}

.faq__item[open] > .faq__question::after {
    content: "–";
}

.faq__answer {
    padding: 0 var(--space-24) var(--space-24);
    color: var(--text-secondary);
}

/* --- Факты о файле: подпись слева, значение справа ---
   Строка появляется только вместе с подтверждённым фактом, поэтому пустых ячеек
   и прочерков в этом списке не бывает (ТЗ ч. 2 разд. 105). */
.spec {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
}

.spec__row {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-8);
    padding-bottom: var(--space-8);
    border-bottom: 1px solid var(--border);
}

.spec__row:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.spec__term {
    margin: 0;
    color: var(--text-secondary);
}

.spec__value {
    margin: 0;
    font-weight: var(--font-weight-medium);
}

/* --- Разбор проблем: что показала система и что с этим делать ---
   Это не FAQ: ответ виден сразу, без раскрытия. Список читают целиком, выискивая
   глазами знакомое окно, поэтому прятать решения под клик здесь незачем. */
.problem-list {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-16);
}

.problem-list__item + .problem-list__item {
    padding-top: var(--space-16);
    border-top: 1px solid var(--border);
}

.problem-list__title {
    margin: 0;
    font-size: var(--font-size-h4);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
}

.problem-list__text {
    margin: var(--space-8) 0 0;
    color: var(--text-secondary);
}

/* --- Таблица сводки ---
   Таблица заводится только там, где она действительно сравнивает данные: сводка
   версий по системам. На узком экране она прокручивается внутри своей обёртки,
   горизонтальной прокрутки самой страницы при этом не появляется. */
.table-wrap {
    overflow-x: auto;
    background-color: var(--surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    padding: var(--space-8);
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-small);
    text-align: left;
}

.table th,
.table td {
    padding: var(--space-12) var(--space-16);
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

.table thead th {
    color: var(--text-secondary);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
}

.table tbody th {
    font-weight: var(--font-weight-semibold);
}

.table tbody tr:last-child th,
.table tbody tr:last-child td {
    border-bottom: 0;
}

/* --- Врезка: пояснение, ограничение, предупреждение --- */

.callout {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
    background-color: var(--brand-soft);
    border-radius: var(--radius-md);
    padding: var(--space-24);
}

.callout--warning {
    background-color: var(--surface-secondary);
}

.callout__title {
    font-size: var(--font-size-h4);
    font-weight: var(--font-weight-semibold);
}

.callout--warning .callout__title {
    color: var(--warning);
}

.callout__text {
    color: var(--text-secondary);
}

/*
 * Блок отсчёта на странице загрузки /download/out/. Крупная цифра держит внимание,
 * кнопки — всегда доступный запасной путь, если скрипт не отработал.
 */
.countdown {
    display: flex;
    flex-direction: column;
    gap: var(--space-16);
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-24);
}

.countdown__lead {
    font-size: var(--font-size-h4);
    line-height: 1.5;
}

.countdown__value {
    display: inline-block;
    min-width: 1.6em;
    padding: 0 var(--space-8);
    font-family: var(--font-family-display);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-h2);
    color: var(--brand);
    font-variant-numeric: tabular-nums;
}

.countdown__fallback {
    margin: 0;
}

/*
 * Статус всегда состоит из точки и подписи: цвет дублируется словом,
 * иначе состояние не читается без цветовосприятия.
 */
.status {
    display: inline-flex;
    align-items: center;
    gap: var(--space-8);
    font-size: var(--font-size-small);
    font-weight: var(--font-weight-medium);
}

.status::before {
    content: "";
    width: var(--space-8);
    height: var(--space-8);
    border-radius: var(--radius-pill);
    background-color: currentColor;
    flex: 0 0 auto;
}

.status--pending {
    color: var(--warning);
}

.status--ready {
    color: var(--success);
}

.status--error {
    color: var(--error);
}

/* --- Списки контента --- */

.list {
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
    padding-left: var(--space-24);
}

.list li::marker {
    color: var(--brand);
}

.link-list {
    list-style: none;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
}

.link-list a {
    text-decoration: none;
}

.link-list a:hover {
    text-decoration: underline;
}

/* --- Иллюстрации ---
   Арт-система одна: friendly flat vector, дуга траектории, две-три плоские заливки
   кобальта и мягкого оттенка. Фон картинок совпадает с цветом бумаги --background,
   поэтому иллюстрация ставится на фон страницы, а не внутрь белой плитки: на белом
   был бы виден прямоугольник подложки. Размеры width и height приходят из реестра
   медиа (app/lib/media.php), поэтому при загрузке страница не дёргается. */
.figure {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-12);
    align-items: center;
}

/* <picture> выбирает формат и ширину кадра, но размеры блока задаёт вёрстка: без явного
   display обёртка стала бы строчной и картинка перестала бы тянуться по колонке. */
.figure picture {
    display: block;
    width: 100%;
    max-width: var(--text-column);
}

.figure__image {
    width: 100%;
    max-width: var(--text-column);
    height: auto;
}

.figure__caption {
    color: var(--text-secondary);
    font-size: var(--font-size-small);
    text-align: center;
    margin: 0;
}

/* Иллюстрация как ячейка bento: половина ряда на десктопе, вся ширина на мобильном. */
@media (min-width: 768px) {
    .bento > .figure {
        grid-column: span 3;
    }
}

/* --- Материал раздела «Статьи» ---
   Текст читается в колонке 680px, разделы разделены воздухом, а не линейками:
   правило content_density из CLAUDE.md — воздуха больше, чем в каталоге. Якорь
   раздела отступает от плавающей шапки, иначе заголовок уезжает под неё. */
.article {
    display: flex;
    flex-direction: column;
    gap: var(--space-40);
}

.article__section {
    display: flex;
    flex-direction: column;
    gap: var(--space-16);
    scroll-margin-top: var(--space-96);
}

.article-meta {
    color: var(--text-secondary);
    font-size: var(--font-size-small);
}

/* --- Порядок действий ---
   Нумерация рисуется счётчиком: цифра — часть оформления шага, а не текста,
   и остаётся крупной, как числа в плитках bento. */
.steps {
    list-style: none;
    counter-reset: steps;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-16);
}

.steps__item {
    counter-increment: steps;
    position: relative;
    background-color: var(--surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    padding: var(--space-24);
    padding-left: var(--space-64);
}

.steps__item::before {
    content: counter(steps);
    position: absolute;
    left: var(--space-24);
    top: var(--space-24);
    font-family: var(--font-family-display);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-h3);
    line-height: var(--line-height-tight);
    color: var(--brand);
}

.steps__title {
    margin: 0;
    font-weight: var(--font-weight-semibold);
}

.steps__text {
    margin: var(--space-8) 0 0;
    color: var(--text-secondary);
}

/* --- Панель согласия на статистику ---
   Появляется только там, где счётчик действительно подключён (partials/consent-bar.php).
   Кнопки работают через скрипт, поэтому без JS панель не показывается: без него
   счётчики всё равно не загружаются, и спрашивать было бы не о чем.
   Панель прижата к нижнему краю, но не растягивается на всю ширину и не перекрывает
   содержимое целиком — на узком экране она остаётся над контентом одной плашкой. */
.consent-bar {
    display: none;
}

.js .consent-bar {
    display: block;
    position: fixed;
    left: var(--space-16);
    right: var(--space-16);
    bottom: var(--space-16);
    z-index: var(--z-sheet);
}

.consent-bar[hidden] {
    display: none;
}

.consent-bar__panel {
    max-width: var(--container);
    margin: 0 auto;
    background-color: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lift);
    padding: var(--space-24);
    display: flex;
    flex-direction: column;
    gap: var(--space-16);
}

.consent-bar__title {
    margin: 0;
    font-family: var(--font-family-display);
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-h4);
    line-height: var(--line-height-tight);
}

.consent-bar__note {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-size-small);
}

.consent-bar__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-12);
}

@media (min-width: 768px) {
    .consent-bar__panel {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-24);
    }

    .consent-bar__actions {
        flex-shrink: 0;
    }
}

/* Кнопка «Изменить решение» на странице политики работает через скрипт,
   поэтому без JS её не видно: без скрипта менять всё равно нечего. */
.consent-reset {
    display: none;
}

.js .consent-reset {
    display: block;
}
