/* ============================================================
   Раздел "Анимации" - локальные стили поверх base.css
   ============================================================ */

/* ---------- Карточки на странице раздела (как на главной) ---------- */
.anim-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--spacing-lg);
}

@media (max-width: 380px) {
    .anim-grid {
        grid-template-columns: 1fr;
    }
}

.anim-card {
    display: flex;
    gap: var(--spacing-md);
    align-items: flex-start;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    text-decoration: none;
    color: var(--text-primary);
    box-shadow: var(--shadow-sm);
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.anim-card:hover {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-lg);
}

.anim-card-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    flex-shrink: 0;
    background: var(--color-primary-bg);
    color: var(--color-primary-dark);
    border-radius: var(--radius-md);
    font-family: var(--font-mono);
    font-size: 1.05rem;
    font-weight: 700;
}


.anim-card-title {
    font-size: 1.1rem;
    font-weight: 700;
    margin-bottom: 4px;
}

/* Заголовок категории в каталоге анимаций */
.anim-cat-heading {
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--text-primary);
    margin: var(--spacing-2xl) 0 var(--spacing-lg);
}

.anim-cat-heading:first-child {
    margin-top: var(--spacing-md);
}

.anim-card-desc {
    font-size: 0.92rem;
    color: var(--text-secondary);
    line-height: 1.5;
}

/* ---------- Переключатели наборов данных ---------- */
.viz-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--spacing-md);
    flex-wrap: nowrap;
    gap: var(--spacing-sm);
}

.viz-header .section-title {
    margin-bottom: 0;
}



.preset-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-lg);
    overflow-x: auto;
    padding-bottom: 4px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

.preset-row::-webkit-scrollbar {
    display: none;
}

.preset-label {
    font-size: 0.9rem;
    color: var(--text-secondary);
    font-weight: 500;
    margin-right: var(--spacing-xs);
    flex-shrink: 0;
}

.preset-chip {
    padding: 5px 14px;
    background: var(--bg-card);
    border: 1px solid #cbd5e1;
    border-radius: 20px;
    color: var(--text-secondary);
    font-family: var(--font-family);
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-base);
    flex-shrink: 0;
}

.preset-chip:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.preset-chip.active {
    background: var(--color-primary-bg);
    border-color: var(--color-primary);
    color: var(--color-primary-dark);
}

/* ---------- Сцена со столбиками (сортировки) ---------- */
.bars-stage {
    display: flex;
    align-items: flex-end;
    gap: 4px;
    height: 280px;
    padding: var(--spacing-lg) var(--spacing-md) 30px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    margin-bottom: var(--spacing-md);
}

.bar {
    flex: 1;
    /* Столбики делят ширину сцены поровну. min-width нужен только как защита от нулевой
       ширины: если поставить его больше реальной доли (при 30 элементах на экране 320px
       это ~5px), flex не даст столбикам сжаться и они вылезут за карточку. */
    min-width: 4px;
    position: relative;
    background: var(--color-primary-light);
    border-radius: 4px 4px 0 0;
    transition: height 0.18s ease, background-color 0.18s ease;
}

.bar-value {
    position: absolute;
    top: -22px;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    font-weight: 600;
    /* text-primary: мелкий шрифт, поэтому берем максимальный контраст к подложке сцены */
    color: var(--text-primary);
    white-space: nowrap;
}

/* Подпись под столбиком: массивная нотация a[0] или короткий номер позиции 0
   (режим выбирает скрипт по фактической ширине столбика) */
.bar-index {
    position: absolute;
    bottom: -24px;
    left: 50%;
    transform: translateX(-50%);
    font-family: var(--font-mono);
    font-size: 0.66rem;
    /* text-secondary, не tertiary: контраст WCAG (Lighthouse low-contrast) */
    color: var(--text-secondary);
    white-space: nowrap;
}

/* Тесная сцена: подписи прячутся по ФАКТИЧЕСКОЙ ширине столбика - ее считает общий
   модуль anim-bars.js (порог по числу элементов был неверен: сцена бывает во всю ширину,
   а бывает в половину, и на узком экране подписи слипались задолго до "22 элементов").
   .hide-values убирает значение над столбиком (2 цифры, шире - прячем раньше);
   .hide-index убирает подпись под столбиком (уже - прячем позже). */
