/* Photo editor (photo_editor) — оформление рабочей области.
   Каркас — Bootstrap 5 + сайтовые токены; акцентная палитра инструмента задана ЛОКАЛЬНЫМИ
   переменными на контейнере .pe и сайтовую тему не трогает (правило image_tools.md).

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

.pe {
    --pe-bg:        #24262b;
    --pe-panel:     #2c2f35;
    --pe-panel-2:   #33373e;
    --pe-line:      #3d424a;
    --pe-text:      #d8dbe0;
    --pe-text-dim:  #9aa0aa;
    --pe-accent:    #6ea8fe;
    --pe-stage:     #1a1c20;
    --pe-radius:    8px;
    /* Высота, которую в рабочей области занимают верхняя строка и быстрая строка вместе
       с отступами. На неё укорачиваются прилипающие кадр и колонка, иначе они, прилипнув,
       уезжают ВНИЗ поверх быстрой строки: прилипающий элемент ограничен не своей ячейкой
       сетки, а всей рабочей областью. Поймано замером 19.09.2026 — нажатие на «More
       adjustments» перехватывал подвал витрины, лежавший поверх кнопки. */
    --pe-chrome:    156px;
    /* Высота рабочего места (кадр и колонка идут вровень). В долях экрана, а не «весь экран
       минус строки»: над рабочей областью стоят шапка сайта, хлебные крошки и заголовок,
       и кадр, растянутый на всю высоту окна, начинался бы ниже его нижнего края. */
    --pe-work-h:    74vh;

    /* РАСКЛАДКА (макет владельца 19.09.2026). Четыре области:
         верхняя строка  — имя снимка, отмена-повтор, скачивание (во всю ширину);
         сцена           — сам кадр;
         колонка         — витрина пресетов ИЛИ панели ползунков (вкладки);
         быстрая строка  — четыре ходовые ручки (во всю ширину, под обеими колонками).
       Колонка шире прежних 300 px: в ней теперь витрина карточек, а не только ползунки —
       библиотека пресетов и есть главная функция инструмента. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) 460px;
    grid-template-areas:
        "top   top"
        "stage deck"
        "quick quick";
    gap: 10px 12px;
    background: var(--pe-bg);
    border-radius: var(--pe-radius);
    padding: 12px;
    color: var(--pe-text);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ---------------- Верхняя строка ---------------- */

/* Пока фотографии нет, показывать нечего: ни имени, ни отмены, ни скачивания. Видимость
   держится на состоянии рабочей области, а не на отдельном hidden — движок и так его ставит. */
.pe:not([data-state="ready"]) .pe__top,
.pe:not([data-state="ready"]) .pe__deck { display: none; }
.pe:not([data-state="ready"]) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "stage";
}
/* Пока фотографии нет, сцена идёт по содержимому: заданная высота рабочего места оставляла бы
   под окном выбора файла пустое чёрное поле в половину экрана. */
.pe:not([data-state="ready"]) .pe__stage {
    height: auto;
    position: static;
}

.pe__top {
    grid-area: top;
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.pe__top-back {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin: 0;
    background: var(--pe-panel);
    border: 1px solid var(--pe-line);
    border-radius: 8px;
    color: var(--pe-text);
    font-size: 16px;
    cursor: pointer;
}
.pe__top-back:hover { background: var(--pe-panel-2); }

.pe__top-file { flex: 1 1 auto; min-width: 0; line-height: 1.25; }
.pe__top-name {
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pe__top-size { font-size: 12px; color: var(--pe-text-dim); }

.pe__top-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 8px;
    color: var(--pe-text);
    font-size: 15px;
    cursor: pointer;
}
.pe__top-btn:hover:not(:disabled) { background: var(--pe-panel-2); }
/* Отключённая кнопка гасится, но не исчезает: прыгающий ряд хуже неактивной кнопки. */
.pe__top-btn:disabled { opacity: .35; cursor: default; }
.pe__top-download { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; }

.pe.is-dragover {
    outline: 2px dashed var(--pe-accent);
    outline-offset: -6px;
}

/* ---------------- Левая колонка: фотография ---------------- */

/* Левая колонка ПРИЛИПАЕТ к верху экрана: правая панель длинная, и при её прокрутке фотография
   не должна уезжать вверх. Так правая колонка листается «независимо» — глазами она отдельная,
   хотя скролл у страницы один и никакого второго ползунка не появляется.
   Заказ владельца 2026-08-16: «я выбираю настройки где-то внизу и уезжаю непонятно куда,
   а фотка остаётся сверху».
   align-self: start обязателен — растянутый на всю высоту элемент прилипать не умеет. */
.pe__stage {
    grid-area: stage;
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
    position: sticky;
    top: 10px;
    align-self: start;
    /* Ровно столько же, сколько отведено колонке справа: кадр и витрина идут вровень, как
       в макете. Высота задана, а не «по содержимому», иначе рядом с длинной витриной под
       снимком оставалось бы пустое чёрное поле в половину экрана. */
    height: var(--pe-work-h);
    max-height: calc(100vh - var(--pe-chrome));
}

/* Кнопки сравнения — НА кадре, в углу. Это просмотр, а не правка: смотреть удобнее там же,
   куда смотришь, а ряд кнопок под кадром в новой раскладке занят быстрыми ползунками. */
.pe__stage-tools {
    position: absolute;
    left: 10px;
    bottom: 10px;
    display: flex;
    gap: 6px;
}
.pe__stage-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: rgba(16, 19, 26, .72);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 8px;
    color: #eef1f5;
    font-size: 15px;
    cursor: pointer;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}