.bars-stage.hide-values .bar-value {
    display: none;
}

.bars-stage.hide-index .bar-index {
    display: none;
}

.bar.compare { background: #f59e0b; }
.bar.swap    { background: var(--color-danger); }
.bar.sorted  { background: var(--color-success); }
.bar.pivot   { background: #7c3aed; }
.bar.purple  { background: #7c3aed; } /* просеиваемый элемент (heap sort) */
.bar.ghost   { visibility: hidden; }

/* Приглушенный столбик (вне текущей зоны интереса). Гасим НЕ через opacity на .bar:
   она распространяется на детей, и подписи a[i]/значения уходили в ~1.9:1 - Lighthouse
   справедливо ловил это как low-contrast. Вместо этого кладем поверх тела столбика
   полупрозрачную подложку сцены: любой цвет (синий, зеленый, янтарный) выцветает,
   а подписи остаются в полном контрасте. */
.bar.faded::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--bg-secondary);
    opacity: 0.65;
    border-radius: inherit;
    pointer-events: none;
}

/* ---------- Дерево двоичной кучи (heap/tournament: массив как дерево) ---------- */
/* Модуль общий: используется пирамидальной и турнирной сортировками.
   Рендерится скриптом анимации как inline-SVG внутри контейнера .heap-tree.
   Раскладка .heap-viz и .heap-viz-col - ниже, одним блоком перед своим @media. */

.heap-tree {
    width: 100%;
    overflow-x: auto;              /* глубокие уровни не ломают ширину страницы */
    overflow-y: hidden;            /* вертикальной прокрутки быть не должно */
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: var(--spacing-md) var(--spacing-sm);
    margin-bottom: var(--spacing-md);
}

/* Размер шрифта узлов задает скрипт (inline на <svg>) - он подбирается под радиус
   узла и коэффициент вписывания в панель. Здесь только запасное значение. */
.heap-tree svg { display: block; margin: 0 auto; font-size: 13px; }

.heap-tree.empty {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 90px;
    color: var(--text-secondary);
    font-size: 0.9rem;
}

.tree-edge {
    stroke: var(--border-color);
    stroke-width: 2;
}

.tree-node circle {
    fill: var(--color-primary);    /* темно-синий: белый текст читается (WCAG AA) */
    stroke: #ffffff;
    stroke-width: 2;
    transition: fill 0.18s ease;
}

.tree-node text {
    fill: #ffffff;
    font-family: var(--font-mono);
    font-weight: 700;
    text-anchor: middle;
    dominant-baseline: central;
}

/* Состояния узлов зеркалят подсветку столбиков */
.tree-node.compare circle { fill: #f59e0b; }
.tree-node.compare text   { fill: #1e293b; } /* темный текст на янтарном - контраст */
.tree-node.match circle   { fill: #f59e0b; }
.tree-node.match text     { fill: #1e293b; }
.tree-node.champion circle { fill: var(--color-success); }
.tree-node.champion text   { fill: #ffffff; }
.tree-node.eliminated circle { fill: var(--bg-secondary); stroke: var(--border-color); }
.tree-node.eliminated text   { fill: var(--text-secondary); }
.tree-node.swap    circle { fill: var(--color-danger); }
.tree-node.sift    circle { fill: #7c3aed; }
.tree-node.root    circle { stroke: var(--color-primary-dark); stroke-width: 3.5; }

/* Аварийный режим: на очень узкой панели дерево вписывается с таким масштабом, что
   цифры стали бы мельче 9px. Их не прочитать - скрипт вешает .dense и мы прячем текст,
   оставляя саму структуру дерева. При штатных размерах панели значения видны всегда. */
.heap-tree.dense .tree-node text { display: none; }

/* Низкая сцена: ряды входа и результата в сортировке подсчетом */
.bars-stage.low {
    height: 190px;
}

/* Подпись-лейбл над панелью визуализации (напр. "Дерево кучи" / "Массив").
   Жирный ведущий термин задает статус подзаголовка панели, пояснение - светлее. */
.viz-caption {
    font-size: 0.85rem;
    color: var(--text-secondary);
    margin: 0 0 8px 2px;
}

.viz-caption strong {
    color: var(--text-primary);
    font-weight: 700;
}

/* Пирамидальная/турнирная: дерево и массив рядом на десктопе (видны вместе),
   стопкой на узких экранах. Остальные сортировки этот блок не используют. */
.heap-viz {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
    width: 100%;
    margin-bottom: var(--spacing-md);
}

.heap-viz-col {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-width: 0; /* чтобы overflow-x внутри дерева работал, а не распирал колонку */
}

.heap-viz-col .heap-tree,
.heap-viz-col .bars-stage {
    margin-bottom: 0; /* вертикальный ритм задает .heap-viz */
}

@media (min-width: 861px) {
    .heap-viz {
        flex-direction: row;
        align-items: stretch;
    }

    .heap-viz-col {
        flex: 1 1 0;
    }

    /* Обе панели одной высоты - ряд читается ровно; дерево центрируем и вписываем
       целиком (скрипт масштабирует SVG под размер панели, прокрутки нет). */
    .heap-viz-col .heap-tree {
        height: 300px;
        display: flex;
        align-items: center;
        justify-content: center;
        overflow: hidden;
    }

    .heap-viz-col .bars-stage {
        height: 300px;
    }
}

/* Сворачиваемые на мобильном блоки (легенда, набор данных): на десктопе всегда
   развернуты (тумблер скрыт, скрипт держит details открытым), на мобильном -
   компактный сворачиваемый блок, чтобы дерево+столбики+кнопки были ближе к экрану. */
.mobile-collapse {
    margin-bottom: var(--spacing-md);
}

.mobile-collapse > summary {
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-secondary);
    padding: 4px 0;
}

.mobile-collapse[open] > summary {
    margin-bottom: 8px;
}

/* Текущий выбор набора данных в свернутом виде (summary) */
.preset-current {
    color: var(--color-primary-dark);
    font-weight: 700;
}

.legend-details .anim-legend,
.preset-details .preset-row {
    margin-bottom: 0;
}

@media (min-width: 861px) {
    /* На десктопе блоки видны всегда - сами тумблеры прячем */
    .mobile-collapse > summary {
        display: none;
    }
}

/* Мобильная компоновка пирамидальной: ниже панели, чтобы больше влезало в экран */
@media (max-width: 860px) {
    .heap-viz .bars-stage {
        height: 210px;
    }
}

/* Легенда цветов */
.anim-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-md);
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.legend-swatch {
    width: 14px;
    height: 14px;
    border-radius: 4px;
    flex-shrink: 0;
}

/* ---------- Строка состояния и счетчики ---------- */
.anim-status {
    background: var(--color-primary-bg);
    border-left: 3px solid var(--color-primary);
    padding: var(--spacing-md);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    font-size: 1rem;
    color: var(--text-primary);
    line-height: 1.6;
    margin-bottom: var(--spacing-md);
    min-height: 76px; /* две строки протокола */
}

/* Ключевые параметры протокола - жирно и заметно */
.anim-status strong {
    font-family: var(--font-mono);
    color: var(--color-primary-dark);
}

.anim-counters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-md);
}

.counter-chip {
    padding: 4px 12px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: 0.88rem;
    color: var(--text-secondary);
}

.counter-chip strong {
    color: var(--text-primary);
    font-family: var(--font-mono);
}

/* Подсветка итогов: лейбл сложности и все счетчики загораются на финише */
.counter-chip.lit,
.anim-counters.done .counter-chip {
    background: #f0fdf4;
    border-color: var(--color-success);
    color: #15803d;
}

.counter-chip.lit strong,
.anim-counters.done .counter-chip strong {
    color: #15803d;
}

/* ---------- Панель управления ---------- */
/* .anim-controls / .control-group / .play-btn - общий компонент в base.css.
   Порядок блоков heap-sort (панель под легендой, до статуса) включает
   .anim-controls.before-status - см. workshop/animations/viz-layout-plan.md */

/* Счетчики оказались последними в секции - лишний отступ снизу не нужен */
.anim-counters:last-child {
    margin-bottom: 0;
}

/* Правый кластер панели: ползунок размера + скорости переносятся ВМЕСТЕ,
   а не по одному (некрасивые переносы на ширинах ~900-1100px) */
.controls-right {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    margin-left: auto;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.speed-wrap {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.speed-wrap input[type="range"] {
    width: 110px;
    accent-color: var(--color-primary);
    cursor: pointer;
}

.speed-wrap .size-readout {
    font-family: var(--font-mono);
    font-weight: 700;
    color: var(--color-primary-dark);
    min-width: 22px;
}

/* Сегмент скоростей (как .control-group из base.css, но компактнее) */
.speed-seg {
    display: inline-flex;
    border: 1px solid #cbd5e1;
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--bg-card);
}

.speed-seg button {
    padding: 8px 14px;
    background: transparent;
    border: none;
    border-right: 1px solid #cbd5e1;
    color: var(--text-secondary);
    font-family: var(--font-family);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: all var(--transition-base);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.speed-seg button:last-child {
    border-right: none;
}

.speed-seg button:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
}

.speed-seg button.active {
    background: var(--text-primary);
    color: #ffffff;
}

@media (max-width: 768px) {
    /* .anim-controls .btn / .control-group - мобильные правила в base.css */
    .controls-right { width: 100%; }
    .speed-wrap { margin-left: 0; width: 100%; }
    .speed-wrap input[type="range"] { flex: 1; width: auto; }
    .speed-seg { width: 100%; display: flex; }
    .speed-seg button { flex: 1; justify-content: center; }
}



/* ---------- Ячейки (сортировка подсчетом) ---------- */
.cells-block {
    margin-bottom: var(--spacing-lg);
}

.cells-title {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: var(--spacing-sm);
}

.cells-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.cell {
    position: relative;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-card);
    border: 1px solid #cbd5e1;
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text-primary);
    transition: background-color 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}

.cell-index {
    position: absolute;
    bottom: -20px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--text-secondary);
}

.cells-row.indexed {
    row-gap: 28px;
    margin-bottom: 22px;
}

.cell.empty {
    background: var(--bg-tertiary);
    color: var(--text-tertiary);
    border-style: dashed;
}

.cell.bump {
    background: var(--color-primary-bg);
    border-color: var(--color-primary);
    transform: translateY(-3px);
}

@media (max-width: 560px) {
    .cell { width: 34px; height: 34px; font-size: 0.9rem; }
    .bars-stage { height: 220px; gap: 2px; }
    .bars-stage.low { height: 150px; }
    .bar-value { font-size: 0.62rem; top: -17px; }
    .bigo-canvas-wrap canvas { height: 260px; }
}

/* ---------- Поиск: бейдж искомого и стрелки-указатели ---------- */
/* Модуль общий для линейного и двоичного поиска. Раньше жил в локальных
   linear-search.css / binary-search.css - двумя почти одинаковыми копиями (временное
   решение на время сборки страниц). Другие анимации этих классов не используют, поэтому
   на них перенос никак не влияет. */

.target-panel {
    display: flex;
    gap: 12px;
    align-items: center;
    /* Высота строки постоянна, даже когда знак сравнения скрыт: иначе его появление
       и исчезновение на каждом шаге двигало бы сцену и кнопки под ней. */
    min-height: 34px;
    margin-bottom: var(--spacing-md);
}

/* Бейдж "Ищем: X" -> "Найдено: X" / "Не найдено: X" */
.search-target {
    display: inline-flex;
    /* center, а не baseline: у метки, значения и знака сравнения разные кегли и шрифты
       (моноширинный против основного), и при выравнивании по базовой линии высота бейджа
       зависела от метрик шрифта. Вместе с фиксированной высотой это гарантирует, что смена
       состояния не двигает верстку. */
    align-items: center;
    gap: 8px;
    height: 34px;
    padding: 0 16px;
    background: var(--color-primary-bg);
    border: 1px solid var(--color-primary);
    border-radius: 20px;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1;
    color: var(--color-primary-dark);
}

.search-target .target-value {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 1.05rem;
    line-height: 1;
}

.search-target.found {
    background: #f0fdf4;
    border-color: var(--color-success);
    color: #15803d;
}

.search-target.not-found {
    background: #fef2f2;
    border-color: var(--color-danger);
    color: var(--color-danger);
}

/* Знак сравнения (=, <, >) - отдельный бейдж рядом с искомым, виден только на шаге сравнения */
.cmp-badge {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--text-primary);
    padding: 0 12px;
}