.pe__stage-btn:hover { background: rgba(16, 19, 26, .9); }
.pe__stage-btn[aria-pressed="true"] {
    background: var(--pe-accent);
    border-color: var(--pe-accent);
    color: #10131a;
}

.pe__drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 380px;
    background: var(--pe-stage);
    border: 1px dashed var(--pe-line);
    border-radius: var(--pe-radius);
    text-align: center;
    padding: 24px;
}

.pe__drop-icon  { font-size: 40px; color: var(--pe-text-dim); line-height: 1; }
.pe__drop-title { font-size: 17px; font-weight: 600; }
.pe__drop-hint  { font-size: 13px; color: var(--pe-text-dim); }
.pe__drop-btn   { margin-top: 6px; cursor: pointer; }
.pe__drop-limit { font-size: 12px; color: var(--pe-text-dim); }

.pe__canvas-wrap {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Кадр занимает всю высоту сцены: рядом стоит длинная колонка витрины, и снимок, прижатый
       к верху, оставлял бы под собой пустое чёрное поле в половину экрана. */
    flex: 1 1 auto;
    min-height: 380px;
    background: var(--pe-stage);
    border-radius: var(--pe-radius);
    overflow: hidden;
    padding: 10px;
}

/* Стопка холстов: размер задаёт нижний (обработанный), исходный ложится поверх ровно на него. */
.pe__canvas-stack {
    position: relative;
    display: block;
    line-height: 0;
}

/* Холст рисуется в разрешении фотографии, а на экране вписывается в сцену. */
.pe__canvas {
    max-width: 100%;
    /* Кадр вписывается в отведённую сцену целиком: высота сцены теперь задана раскладкой,
       и собственный потолок в долях экрана резал бы картинку раньше неё. */
    max-height: 100%;
    object-fit: contain;
    border-radius: 4px;
    display: block;
}

/* Шторка «до/после». Доля открытой части — одна переменная: её двигает движок, и от неё же
   зависят и обрезка исходного холста, и положение ручки. Две независимые величины разъехались
   бы при первом же изменении размера окна. */
.pe__canvas-stack { --pe-split: 50%; }

.pe__canvas--orig {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    /* Видна ЛЕВАЯ часть: «до» слева — так читают слева направо. */
    clip-path: inset(0 calc(100% - var(--pe-split)) 0 0);
}

.pe__split {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.pe__split-line {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--pe-split);
    width: 2px;
    margin-left: -1px;
    background: rgba(255, 255, 255, .85);
    box-shadow: 0 0 6px rgba(0, 0, 0, .55);
}
.pe__split-grip {
    position: absolute;
    top: 50%;
    left: var(--pe-split);
    transform: translate(-50%, -50%);
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: rgba(20, 22, 26, .82);
    border: 2px solid rgba(255, 255, 255, .85);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1px;
    font-size: 11px;
    line-height: 1;
    cursor: ew-resize;
    pointer-events: auto;
    touch-action: none;
}
.pe__split-grip:focus-visible { border-color: var(--pe-accent, #4a7fe0); outline: none; }

.pe__split-tag {
    position: absolute;
    top: 10px;
    padding: 2px 8px;
    border-radius: 3px;
    background: rgba(20, 22, 26, .72);
    color: #fff;
    font-size: 11px;
    line-height: 1.6;
}
.pe__split-tag--left  { left: 10px; }
.pe__split-tag--right { right: 10px; }

.pe__badge {
    position: absolute;
    top: 14px;
    left: 14px;
    padding: 3px 9px;
    border-radius: 4px;
    background: rgba(0, 0, 0, .62);
    color: #fff;
    font-size: 12px;
    letter-spacing: .02em;
    pointer-events: none;
}

/* ---------------- Ход работы: полоса, подпись и шестерёнки ---------------- */

/* ⚠ ПОЧЕМУ ЗДЕСЬ ТРАНСФОРМАЦИИ, А НЕ width.
   Тяжёлые шаги (сборка файла в полном разрешении) занимают главный поток, и всё, что браузер
   считает на нём, на это время замирает: анимация по width встала бы ровно тогда, когда она
   нужнее всего, и человек решил бы, что инструмент завис. Трансформации (scaleX, rotate)
   браузер крутит отдельно от главного потока и не останавливает. Не переписывать на width. */

.pe__work {
    position: absolute;
    inset: 0;
    z-index: 6;
    display: flex;
    /* Не по центру: на телефоне рабочая область высокая (фотография + лента фильтров + кнопки),
       и середина такой области оказывается за краем экрана. */
    align-items: flex-start;
    justify-content: center;
    padding: 16px;
    background: rgba(26, 28, 32, .86);
    border-radius: var(--pe-radius);
}
.pe__work-box {
    width: min(330px, 100%);
    text-align: center;
    /* ⚠ Карточка ЛИПНЕТ к экрану. Кнопка «Download» на телефоне стоит внизу длинной колонки:
       без этого человек нажимает её и не видит вообще ничего — панель осталась наверху, за
       краем экрана, и выглядит это как «нажал, и ничего не произошло». Липкость держит карточку
       в поле зрения, куда бы человек ни пролистал. */
    position: sticky;
    top: 22vh;
    /* Своя подложка: под панелью просвечивает разметка, и текст на ней читался бы плохо. */
    padding: 18px 16px 16px;
    background: var(--pe-panel);
    border: 1px solid var(--pe-line);
    border-radius: var(--pe-radius);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
.pe__work-gears {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 2px;
    margin-bottom: 10px;
    color: var(--pe-accent);
}
.pe__gear { display: block; }
.pe__gear--big   { animation: pe-gear-cw  3.2s linear infinite; }
.pe__gear--small { animation: pe-gear-ccw 2.1s linear infinite; margin-bottom: 4px; opacity: .7; }
@keyframes pe-gear-cw  { to { transform: rotate(360deg); } }
@keyframes pe-gear-ccw { to { transform: rotate(-360deg); } }

.pe__work-title { font-size: 15px; font-weight: 600; margin-bottom: 10px; }
.pe__work-track {
    height: 6px;
    border-radius: 3px;
    background: var(--pe-line);
    overflow: hidden;
}
.pe__work-fill {
    height: 100%;
    width: 100%;
    border-radius: 3px;
    background: var(--pe-accent);
    /* Полоса растёт из левого края: масштабируем по X, а не меняем ширину (см. шапку раздела). */
    transform-origin: left center;
    transform: scaleX(0);
    /* Длительность ставит скрипт под ожидаемое время шага; здесь только характер движения. */
    transition-property: transform;
    transition-timing-function: cubic-bezier(.25, .8, .35, 1);
    transition-duration: 0s;
}
.pe__work-step { margin-top: 8px; font-size: 13px; color: var(--pe-text); }
.pe__work-note { margin-top: 6px; font-size: 12px; line-height: 1.45; color: var(--pe-text-dim); }

/* Человеку, который просил меньше движения, оставляем смысл и убираем мельтешение. */
@media (prefers-reduced-motion: reduce) {
    .pe__gear--big   { animation-duration: 12s; }
    .pe__gear--small { animation-duration: 9s; }
}

.pe__notice {
    display: flex;
    flex-direction: column;
    gap: 6px;
    justify-content: center;
    min-height: 380px;
    padding: 24px;
    text-align: center;
    background: var(--pe-stage);
    border-radius: var(--pe-radius);
}
.pe__notice-title { font-size: 16px; font-weight: 600; }
.pe__notice-text  { font-size: 13px; color: var(--pe-text-dim); max-width: 46ch; margin: 0 auto; }

.pe__error {
    padding: 9px 12px;
    border-radius: 6px;
    background: #4a2326;
    color: #f3c7c9;
    font-size: 13px;
}

/* ---------------- Лента пресетов под фотографией ---------------- */

/* ---------------- Колонка: витрина пресетов и панели ползунков ---------------- */

/* Колонка ПРИЛИПАЕТ к верху вместе со сценой и прокручивается внутри себя: витрина из
   451 карточки длиннее любого экрана, и тянуть страницу вниз ради неё не надо — кадр должен
   оставаться на виду (заказ владельца 2026-08-16 про фотографию, которая «остаётся сверху»). */
.pe__deck {
    grid-area: deck;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    position: sticky;
    top: 10px;
    align-self: start;
    height: var(--pe-work-h);
    max-height: calc(100vh - var(--pe-chrome));
    /* ⚠ ОБЯЗАТЕЛЬНО. Без обрезки колонка вылезает за свою ячейку вниз и НАКРЫВАЕТ быструю
       строку: сама она ограничена по высоте, а витрина внутри — нет, и переполнение остаётся
       видимым. Поймано замером 19.09.2026 — нажатие на «More adjustments» перехватывал подвал
       витрины, лежавший поверх кнопки. */
    overflow: hidden;
}

.pe__deck-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}

.pe__deck-tabs {
    display: flex;
    gap: 4px;
    padding: 3px;
    background: var(--pe-panel);
    border-radius: 8px;
}
.pe__deck-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    background: transparent;
    border: 0;
    border-radius: 6px;
    color: var(--pe-text-dim);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.pe__deck-tab:hover { color: var(--pe-text); }
.pe__deck-tab.is-active { background: var(--pe-panel-2); color: var(--pe-text); }

/* Вкладки колонки. Показывается та, чьё имя стоит в data-deck: содержимое МЕНЯЕТСЯ,
   а не накрывается — кадр при работе с ползунками остаётся видимым. */
.pe__pane { display: none; min-height: 0; flex: 1 1 auto; }
.pe[data-deck="presets"] .pe__pane--presets,
.pe[data-deck="adjust"]  .pe__pane--adjust { display: flex; flex-direction: column; }

.pe__presets {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
    flex: 1 1 auto;
    background: var(--pe-panel);
    border-radius: 6px;
    padding: 8px;
}

.pe__presets-head { margin-bottom: 8px; }

/* Чипсы категорий: тринадцать наборов, поэтому ряд прокручивается вбок — это список, а не
   поехавшая вёрстка (общий запрет горизонтальной прокрутки касается страницы, см. _common.md,
   и проверка пропускает элементы с data-hscroll). */
.pe__chips {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding-bottom: 4px;
    scrollbar-width: thin;
}
/* Полосу прокрутки у чипсов прячем: системная полоса поперёк ряда кнопок выглядит поломкой,
   а то, что ряд продолжается, видно по обрезанному краю последнего чипса. */
.pe__chips { scrollbar-width: none; -ms-overflow-style: none; }
.pe__chips::-webkit-scrollbar { display: none; }
.pe__chip {
    flex: 0 0 auto;
    padding: 5px 12px;
    background: var(--pe-panel-2);
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--pe-text-dim);
    font-size: 12px;
    white-space: nowrap;
    cursor: pointer;
}
.pe__chip:hover { color: var(--pe-text); }
.pe__chip.is-active {
    background: var(--pe-accent);
    border-color: var(--pe-accent);
    color: #10131a;
    font-weight: 600;
}

/* Имя выбранного пресета — крупнее прочего: при переборе смотрят именно на него. */
.pe__presets-now {
    font-size: 12px;
    font-weight: 600;
    color: var(--pe-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 40%;
}
.pe__presets-note {
    font-size: 11px;
    color: var(--pe-text-dim);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pe__presets-space { flex: 1 1 auto; }

/* Поиск по названию: пресетов больше четырёх сотен. Ширина небольшая — поле стоит в одном ряду
   с выбором категории и не должно вытеснять имя выбранного пресета. */
.pe__presets-search {
    flex: 0 1 150px;
    width: auto;
    font-size: 12px;
}

/* Кнопка «свои пресеты» — рядом со стрелками перебора. */
.pe__presets-add {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 4px 9px;
    background: var(--pe-panel-2);
    border: 1px solid var(--pe-line);
    border-radius: 4px;
    color: var(--pe-text);
    font-size: 12px;
    cursor: pointer;
}
.pe__presets-add:hover { background: var(--pe-line); }

/* Отмена и повтор — только значком: подпись съела бы место в тесном ряду, а жест общеизвестен
   (и продублирован клавишами). Отключённая кнопка гасится, но не исчезает: прыгающий ряд хуже. */
.pe__bar-btn--icon { padding-left: 8px; padding-right: 8px; }
.pe__bar-btn--icon:disabled { opacity: .4; }

/* Гистограмма: верх правой колонки, как в любом редакторе. */
.pe__histogram {
    background: var(--pe-panel);
    border-radius: 6px;
    padding: 7px 8px 6px;
    margin-bottom: 8px;
}
.pe__histogram-canvas {
    display: block;
    width: 100%;
    /* Высота задаётся движком из конфига; здесь только запрет на растяжение по вертикали.
       Потолок — страховка на случай, когда холст посчитан при закрытой вкладке и его
       соотношение сторон оказалось нелепым (см. sizeCanvas в движке). */
    height: auto;
    max-height: 200px;
    background: var(--pe-panel-2);
    border-radius: 4px;
}
.pe__histogram-legend {
    margin-top: 4px;
    font-size: 11px;
    color: var(--pe-text-dim);
    min-height: 14px;
}
/* Выбитые света и проваленные тени — не ошибка, но о них стоит сказать заметнее. */
.pe__histogram-legend.is-warn { color: #e8a33a; }

/* Вес будущего файла: кнопка и результат в одной строке. */
.pe__weight {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
}
.pe__weight-value {
    font-size: 12px;
    font-weight: 600;
    color: var(--pe-text);
}

/* Строка с именем для своего сохранённого вида. */
.pe__presets-save {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
}
.pe__presets-name {
    flex: 0 1 220px;
    width: auto;
    font-size: 12px;
}

/* Итог загрузки своих пресетов и пустая выдача поиска. */
.pe__presets-msg {
    margin-top: 5px;
    font-size: 11px;
    color: var(--pe-text-dim);
}
.pe__presets-empty {
    font-size: 12px;
    color: var(--pe-text-dim);
    padding: 5px 2px;
}

/* Свой пресет: кнопка выбора и кнопка удаления стоят парой. */
.pe__preset-own {
    flex: 0 0 auto;
    display: flex;
    align-items: stretch;
    gap: 2px;
}
.pe__preset-del {
    flex: 0 0 auto;
    width: 22px;
    background: var(--pe-panel-2);
    border: 1px solid transparent;
    border-radius: 4px;
    color: var(--pe-text-dim);
    cursor: pointer;
    font-size: 12px;
    line-height: 1;
}
.pe__preset-del:hover { background: var(--pe-line); color: var(--pe-text); }

.pe__presets-nav {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--pe-panel-2);
    border: 1px solid var(--pe-line);
    border-radius: 4px;
    color: var(--pe-text);
    cursor: pointer;
    font-size: 12px;
}
.pe__presets-nav:hover { background: var(--pe-line); }

/* Лента: одна строка с горизонтальной прокруткой. Полоса прокрутки здесь УМЕСТНА — это
   отдельный список, а не страница (общий запрет горизонтального скролла касается страницы). */
/* ВИТРИНА. Карточки идут сеткой и листаются обычной прокруткой — колесом на столе, пальцем
   на телефоне. Колонок столько, сколько влезло: ширина карточки берётся из конфига
   (library.card_width) и подставляется движком переменной, поэтому на телефоне колонок две,
   а на широком экране — четыре и больше. Прежняя лента показывала семь пресетов из 451. */
.pe__grid {
    /* Запасное значение: настоящую ширину карточки ставит движок из конфига (library.card_width). */
    --pe-card: 100px;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--pe-card), 1fr));
    gap: 8px;
    overflow-y: auto;
    overscroll-behavior: contain;
    min-height: 0;
    flex: 1 1 auto;
    padding-right: 4px;
    scrollbar-width: thin;
}
.pe__grid::-webkit-scrollbar { width: 8px; }
.pe__grid::-webkit-scrollbar-thumb { background: var(--pe-line); border-radius: 4px; }