/* Стрелки-указатели под столбиками: i (линейный поиск), lo/mid (двоичный) */
.bar-pointer {
    position: absolute;
    bottom: -42px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    pointer-events: none;
    z-index: 2;
}

.bar-pointer .ptr-arrow {
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-bottom: 6px solid var(--text-secondary);
}

.bar-pointer .ptr-label {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-weight: 700;
    white-space: nowrap;
    line-height: 1;
    margin-top: 1px;
}

/* Янтарная стрелка - активный элемент (i / mid), синяя - граница диапазона (lo, hi) */
.bar-pointer.ptr-mid .ptr-arrow { border-bottom-color: #f59e0b; }
.bar-pointer.ptr-mid .ptr-label { color: #f59e0b; }
.bar-pointer.ptr-lo .ptr-arrow  { border-bottom-color: var(--color-primary); }
.bar-pointer.ptr-lo .ptr-label  { color: var(--color-primary); }

/* Место под стрелки внизу сцены */
.bars-stage.has-pointers {
    padding-bottom: 48px;
}

/* Столбики стали слишком узкими для подписей (класс вешает anim-bars.js) - значит и
   стрелка под ними уже не читается: прячем ее вместе с подписями */
.bars-stage.hide-index .bar-pointer {
    display: none;
}

/* Мобильные переопределения стрелок ДОЛЖНЫ идти после базовых правил выше: медиазапрос
   не повышает специфичность, и при равной специфичности выигрывает то, что ниже. */
@media (max-width: 560px) {
    .bar-pointer {
        bottom: -38px;
    }

    .bar-pointer .ptr-label {
        font-size: 0.56rem;
    }
}

/* ---------- График O-нотации ---------- */
.bigo-canvas-wrap {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: var(--spacing-sm);
    margin-bottom: var(--spacing-md);
}

.bigo-canvas-wrap canvas {
    display: block;
    width: 100%;
    height: 340px;
}

/* Легенда классов сложности под графиком O-нотации: моноширинные подписи "O(1)" и т.п.
   Кривые не выключаются (все 7 нужны всегда), поэтому это статичная легенда, а не чипы.
   Раскладку и перенос дает общий .anim-legend; здесь только шрифт формул. */
.bigo-legend .legend-item {
    font-family: var(--font-mono);
    font-weight: 600;
}

/* Текущее n в панели управления графиком */
.n-value {
    font-family: var(--font-mono);
    font-weight: 700;
    color: var(--color-primary-dark);
    min-width: 62px;
}

/* Подзаголовки свойств алгоритма (По времени / По памяти) */
.prop-title {
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 8px;
}

/* ---------- Таблицы сложности ---------- */
.complexity-table {
    overflow-x: auto;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
}

.complexity-table table {
    width: 100%;
    border-collapse: collapse;
}

.complexity-table th,
.complexity-table td {
    padding: 10px var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid var(--border-color);
}

.complexity-table th {
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 0.85rem;
}

.complexity-table tbody tr:nth-child(even) {
    background: var(--bg-secondary);
}

.complexity-table tr:last-child td {
    border-bottom: none;
}

.complexity-table .mono {
    font-family: var(--font-mono);
    color: var(--color-primary-dark);
    white-space: nowrap;
}

/* Таблица O-нотации: столбец "Операций" держим фиксированной ШИРИНЫ под максимум
   (пределы при n = 256 известны заранее) - иначе он раздвигается по мере роста чисел
   в анимации. min-width покрывает и заголовок "Операций при n = 256", и значение вида
   "1.2·10^77", так что столбец не шевелится. Степень 10^N гасим по ВЫСОТЕ строки:
   line-height:0 у <sup>, иначе надстрочная цифра растягивала бы ряд. */
.values-table th:nth-child(3),
.values-table td:nth-child(3) {
    min-width: 180px;
}

.values-table sup {
    line-height: 0;
}

/* ---------- Скрытие блока кода ---------- */
.code-wrapper.collapsed {
    display: none;
}

/* Убираем "коробку в коробке" для кода */
.code-wrapper pre {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
    margin: 12px 0 0 0 !important;
}

.code-wrapper code.hljs {
    background: #f8fafc; /* Светло-серый фон для кода */
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 16px;
    display: block;
}

@media (max-width: 768px) {
    /* Мобильные таблицы сложности */
    .complexity-table table, 
    .complexity-table tbody { display: block; width: 100%; }
    .complexity-table thead { display: none; }
    .complexity-table tr { 
        display: flex; 
        flex-wrap: wrap; 
        padding: 12px 16px; 
        border-bottom: 1px solid var(--border-color) !important;
    }
    .complexity-table tr:last-child { border-bottom: none !important; }
    .complexity-table td { border: none !important; padding: 0 !important; }
    .complexity-table td:nth-child(1) { flex: 1; font-weight: 600; color: var(--text-primary); padding-right: 12px !important; }
    .complexity-table td:nth-child(2) { text-align: right; }
    .complexity-table td:nth-child(3) { width: 100%; margin-top: 6px; font-size: 0.85rem; color: var(--text-secondary); }
    /* Но в таблице O-нотации значения (число операций) - синие и на мобильном, как на
       десктопе: это "ответ" строки, а не второстепенная деталь. Общее правило выше красит
       3-й столбец в серый (для "Комментария" в таблицах сортировок это верно), здесь
       возвращаем акцентный цвет. Идет ПОСЛЕ общего - при равной специфичности выигрывает. */
    .values-table td:nth-child(3) { color: var(--color-primary-dark); }

    /* Переносы в блоках с кодом */
    .code-wrapper pre {
        white-space: pre-wrap !important;
        word-wrap: break-word;
        padding: 12px;
    }
    .code-wrapper code {
        white-space: pre-wrap !important;
        font-size: 0.8rem;
    }

    /* Фиксируем высоту статуса, чтобы кнопки не прыгали при переносах текста.
       150px = самое длинное сообщение протокола (4 строки на 320px).
       НЕ уменьшать ради экономии пустоты - иначе панель скачет при проигрывании. */
    .anim-status {
        min-height: 150px;
        display: flex;
        flex-direction: column;
        justify-content: center;
    }


}

/* ==================== КНОПКА "СКОПИРОВАТЬ КОД" ==================== */
/* Обертку и кнопку вставляет anim-bars.js в каждый листинг pre > code */

.code-copy-wrap {
    position: relative;
}

.copy-btn {
    position: absolute;
    top: 12px;
    right: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 4px;
    color: var(--text-secondary);
    cursor: pointer;
}

.copy-btn:hover {
    color: var(--text-primary);
}

.copy-btn.copied {
    color: var(--color-success);
    border-color: var(--color-success);
}

/* ---------- Корзины (поразрядная сортировка) ---------- */
.radix-buckets {
    display: flex;
    gap: 8px;
    justify-content: center;
    flex-wrap: wrap;
    width: 100%;
    margin-top: 16px;
    margin-bottom: var(--spacing-md);
}

.radix-buckets .bucket {
    display: flex;
    flex-direction: column;
    align-items: center;
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 4px;
    background: var(--bg-card);
    min-width: 48px;
    min-height: 80px;
    justify-content: flex-end;
    transition: border-color var(--transition-base), background-color var(--transition-base);
}

.bucket-label {
    font-size: 14px;
    font-weight: bold;
    color: var(--text-secondary);
    border-top: 1px solid var(--border-color);
    width: 100%;
    text-align: center;
    margin-top: 4px;
    padding-top: 4px;
}

.bucket-items {
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: center;
    min-height: 40px;
}

.radix-buckets .bucket.active {
    border-color: var(--color-primary);
    background: var(--color-primary-bg);
}

.radix-buckets .bucket .cell {
    width: 36px;
    height: 36px;
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-card);
    border: 2px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-weight: bold;
    color: var(--text-primary);
}

.radix-buckets .bucket .cell.empty {
    border-color: transparent;
    background: transparent;
}

.radix-buckets .bucket .cell.active {
    border-color: var(--color-primary);
    background: #ffffff;
    color: var(--text-primary);
}

@media (max-width: 768px) {
    .radix-buckets { gap: 4px; }
    .radix-buckets .bucket { min-width: 32px; padding: 2px; }
    .radix-buckets .bucket .cell { width: 24px; height: 24px; font-size: 10px; }
    .bucket-label { font-size: 12px; }
}

/* ---------- Корзины (блочная сортировка) ---------- */
.bucket-scale-wrap {
    overflow: hidden;
    position: relative;
}

.bucket-zone {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: var(--spacing-md);
    transform-origin: top left;
}

.bucket-zone .bucket {
    display: flex;
    flex-direction: row;
    align-items: center;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 8px 12px;
    gap: 10px;
    transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.bucket-zone .bucket.active {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px var(--color-primary-bg);
}

.bucket-header {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 54px;
    padding-right: 10px;
    border-right: 1px solid var(--border-color);
    flex-shrink: 0;
    align-self: stretch;
}

.bucket-content {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    align-content: center;
    min-height: 40px;
    padding: 2px;
    flex-grow: 1;
}

.bucket-content .cell {
    width: 40px;
    height: 40px;
    font-size: 1rem;
    font-weight: 600;
}

.result-block {
    margin-bottom: var(--spacing-md);
}

.result-title {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: var(--spacing-sm);
}

.result-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    align-content: center;
    min-height: 44px;
}

.result-row .cell {
    width: 40px;
    height: 40px;
    font-size: 1rem;
    font-weight: 600;
    background: #f0fdf4;
    border-color: var(--color-success);
    color: #15803d;
}

.result-row .cell.bump {
    background: var(--color-primary-bg);
    border-color: var(--color-primary);
    color: var(--color-primary-dark);
    transform: translateY(-3px);
}


/* ---------- Внешняя сортировка ---------- */
.ext-sort-stage {
    display: flex;
    flex-direction: column;
    gap: 16px;
    align-items: center;
    width: 100%;
}

.ext-sort-stage .zone-title {
    font-size: 14px;
    font-weight: bold;
    color: var(--text-secondary);
    margin-bottom: 4px;
    text-align: left;
    width: 100%;
    border-bottom: 1px solid var(--border-color);
    padding-bottom: 4px;
}

.ext-sort-stage .zone-container {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.ext-sort-stage .cell-row {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.ext-sort-stage .cell-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

.ext-sort-stage .cell-index {
    position: static;
    transform: none;
    font-size: 11px;
    color: var(--text-secondary);
}

.ext-sort-stage .cell {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-card);
    border: 2px solid var(--border-color);
    border-radius: 4px;
    font-family: var(--font-mono);
    font-size: 14px;
    font-weight: bold;
    color: var(--text-primary);
    transition: all 0.2s ease;
}

.ext-sort-stage .cell.empty {
    border-color: transparent;
    background: transparent;
    color: transparent;
}

.ext-sort-stage .cell.active {
    border-color: var(--color-primary);
    background: var(--color-primary-bg);
    color: var(--color-primary-dark);
}

.ext-sort-stage .cell.compare {
    border-color: var(--color-warning);
    background: #fef3c7;
    color: #92400e;
}

.ext-sort-stage .cell.sorted {
    border-color: var(--color-success);
    background: #dcfce7;
    color: #166534;
}

.mem-buffer {
    display: flex;
    gap: 8px;
    padding: 8px;
    border: 2px dashed var(--color-primary);
    border-radius: 8px;
    background: var(--bg-secondary);
    min-height: 48px;
}

.mem-buffer .cell {
    width: 40px;
    height: 40px;
    font-size: 16px;
}

.run-block {
    display: flex;
    gap: 4px;
    padding: 6px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--bg-tertiary);
}

.disk-output.bars-stage {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 2px;
    width: 100%;
    height: 120px;
    margin-top: 8px;
}

@media (max-width: 768px) {
    .ext-sort-stage .cell { width: 24px; height: 24px; font-size: 12px; }
    .mem-buffer .cell { width: 32px; height: 32px; font-size: 14px; }
    .disk-output.bars-stage { height: 80px; }
}

/* ---------- Timsort (прогоны массива) ---------- */
.runs-bar {
    display: flex;
    width: 100%;
    height: 28px;
    background: var(--bg-card);
    border-radius: 4px;
    overflow: hidden;
    gap: 2px;
    margin-bottom: var(--spacing-md);
}

.run-segment {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: bold;
    color: var(--text-secondary);
    background: var(--border-color);
    transition: all 0.2s;
    box-sizing: border-box;
    white-space: nowrap;
    overflow: hidden;
}

.run-segment.active {
    background: var(--color-primary);
    color: white;
}

.run-segment.merging {
    background: var(--color-warning);
    color: var(--text-primary);
}

.run-segment.merged {
    background: var(--color-success);
    color: white;
}