/* Пресет — карточка: сверху миниатюра ЕГО фотографии с этим пресетом, снизу название.
   По одним названиям пресеты не выбирают: «Portra 400» ничего не говорит тому, кто не снимал
   на плёнку, а картинка говорит всё. Ширина миниатюры задаётся движком из конфига. */
.pe__preset {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 5px;
    width: 100%;
    padding: 4px 4px 6px;
    background: var(--pe-panel-2);
    border: 2px solid transparent;
    border-radius: 8px;
    color: var(--pe-text);
    font-size: 11px;
    text-align: center;
    cursor: pointer;
}

/* Рамка держит место под миниатюру ДО того, как та посчиталась: иначе лента прыгала бы,
   пока картинки догоняют. Размер ставит движок — он знает пропорции снимка. */
.pe__preset-frame {
    display: block;
    width: 100%;
    border-radius: 5px;
    background: var(--pe-line);
    overflow: hidden;
}
.pe__preset-thumb {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.pe__preset-name {
    display: block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pe__preset:hover { background: var(--pe-line); }
/* Выбранная карточка обводится, а не заливается: заливка перекрашивала бы подпись, а глаз
   на витрине ищет именно картинку, и рамка вокруг неё заметна лучше. */
.pe__preset.is-active {
    border-color: var(--pe-accent);
    background: var(--pe-line);
    font-weight: 600;
}

/* Подвал витрины: что выбрано, перебор подряд и работа со своими пресетами. */
.pe__presets-foot {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

/* ---------------- Быстрая строка ---------------- */

/* Четыре ходовые ручки под кадром и дверь к остальным. Строка тянется во всю ширину, потому
   что это главное рабочее место после выбора фильтра: пресет нажат — здесь его подгоняют. */
.pe__quick {
    grid-area: quick;
    display: flex;
    align-items: flex-end;
    gap: 14px;
    flex-wrap: wrap;
    background: var(--pe-panel);
    border-radius: var(--pe-radius);
    padding: 10px 12px;
}
.pe__quick-space { flex: 1 1 auto; }

.pe__quick-slider {
    flex: 1 1 150px;
    min-width: 130px;
    max-width: 260px;
}
.pe__quick-slider .pe__slider-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pe__quick-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    background: var(--pe-panel-2);
    border: 1px solid var(--pe-line);
    border-radius: 8px;
    color: var(--pe-text);
    font-size: 13px;
    white-space: nowrap;
    cursor: pointer;
}
.pe__quick-btn:hover { background: var(--pe-line); }
/* «Auto» выделена цветом: это единственное действие строки, которое само меняет кадр. */
.pe__quick-btn--auto {
    border-color: var(--pe-accent);
    color: var(--pe-accent);
    font-weight: 600;
}
.pe__quick-btn--auto:hover { background: rgba(110, 168, 254, .14); }
.pe__quick-btn--more.is-open { background: var(--pe-line); }

/* Ни синего кольца, ни нативной обводки на новых кнопках раскладки — общесайтовое правило
   (CLAUDE.md: «без bootstrap/браузерного обрамления поля при нажатии»). Глобальный сброс в
   theme.css знает про .btn и поля формы, а эти кнопки свои, поэтому сброс повторён здесь. */
.pe__chip:focus,
.pe__chip:focus-visible,
.pe__deck-tab:focus,
.pe__deck-tab:focus-visible,
.pe__quick-btn:focus,
.pe__quick-btn:focus-visible,
.pe__stage-btn:focus,
.pe__stage-btn:focus-visible,
.pe__top-btn:focus,
.pe__top-btn:focus-visible,
.pe__top-back:focus,
.pe__top-back:focus-visible {
    outline: none;
    box-shadow: none;
}

/* Кнопки на тёмном фоне: сайтовый outline-secondary на нём не читается. */
.pe .btn-outline-secondary {
    color: var(--pe-text);
    border-color: var(--pe-line);
    background: var(--pe-panel);
}
.pe .btn-outline-secondary:hover {
    color: #fff;
    background: var(--pe-panel-2);
    border-color: var(--pe-line);
}

/* ---------------- Вкладка «Adjust»: панели ползунков ---------------- */

/* Высота колонки — по содержимому, своего скролла у неё НЕТ.
   Собственный скролл здесь пробовался и был убран: при раскрытой панели он обрезал список
   посреди ползунка, и это читалось как сломанная вёрстка. Панели, кроме первой, свёрнуты,
   поэтому колонка остаётся обозримой, а длинный список прокручивается вместе со страницей. */
/* Панели ползунков прокручиваются ВНУТРИ вкладки, как и витрина: длина у них разная, а кадр
   должен оставаться на месте в обоих случаях. */
.pe__side {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    min-height: 0;
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: 4px;
    scrollbar-width: thin;
}
.pe__side::-webkit-scrollbar { width: 8px; }
.pe__side::-webkit-scrollbar-thumb { background: var(--pe-line); border-radius: 4px; }

.pe__panel {
    /* Панели не сжимаются: колонка — это прокручиваемый список, и при нехватке места он
       обязан прокручиваться, а не давить заголовки панелей в полоску (замер 19.09.2026:
       свёрнутая панель оказывалась высотой 7 px). */
    flex: 0 0 auto;
    background: var(--pe-panel);
    border-radius: 6px;
    overflow: hidden;
}

.pe__panel-head {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 9px 11px;
    background: transparent;
    border: 0;
    color: var(--pe-text);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    text-align: left;
    cursor: pointer;
}
.pe__panel-head:hover { background: var(--pe-panel-2); }

.pe__panel-name  { flex: 1 1 auto; }
.pe__panel-soon  {
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .04em;
    color: var(--pe-text-dim);
    border: 1px solid var(--pe-line);
    border-radius: 3px;
    padding: 1px 5px;
    text-transform: lowercase;
}
.pe__panel-arrow { font-size: 11px; color: var(--pe-text-dim); transition: transform .15s; }
.pe__panel-head[aria-expanded="true"] .pe__panel-arrow { transform: rotate(180deg); }

.pe__panel.is-unready .pe__panel-name { color: var(--pe-text-dim); }

.pe__panel-body { padding: 2px 11px 11px; }

.pe__group + .pe__group {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--pe-line);
}

.pe__group-title {
    font-size: 11px;
    color: var(--pe-text-dim);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-bottom: 6px;
}

/* Переключатель цветов у микшера: восемь кружков вместо 24 ползунков подряд. */
.pe__tabs {
    display: flex;
    gap: 4px;
    margin: 4px 0 2px;
}
.pe__tab {
    flex: 1 1 0;
    min-width: 0;
    padding: 5px 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    justify-content: center;
}
.pe__tab:hover { background: var(--pe-panel-2); }
.pe__tab.is-active {
    background: var(--pe-panel-2);
    border-color: var(--pe-line);
}
.pe__tab-dot {
    width: 13px;
    height: 13px;
    border-radius: 50%;
    display: block;
}
.pe__tab.is-active .pe__tab-dot { box-shadow: 0 0 0 2px var(--pe-bg), 0 0 0 3px #cfd4db; }

.pe__tab-name {
    font-size: 11px;
    color: var(--pe-text-dim);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin: 6px 0 6px;
}

.pe__slider { margin-bottom: 9px; }
.pe__slider:last-child { margin-bottom: 0; }

.pe__slider-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 2px;
}

.pe__slider-label {
    font-size: 12px;
    color: var(--pe-text);
    margin: 0;
}

.pe__slider-value {
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--pe-text-dim);
}
/* Изменённый ползунок подсвечивается — видно, что тронуто, не разворачивая все панели. */
.pe__slider.is-changed .pe__slider-value { color: var(--pe-accent); }
.pe__slider.is-changed .pe__slider-label { color: #fff; }

/* Редактор тоновой кривой. Квадратный: по горизонтали — исходная яркость, по вертикали —
   что она станет. Внутреннее разрешение холста выше экранного, чтобы линия была гладкой. */
.pe__curve {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--pe-stage);
    border: 1px solid var(--pe-line);
    border-radius: 4px;
    margin-top: 6px;
    cursor: crosshair;
    touch-action: none;
}
.pe__curve-hint {
    font-size: 11px;
    color: var(--pe-text-dim);
    margin-top: 5px;
    line-height: 1.35;
}

/* Флажок (чёрно-белый режим). */
.pe__toggle {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: 10px;
}
.pe__toggle .form-check-input {
    margin: 0;
    flex: 0 0 auto;
    background-color: var(--pe-panel-2);
    border-color: var(--pe-line);
}
.pe__toggle .form-check-input:checked {
    background-color: var(--pe-accent);
    border-color: var(--pe-accent);
}
.pe__toggle-label {
    font-size: 12px;
    margin: 0;
    cursor: pointer;
    color: var(--pe-text);
}
.pe__toggle.is-changed .pe__toggle-label { color: #fff; }

.pe__field { margin-bottom: 9px; }
.pe__field-label { font-size: 12px; margin-bottom: 3px; display: block; }

/* Поля ввода на тёмной сцене: у Bootstrap они светлые и на этой подложке выглядят заплаткой. */
.pe .form-select,
.pe .form-control {
    background-color: var(--pe-panel-2);
    border-color: var(--pe-line);
    color: var(--pe-text);
}
.pe .form-control::placeholder { color: var(--pe-text-dim); }
/* Крестик очистки у поля поиска в webkit по умолчанию тёмный — на тёмном фоне его не видно. */
.pe .form-control[type="search"]::-webkit-search-cancel-button {
    filter: invert(1);
    opacity: .5;
    cursor: pointer;
}

/* Ползунок: сайтовый bootstrap-вид на тёмном фоне не читается, поэтому свой. */
.pe__range {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 16px;
    background: transparent;
    cursor: pointer;
    display: block;
}
.pe__range::-webkit-slider-runnable-track {
    height: 3px;
    border-radius: 2px;
    background: var(--pe-line);
}
.pe__range::-moz-range-track {
    height: 3px;
    border-radius: 2px;
    background: var(--pe-line);
}
.pe__range::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 12px;
    height: 12px;
    margin-top: -4.5px;
    border-radius: 50%;
    background: #cfd4db;
    border: 0;
}
.pe__range::-moz-range-thumb {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #cfd4db;
    border: 0;
}
.pe__slider.is-changed .pe__range::-webkit-slider-thumb { background: var(--pe-accent); }
.pe__slider.is-changed .pe__range::-moz-range-thumb     { background: var(--pe-accent); }

/* ---------------- Мобайл: фото сверху, настройки под ним ---------------- */

/* ---------------- Телефон: кадр сверху и всегда на виду ---------------- */

@media (max-width: 860px) {
    .pe {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "top"
            "stage"
            "deck"
            "quick";
        padding: 8px;
    }
    .pe:not([data-state="ready"]) { grid-template-areas: "stage"; }

    /* КАДР ПРИЛИПАЕТ К ВЕРХУ и остаётся виден, пока листаешь витрину и крутишь ползунки.
       Шторок поверх снимка нет и быть не должно: человек правит фотографию, а не смотрит
       на панель, накрывшую её (прямое замечание владельца 19.09.2026). Поэтому «More
       adjustments» меняет содержимое НИЖНЕЙ части, а кадр стоит на месте. */
    .pe__stage {
        position: sticky;
        top: 0;
        z-index: 3;
        height: auto;
        max-height: none;
        padding-bottom: 6px;
        background: var(--pe-bg);
    }
    .pe__canvas { max-height: 38vh; }   /* на телефоне кадр делит экран с витриной */
    .pe__drop, .pe__canvas-wrap, .pe__notice { min-height: 220px; }
    .pe__canvas-wrap { flex: 0 0 auto; }

    /* Колонка на телефоне идёт следом за кадром обычным потоком, а вот витрина и панели
       прокручиваются ВНУТРИ СЕБЯ и дальше экрана не растут.
       ⚠ Это не украшение. Замер 19.09.2026: без потолка все 451 карточка встают в поток и
       страница вырастает до ~21 000 px — быстрая строка с ползунками уезжает в самый низ, и
       добраться до неё, листая витрину, нельзя. Потолок держит кадр, витрину и ползунки
       на одном экране, как в макете. */
    .pe__deck {
        position: static;
        height: auto;
        max-height: none;
        overflow: visible;
    }
    .pe__grid {
        max-height: 46vh;
        padding-right: 2px;
    }
    .pe__side {
        max-height: 52vh;
        padding-right: 2px;
    }
    .pe__grid { --pe-card: 104px; }

    .pe__presets-now { max-width: 100%; }

    /* БЫСТРАЯ СТРОКА НА ТЕЛЕФОНЕ — сеткой в две колонки, а не переносами: при переносе
       ползунки вставали как придётся, подписи обрезались, и строка читалась как поломка.
       Порядок: «Auto» во всю ширину, под ней четыре ручки парами, внизу сброс и дверь
       в остальные настройки. */
    .pe__quick {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: end;
        gap: 12px 10px;
        /* Прокрутка к строке не должна заводить её ПОД прилипший кадр. */
        scroll-margin-top: 48vh;
    }
    .pe__quick-space { display: none; }
    .pe__quick-slider { min-width: 0; max-width: none; }
    /* Подписи кнопок не прячем — при нехватке места уменьшаем шрифт (правило _common.md). */
    .pe__quick-btn { font-size: 12px; justify-content: center; }
    .pe__quick-btn--auto { grid-column: 1 / -1; }
    .pe__deck { scroll-margin-top: 48vh; }
}

@media (max-width: 400px) {
    .pe__quick { gap: 10px; }
    .pe__quick-btn { font-size: 11px; padding: 6px 9px; }
    .pe__grid { --pe-card: 92px; }
}
