/* =====================================================================
   Sketchbe — стили поверх Bootstrap 5. Вся вёрстка бутстраповская, здесь только
   то, чего в Bootstrap нет: холст, панель инструментов, плитки работ.
   Цвета и размеры — токенами, магических чисел по месту нет.
   ===================================================================== */

:root {
    --pw-bg:          #f6f7fb;
    --pw-surface:     #ffffff;
    --pw-border:      #e2e6ef;
    --pw-ink:         #1f2430;
    --pw-muted:       #6b7280;
    --pw-accent:      #4f46e5;
    --pw-accent-soft: #eef0ff;
    --pw-radius:      .75rem;
    --pw-shadow:      0 1px 2px rgba(16, 24, 40, .06), 0 8px 24px rgba(16, 24, 40, .06);
    --pw-checker:     #eef1f6;
    --pw-gap:         .5rem;
    /* Показ холста. Логический размер задаёт движок (--pw-w/--pw-h), а эти два числа
       решают, каким его показать: мелкий пиксель-арт растягиваем до читаемого, крупный
       холст не раздуваем сверх его же пикселей и не даём вытеснить панель за экран. */
    --pw-canvas-min:  640px;
    --pw-canvas-cap:  50vh;

    /* Тёплая «бумажная» палитра редактора — язык, взятый у sketchpad'а на toolster:
       белая карточка инструмента, кремовая панель, бежевая подложка вокруг листа,
       сам лист чуть тёплый и с тенью, активная кнопка — графитовая заливка. */
    --pw-warm-ink:    #2b2f38;
    --pw-warm-bar:    #f6f5f1;
    --pw-warm-mat:    #eceae3;
    --pw-warm-paper:  #fffdf7;
    --pw-warm-border: #dcd9d0;
    --pw-warm-hover:  #efeee9;
    --pw-warm-accent: #e8590c;
    --pw-radius-sm:   10px;
    --pw-radius-xs:   8px;
    /* Появление меню на телефоне (см. блок «МЕНЮ НА ТЕЛЕФОНЕ — ПОВЕРХ СТРАНИЦЫ»). */
    --pw-nav-open:    .16s;
    --pw-nav-panel:   #fff;
    --pw-nav-veil:    rgba(15, 23, 42, .38);   /* затемнение сайта под открытым меню телефона */
}

/**
 * МЕНЮ НА ТЕЛЕФОНЕ — ПОВЕРХ СТРАНИЦЫ, а не в её потоке (23.09.2026, вторая жалоба
 * владельца: «бургер разворачивается медленно и с тормозами, ближе к концу особенно»).
 *
 * Бутстрап раскрывает меню, ТЯНУЯ ЕГО ВЫСОТУ, а меню стояло в потоке страницы — и
 * каждый кадр раскрытия сдвигал вниз всё под шапкой: редактор с холстом, урок,
 * ленту. Это раскладка и перерисовка страницы целиком шестьдесят раз в секунду; на
 * эмуляторе кадры ровные (он не тормозит видеокарту), на телефоне — нет. Сократить
 * длительность (первая попытка, 23.09.2026) цену кадра не трогает вовсе.
 *
 * Теперь меню — панель ПОВЕРХ страницы: под ним ничего не двигается, а появляется
 * оно прозрачностью и сдвигом — это делает видеокарта, не пересчитывая страницу.
 * Высоту бутстрапа снимаем: его таймер закрытия при нулевой длительности отрабатывает
 * сразу, а анимацию даёт класс `show`.
 */
/*
 * Панель — ПРОДОЛЖЕНИЕ ШАПКИ, а не отдельное окно (владелец 23.09.2026: «меню как
 * часть шапки по цвету, без уголков и отступа сверху, а пока оно открыто, сайт ниже
 * затемняется — как в тестборо»): во всю ширину шапки, вплотную под ней, без
 * скруглений и без рамки по бокам — кромка шапки уходит под панель. Сайт под
 * открытым меню притушен затемнением; шапка остаётся светлой, и меню читается её
 * частью. Нажатие по затемнению закрывает меню (скрипт в layout.php) и до холста
 * не доходит — иначе закрытие меню оставляло бы на рисунке точку.
 */
@media (max-width: 991.98px) {
    .navbar-collapse {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        margin-top: -1px;
        padding: .25rem .85rem .85rem;
        background: var(--pw-nav-panel);
        border-bottom: 1px solid var(--pw-border);
        border-radius: 0;
        box-shadow: 0 14px 24px rgba(0, 0, 0, .10);
    }
    .navbar-collapse.show::after {
        content: "";
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        height: 100vh;
        margin-top: 1px;
        background: var(--pw-nav-veil);
    }
    .navbar-collapse.collapsing {
        height: auto !important;
        transition: none;
    }
    .navbar-collapse.show {
        animation: pw-nav-drop var(--pw-nav-open) cubic-bezier(.22, .61, .36, 1);
    }
}
@keyframes pw-nav-drop {
    from { opacity: 0; transform: translateY(-8px); }
    to   { opacity: 1; transform: none; }
}

/* ВХОД И АККАУНТ ЛЕВЕЕ БУРГЕРА (заказ владельца 23.09.2026). В разметке блок стоит
   ПОСЛЕ меню — его место на экране задаёт `order`, а не порядок в документе. */
.pw-nav-user__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: var(--pw-radius-sm);
    background: transparent;
    color: inherit;
    font-size: 1.35rem;
    line-height: 1;
    text-decoration: none;
}
.pw-nav-user__btn:hover,
.pw-nav-user__btn:focus-visible { background: var(--pw-accent-soft); }
/* Колокольчик в шапке телефона: у него крупнее знак, чем у профиля, и точка
   непрочитанного в правом верхнем углу знака. */
.pw-nav-user .bi-bell { font-size: 1.2rem; }
.pw-nav-user__dot {
    position: absolute;
    top: 9px;
    right: 9px;
    width: 9px;
    height: 9px;
    background: var(--bs-danger);
    border: 2px solid var(--pw-nav-panel);
    border-radius: 50%;
}

@media (max-width: 991.98px) {
    .pw-nav-user   { order: 1; margin-left: auto; }
    .navbar-toggler { order: 2; }
    .navbar-collapse { order: 3; }
}

@media (prefers-reduced-motion: reduce) {
    .navbar-collapse.show { animation: none; }
}

body {
    background: var(--pw-bg);
    color: var(--pw-ink);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* Никакого синего обрамления полей при фокусе — оно раздражает.
   Бургер тоже: после закрытия меню фокус остаётся на нём, и кольцо бутстрапа
   висело вокруг кнопки как «выделенная» (жалоба владельца 23.09.2026). Кромку
   не трогаем: у бургера она своя, а не цвет полей. */
.navbar-toggler:focus { box-shadow: none; outline: none; }
.form-control:focus,
.form-select:focus,
.form-check-input:focus,
.form-control-color:focus,
.form-range:focus,
.btn:focus,
.btn:active:focus {
    box-shadow: none;
    outline: none;
    border-color: var(--pw-border);
}
.form-check-input:checked { border-color: var(--pw-accent); }

a { text-underline-offset: .2em; }

/* ---------------------------------------------------------------
   Холст. Ширина ограничена логическим размером: растягивать 64×64
   пиксель-арт до километра бессмысленно, а сжимать — можно всегда.
   --------------------------------------------------------------- */
/* Подложка вокруг листа: холст лежит НА столе, а не приклеен к странице. */
.pw-canvas-host {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    width: 100%;
    padding: 22px;
    background: var(--pw-warm-mat);
    border: 1px solid var(--pw-warm-border);
    border-radius: var(--pw-radius-sm);
    overflow: auto;
}

/* Ширина показа: не мельче читаемого, не крупнее собственных пикселей холста
   и не выше отведённой доли экрана — иначе панель уезжает за нижний край. */
.pw-editor,
.pw-canvas-host {
    --pw-stage-width: min(
        100%,
        max(calc(var(--pw-w, 800) * 1px), var(--pw-canvas-min)),
        calc(var(--pw-canvas-cap) * var(--pw-w, 800) / var(--pw-h, 600))
    );
}

.pw-stage {
    position: relative;
    width: var(--pw-stage-width, 100%);
    background: var(--pw-warm-paper);
    border-radius: 3px;
    box-shadow: 0 4px 18px rgba(30, 28, 20, .14);
    overflow: hidden;
    touch-action: none;
}

.pw-layer {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    border-radius: 3px;
}

.pw-layer--ink { cursor: crosshair; }

.pw-stage--pixelated .pw-layer { image-rendering: pixelated; }

.pw-editor.is-finished .pw-layer--ink { cursor: not-allowed; }

/* ---------------------------------------------------------------
   Панель инструментов
   --------------------------------------------------------------- */
.pw-editor {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    background: var(--pw-surface);
    border: 1px solid var(--pw-warm-border);
    border-radius: var(--pw-radius);
    box-shadow: 0 2px 14px rgba(30, 28, 20, .06);
    padding: 1rem;
    color: var(--pw-warm-ink);
}

.pw-toolbar,
.pw-settings,
.pw-actions,
.pw-hud {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--pw-gap);
}

.pw-toolbar {
    gap: .5rem .625rem;
    padding: .5rem;
    background: var(--pw-warm-bar);
    border: 1px solid var(--pw-warm-border);
    border-radius: var(--pw-radius-sm);
}

/* Группы — белые «таблетки» на кремовой панели: инструменты, размеры, цвета. */
.pw-group {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: 3px;
    background: #fff;
    border: 1px solid var(--pw-warm-border);
    border-radius: var(--pw-radius-xs);
    flex-wrap: wrap;
}

.pw-tool {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    border: 0;
    background: transparent;
    color: var(--pw-warm-ink);
    font-size: .9rem;
    font-weight: 600;
    line-height: 1;
    padding: .4375rem .625rem;
    border-radius: var(--pw-radius-xs);
    cursor: pointer;
}
.pw-tool i { font-size: 1.05rem; line-height: 0; }
.pw-tool:hover { background: var(--pw-warm-hover); }
.pw-tool.active { background: var(--pw-warm-ink); color: #fff; }

/* Размер — точками, как в бумажном блокноте: видно, чем рисуешь, до первого штриха. */
.pw-size {
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    border-radius: var(--pw-radius-xs);
    cursor: pointer;
}
.pw-size:hover { background: var(--pw-warm-hover); }
.pw-size.is-active { background: var(--pw-warm-ink); }
.pw-size__dot {
    display: block;
    width: var(--d, 8px);
    height: var(--d, 8px);
    max-width: 18px;
    max-height: 18px;
    background: var(--pw-warm-ink);
    border-radius: 50%;
}
.pw-size.is-active .pw-size__dot { background: #fff; }

.pw-palette { gap: .3125rem; }

.pw-swatch {
    width: 26px;
    height: 26px;
    padding: 0;
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px var(--pw-warm-border);
    border-radius: 50%;
    cursor: pointer;
}
.pw-swatch.is-active { box-shadow: 0 0 0 2px var(--pw-warm-accent); }
.pw-swatch--editable::after { content: '×'; color: #fff; font-size: .8rem; opacity: 0; }
.pw-swatch--editable:hover::after { opacity: .9; }

.pw-swatch-custom.form-control-color {
    width: 26px;
    height: 26px;
    padding: 2px;
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px var(--pw-warm-border);
    border-radius: 50%;
}

/* --- конструктор среды: ФОРМА ХОЛСТА ---
   Размер выбирается прямоугольником, а не числами (заказ владельца 21.09.2026):
   «квадрат / альбом / портрет» видно с одного взгляда, а цифры под фигуркой читают
   только тогда, когда они уже понадобились. Пропорцию фигурке задаёт РАЗМЕТКА из
   чисел пресета (`engine.canvas.presets`) — здесь этих чисел нет и быть не может,
   иначе правка пресета в конфиге не меняла бы картинку. */
.pw-shapes {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
}
.pw-shape {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .15rem;
    /* Плитки одного роста и НЕ растягиваются на остаток строки: растянутая
       «Custom» во всю ширину читалась бы главным выбором, а она запасной. */
    flex: 0 0 auto;
    min-width: 5.5rem;
    padding: .4rem .3rem .35rem;
    background: #fff;
    border: 1px solid var(--pw-warm-border);
    border-radius: .6rem;
    cursor: pointer;
    line-height: 1.15;
}
.pw-shape.is-active {
    border-color: var(--pw-warm-accent);
    box-shadow: 0 0 0 2px var(--pw-warm-accent);
}
/* Браузерного обрамления при нажатии на сайте нет (правило в шапке файла). Клавиатуру
   при этом не бросаем: у фокуса свой аккуратный признак — та же рамка токеном, что
   у выбранной плитки, но без второго кольца. */
.pw-shape:focus { outline: none; }
.pw-shape:focus-visible { border-color: var(--pw-warm-accent); }
/* Площадка постоянного роста: без неё фигурки разной высоты рвали бы ряд подписей. */
.pw-shape__box {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--pw-shape-side);
    height: var(--pw-shape-side);
}
.pw-shape__form {
    background: var(--pw-warm-mat);
    border: 1.5px solid var(--pw-muted);
    border-radius: 2px;
}
/* У «Custom» пропорции ещё нет — поэтому у него и фигуры нет, а есть пунктирное
   место под неё: сплошной прямоугольник обещал бы конкретную форму. */
.pw-shape__form--custom {
    width: 100%;
    height: 100%;
    background: none;
    border-style: dashed;
}
.pw-shape__name { font-size: .75rem; font-weight: 600; }
.pw-shape__dim {
    font-size: .6875rem;
    color: var(--pw-muted);
    font-variant-numeric: tabular-nums;
}

/* --- конструктор среды: кисти со звёздочкой и заморозкой, стартовая картинка --- */
.pw-cfgbrushes { display: flex; flex-direction: column; gap: .25rem; }

.pw-cfgbrush {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    min-height: 2rem;
}
.pw-cfgbrush__on { margin: 0; }
/* `hidden` у группы кнопок сам по себе не работает: .btn-group ставит display:inline-flex
   и перебивает браузерное правило скрытия. */
.pw-cfgbrush__acts[hidden] { display: none; }
/* Звёздочка и замки — мелкие кнопки: они подпись кисти не перевешивают. */
.pw-cfgbrush__acts .btn {
    --bs-btn-padding-y: .1rem;
    --bs-btn-padding-x: .4rem;
    --bs-btn-font-size: .75rem;
    display: inline-flex;
    align-items: center;
    gap: .2rem;
}

.pw-startpick {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
}
.pw-startpick__item {
    width: 58px;
    height: 58px;
    padding: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    border: 1px solid var(--pw-warm-border);
    border-radius: .5rem;
    cursor: pointer;
}
.pw-startpick__item.is-active { box-shadow: 0 0 0 2px var(--pw-warm-accent); }
.pw-startpick__item img { max-width: 100%; max-height: 100%; object-fit: contain; }
.pw-startpick__none {
    font-size: .6875rem;
    line-height: 1.1;
    padding: .25rem;
    color: var(--pw-muted);
}

.pw-settings { padding: 0 .125rem; }

.pw-setting {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .875rem;
    color: var(--pw-muted);
}
.pw-setting__name { min-width: 4.5rem; }
.pw-setting__range { width: 9rem; }
.pw-setting__value { min-width: 3rem; font-variant-numeric: tabular-nums; }

.pw-hud {
    font-size: .9rem;
    color: var(--pw-muted);
    gap: 1rem;
    padding: 0 .125rem;
}
.pw-hud__item:empty { display: none; }

/* Действия — справа, как в блокноте: главное действие тёмное, остальное тихое. */
.pw-actions { justify-content: flex-end; }
.pw-actions .btn { --bs-btn-padding-y: .4rem; --bs-btn-padding-x: .7rem; font-weight: 600; }
.pw-actions .pw-publish {
    --bs-btn-bg: var(--pw-warm-ink);
    --bs-btn-border-color: var(--pw-warm-ink);
    --bs-btn-hover-bg: #1f2329;
    --bs-btn-hover-border-color: #1f2329;
    --bs-btn-disabled-bg: var(--pw-warm-ink);
    --bs-btn-disabled-border-color: var(--pw-warm-ink);
}

/* =====================================================================
   Оболочка «studio» — вид по макету владельца (07.09.2026).

   Обвязка (линейка, строка свойств, правая колонка, статус-бар) — светлая и
   нейтральная, как в макете. А сам ЛИСТ остаётся тёплым и с тенью: это отдельное
   решение владельца от 03.09.2026, и макет ему не противоречит — он про раскладку
   и инструменты, а не про цвет бумаги. Подложка вокруг листа сделана нейтральной,
   чтобы бежевое не спорило с серой обвязкой.

   Старая панель (.pw-toolbar и соседи выше) НЕ удалена: конфиг editor.shell умеет
   вернуть её одним словом, и без своих стилей она была бы сломана.
   ===================================================================== */
:root {
    --pw-st-panel:  #ffffff;
    --pw-st-quiet:  #fbfcfe;
    --pw-st-mat:    #eef1f6;
    --pw-st-border: #e3e7ee;
    --pw-st-ink:    #1f2430;
    --pw-st-muted:  #6b7280;
    --pw-st-hover:  #f2f4f8;
    --pw-st-active: #e8edff;
    --pw-st-accent: #3b6cf6;
    /* Плашка (поле ввода, кнопка-знак, всплывающая панель) и рамка ВЫБРАННОГО.
       Заведены токенами 12.09.2026 вместе с темами: тема — это шкура, и она обязана
       перекрашиваться сменой значений, а не переписыванием каждого правила. */
    --pw-st-field:  #ffffff;
    --pw-st-edge:   var(--pw-st-edge);
    --pw-rail-w:    84px;
}

.pw-studio {
    display: block;
    padding: 0;
    overflow: hidden;
    /* Обвязки у этой оболочки больше, чем у старой панели, поэтому листу отдаётся
       больше высоты экрана — иначе холст в окне редактора выглядит маркой.
       На обычном ноутбуке этого хватает, чтобы холст 800×600 показывался пиксель
       в пиксель: рисовать по своему же разрешению точнее, чем по уменьшенному. */
    --pw-canvas-cap: 66vh;
    /* ЧИСЛА КОЛОНОК. Шапка обязана повторять колонки тела (заказ владельца
       21.09.2026): New стоит по центру линейки, а отмена и возврат начинаются
       правее левого края строки свойств. Значит, поля и зазоры тела — это числа
       ОБОЛОЧКИ, а не значения, вписанные по месту в каждое правило: тема двигает
       их сменой токена, и шапка узнаёт об этом сама. На узком экране колонок нет —
       там `--pw-head-lead/hist` гасятся медиазапросом. */
    --pw-gutter:     0px;     /* боковое поле тела — оно же НИЖНЕЕ (см. `__body`) */
    --pw-colgap:     0px;     /* зазор между колонками */
    /* Рост строки состояния: по нему равняются надпись размера и таблетка зума
       (заказ владельца 22.09.2026 — «размеры и зум нужно отравнять»). Число одно,
       иначе два края одной строки разъезжаются по высоте. Оно же держит полосу
       НИЗКОЙ: зум — дополнительная опция, а не ручка инструмента. */
    --pw-status-h:   26px;
    --pw-optbar-pad: .65rem;  /* боковое поле строки свойств */
    --pw-head-gap:   .4rem;   /* зазор между ячейками шапки */
    --pw-head-lead:  var(--pw-rail-w);  /* ячейка New = колонка линейки */
    /* Отмена и возврат начинаются от содержимого строки свойств; зазор шапки
       флекс уже поставил сам, поэтому он вычитается. */
    --pw-head-hist:  calc(var(--pw-colgap) + var(--pw-optbar-pad) - var(--pw-head-gap));
    background: var(--pw-st-panel);
    border-color: var(--pw-st-border);
    color: var(--pw-st-ink);
}

.pw-studio__body {
    display: grid;
    /* Колонки ДВЕ: линейка и холст. Правая колонка цвета убрана 22.09.2026 —
       цвет открывается знаком линейки в своём окне. */
    grid-template-columns: var(--pw-rail-w) minmax(0, 1fr);
    align-items: stretch;
    gap: var(--pw-colgap);
    padding-inline: var(--pw-gutter);
    /* Поле СНИЗУ — то же, что по бокам (заказ владельца 22.09.2026: «в нижней части
       редактора нет отступов, зум и размеры тупо впритык стоят»). Берётся тем же
       токеном: у темы, которая раздвигает колонки, низ обязан раздвинуться на
       столько же, а у темы без полей его по-прежнему нет. */
    padding-bottom: var(--pw-gutter);
}
.pw-studio__center { display: flex; flex-direction: column; min-width: 0; }

/* ---- левая линейка ---- */
.pw-rail {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    padding: .5rem .35rem;
    background: var(--pw-st-quiet);
    border-right: 1px solid var(--pw-st-border);
    overflow: auto;
    /* ПОЛОСЫ ПРОКРУТКИ В ЛИНЕЙКЕ НЕТ (владелец 21.09.2026: «скроллбара быть не должно»).
       Дело не только в виде: полоса забирает ширину у колонки, и подписи знаков
       обрезались («Eyedropper» упиралось в неё). Прокрутка колесом при этом цела —
       на низком окне до нижнего знака по-прежнему можно добраться. */
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* РОСТ ОДНОГО МЕСТА линейки: картинка знака плюс строка подписи. Одно число на
       пустое место и на кнопку разворачивания — они занимают ОДНО И ТО ЖЕ место. */
    --pw-rail-slot: calc(34px + 1px + 1.5 * .6875rem);
}
.pw-rail::-webkit-scrollbar { width: 0; height: 0; }
.pw-rail__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    padding: .4rem .2rem .3rem;
    border: 1px solid transparent;
    background: transparent;
    border-radius: 12px;
    cursor: pointer;
}
.pw-rail__item:hover { background: var(--pw-st-hover); }
.pw-rail__item.is-active { background: var(--pw-st-active); border-color: var(--pw-st-edge); }
.pw-rail__icon { display: block; position: relative; line-height: 0; }
/* ЗНАК-ПАНЕЛЬ (цвет) — ЭТО САМ ЦВЕТ, а не картинка с кружком в углу (заказ
   владельца 22.09.2026: «просто цвет без иконки, просто кружок с цветом»).
   Картинки палитры у знака нет вовсе, поэтому место знака держит не `img`, а
   этот кружок: он занимает ВЕСЬ рост знака, как занимала бы картинка, и полоса
   от этого не едет. Это единственное место, где видно, чем сейчас рисуют
   (свотча в шапке с 22.09.2026 нет, правило «одно действие — одно место»). */
.pw-rail__item--panel .pw-rail__icon {
    width: 34px;
    height: 34px;
}
.pw-rail__swatch {
    position: absolute;
    inset: 2px;
    border-radius: 50%;
    /* ОПРАВА обязательна: без неё белая краска слилась бы с линейкой и знак
       пропал бы совсем. Светлое кольцо отделяет краску от фона, тёмная кромка
       держит границу, внутренняя тень даёт объём — как у настоящего свотча. */
    box-shadow:
        0 0 0 2px var(--pw-st-quiet),
        0 0 0 3px rgba(16, 24, 40, .22),
        0 1px 3px rgba(16, 24, 40, .22),
        inset 0 -2px 4px rgba(16, 24, 40, .14);
}
.pw-rail__icon img { width: 34px; height: 34px; display: block; }
.pw-rail__label {
    font-size: .6875rem;
    font-weight: 600;
    color: var(--pw-st-muted);
    letter-spacing: -.01em;
}
.pw-rail__item.is-active .pw-rail__label { color: var(--pw-st-accent); }
.pw-rail__item.is-soon { opacity: .45; }

/* ПУСТОЕ МЕСТО линейки (`'~'` в `editor.rail`, заказ владельца 21.09.2026): держит
   высоту одного знака, но знаком не является — ни кнопки, ни подписи, ни нажатия.
   Высота собрана из тех же двух слагаемых, что и у знака: картинка и строка подписи. */
.pw-rail__gap {
    display: block;
    flex: 0 0 auto;
    padding: .4rem .2rem .3rem;
    border: 1px solid transparent;
    pointer-events: none;
}
.pw-rail__gap::before {
    content: '';
    display: block;
    width: 34px;
    height: var(--pw-rail-slot);
}

/* ---- СПРЯТАННАЯ ЧАСТЬ ЛИНЕЙКИ ('>' в `editor.rail`) ----
   Владелец 21.09.2026: «юзер по умолчанию видит три инструмента, а остальные
   разворачивает нажатием, и они красиво развернутся в текущий вид».
   Высота растёт САМА (`grid-template-rows: 0fr → 1fr`): числа высоты нет ни в CSS,
   ни в JS, поэтому список из пяти знаков и из восьми открываются одинаково ровно.
   `visibility` гасится ПОСЛЕ анимации — свёрнутый знак не должен ловить Tab. */
.pw-rail__rest {
    display: grid;
    grid-template-rows: 0fr;
    gap: inherit;
    visibility: hidden;
    transition: grid-template-rows .28s cubic-bezier(.22, .61, .36, 1), visibility 0s linear .28s;
}
.pw-rail.is-open .pw-rail__rest {
    grid-template-rows: 1fr;
    visibility: visible;
    transition: grid-template-rows .28s cubic-bezier(.22, .61, .36, 1), visibility 0s;
}
.pw-rail__restIn {
    display: flex;
    flex-direction: column;
    gap: inherit;
    min-height: 0;
    overflow: hidden;
}
/* Знаки не просто появляются, а выезжают следом за высотой. */
.pw-rail__restIn > * {
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity .18s ease, transform .24s cubic-bezier(.22, .61, .36, 1);
}
.pw-rail.is-open .pw-rail__restIn > * { opacity: 1; transform: none; }

/* Кнопка-намёк: шеврон с короткой подписью (владелец 21.09.2026: «подпиши More не
   слишком броским цветом и поменьше шрифтом»). Она стоит в колонке знаков и обязана
   быть ТИШЕ их: подпись мельче и того же приглушённого тона, что подписи знаков. */
.pw-rail__more {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    padding: .15rem 0;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: var(--pw-st-muted);
    cursor: pointer;
}
.pw-rail__moreIn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    line-height: 1;
}
.pw-rail__moreLabel {
    font-size: .6rem;
    font-weight: 600;
    color: var(--pw-st-muted);
    letter-spacing: -.01em;
}
.pw-rail__more:hover { background: var(--pw-st-hover); color: var(--pw-st-ink); }
/* Под курсором кнопка темнеет ЦЕЛИКОМ: подпись — её часть, а не отдельная надпись. */
.pw-rail__more:hover .pw-rail__moreLabel { color: inherit; }
.pw-rail__more .bi {
    display: block;
    line-height: 1;
    transition: transform .28s cubic-bezier(.22, .61, .36, 1);
}
.pw-rail.is-open .pw-rail__more .bi { transform: rotate(180deg); }
/* Развернули — кнопка уезжает НАВЕРХ, в пустое место линейки, и занимает РОВНО ЕГО:
   то же место, тот же рост, вместо него. Поэтому развёрнутая линейка стоит пиксель
   в пиксель там же, где стояла до всей этой правки (владелец 21.09.2026: «сдвигов
   относительно положения ДО правок быть не должно»), и лишней высоты, от которой
   заводилась прокрутка, у неё нет. */
.pw-rail.is-open .pw-rail__gap { display: none; }
.pw-rail.is-open .pw-rail__more {
    order: -1;
    display: grid;
    place-items: center;
    padding: .4rem .2rem .3rem;
    border: 1px solid transparent;
    border-radius: 12px;
}
/* Знак с подписью лежат НА месте слота, а не под ним: ячейка одна и та же. */
.pw-rail.is-open .pw-rail__more::before {
    content: '';
    grid-area: 1 / 1;
    width: 34px;
    height: var(--pw-rail-slot);
}
.pw-rail.is-open .pw-rail__moreIn { grid-area: 1 / 1; }

@media (prefers-reduced-motion: reduce) {
    .pw-rail__rest,
    .pw-rail__restIn > *,
    .pw-rail__more .bi { transition: none; }
}

/* ---- строка свойств ---- */
/* Строка свойств НЕ переносится: перенос рвёт её на куски и отправляет отмену на второй
   ряд. Не влезло — ручки прокручиваются вбок, а отмена/возврат остаются на месте:
   они нужны всегда и уезжать за край не должны. */
.pw-optbar {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: .4rem;
    padding: .5rem var(--pw-optbar-pad);
    background: var(--pw-st-panel);
    border-bottom: 1px solid var(--pw-st-border);
}
.pw-optbar__scroll {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: .4rem .6rem;
    min-width: 0;
    flex: 1 1 auto;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
}
.pw-optbar__scroll > * { flex: 0 0 auto; }


/* Имя активного инструмента: строка свойств не должна быть безымянной полосой.
   БЕЗ ЖИРНОГО (заказ владельца 22.09.2026: «убери болд у названия панелей в верхних
   настройках»): имя стоит первым в строке и так, а жирным оно кричало громче самих
   ручек, ради которых строка и существует. */
.pw-optbar__tool {
    font-size: .8125rem;
    font-weight: 500;
    color: var(--pw-st-ink);
    white-space: nowrap;
    padding-right: .15rem;
}

.pw-opt {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin: 0;
    font-size: .8125rem;
    color: var(--pw-st-muted);
}
.pw-opt__name { font-weight: 600; white-space: nowrap; }
/* «Size: 4» — двоеточие ставит вёрстка, а не локализация: это пунктуация формы,
   а не текст, и в ключе `prop.size` ему делать нечего. */
.pw-opt--num .pw-opt__name::after { content: ':'; }

/* ---- ЧИСЛО: «Подпись: [значение] ⌄» ----
   Постоянно видимого ползунка у числа НЕТ ни у одного инструмента (заказ владельца
   21.09.2026). Число тянут по горизонтали, кликают — вводят, крутят колесом и
   стрелками ↑↓, а ползунок на весь диапазон открывается шевроном справа. */
.pw-num {
    display: inline-flex;
    align-items: center;
    gap: .1rem;
    padding: .05rem .1rem .05rem .15rem;
    background: var(--pw-st-field);
    border: 1px solid var(--pw-st-border);
    border-radius: 8px;
}
.pw-num__field {
    width: 3.1rem;
    padding: .1rem .2rem;
    text-align: center;
    font: inherit;
    font-variant-numeric: tabular-nums;
    color: var(--pw-st-ink);
    background: transparent;
    border: 0;
    outline: none;
    /* Плашку ТЯНУТ — значит курсор обязан это обещать. */
    cursor: ew-resize;
}
.pw-num__field:focus { cursor: text; }
/* Ввод отмечает себя РАМКОЙ ручки, а не выделением числа (заказ владельца
   21.09.2026): курсор стоит справа от значения, а плашка чуть меняет кромку —
   этого хватает, чтобы понять, куда сейчас пойдут цифры. */
.pw-num:focus-within { border-color: var(--pw-st-edge); }
.pw-num.is-scrub { border-color: var(--pw-st-accent); }
.pw-num.is-scrub .pw-num__field { user-select: none; }
.pw-num__unit { font-size: .75rem; color: var(--pw-st-muted); }
.pw-num__more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    font-size: .75rem;
    color: var(--pw-st-muted);
    background: transparent;
    border: 0;
    border-radius: 6px;
    cursor: pointer;
}
.pw-num__more:hover { background: var(--pw-st-hover); color: var(--pw-st-ink); }
.pw-num__more .bi { font-size: .7rem; line-height: 1; }

/* Кружок НАСТОЯЩЕГО диаметра внутри ручки размера: кисть 40 и кисть 80 обязаны
   отличаться на глаз (правило 3 оболочки). Больше плашки — обрезается, и это честно
   (число рядом). Мелкая кисть кружок не показывает: точка в 4 px — мусор. */
.pw-num__dot {
    display: block;
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
}

/* Ползунок во всплывашке: грубая наводка на весь диапазон — то, ради чего её открыли.
   Больше в ней НЕТ НИЧЕГО (заказ владельца 21.09.2026): ни заголовка, ни числа с
   единицами. Панель вылезает из-под той самой ручки, подпись которой человек только
   что прочитал, а значение стоит в поле над ней и меняется, пока тянут бегунок. */
.pw-pop--num { width: 188px; padding: .45rem .55rem; }
.pw-numpop { display: flex; align-items: center; }
/* Бегунок красится ЧЕРНИЛАМИ оболочки: синий бегунок Bootstrap в этой панели —
   такой же чужой цвет, как синее обрамление полей при фокусе (общий сброс выше).
   Цвет здесь ЗАБИТ правилами, а не переменной `--bs-form-range-*`: в нашей сборке
   Bootstrap 5.1 он записан литералом `#0d6efd`, и переменной его не перебить.
   Правила бегунка у webkit и у gecko ОТДЕЛЬНЫЕ: незнакомый псевдоэлемент в списке
   селекторов роняет всё правило целиком, и покрасились бы ноль браузеров. */
.pw-numpop__range { flex: 1 1 auto; }
/* Бегунок — ДОМИК ОСТРИЁМ ВВЕРХ, как в Photoshop (заказ владельца 21.09.2026):
   остриё показывает точку на дорожке, а круглый бегунок её только закрывает.
   Форма вырезана `clip-path` из обычного прямоугольного бегунка — своего элемента
   у него нет, нарисовать в нём треугольник нечем. Правила webkit и gecko ОТДЕЛЬНЫЕ:
   незнакомый псевдоэлемент в списке селекторов роняет правило целиком. */
.pw-numpop__range::-webkit-slider-thumb {
    width: 13px;
    height: 15px;
    /* Дорожка Bootstrap — 8px; бегунок садится на неё серединой: (8 − 15) / 2. */
    margin-top: -3.5px;
    border-radius: 2px;
    background-color: var(--pw-st-ink);
    clip-path: polygon(50% 0%, 100% 42%, 100% 100%, 0% 100%, 0% 42%);
}
.pw-numpop__range::-moz-range-thumb {
    width: 13px;
    height: 15px;
    border: 0;
    border-radius: 2px;
    background-color: var(--pw-st-ink);
    clip-path: polygon(50% 0%, 100% 42%, 100% 100%, 0% 100%, 0% 42%);
}
.pw-numpop__range::-webkit-slider-runnable-track { background-color: var(--pw-st-border); }
.pw-numpop__range::-moz-range-track { background-color: var(--pw-st-border); }

/* ---- ВЫБОР КАРТИНКИ: кнопка со знаком + сетка знаков ---- */
.pw-pick {
    display: inline-flex;
    align-items: center;
    gap: .15rem;
    min-width: 44px;
    height: 28px;
    padding: 0 .25rem;
    background: var(--pw-st-field);
    border: 1px solid var(--pw-st-border);
    border-radius: 8px;
    color: var(--pw-st-ink);
    cursor: pointer;
}
.pw-pick:hover { background: var(--pw-st-hover); }
.pw-pick__face {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    font-size: 1rem;
    line-height: 1;
}
.pw-pick .bi-chevron-down { font-size: .65rem; color: var(--pw-st-muted); }

.pw-pop--pick { width: 226px; padding: .5rem; }
.pw-pickgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .25rem; }
.pw-pickitem {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .15rem;
    padding: .4rem .2rem .3rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 9px;
    color: var(--pw-st-ink);
    cursor: pointer;
}
.pw-pickitem:hover { background: var(--pw-st-hover); }
.pw-pickitem.is-active { background: var(--pw-st-active); border-color: var(--pw-st-edge); }
.pw-pickitem__art { font-size: 1.15rem; line-height: 1.2; }
.pw-pickitem__name { font-size: .6875rem; color: var(--pw-st-muted); text-align: center; }

/* Инструмент без ручек говорит, что он умеет, вместо пустой полосы. */
.pw-opt__hint { font-size: .8125rem; color: var(--pw-st-muted); white-space: nowrap; }

.pw-optbtn {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .5rem;
    font-size: .8125rem;
    background: var(--pw-st-field);
    border: 1px solid var(--pw-st-border);
    border-radius: 8px;
    color: var(--pw-st-ink);
    cursor: pointer;
    white-space: nowrap;
}
.pw-optbtn:hover { background: var(--pw-st-hover); }

/* Отмена и возврат стоят парой и потому вплотную: это одно действие в две стороны. */
.pw-history { display: inline-flex; gap: 0; }

.pw-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    background: transparent;
    border-radius: 8px;
    color: var(--pw-st-muted);
    cursor: pointer;
}
.pw-icon-btn:hover:not(:disabled) { background: var(--pw-st-hover); color: var(--pw-st-ink); }
/* ВЗВЕДЁННАЯ кнопка (разовая пипетка окна цвета) видна нажатой: человек должен
   понимать, что следующее нажатие по холсту снимет цвет, а не проведёт линию. */
.pw-icon-btn[aria-pressed="true"] { background: var(--pw-st-active, var(--pw-st-hover)); color: var(--pw-st-ink); }
/* Свой знак (отмена, возврат) ведёт себя как шрифтовой: размер от кегля, цвет от кнопки. */
.pw-glyph { width: 1em; height: 1em; display: block; }
.pw-icon-btn:disabled { opacity: .35; cursor: default; }

/* ---- шапка редактора: знак, New, отмена, возврат, цвет, Save, Publish ----
   Отмена и возврат стоят ЗДЕСЬ, а не в строке свойств: это действия над работой,
   а не ручки инструмента (§2 спеки владельца 12.09.2026). Имени работы и подписи
   темы в полосе нет с 21.09.2026 — заголовок страницы стоит под холстом (этап E). */
.pw-head {
    display: flex;
    align-items: center;
    gap: var(--pw-head-gap);
    /* Слева у шапки не своё поле, а поле ТЕЛА: только так первая ячейка совпадает
       с колонкой линейки. */
    padding: .4rem .6rem .4rem var(--pw-gutter);
    border-bottom: 1px solid var(--pw-st-border);
    background: var(--pw-st-quiet);
}
/* Распорка вместо имени работы: имени в шапке нет с 21.09.2026, а правый край
   полосы (цвет, полный экран, Save, Publish) обязан остаться правым краем. */
.pw-head__gap { flex: 1 1 auto; min-width: 0; }
/* Отмена и возврат — такие же кнопки полосы, как New, полный экран и Save
   (`btn btn-sm btn-outline-secondary`, заказ владельца 21.09.2026): рамка, угол и
   поля у них приходят оттуда же, и тема красит их теми же токенами. Своего здесь
   два: КЕГЕЛЬ (знак `.pw-glyph` — квадрат в 1em, и 1.3em делает его крупнее букв
   соседей — владелец просил сменить оформление, а не иконку) и выкладка содержимого
   флексом: у `.btn` высоту задаёт строка текста, а текста тут нет — есть знак. */
.pw-head__undo,
.pw-head__redo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3em;
}
/* Пара начинается не у края шапки, а у СОДЕРЖИМОГО строки свойств: её левая
   граница обязана остаться левее кнопок (заказ владельца 21.09.2026). */
.pw-head .pw-history { margin-left: var(--pw-head-hist); }
/* Кнопка поворота — свой знак обводкой (`GLYPHS.rotate`), ростом с соседей-шрифтовых. */
.pw-head__rot { display: inline-flex; align-items: center; justify-content: center; }
.pw-head__rot .pw-glyph { width: 1em; height: 1em; }
.pw-head__export { --bs-btn-padding-y: .25rem; --bs-btn-padding-x: .6rem; font-weight: 600; }

/* Действия над РАБОТОЙ (New, Publish) стоят в шапке, рядом с отменой и выгрузкой
   (этап E разбора 12.09.2026, §5.1). Отдельной плашкой под холстом они оказывались
   на границе экрана, и «Publish» уезжал за нижний край окна. */
.pw-studio .pw-head .pw-actions {
    flex: 0 0 auto;
    gap: .35rem;
    padding: 0;
    background: transparent;
    border: 0;
}
/* Группа слева (New) — это ячейка шириной с ЛИНЕЙКУ, и кнопка стоит по её центру:
   над линейкой, а не над её левым краем (заказ владельца 21.09.2026). */
.pw-studio .pw-head .pw-actions--lead {
    flex: 0 0 var(--pw-head-lead);
    justify-content: center;
}
.pw-studio .pw-head .pw-actions .btn { --bs-btn-padding-y: .25rem; --bs-btn-padding-x: .6rem; }

/* Разделитель линейки: группы операций (рисование / фигуры / навигация). */
.pw-rail__sep {
    display: block;
    height: 1px;
    margin: .35rem .5rem;
    background: var(--pw-st-border);
}

/* ---- кнопка текущей кисти и библиотека кистей ----
   В ЗАКРЫТОМ виде кнопка — знак и имя (заказ владельца 21.09.2026): настоящий штрих
   занимал в строке 74 px ради картинки, которую всё равно сравнивают в библиотеке.
   В библиотеке он остаётся у КАЖДОЙ кисти и нарисован тем же кодом, что ведёт линию
   по холсту, — картинка кисти врала бы о её характере.

   Знак кисти — строгий контур, красится от кнопки: файл кладётся МАСКОЙ, а не
   картинкой, потому что `<img>` цвет текста не наследует, а знак обязан темнеть
   вместе с именем на выбранной строке. */
.pw-brushicon {
    display: block;
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    background: currentColor;
    -webkit-mask: var(--pw-icon) center / contain no-repeat;
    mask: var(--pw-icon) center / contain no-repeat;
}
.pw-brushbtn {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .15rem .4rem .15rem .3rem;
    background: var(--pw-st-field);
    border: 1px solid var(--pw-st-border);
    border-radius: 10px;
    color: var(--pw-st-ink);
    font-size: .8125rem;
    font-weight: 600;
    cursor: pointer;
}
.pw-brushbtn:hover { background: var(--pw-st-hover); }
.pw-brushbtn__name { white-space: nowrap; }

.pw-pop--brushes { width: 236px; padding: .45rem; max-height: 70vh; overflow-y: auto; }
.pw-pop__head {
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--pw-st-muted);
    margin-bottom: .35rem;
}
.pw-pop__group {
    margin: .5rem 0 .3rem;
    font-size: .6875rem;
    font-weight: 700;
    color: var(--pw-st-muted);
}
/* Знак и имя — в одну строку, настоящий штрих — под ними во всю ширину. */
.pw-brushrow {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: .1rem .45rem;
    width: 100%;
    padding: .35rem .45rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 9px;
    cursor: pointer;
    text-align: left;
    color: var(--pw-st-ink);
}
.pw-brushrow:hover { background: var(--pw-st-hover); }
.pw-brushrow.is-active { background: var(--pw-st-active); border-color: var(--pw-st-edge); }
.pw-brushrow .pw-brushicon { grid-column: 1; }
.pw-brushrow__name { grid-column: 2; font-size: .8125rem; font-weight: 600; color: var(--pw-st-ink); }
.pw-brushrow__art { grid-column: 1 / -1; display: block; width: 100%; height: 34px; }

/* ---- дополнительные настройки […] ----
   Кнопка существует, только если под ней что-то есть: пустого […] не бывает. */
.pw-pop--adv { width: 250px; padding: .55rem .6rem; }
.pw-opt--stacked {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: .2rem .5rem;
    margin: 0 0 .45rem;
    padding: 0;
    background: transparent;
    border: 0;
}
.pw-opt--stacked .pw-opt__name { grid-column: 1; }
/* В поповере […] контрол стоит вторым столбцом и подписан: одни знаки в столбик
   не читаются, а места на подпись там, в отличие от строки, хватает. */
.pw-opt--stacked > :nth-child(2) { grid-column: 2; justify-self: end; }
.pw-opt--stacked .pw-segment { justify-self: end; }

/* Свотч-ЗНАЧЕНИЕ: показывает цвет свойства и открывает ОБЩИЙ выбор цвета. */
.pw-opt--swatch { gap: .35rem; }
.pw-valswatch {
    width: 26px;
    height: 22px;
    padding: 0;
    border: 1px solid var(--pw-st-border);
    border-radius: 6px;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .6);
    cursor: pointer;
}
/* «Нет» у заливки или контура: перечёркнутый белый квадрат — так это показывают
   во всех редакторах, и спутать его с белым цветом нельзя. */
.pw-valswatch.is-none {
    background:
        linear-gradient(to top right,
            transparent calc(50% - 1px), #d64545 calc(50% - 1px),
            #d64545 calc(50% + 1px), transparent calc(50% + 1px)),
        #ffffff;
}
/* ВЫКЛЮЧАТЕЛЬ — одна кнопка-знак на все ответы «да/нет»: смежная заливка, начертание
   надписи, нажим, пропорции рамки. Раньше на это отвечали чекбокс, кнопка-буква и
   тумблер — три вида одного и того же (разбор 12.09.2026 §2.1). */
.pw-optbtn {
    justify-content: center;
    min-width: 28px;
    height: 28px;
    padding: 0 .35rem;
    font-size: .9375rem;
    line-height: 1;
}
.pw-optbtn.is-on { background: var(--pw-st-active); border-color: var(--pw-st-edge); color: var(--pw-st-accent); }
.pw-opt--acts { gap: .35rem; margin-left: .25rem; }
.pw-opt--acts .btn { --bs-btn-padding-y: .15rem; --bs-btn-padding-x: .5rem; font-weight: 600; }

/* Курсоры трансформации: у каждой ручки свой, иначе непонятно, что сделает нажатие. */
.pw-studio[data-cursor="nwse-resize"] .pw-layer--ink { cursor: nwse-resize; }
.pw-studio[data-cursor="nesw-resize"] .pw-layer--ink { cursor: nesw-resize; }
.pw-studio[data-cursor="ns-resize"] .pw-layer--ink   { cursor: ns-resize; }
.pw-studio[data-cursor="ew-resize"] .pw-layer--ink   { cursor: ew-resize; }

/* СЕГМЕНТ: два-три взаимоисключающих значения одним нажатием, а не выпадающим списком.
   Значение со знаком показывается знаком, без знака — коротким словом (стабилизация). */
.pw-segment { display: inline-flex; border: 1px solid var(--pw-st-border); border-radius: 8px; overflow: hidden; }
.pw-segment__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 28px;
    padding: 0 .45rem;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--pw-st-muted);
    background: var(--pw-st-field);
    border: 0;
    border-right: 1px solid var(--pw-st-border);
    cursor: pointer;
}
.pw-segment__btn .bi { font-size: .95rem; line-height: 1; }
.pw-segment__btn:last-child { border-right: 0; }
.pw-segment__btn:hover { background: var(--pw-st-hover); }
.pw-segment__btn.is-on { background: var(--pw-st-active); color: var(--pw-st-accent); }

/* Текстовый блок набирается прямо в своей рамке и переносится так же, как ляжет. */
.pw-textinput--box {
    resize: none;
    overflow: hidden;
    white-space: pre-wrap;
    max-width: none;
    border: 1px dashed rgba(16, 24, 40, .45);
    border-radius: 2px;
}

/* Узкий экран прячет колонку цвета — этот свотч в ШАПКЕ редактора открывает тот же
   выбор всплывающей панелью (§3.2 разбора 12.09.2026; с этапа E он стоит в шапке,
   потому что строка состояния на телефоне перестала быть полосой — §5.2).
   Свотч ПОКАЗЫВАЕТ текущий цвет: на телефоне это единственное место, где его видно. */

/* ---- холст ---- */
.pw-studio .pw-canvas-host {
    padding: 18px;
    background: var(--pw-st-mat);
    border: 0;
    border-radius: 0;
    min-height: 260px;
    /* Окно показа ограничено по высоте: иначе зум растил бы САМУ СТРАНИЦУ вместо того,
       чтобы прокручивать холст внутри редактора (замерено 07.09.2026: при зуме 3 окно
       вытягивалось до 1836px и середина холста уезжала за нижний край экрана).
       Слагаемое — внутренние отступы окна, чтобы при зуме 1 лист влезал ровно. */
    max-height: calc(var(--pw-canvas-cap) + 36px);
    /* safe: пока лист влезает — он по центру; как только его увеличили зумом, выравнивание
       переключается на край, иначе половина холста уходит влево и туда НЕ ПРОКРУТИТЬ. */
    justify-content: safe center;
    align-items: safe center;
}
/* ЛИСТ ПОКАЗАН РОВНО СТОЛЬКО, СКОЛЬКО ГОВОРИТ ПОДПИСЬ ЗУМА (22.09.2026).
   Ширина показа — это пиксели холста, умноженные на масштаб, и другого множителя
   нет. До этой правки масштабов было ДВА: свой у CSS (`--pw-stage-width` вписывал
   лист в остаток экрана) и свой у движка (`--pw-zoom`), — и строка состояния писала
   «100 %», когда лист на деле был показан в 0,61 своего размера. Слова владельца:
   «Почему я вижу внизу 1200 на 900 и масштаб 100 процентов, если это явное враньё».
   Вписывание никуда не делось, но считает его теперь ОБОЛОЧКА (`Editor.autoZoom`)
   и кладёт готовое число в `--pw-zoom`. Логический холст при этом не меняется
   (инвариант 1): масштаб — свойство экрана и в рисунок не попадает. */
.pw-studio .pw-stage {
    width: calc(var(--pw-w, 800) * 1px * var(--pw-zoom, 1));
    /* Флекс-элемент по умолчанию ужимается до контейнера — тогда зум не увеличивал бы
       ничего вообще (замерено 07.09.2026: при зуме 3 лист оставался шириной с окно). */
    flex: 0 0 auto;
    /* Своя область наложения: режим слоя должен смешиваться с бумагой, а не со страницей. */
    isolation: isolate;
}

/* Курсор выбирается по ТИПУ ДЕЙСТВИЯ (`editor.cursor.modes`), а не по имени
   инструмента: ring и glyph рисует сам редактор, остальное — система. */
.pw-studio[data-cursor="ring"] .pw-layer--ink,
.pw-studio[data-cursor="glyph"] .pw-layer--ink     { cursor: none; }
.pw-studio[data-cursor="crosshair"] .pw-layer--ink { cursor: crosshair; }
.pw-studio[data-cursor="text"] .pw-layer--ink      { cursor: text; }
.pw-studio[data-cursor="grab"] .pw-layer--ink      { cursor: grab; }
.pw-studio[data-cursor="grab"].is-dragging .pw-layer--ink { cursor: grabbing; }
.pw-studio[data-cursor="zoom-in"] .pw-layer--ink   { cursor: zoom-in; }
.pw-studio[data-cursor="zoom-out"] .pw-layer--ink  { cursor: zoom-out; }
.pw-studio[data-cursor="move"] .pw-layer--ink      { cursor: move; }
.pw-studio[data-cursor="default"] .pw-layer--ink   { cursor: default; }

/* ---- строка состояния ---- */
.pw-statusbar {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .35rem .75rem;
    font-size: .8125rem;
    color: var(--pw-st-muted);
    background: var(--pw-st-panel);
    border-top: 1px solid var(--pw-st-border);
}
/* Размер холста и зум стоят по КРАЯМ ОДНОЙ СТРОКИ и на одной высоте (заказ
   владельца 22.09.2026: «размеры и зум нужно отравнять»). Поэтому у надписи тот же
   рост, что у таблетки зума: текст без плашки иначе висит выше её середины, и два
   края строки читаются как две разные строки. */
.pw-status__size {
    display: inline-flex;
    align-items: center;
    min-height: var(--pw-status-h);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.pw-studio .pw-hud { flex: 1 1 auto; justify-content: center; padding: 0; }
.pw-zoombar {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: .1rem;
    min-height: var(--pw-status-h);
    padding: 1px 3px;
    border: 1px solid var(--pw-st-border);
    border-radius: 999px;
}
.pw-zoombar .pw-icon-btn { width: 22px; height: 22px; }
/* ЗУМ — ДОПОЛНИТЕЛЬНАЯ ОПЦИЯ, и весит он ровно столько (заказ владельца 22.09.2026:
   «белый фон и прочее не нужно; есть плюс, есть минус, между ними циферка с
   процентами; и размеры поменьше — зум это ж дополнительная опция»). Поэтому число
   тут ГОЛОЕ: ни фона, ни кромки, ни шеврона. Плашка проявляется РОВНО ТОГДА, когда
   в число пишут или его тянут, — это и есть ответ «да, сюда можно вводить».
   Три класса в селекторе не для красоты: тема задаёт `.pw-num` свою высоту, фон и
   кегль двумя классами и лежит ниже — двух классов не хватило бы, чтобы их перебить. */
.pw-statusbar .pw-zoombar .pw-num {
    min-width: 0;
    height: auto;
    gap: .05rem;
    padding: 0 .2rem;
    background: transparent;
    border-color: transparent;
    border-radius: 999px;
}
.pw-statusbar .pw-zoombar .pw-num:focus-within,
.pw-statusbar .pw-zoombar .pw-num.is-scrub,
.pw-statusbar .pw-zoombar .pw-num[aria-expanded="true"] {
    background: var(--pw-st-field);
    border-color: var(--pw-st-edge);
}
.pw-statusbar .pw-zoombar .pw-num .pw-num__field {
    width: 2.1rem;
    padding: 0;
    font: inherit;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.pw-statusbar .pw-zoombar .pw-num .pw-num__unit { font-size: inherit; }

/* ---------------------------------------------------------------
   ОКНО ЦВЕТА (заказ владельца 22.09.2026)

   Правой колонки больше нет: цвет открывается знаком линейки и живёт в СВОЁМ окне.
   Окно лежит в <body>, таскается за свою полосу и не закрывается само — им
   пользуются ПО ХОДУ рисования. На телефоне окна нет: там шторка снизу, как у
   остальных панелей редактора (этап E, §5.2).
   --------------------------------------------------------------- */
.pw-cdlg {
    position: fixed;
    z-index: 1080;
    width: max-content;
    max-width: calc(100vw - 16px);
    background: var(--pw-st-field);
    border: 1px solid var(--pw-st-border);
    border-radius: 14px;
    box-shadow: 0 18px 44px rgba(16, 24, 40, .26);
    overflow: hidden;
    /* КАСАНИЕ ОКНА — ДЕЛО ОКНА (жалоба владельца 24.09.2026: на телефоне касание
       пустого места шторки «захватывало страницу под палитрой»). Палец, начавший
       на подписи или в зазоре, прокручивал страницу под шторкой (замер: 0 → 235 px),
       а долгое нажатие выделяло текст. Прокручивать в окне нечего, выделять — тоже:
       поле, полоса тона и полоса окна и так держат `touch-action: none`. */
    touch-action: none;
    overscroll-behavior: contain;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
    -webkit-tap-highlight-color: transparent;
}
/* Код цвета остаётся полем ввода: в него вставляют и в нём выделяют. */
.pw-cdlg input { user-select: text; -webkit-user-select: text; }
/* Полоса окна — ЕДИНСТВЕННОЕ место, за которое его тянут: `touch-action: none`
   здесь обязателен, иначе палец уводит страницу, а не окно. */
.pw-cdlg__head {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .35rem .35rem .35rem .75rem;
    background: var(--pw-st-quiet);
    border-bottom: 1px solid var(--pw-st-border);
    cursor: move;
    touch-action: none;
    user-select: none;
}
.pw-cdlg__title { flex: 1 1 auto; font-size: .8125rem; font-weight: 600; color: var(--pw-st-ink); }
.pw-cdlg__close { width: 26px; height: 26px; }
/* Сверху поля нет: подпись «Recent» стоит сразу под полосой окна — отступ над ней
   ничего не разделял (владелец 22.09.2026: «непонятно зачем нужен»). */
.pw-cdlg__body { padding: .35rem .75rem .8rem; }
/* Шторка снизу: телефон. Место ей даёт край экрана, поэтому координаты снимаются. */
.pw-cdlg.is-sheet {
    left: 0;
    right: 0;
    top: auto;
    bottom: 0;
    width: 100%;
    max-width: none;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -10px 30px rgba(16, 24, 40, .22);
}
/* Полоса шторки — РУЧКА: за неё шторку смахивают вниз (`ColorDialog.bindSwipe`).
   Чёрточка по центру — общепринятый знак «тяни» у нижних шторок; жест начинается
   только здесь, поле и кружки его не запускают. Шторка едет за пальцем без
   перехода (`is-swiping`), а отпущенная — возвращается или уезжает им. */
.pw-cdlg.is-sheet { transition: transform .2s ease; }
.pw-cdlg.is-sheet.is-swiping { transition: none; }
.pw-cdlg.is-sheet .pw-cdlg__head {
    position: relative;
    cursor: grab;
    padding-top: .7rem;
}
.pw-cdlg.is-sheet .pw-cdlg__head::before {
    content: '';
    position: absolute;
    top: 6px;
    left: 50%;
    width: 36px;
    height: 4px;
    margin-left: -18px;
    border-radius: 2px;
    background: currentColor;
    opacity: .22;
}
@media (prefers-reduced-motion: reduce) {
    .pw-cdlg.is-sheet { transition: none; }
}
/* «ОК» и «ОТМЕНА» В ШТОРКЕ СТОЯТ ТАМ ЖЕ, ГДЕ В ОКНЕ — справа наверху, друг под
   другом (заказ владельца 23.09.2026: «всегда должны быть там же, где на десктопе;
   не влезают — адаптируй»). До этого шторка переносила всю правую колонку строкой
   ПОД поле, и кнопки уезжали влево вниз.
   И ВСЯ ПРАВАЯ КОЛОНКА — КАК В ОКНЕ (владелец в тот же день, по первой попытке,
   где пара и hex встали строкой под полем: «укомпонуй тогда уж всё как на
   десктопе»): кнопки, под ними «новый / текущий», под ними hex с пипеткой —
   та же сетка, что в окне, шторка её не перестраивает.
   Уступает место ПОЛЕ: оно сжимается по ширине, а не выталкивает колонку.
   Указатели поля и тона стоят в процентах, а касание пересчитывается по
   настоящему размеру холста (`bindCanvas`), поэтому масштаб поля ничего не ломает.
   Поле hex в шторке чуть уже: шесть знаков в него влезают и так. */
.pw-cdlg.is-sheet .pw-cpick__main { flex: 1 1 auto; }
.pw-cdlg.is-sheet .pw-cpick__aside { flex: 0 0 auto; }
/* ПАЛИТРА СРЕДЫ — В ЛЕВОЙ КОЛОНКЕ, под полем (владелец 23.09.2026: «на мобайле
   кружки палитры укомпонуй в эту область, а то место жрёт» — показал пустоту
   под полем, слева от пары и hex). Правая колонка выше поля, и ряд во всю ширину
   под ними обоими съедал высоту, которой у телефона нет. Выбор цвета становится
   сеткой из двух колонок: ряд поля распадается (`display: contents`), правая
   колонка тянется на все три строки, подпись и кружки палитры встают слева.
   Кружки палитры в шторке мельче, чтобы в узкой колонке ряд вышел в две строки. */
.pw-cdlg.is-sheet .pw-cpick {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: .55rem;
    align-items: start;
}
.pw-cdlg.is-sheet .pw-cpick__row { display: contents; }
.pw-cdlg.is-sheet .pw-cpick__main { grid-row: 1; grid-column: 1; }
.pw-cdlg.is-sheet .pw-cpick__aside { grid-row: 1 / span 3; grid-column: 2; }
.pw-cdlg.is-sheet .pw-swatches__head--palette { grid-row: 2; grid-column: 1; }
.pw-cdlg.is-sheet .pw-swatches--palette { grid-row: 3; grid-column: 1; gap: .3rem; }
.pw-cdlg.is-sheet .pw-swatches--palette .pw-swatch { width: 24px; height: 24px; }
.pw-cdlg.is-sheet .pw-hexrow__input { width: 4.8rem; }
/* Поле тянется за колонкой, полоса тона — за ростом поля. */
.pw-cdlg.is-sheet .pw-cpick__free { align-items: stretch; }
.pw-cdlg.is-sheet .pw-cfield { flex: 1 1 auto; min-width: 0; }
.pw-cdlg.is-sheet .pw-cfield__canvas { width: 100%; height: auto; max-height: 38vh; }
/* Поле растёт по ширине экрана, а рост берёт из пропорции — в горизонтали телефона
   (844×390) это 500 px поля и шторка в 595 px, верх которой с «ОК» и «Отменой» уходил
   за край экрана (замер 24.09.2026). Потолок роста держит шторку на экране; поле при
   этом только сплющивается — указатели стоят в процентах, касание считается по
   настоящему размеру (`bindCanvas`). */
/* `height: 0` + `min-height: 100%`: своя высота холста тона (по полю в полный
   размер) не должна растягивать ряд — рост задаёт ТОЛЬКО поле. */
.pw-cdlg.is-sheet .pw-chue__canvas { height: 0; min-height: 100%; }
/* В ГОРИЗОНТАЛИ ТЕЛЕФОНА шторка НЕ во всю ширину (владелец 24.09.2026: «палитра во
   весь телефон растягивается — так быть не должно»): на экране в 844 px она
   накрывала холст от края до края. Ширина — как у шторки портрета, по центру;
   высоты это не прибавляет (поле и так упирается в `max-height`). Условие — то же,
   что включает телефонную раскладку по высоте. */
@media (orientation: landscape) and (max-height: 540px) {
    .pw-cdlg.is-sheet {
        width: 440px;
        max-width: 100%;
        margin-inline: auto;
    }
}

/* ---- сам выбор цвета ---- */
/* ПОРЯДОК: ряд последних цветов сверху, под ним поле с полосой тона и сравнение
   «новый / текущий» с hex, ниже — палитра среды. Порядок задан заказом владельца,
   а не темой: тема двигает размеры и рамки, но не то, что чем важнее. */
.pw-cpick__row { display: flex; align-items: flex-start; gap: .55rem; }
/* ЛЕВАЯ колонка: последние цвета и поле. Ряд последних ограничен её шириной —
   в правую колонку он не заезжает никогда (жалоба владельца 22.09.2026). */
.pw-cpick__main { display: flex; flex-direction: column; flex: 0 0 auto; min-width: 0; }
.pw-cfield { position: relative; flex: 0 0 auto; line-height: 0; }
.pw-cfield__canvas {
    display: block;
    max-width: 100%;
    border-radius: 6px;
    touch-action: none;
    cursor: crosshair;
}
.pw-cfield__dot {
    position: absolute;
    width: 14px;
    height: 14px;
    margin: -7px 0 0 -7px;
    border: 2px solid #fff;
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(16, 24, 40, .45);
    pointer-events: none;
}
.pw-chue { position: relative; flex: 0 0 auto; line-height: 0; }
.pw-chue__canvas {
    display: block;
    border-radius: 4px;
    touch-action: none;
    /* Полоса тона — ПОЛЗУНОК, его тянут вдоль, поэтому курсор — рука (владелец
       24.09.2026: «крестик нелогичен, пусть будет рука, символ драга»). Крестик
       остаётся у поля насыщенности/яркости: там целятся в точку. */
    cursor: grab;
}
.pw-chue__canvas:active { cursor: grabbing; }
.pw-chue__dot {
    position: absolute;
    left: -3px;
    right: -3px;
    height: 6px;
    margin-top: -3px;
    border: 2px solid #fff;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(16, 24, 40, .45);
    pointer-events: none;
}

/* ПРАВАЯ КОЛОНКА — это сетка строки hex: решётка | поле ввода | пипетка. Пара
   «новый / текущий» живёт во ВТОРОЙ колонке и потому стоит ровно над самим полем,
   а не над строкой целиком (владелец 22.09.2026: «отцентровать по центру поля,
   которое внизу слева от пипетки»). Кнопки окна идут поперёк всех трёх.
   Числа сдвига здесь не появятся: место считает сама строка hex. */
.pw-cpick__aside {
    display: grid;
    grid-template-columns: auto auto auto;
    align-content: start;
    gap: .55rem .25rem;
    min-width: 0;
}

/* «ОК» и «ОТМЕНА» — СПРАВА НАВЕРХУ, ДРУГ ПОД ДРУГОМ (заказ владельца 22.09.2026 со
   скрином фотошопа). Место держит выбор цвета, кнопки ставит окно: пустое место
   исчезает само, поэтому выбор цвета без хозяина ничего лишнего не рисует.
   Цвет применяется живьём, но ВЫБРАННЫМ считается только закрытием окна — тогда же
   он уезжает в ряд «последних». */
.pw-cpick__acts { display: flex; flex-direction: column; grid-column: 1 / -1; }
.pw-cpick__acts:empty { display: none; }
.pw-cdlg__acts { display: flex; flex-direction: column; gap: .3rem; width: 100%; }
.pw-cdlg__acts .btn { width: 100%; --bs-btn-padding-y: .2rem; }

/* НОВЫЙ И ТЕКУЩИЙ — это ДО и ПОСЛЕ одного цвета, а не пара цветов: пары с обменом
   в продукте больше нет (владелец 22.09.2026). Нижняя половина нажимается и
   возвращает тот цвет, с которым окно открыли.
   Ширина у пары СВОЯ и небольшая (владелец: «чуть поуже, сейчас это слишком
   растянутый прямоугольник»): растягиваясь на всю колонку, она тянулась за полем
   hex и читалась плашкой, а не образцом цвета. */
/* Пара стоит НАД САМИМ ПОЛЕМ hex: она во второй колонке сетки, той же, в которой
   лежит поле ввода (владелец 22.09.2026: «подвинь нью-куррент блок чуть правее,
   чтобы он своим центром встал над центром поля снизу»). Число сдвига поэтому
   не пишется — пара равняется по полю сама. */
.pw-compare {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    grid-row: 2;
    grid-column: 2;
    justify-self: center;
    width: 4.6rem;
}
.pw-compare__cap {
    font-size: .6875rem;
    line-height: 1.4;
    text-align: center;
    color: var(--pw-st-muted);
}
.pw-compare__new,
.pw-compare__cur {
    display: block;
    width: 100%;
    height: 24px;
    padding: 0;
    border: 1px solid var(--pw-st-border);
}
.pw-compare__new { border-radius: 6px 6px 0 0; border-bottom: 0; }
.pw-compare__cur { border-radius: 0 0 6px 6px; cursor: pointer; }

/* HEX — ЕДИНСТВЕННАЯ числовая запись цвета: её копируют и вставляют. Ни HSB, ни Lab,
   ни CMYK, ни переключателя форматов здесь нет и не заводится (владелец 22.09.2026). */
/* Строка hex сама по себе не коробка: её три части — ячейки сетки правой колонки
   (см. `.pw-cpick__aside`), и по ним равняется пара «новый / текущий». Места
   названы ЯВНО: без этого решётка встаёт в свободную клетку рядом с парой, а поле
   уезжает строкой ниже (поймано замером). В шторке телефона колонка снова ряд,
   и строка там обычный flex — см. `.is-sheet`. */
.pw-cpick__hex { display: contents; }
.pw-cpick__hash { grid-row: 3; grid-column: 1; }
.pw-cpick__hex .pw-hexrow__input { grid-row: 3; grid-column: 2; }
.pw-cpick__hex .pw-hexrow__pick { grid-row: 3; grid-column: 3; }
.pw-cpick__hash { align-self: center; font-size: .8125rem; color: var(--pw-st-muted); }
.pw-hexrow__input {
    min-width: 0;
    width: 5.4rem;
    font-variant-numeric: tabular-nums;
    text-transform: uppercase;
}

/* Ряды образцов: последние цвета и палитра среды. Каждый ряд подписан — что это. */
.pw-swatches { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem; }
.pw-swatches__head {
    margin: .1rem 0 .35rem;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--pw-st-muted);
}
.pw-swatches--palette { margin-bottom: .1rem; }
/* Ряд ПОСЛЕДНИХ — одна строка и не шире своей колонки: перенос делал из него
   сетку на пол-окна, а окно цвета — не библиотека образцов. */
.pw-swatches--recent { flex-wrap: nowrap; overflow: hidden; margin-bottom: .5rem; }
.pw-swatches__head--recent { margin-top: 0; }
.pw-swatches__head--palette { margin-top: .6rem; }
/* Поле и полоса тона — один ряд внутри левой колонки. */
.pw-cpick__free { display: flex; align-items: flex-start; gap: .55rem; margin: 0; }
/* «Нет заливки» — такой же свотч в ряду палитры, а не отдельная серая кнопка:
   прежняя читалась как заголовок панели (разбор 12.09.2026 §7). */
.pw-swatch--none {
    background:
        linear-gradient(to top right,
            transparent calc(50% - 1px), #d64545 calc(50% - 1px),
            #d64545 calc(50% + 1px), transparent calc(50% + 1px)),
        #ffffff;
}

/* Окно имени работы: своё, а не `prompt()` браузера (заказ владельца 22.09.2026). */
.pw-askmodal .modal-content { border-radius: 14px; }
.pw-askmodal__label { font-size: .875rem; color: var(--pw-st-muted); }

/* ---- действия и сообщения ---- */
.pw-studio .pw-actions {
    justify-content: flex-end;
    padding: .6rem .75rem;
    background: var(--pw-st-panel);
    border-top: 1px solid var(--pw-st-border);
}
.pw-studio .pw-notice { margin: .6rem .75rem 0; }

/* ---------------------------------------------------------------
   Всплывающие панели
   Лежат в <body>, а не в строке свойств: строка прокручивается вбок и потому
   обрезает по вертикали (overflow-y: hidden) — меню внутри неё открывалось
   и было НЕВИДИМО (замер 11.09.2026, выбор кисти).
   --------------------------------------------------------------- */
/* ---------------------------------------------------------------
   Подсказка «Landscape» (24.09.2026): телефон держат боком, а страница стоит
   портретом (системный автоповорот выключен). Одно нажатие — полный экран
   горизонтально. Повёрнута так, как держат телефон (`--pw-tilt-turn` ставит JS
   по датчику), иначе подпись читалась бы лёжа на боку. Лежит в <body>.
   --------------------------------------------------------------- */
.pw-tilt-hint {
    position: fixed;
    z-index: 1075;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) rotate(var(--pw-tilt-turn, 90deg));
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem 1.1rem;
    border-radius: 999px;
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 6px 24px rgba(0, 0, 0, .22);
}
.pw-tilt-hint .pw-glyph { width: 1.4em; height: 1.4em; }

.pw-pop {
    position: fixed;
    z-index: 1080;
    max-height: min(78vh, 620px);
    overflow: auto;
    padding: .35rem;
    background: var(--pw-st-field);
    border: 1px solid var(--pw-st-border);
    border-radius: 12px;
    box-shadow: 0 10px 32px rgba(16, 24, 40, .18);
}
/* ---------------------------------------------------------------
   Курсор на холсте: кольцо настоящего диаметра и знак инструмента.
   Браузерный курсор размер кисти показать не может, а без размера рисовать
   неудобно — толщину приходилось узнавать, проведя линию и отменив её.
   --------------------------------------------------------------- */
.pw-cursor {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1090;
    pointer-events: none;
    will-change: transform;
}
.pw-cursor__ring,
.pw-cursor__dot {
    position: absolute;
    top: 0;
    left: 0;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    /* Белая линия с тёмной обводкой читается и на бумаге, и на залитом чёрном. */
    border: 1px solid rgba(255, 255, 255, .95);
    box-shadow: 0 0 0 1px rgba(16, 24, 40, .65), inset 0 0 0 1px rgba(16, 24, 40, .35);
}
/* Кисть в 1-3 пикселя кольцом не показать — кольцо такого размера сливается в пятно.
   Там честнее перекрестье: оно указывает точку, не притворяясь размером. */
.pw-cursor__dot {
    border: 0;
    box-shadow: none;
    background: none;
}
.pw-cursor__dot::before,
.pw-cursor__dot::after {
    content: '';
    position: absolute;
    background: rgba(16, 24, 40, .85);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .9);
}
.pw-cursor__dot::before { left: 50%; top: 0; width: 1px; height: 100%; transform: translateX(-50%); }
.pw-cursor__dot::after  { top: 50%; left: 0; height: 1px; width: 100%; transform: translateY(-50%); }
.pw-cursor__glyph {
    position: absolute;
    display: block;
    filter: drop-shadow(0 1px 2px rgba(16, 24, 40, .35));
}
/* Плотная середина мягкой кисти: по одному внешнему кольцу не видно, кладёт она
   плотное пятно или туман. */
.pw-cursor__ring--core { border-color: rgba(255, 255, 255, .6); box-shadow: 0 0 0 1px rgba(16, 24, 40, .35); }
/* Space держит панораму любым инструментом — курсор обязан это показать. */
.pw-studio.is-panning .pw-layer--ink { cursor: grab !important; }
.pw-studio.is-panning.is-dragging .pw-layer--ink { cursor: grabbing !important; }

/* Надпись набирается ПРЯМО НА ХОЛСТЕ и выглядит так же, как будущая надпись. */
.pw-textinput {
    position: absolute;
    z-index: 4;
    min-width: 3rem;
    max-width: 90%;
    padding: 0 .1rem;
    background: rgba(255, 255, 255, .72);
    border: 0;
    border-bottom: 2px dashed rgba(16, 24, 40, .45);
    outline: none;
    line-height: 1.1;
}

.pw-hud__item--gesture { font-variant-numeric: tabular-nums; font-weight: 600; }

.pw-notice { display: flex; align-items: center; gap: .5rem; }
.pw-notice__text { flex: 1 1 auto; }
.pw-notice__act { flex: 0 0 auto; padding: 0; font-weight: 600; }
.pw-notice__close { flex: 0 0 auto; }

/* ---- узкий экран: холст важнее панелей (§5.4) ---- */
/* «Узкий» здесь — это И НИЗКИЙ экран тоже. Телефон, повёрнутый горизонтально в
   полноэкранном режиме (заказ владельца 21.09.2026), по ширине уже не телефон
   (≈850 px), а по высоте — 390: правая колонка и вертикальная линейка отнимают
   у холста ровно то, ради чего экран и разворачивали. Порог 540 px выбран по
   самому высокому из ходовых телефонов в горизонтали (iPhone Pro Max ≈ 430).
   Настольных окон он не задевает: приёмка гоняет 1440×900, 1440×700 и 900×1000. */
@media (max-width: 991.98px), (max-height: 540px) {
    .pw-studio__body { grid-template-columns: 1fr; }
    /* Полосы встают друг под другом, и остаток высоты забирает холст, а не линейка:
       ряд холста растяжимый, линейка — своего роста (этап E).
       ЛИНЕЙКА СВЕРХУ (заказ владельца 23.09.2026): шапка работы, под ней ряд
       инструментов, под ним строка свойств, и только потом холст. Порядок берётся
       из разметки (линейка стоит в ней раньше холста), `order` не нужен. */
    .pw-screen--full .pw-studio__body { grid-template-rows: auto minmax(0, 1fr); }
    /* Холсту отдаётся почти весь экран: на телефоне он был 328×246 посреди страницы
       высотой 1988 px (замер 11.09.2026) — рисовать в таком окошке нечем. */
    /* Колонок тут нет (линейка легла рядом под холстом), и выравнивать шапку
       не по чему: New снова по содержимому, пара отмены — сразу за ним. */
    .pw-studio { --pw-canvas-cap: 58vh; --pw-head-lead: auto; --pw-head-hist: 0px; }
    .pw-studio .pw-head { padding-left: .6rem; }
    .pw-studio .pw-canvas-host { padding: 8px; }
    .pw-rail {
        flex-direction: row;
        align-items: stretch;
        border-right: 0;
        border-bottom: 1px solid var(--pw-st-border);
    }
    .pw-rail__item { flex: 0 1 58px; min-width: 0; }
    .pw-rail__icon img { width: 28px; height: 28px; }
    /* Линейка легла в РЯД: пустое место съедало бы ширину живого знака, а ряд обязан
       влезать без прокрутки (этап E). Наверху вертикальной линейки оно остаётся. */
    .pw-rail__gap { display: none; }

    /* СВЁРНУТА И В РЯДУ — как на десктопе (заказ владельца 23.09.2026: «количество
       видимых инструментов такое же, как на десктопе, и more открывает вправо»).
       Та же спрятанная часть, та же кнопка, только растёт она ШИРИНОЙ
       (`grid-template-columns: 0fr → 1fr`), а кнопка стоит на месте, ПЕРЕД
       спрятанными знаками: палец, открывший ряд, тем же местом его и закрывает.
       Шеврон смотрит вправо, открытый — влево. */
    .pw-rail__rest {
        order: 1;
        min-width: 0;
        grid-template-rows: none;
        grid-template-columns: 0fr;
        transition: grid-template-columns .28s cubic-bezier(.22, .61, .36, 1), visibility 0s linear .28s;
    }
    .pw-rail.is-open .pw-rail__rest {
        grid-template-columns: 1fr;
        transition: grid-template-columns .28s cubic-bezier(.22, .61, .36, 1), visibility 0s;
    }
    .pw-rail__restIn { flex-direction: row; align-items: stretch; min-width: 0; }
    .pw-rail__restIn > * { transform: translateX(-6px); }
    .pw-rail__more { flex: 0 0 auto; padding: 0 .35rem; }
    .pw-rail__more .bi { transform: rotate(-90deg); }
    .pw-rail.is-open .pw-rail__more .bi { transform: rotate(90deg); }
    /* Развёрнутая кнопка на десктопе уезжает в пустое место наверху колонки —
       в ряду такого места нет, и она остаётся, где стояла. */
    .pw-rail.is-open .pw-rail__more { order: 0; display: flex; padding: 0 .35rem; }
    .pw-rail.is-open .pw-rail__more::before { content: none; }
    /* Разделитель в ряду — вертикальная черта. */
    .pw-rail__sep { width: 1px; height: auto; margin: .35rem .2rem; align-self: stretch; }
}

@media (max-width: 767.98px), (max-height: 540px) {
    .pw-studio { --pw-canvas-cap: 64vh; }
    .pw-optbar { gap: .4rem .6rem; }
    .pw-num__field { width: 2.7rem; }
    /* Палец, а не курсор: касаться нечего, если цель меньше сорока пикселей. */
    .pw-cdlg .pw-swatch { width: 2rem; height: 2rem; }
}

/* Пальцем свой курсор не нужен — там и так видно, куда попал палец. */
@media (hover: none) {
    .pw-cursor { display: none; }
    .pw-studio[data-cursor] .pw-layer--ink { cursor: crosshair; }
}

/* =====================================================================
   ЭКРАН: редактор владеет окном (этап E разбора 12.09.2026, §5)

   До этого редактор стоял в потоке обычной страницы: шапка сайта, H1, абзац —
   и только на y = 158 начинался холст (замер 1440×900), которому доставалось
   792×594 вместо честных 800×600, а полоса с «Publish» падала на границу экрана.
   Метку ставит страница (класс `pw-screen` на <body>, имена — в `editor.screen`),
   раскладку делает этот раздел, а ВЫСОТУ листа считает оболочка: сколько осталось
   до низа окна, столько лист и получает (`--pw-screen-fit` → `Editor.fitScreen`).
   Доля экрана для этого не годится — над холстом у разных страниц разное.
   ===================================================================== */
.pw-screen--full { --pw-screen-fit: 1; }

/* Шапка сайта сжимается в одну узкую строку: на странице рисования она указатель,
   а не витрина. Меню и кнопки остаются на местах — меняется только рост. */
.pw-screen .navbar { padding-top: .1rem; padding-bottom: .1rem; }
.pw-screen .navbar-brand { padding-top: .1rem; padding-bottom: .1rem; font-size: .9375rem; }
.pw-screen .pw-brand__mark { width: 26px; height: 26px; }
.pw-screen .navbar .nav-link { padding-top: .2rem; padding-bottom: .2rem; }
.pw-screen .navbar .btn-sm { --bs-btn-padding-y: .15rem; }

/* Главная колонка отдаёт редактору всю ширину и не добавляет своих полей.
   Конструктору поля всё же нужны — там рядом с редактором стоит форма. */
.pw-screen__main { padding: 0; width: 100%; max-width: none; }
.pw-screen__main--pad { padding: .75rem .75rem 0; }

/* Редактор перестаёт быть карточкой: рамка, тень и скругления не нужны тому,
   кто занимает весь экран. */
.pw-screen--full .pw-editor {
    gap: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}
/* Внутри окна редактор делится так: полосы своего роста, окно показа — всё остальное.
   Высоту редактору ставит оболочка, поэтому ни одна полоса не может растолкать его
   за край экрана: замер 12.09.2026 — на окне 700 px линейка из девяти операций была
   выше холста и вытягивала редактор до 743 px. */
.pw-screen--full .pw-studio { display: flex; flex-direction: column; }
.pw-screen--full .pw-studio__body { flex: 1 1 auto; min-height: 0; }
.pw-screen--full .pw-studio__center { min-height: 0; }
.pw-screen--full .pw-studio .pw-canvas-host {
    flex: 1 1 auto;
    min-height: 0;
    max-height: none;
}
/* Не влезла линейка — прокручивается сама, а не растит окно. */
.pw-screen--full .pw-rail { min-height: 0; overflow: auto; }

/* Конструктор делит окно с формой, и остаток экрана ему полагается ТОЛЬКО пока они
   стоят в два столбца. Схлопнулись — редактор оказывается ПОД длинной формой,
   и «остаток экрана» для него уже ничего не значит: там работает доля экрана. */
@media (min-width: 992px) {
    .pw-screen--form { --pw-screen-fit: 1; }
    /* Остаток экрана без этих правил — ловушка: оболочка отдаёт редактору рост, но
       окно показа растёт по содержимому, то есть по ЛИСТУ, и `fitScreen` мерит лист
       сам себе. Каждый замер ужимал его ещё раз (`ResizeObserver`): 768 → 570 → 299 px
       на форме урока при редакторе в 1042 px (замер 24.09.2026). */
    .pw-screen--form .pw-studio { display: flex; flex-direction: column; }
    .pw-screen--form .pw-studio__body { flex: 1 1 auto; min-height: 0; }
    .pw-screen--form .pw-studio__center { min-height: 0; }
    .pw-screen--form .pw-studio .pw-canvas-host { flex: 1 1 auto; min-height: 0; max-height: none; }
}

/* ---------------------------------------------------------------
   ПОЛНЫЙ ЭКРАН (заказ владельца 21.09.2026: «кнопка как на ютубе»)

   Полноэкранный режим — это НЕ третья раскладка: оболочка надевает на <body> те же
   классы, что и страница рисования (`pw-screen pw-screen--full`), и всё, что уже
   написано выше, работает как есть — включая телефонные две полосы, шторку свойств
   и строку состояния над холстом. Здесь добавляется ровно одно: редактор ложится
   поверх страницы и занимает окно целиком.

   Почему не «развернуть сам редактор» средствами браузера: всплывающие панели
   (цвет, кисти, ползунки) лежат в <body> и в поддерево редактора не входят —
   системная полноэкранка одного узла попросту перестала бы их показывать.
   Поэтому в полный экран уходит документ, а место редактору даёт этот блок.

   z-index 1040: выше шапки сайта (sticky-top у Bootstrap — 1020), но НИЖЕ панелей
   (1080) и курсора (1090). Иначе полноэкранный редактор закрыл бы собой
   собственный выбор цвета.
   --------------------------------------------------------------- */
body.pw-fs { overflow: hidden; }
body.pw-fs .pw-editor {
    position: fixed;
    inset: 0;
    z-index: 1040;
    height: auto;
    background: var(--pw-bg);
}

/* Задание над редактором — ОДНА строка (стена, продолжение, ответ). Описание стены
   и есть задача, ради которой человек пришёл: под холст его прятать нельзя. */
.pw-brief {
    padding: .4rem .75rem;
    background: var(--pw-st-quiet);
    border-bottom: 1px solid var(--pw-st-border);
}
/* Задание не режем одной строкой: это ТЕКСТ ЗАДАЧИ, и на телефоне он обязан
   читаться. Две строки — потолок, дальше человек идёт на страницу самой стены. */
.pw-brief__note {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    min-width: 0;
    overflow: hidden;
}

/* Заголовок, лид и ленты стоят ПОД холстом и из разметки никуда не делись:
   страницы `/draw/*` индексируются (§16), и тексты нужны поиску и читателю.

   Вертикальный ритм полосы задаётся ЗДЕСЬ, а не утилитами Bootstrap в разметке
   (21.09.2026): утилиты объявлены `!important`, и тема, которой полоса достаётся
   карточкой со своими полями, перебить их не может. Разметка теперь несёт только
   `pw-under-editor container`, поля — дело CSS. */
.pw-under-editor {
    background: var(--pw-bg);
    padding-block: .75rem 1.5rem;
}

/* ---------------------------------------------------------------
   Телефон: холст = экран минус ТРИ полосы (§5.2, переставлено 23.09.2026)

   Сверху вниз: шапка работы, ряд инструментов, строка свойств — и холст. До
   23.09.2026 линейка стояла внизу, а строка свойств была ШТОРКОЙ над ней и
   открывалась повторным нажатием на активный инструмент; владелец заказал
   «панель инструментов не снизу, а сверху, под ундо-редо; опции инструментов —
   третьей строкой под строкой инструментов». Шторки больше нет: строка свойств
   стоит в потоке, как на десктопе, и не влезающие ручки прокручиваются вбок.
   Строка состояния по-прежнему не полоса: она висит у НИЖНЕГО края холста
   (верх теперь занят строкой свойств).
   --------------------------------------------------------------- */
@media (max-width: 767.98px), (max-height: 540px) {
    .pw-screen--full {
        /* Признак «телефон» для оболочки: ползунок числа и окно цвета идут шторкой. */
        --pw-screen-sheet: 1;
        --pw-rail-h: 54px;
    }

    /* ---- шапка работы: знаки ПОКРУПНЕЕ, Publish — словом ----
       Заказ владельца 23.09.2026: «чуть больше верхние кнопки на мобайле». Цель
       пальца — 40 px. Размер ставится свойствами, а не `--bs-btn-*`: тёплая тема
       задаёт шапочным кнопкам поля напрямую (2px 5px), и переменная их не перебьёт.
       `.pw-studio` в селекторе — ради веса против двух классов темы. */
    .pw-screen--full .pw-studio .pw-head { gap: .3rem; padding: .3rem .4rem; }
    .pw-screen--full .pw-head .pw-btn__text { display: none; }
    .pw-screen--full .pw-studio .pw-head .btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 40px;
        height: 40px;
        padding: 0 .5rem;
        font-size: 1.15rem;
    }
    .pw-screen--full .pw-studio .pw-head__undo,
    .pw-screen--full .pw-studio .pw-head__redo { font-size: 1.45rem; }
    /* Publish — ТЕКСТОМ, без знака (там и нет знака): это главное действие, и
       по одному знаку его не узнать. */
    .pw-screen--full .pw-studio .pw-head .pw-publish { padding: 0 .85rem; font-size: .95rem; font-weight: 600; }
    .pw-screen--full .pw-head .pw-publish .pw-btn__text { display: inline; }

    /* ---- линейка: знаки без подписей, РАСКРЫТЫЙ ряд листается пальцем ----
       Заказ владельца 23.09.2026: «значки сделай больше; ты их сплющил, чтобы при
       More они влезали, но они не обязаны влезать — в раскрытом виде полоса
       двигается пальцем вправо-влево». До этого ширина знака считалась от их числа
       (все обязаны были влезть), и на 380 px знак выходил в 27 px.
       Знак теперь ПОСТОЯННОЙ ширины, свёрнутый ряд влезает сам (там четыре знака),
       раскрытый — шире экрана и прокручивается. Отличить «листаю» от «выбираю»
       поручено БРАУЗЕРУ: выбор висит на `click`, а палец, ушедший дальше порога
       касания, превращается в прокрутку, и `click` браузер уже не отдаёт.
       `pan-x` — ряд сам ведёт только горизонталь, вертикаль остаётся странице. */
    .pw-screen--full .pw-rail {
        height: var(--pw-rail-h);
        padding: .2rem .15rem;
        gap: 0;
        overflow-x: auto;
        overflow-y: hidden;
        overscroll-behavior-x: contain;
        touch-action: pan-x;
        scrollbar-width: none;
    }
    .pw-screen--full .pw-rail::-webkit-scrollbar { height: 0; }
    .pw-screen--full .pw-rail__rest { flex: 0 0 auto; }
    .pw-screen--full .pw-rail__item {
        flex: 0 0 50px;
        min-width: 0;
        padding: .2rem 0;
        justify-content: center;
    }
    .pw-screen--full .pw-rail__more,
    .pw-screen--full .pw-rail.is-open .pw-rail__more { flex: 0 0 38px; padding: 0; }
    .pw-screen--full .pw-rail__label { display: none; }
    .pw-screen--full .pw-rail__icon img { width: 34px; height: 34px; }
    .pw-screen--full .pw-rail__item--panel .pw-rail__icon { width: 34px; height: 34px; }
    .pw-screen--full .pw-rail__sep {
        flex: 0 0 1px;
        width: 1px;
        height: 60%;
        align-self: center;
        margin: 0 2.5px;
    }

    /* ---- строка свойств: третья строка, в потоке ---- */
    .pw-screen--full .pw-optbar { padding: .3rem .5rem; }
    /* Полосы прокрутки не видно — вбок строку листает палец. */
    .pw-screen--full .pw-optbar__scroll { scrollbar-width: none; }
    .pw-screen--full .pw-optbar__scroll::-webkit-scrollbar { height: 0; }

    /* ---- строка состояния: не полоса, а надпись у нижнего края холста ---- */
    .pw-screen--full .pw-studio__center { position: relative; }
    .pw-screen--full .pw-statusbar {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 4;
        padding: .3rem .4rem;
        background: transparent;
        border: 0;
        pointer-events: none;
    }
    .pw-screen--full .pw-status__size { display: none; }
    .pw-screen--full .pw-statusbar .pw-hud__item:not(:empty) {
        padding: .1rem .5rem;
        background: var(--pw-st-field);
        border-radius: 999px;
        box-shadow: 0 1px 4px rgba(16, 24, 40, .14);
    }
    /* Зум остаётся ступенями и числом: пинч даёт масштаб «на глаз», а ровные 100 %
       пальцами не поймать. Полосы он не занимает — это таблетка поверх подложки. */
    .pw-screen--full .pw-zoombar {
        pointer-events: auto;
        background: var(--pw-st-field);
        box-shadow: 0 1px 4px rgba(16, 24, 40, .14);
    }
}

/* ---------------------------------------------------------------
   ТЕЛЕФОН В ПОРТРЕТЕ: ИНСТРУМЕНТЫ ВНИЗУ, СВОЙСТВА НАД НИМИ (23.09.2026)

   Заказ владельца с макетом: «перенеси панель инструментов в самый низ, а опции
   над ней, и по размерам адаптируй». Сверху вниз: шапка работы, холст (зум —
   таблеткой у его нижнего края), строка свойств, ряд инструментов у края экрана —
   под большим пальцем. Это отменяет утреннюю раскладку того же дня (ряд и
   свойства сверху).
   Разметка не меняется: порядок задаёт сетка. Середина (строка свойств, холст,
   строка состояния) стала сеткой из двух строк, и строка состояния лежит В ТОЙ ЖЕ
   клетке, что холст, прижатая к низу: абсолютной она накрыла бы строку свойств,
   которая теперь стоит ниже холста.
   Горизонталь телефона не трогается — там линейка колонкой слева (блок ниже).
   --------------------------------------------------------------- */
@media (max-width: 767.98px) and (orientation: portrait), (max-height: 540px) and (orientation: portrait) {
    .pw-screen--full { --pw-rail-h: 62px; }
    .pw-screen--full .pw-studio__body { grid-template-rows: minmax(0, 1fr) auto; }
    .pw-screen--full .pw-rail {
        grid-row: 2;
        border-bottom: 0;
        border-top: 1px solid var(--pw-st-border);
    }
    .pw-screen--full .pw-studio__center {
        grid-row: 1;
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: minmax(0, 1fr) auto;
    }
    .pw-screen--full .pw-canvas-host { grid-row: 1; grid-column: 1; }
    .pw-screen--full .pw-statusbar { position: static; grid-row: 1; grid-column: 1; align-self: end; }
    .pw-screen--full .pw-optbar { grid-row: 2; }

    /* ЛЕНТА (владелец 23.09.2026, второй заход по макету): знак — КВАДРАТ, и
       подсветка нажатого тоже квадрат, зазоры между знаками мелкие. Все знаки
       стоят в ленте всегда: спрятанная часть не сворачивается, её просто не видно
       за правым краем, и ленту листают пальцем сразу. More — ПОМОЩНИК в ленте за
       видимыми знаками: мотает её до себя и становится «Less» (`railStrip` в
       studio.js). Хвост следующего знака, торчащий из-за края, — подсказка, что
       лента листается. */
    .pw-screen--full { --pw-rail-strip: 1; }
    .pw-screen--full .pw-rail { gap: 4px; padding: 5px 6px; align-items: center; }
    .pw-screen--full .pw-rail__restIn { gap: 4px; }
    .pw-screen--full .pw-rail__rest,
    .pw-screen--full .pw-rail.is-open .pw-rail__rest {
        grid-template-columns: 1fr;
        visibility: visible;
        transition: none;
    }
    .pw-screen--full .pw-rail__restIn > *,
    .pw-screen--full .pw-rail.is-open .pw-rail__restIn > * { opacity: 1; transform: none; transition: none; }
    .pw-screen--full .pw-rail__item {
        flex: 0 0 52px;
        height: 52px;
        padding: 0;
        align-items: center;
        border-radius: 12px;
    }
    .pw-screen--full .pw-rail__icon img,
    .pw-screen--full .pw-rail__item--panel .pw-rail__icon { width: 36px; height: 36px; }
    .pw-screen--full .pw-rail__more,
    .pw-screen--full .pw-rail.is-open .pw-rail__more {
        flex: 0 0 52px;
        height: 52px;
        border-radius: 12px;
    }
    .pw-screen--full .pw-rail__moreLabel { display: block; }
}

/* ---------------------------------------------------------------
   ТЕЛЕФОН, ПОВЁРНУТЫЙ ГОРИЗОНТАЛЬНО (21.09.2026)

   Тут дефицит не ширины, а ВЫСОТЫ: 844×390. Всё, что выше по файлу, писалось под
   портрет, где ровно наоборот, — и в горизонтали давало обратный эффект: линейка
   ложилась полосой ВНИЗ и съедала 54 px высоты, поля вокруг листа — ещё 44, шапка
   работы — 44. Холсту 4:3 оставалось 368×276 при экране 844 в ширину: владелец
   повернул телефон, чтобы увидеть БОЛЬШЕ, и не увидел ничего нового.

   Поэтому здесь линейка возвращается в ЛЕВЫЙ СТОЛБЕЦ — она встаёт вдоль длинной
   стороны экрана и не отнимает у холста ни пикселя высоты, а ширины у нас избыток.
   Плюс убраны поля окна показа и сжата шапка. Замер после правки: 490×368 вместо
   368×276 — площадь листа выросла в 1,8 раза, а потолок для 4:3 на этом экране
   (если убрать вообще всё) — 520×390.
   --------------------------------------------------------------- */
@media (max-height: 540px) and (orientation: landscape) {
    .pw-screen--full {
        /* Узкая линейка: подписей в ней нет, знака хватает. */
        --pw-rail-w: 52px;
        /* Линейка ушла влево: рост ряда ей больше не задаёт высоту. */
        --pw-rail-h: 0px;
    }
    .pw-screen--full .pw-studio__body {
        grid-template-columns: var(--pw-rail-w) minmax(0, 1fr);
        grid-template-rows: minmax(0, 1fr);
    }
    .pw-screen--full .pw-rail {
        flex-direction: column;
        height: auto;
        padding: .15rem .2rem;
        gap: 0;
        border-bottom: 0;
        border-right: 1px solid var(--pw-st-border);
        overflow: hidden;
        touch-action: auto;
    }
    /* Знаки своего роста и сжимаются, если высоты не хватает: свёрнутая линейка
       (четыре знака и кнопка) не должна растягивать их на всю колонку. */
    .pw-screen--full .pw-rail__item {
        flex: 0 1 40px;
        min-height: 0;
        min-width: 0;
        padding: 0;
        border-radius: 8px;
    }
    .pw-screen--full .pw-rail__icon img,
    .pw-screen--full .pw-rail__item--panel .pw-rail__icon { width: 24px; height: 24px; }
    /* Разделитель снова горизонтальный: линейка вертикальная. */
    .pw-screen--full .pw-rail__sep {
        width: 60%;
        height: 1px;
        margin: .1rem auto;
        align-self: center;
    }
    /* Спрятанная часть в колонке растёт ВНИЗ, как на десктопе; кнопка стоит на месте. */
    .pw-screen--full .pw-rail__rest { flex: 0 1 auto; grid-template-columns: none; grid-template-rows: 0fr; min-height: 0; }
    .pw-screen--full .pw-rail.is-open .pw-rail__rest { grid-template-rows: 1fr; }
    .pw-screen--full .pw-rail__restIn { flex-direction: column; }
    .pw-screen--full .pw-rail__restIn > * { transform: translateY(-6px); }
    .pw-screen--full .pw-rail.is-open .pw-rail__restIn > * { transform: none; }
    .pw-screen--full .pw-rail__more { padding: .15rem 0; }
    .pw-screen--full .pw-rail__more .bi { transform: none; }
    .pw-screen--full .pw-rail.is-open .pw-rail__more .bi { transform: rotate(180deg); }
    .pw-screen--full .pw-rail__moreLabel { display: none; }

    /* Поля вокруг листа: в горизонтали каждый пиксель высоты — это холст. */
    .pw-screen--full .pw-studio .pw-canvas-host { padding: 4px; }

    /* Шапка работы — одна тонкая строка: она единственная, что ещё отнимает высоту
       у холста (замер: 53 px из 390), и каждый её пиксель виден на листе. */
    /* `.pw-studio` в селекторе — не украшение: тёплая тема правит шапку правилами
       из ДВУХ классов (`.pw-theme--cozy .pw-head`), её файл подключается после
       `app.css`, и при равном весе побеждала она (замер: padding оставался .45rem,
       шапка — 48 px вместо 30). Третий класс снимает спор раз и навсегда. */
    .pw-screen--full .pw-studio .pw-head { padding: .1rem .4rem; gap: .25rem; }
    .pw-screen--full .pw-studio .pw-head__mark { display: none; }
    /* Знаки шапки крупнее прежнего (23.09.2026), но ниже портретных 40 px:
       в горизонтали высота дороже. */
    .pw-screen--full .pw-studio .pw-head .btn { min-width: 34px; height: 34px; font-size: 1rem; }
    .pw-screen--full .pw-studio .pw-head__undo,
    .pw-screen--full .pw-studio .pw-head__redo { font-size: 1.25rem; }
    .pw-screen--full .pw-studio .pw-head .pw-publish { font-size: .875rem; }

    /* Строка свойств в горизонтали — над холстом, как в портрете, но теснее. */
    .pw-screen--full .pw-optbar { padding: .15rem .4rem; }
}

/* Всплывающая панель ростом с содержимое (цвет, кисти, «…») на телефоне становится
   ШТОРКОЙ снизу: до верха экрана пальцем не достать, а колесо цвета в карточку у
   кнопки не влезает. Координаты в этом режиме ставит CSS, а не `Popover.place`. */
.pw-pop--sheetable.is-sheet {
    left: 0;
    right: 0;
    top: auto;
    bottom: 0;
    width: 100%;
    max-width: none;
    max-height: 72vh;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -10px 30px rgba(16, 24, 40, .22);
}

/* ---------------------------------------------------------------
   ПЛЕЕР ПОКАЗА (22.09.2026). Показ выглядит видеоплеером, а не редактором:
   картинка, кнопка плей по центру, полоса управления ВПРИТЫК под картинкой.
   Слева за краем картинки — два знака: чем рисуют и каким цветом.

   Ширину считает ЗДЕСЬ, на корне плеера: полоса управления обязана быть ровно
   такой же ширины, как картинка, а у неё своего размера нет. Логические числа
   холста ставит JS (`--pw-w`/`--pw-h`).
   --------------------------------------------------------------- */
.pw-player {
    --pw-player-badge: 44px;
    /* Дорожка ползунка: рамочные токены на тёплом фоне не видно вовсе. */
    --pw-player-track: rgba(43, 47, 56, .16);
    --pw-player-gutter: calc(var(--pw-player-badge) + 16px);
    --pw-stage-width: min(
        100%,
        max(calc(var(--pw-w, 800) * 1px), var(--pw-canvas-min)),
        calc(var(--pw-canvas-cap) * var(--pw-w, 800) / var(--pw-h, 600))
    );
    position: relative;
    /* Знаки стоят ЗА картинкой, но не за плеером: отступ держит для них место,
       иначе отрицательное смещение уехало бы за край колонки. */
    padding-left: var(--pw-player-gutter);
}

/* Плеер берёт клавиши, когда фокус внутри него: фокус обязан быть ВИДЕН. */
.pw-player:focus { outline: none; }
.pw-player:focus-visible { outline: 2px solid var(--pw-accent); outline-offset: 6px; }

.pw-player__frame {
    position: relative;
    width: var(--pw-stage-width);
    max-width: 100%;
}

.pw-player .pw-stage { width: 100%; }

/* Стекло поверх картинки: оно же кнопка «плей», оно же пауза по щелчку. */
.pw-player__veil {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 3px;
    /* Работу НЕ затемняем: приглушённый чужой рисунок рядом с белым листом практики
       читается как выцветший, а не как «видео на паузе». Плеер узнаётся кнопкой. */
    background: transparent;
    cursor: pointer;
    transition: background .2s ease;
}
.pw-player__veil:hover { background: rgba(24, 20, 16, .06); }
.pw-player.is-playing .pw-player__veil:hover { background: transparent; }

.pw-player__big {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 76px;
    height: 76px;
    border-radius: 50%;
    background: var(--pw-accent);
    color: #fff;
    font-size: 2.2rem;
    line-height: 1;
    box-shadow: 0 6px 22px rgba(16, 24, 40, .28);
    transition: transform .16s ease, opacity .2s ease;
}
.pw-player__big > i { transform: translateX(3px); }   /* треугольник тяжелее слева */
.pw-player__veil:hover .pw-player__big { transform: scale(1.06); }
/* НАЖАТИЕ ВИДНО СРАЗУ (23.09.2026, жалоба владельца: «кнопка должна визуально
   откликаться на нажатие»). Класс ставит касание (`Replay`), а не `:active` —
   Safari на телефоне `:active` без слушателя касаний не показывает. */
.pw-player__veil.is-press .pw-player__big,
.pw-player__veil:active .pw-player__big { transform: scale(.9); transition-duration: .06s; }
.pw-replay-play.is-press { transform: scale(.9); }
.pw-player.is-playing .pw-player__big { opacity: 0; transform: scale(.78); }
/* ПАУЗА РУКОЙ — не стоп (заказ владельца 23.09.2026, «логика ютуба»): большая кнопка
   не возвращается и стекло под курсором не темнеет — человек рассматривает кадр.
   Раньше кнопка всплывала из .78 и «дорастала» — этого эффекта здесь больше нет. */
.pw-player.is-held .pw-player__big { opacity: 0; transform: scale(.78); transition: none; }
.pw-player.is-held .pw-player__veil:hover { background: transparent; }

/* Мгновенный знак действия: белый знак в полупрозрачном тёмном кружке, на миг — и
   пропадает. Ставит его `Replay.blip`, снимает конец анимации. */
.pw-player__blip {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 64px;
    height: 64px;
    margin: -32px 0 0 -32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(0, 0, 0, .5);
    color: #fff;
    font-size: 2rem;
    line-height: 1;
    opacity: 0;
    pointer-events: none;
}
.pw-player__blip.is-play > i { transform: translateX(2px); }
.pw-player__blip.is-on { animation: pw-blip .65s ease-out; }
@keyframes pw-blip {
    0%   { opacity: 0; transform: scale(.9); }
    15%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.3); }
}
@media (prefers-reduced-motion: reduce) {
    @keyframes pw-blip { 0%, 60% { opacity: 1; } 100% { opacity: 0; } }
}

/* Два знака за левым краем картинки. */
.pw-player__side {
    position: absolute;
    top: 0;
    left: 0;
    transform: translateX(calc(-1 * var(--pw-player-gutter)));
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.pw-player__badge {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--pw-player-badge);
    height: var(--pw-player-badge);
    border-radius: var(--pw-radius-sm);
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    box-shadow: var(--pw-shadow);
}
/* Пустого знака в интерфейсе нет: нечего показать — знака не видно. */
.pw-player__badge.is-empty { visibility: hidden; }
.pw-player__icon { display: block; width: 26px; height: 26px; }
.pw-player__chip {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1px solid rgba(16, 24, 40, .18);
}
/* Ластик краски не кладёт — цвета у действия нет, и выдумывать его нельзя. */
.pw-player__badge--color.is-none .pw-player__chip {
    background: linear-gradient(
        to bottom right,
        transparent calc(50% - 1px), var(--pw-muted) calc(50% - 1px),
        var(--pw-muted) calc(50% + 1px), transparent calc(50% + 1px)
    );
}

/* Смена инструмента видна вспышкой. Время живёт ЗДЕСЬ, а не в JS: класс снимать
   по таймеру незачем — он просто перезапускается на следующей смене. */
@keyframes pw-player-swap {
    0%   { transform: scale(.7); box-shadow: 0 0 0 0 var(--pw-accent); }
    55%  { transform: scale(1.12); box-shadow: 0 0 0 6px transparent; }
    100% { transform: scale(1); box-shadow: var(--pw-shadow); }
}
.pw-player__badge.is-swap { animation: pw-player-swap .42s ease-out; }

/* Полоса управления — ВПРИТЫК под картинкой и ровно её ширины. */
.pw-replay-bar {
    display: flex;
    align-items: center;
    gap: .5rem;
    width: var(--pw-stage-width);
    max-width: 100%;
    margin-top: 0;
    padding-top: .4rem;
}
.pw-replay-range { flex: 1 1 auto; }
/* Бегунок красится ЦВЕТОМ САЙТА: синий бегунок Bootstrap здесь такой же чужой, как
   в панелях редактора. Цвет забивается правилами, а не переменной — в нашей сборке
   Bootstrap 5.1 он записан литералом. Правила webkit и gecko ОТДЕЛЬНЫЕ: незнакомый
   псевдоэлемент в списке селекторов роняет всё правило целиком. */
.pw-replay-range::-webkit-slider-thumb {
    width: 14px;
    height: 14px;
    margin-top: -3px;
    background-color: var(--pw-accent);
}
.pw-replay-range::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border: 0;
    background-color: var(--pw-accent);
}
.pw-replay-range::-webkit-slider-runnable-track { height: 8px; background-color: var(--pw-player-track); }
.pw-replay-range::-moz-range-track { height: 8px; background-color: var(--pw-player-track); }

/* Пресеты ускорения — СВОЕЙ строкой под полосой, по правому краю картинки:
   в самой полосе четыре кнопки рядом с ползунком снова сделали бы из неё панель. */
.pw-replay-speeds {
    display: flex;
    justify-content: flex-end;
    width: var(--pw-stage-width);
    max-width: 100%;
    margin-top: .35rem;
}
.pw-replay-speeds .btn { min-width: 2.6rem; }
.pw-replay-speeds .btn.active {
    background: var(--pw-accent);
    border-color: var(--pw-accent);
    color: #fff;
}

/* На телефоне места слева нет: знаки встают РЯДОМ над картинкой. */
@media (max-width: 767.98px) {
    .pw-player {
        padding-left: 0;
        padding-top: calc(var(--pw-player-badge) + 10px);
    }
    .pw-player__side {
        top: calc(-1 * (var(--pw-player-badge) + 10px));
        transform: none;
        flex-direction: row;
    }
    .pw-player__big { width: 60px; height: 60px; font-size: 1.7rem; }
    .pw-player__blip { width: 52px; height: 52px; margin: -26px 0 0 -26px; font-size: 1.6rem; }
}

/* ---------------------------------------------------------------
   Плитки работ
   --------------------------------------------------------------- */
/* Плитки НЕ растягиваются по высоте строки: каждая ровно такая, какой её делает работа. */
.pw-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    align-items: start;
    gap: 1rem;
}
.pw-grid--tight { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: .75rem; }

.pw-card {
    display: block;
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-radius: var(--pw-radius);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: box-shadow .15s ease, transform .15s ease;
}
.pw-card:hover { box-shadow: var(--pw-shadow); transform: translateY(-2px); }

/* Плитка — уменьшенная копия холста: пропорции приходят от самой работы (--pw-ar).
   Атрибуты width/height у картинки не ставим: они бьют CSS-пропорцию и вытягивают
   плитку в столбик (замерено 03.09.2026 — превью 800×600 занимало 169×600). */
.pw-card__art {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: var(--pw-ar, 4 / 3);
    object-fit: contain;
    background: var(--pw-warm-paper);
    border-bottom: 1px solid var(--pw-border);
}
.pw-card__body { padding: .5rem .65rem .6rem; font-size: .8125rem; }
.pw-card__title { font-weight: 600; }
/* Описание урока в плитке: две строки, дальше — многоточие (плитки в ряду одной высоты). */
.pw-card__desc {
    margin: .15rem 0 .3rem;
    font-size: .85em;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.pw-card__meta { color: var(--pw-muted); display: flex; gap: .6rem; flex-wrap: wrap; }

.pw-empty {
    padding: 2.5rem 1rem;
    text-align: center;
    color: var(--pw-muted);
    border: 1px dashed var(--pw-border);
    border-radius: var(--pw-radius);
}

.pw-hero-title { font-weight: 700; letter-spacing: -.02em; }

.pw-rule-badge {
    background: var(--pw-accent-soft);
    color: var(--pw-accent);
    border-radius: 999px;
    padding: .15rem .6rem;
    font-size: .8125rem;
    white-space: nowrap;
}

/* ---------------------------------------------------------------
   Мобильная раскладка: холст важнее панелей (§5.4 спеки).
   Панель инструментов уезжает вниз и становится липкой, чтобы
   до кистей можно было дотянуться большим пальцем.
   --------------------------------------------------------------- */
@media (max-width: 767.98px) {
    /* ЭТО ПРАВИЛА ПРЕЖНЕЙ ПАНЕЛИ (`editor.shell = classic`), и с этапа E они прямо
       сказаны: обе оболочки стоят на одном корне `.pw-editor`, и порядок, заданный
       здесь, доставался ТАКЖЕ новой оболочке. Замер 12.09.2026: `order: 2` у HUD
       переставлял правила стены ЗА зум в строке состояния, и таблетка зума на
       телефоне уезжала к левому краю. Новая оболочка добавляет к корню `pw-studio` —
       по нему прежние правила её и обходят. */
    .pw-editor:not(.pw-studio) { gap: .4rem; }

    /* На телефоне холст важнее панелей: панель липкая внизу, места ей нужно немного. */
    :root { --pw-canvas-cap: 52vh; --pw-canvas-min: 100%; }

    .pw-editor:not(.pw-studio) .pw-toolbar {
        order: 3;
        position: sticky;
        bottom: 0;
        z-index: 5;
        padding: .4rem .5rem;
        box-shadow: 0 -4px 16px rgba(16, 24, 40, .08);
    }
    .pw-editor:not(.pw-studio) .pw-settings { order: 4; }
    .pw-editor:not(.pw-studio) .pw-actions  { order: 5; }
    .pw-editor:not(.pw-studio) .pw-hud      { order: 2; }
    .pw-editor:not(.pw-studio) .pw-canvas-host { order: 1; }

    .pw-tool.btn { --bs-btn-padding-x: .5rem; font-size: .8125rem; }
    .pw-tool.btn span { display: none; }
    .pw-setting__name { min-width: 3.5rem; }
    .pw-setting__range { width: 7rem; }
    .pw-swatch { width: 1.9rem; height: 1.9rem; }   /* палец, а не курсор */
    .pw-editor:not(.pw-studio) .pw-actions .btn { flex: 1 1 auto; }
}

/* ---------------------------------------------------------------
   Украшение страницы, заказанное темой (templates/partials/decor.php).
   Слой лежит ПОД содержимым и не ловит нажатия: тема украшает страницу,
   а не отбирает у неё клики. Где что стоит — решает сама тема.
   --------------------------------------------------------------- */
.pw-decor {
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
}
.pw-decor__item,
.pw-decor__note { position: absolute; }

/* ---------------------------------------------------------------
   Выбор оформления в кабинете. Тема — свойство человека, и выбирается
   она картинкой, а не названием в выпадающем списке: словами «Studio»
   и «Cozy Desk» разницу не объяснить.
   --------------------------------------------------------------- */
.pw-themes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: .6rem;
}
.pw-themes__item {
    display: block;
    padding: .4rem;
    background: var(--pw-surface);
    border: 1px solid var(--pw-border);
    border-radius: var(--pw-radius);
    cursor: pointer;
}
.pw-themes__item:hover { border-color: var(--pw-muted); }
.pw-themes__item.is-on { border-color: var(--pw-accent); box-shadow: 0 0 0 2px var(--pw-accent-soft); }
/* Радио спрятано, но фокус с клавиатуры обязан быть виден — иначе выбор теряется. */
.pw-themes__item:focus-within { border-color: var(--pw-accent); }
.pw-themes__art {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    border-radius: calc(var(--pw-radius) - .3rem);
    border: 1px solid var(--pw-border);
}
.pw-themes__name { display: block; margin-top: .35rem; font-size: .8125rem; font-weight: 600; }
.pw-themes__note { display: block; font-size: .75rem; color: var(--pw-muted); }

/* =====================================================================
   ПОКАЗ: тот же редактор, которым правит лента событий
   (заказ владельца 21.09.2026: «чтобы было видно курсор, инструмент и опции —
   как будто реалтайм смотришь за человеком»)

   Своего вида у показа нет и не заводится: это `studio.js` в режиме `watch`.
   Здесь ровно три вещи, которых у работы не бывает, — стекло поверх редактора,
   видимая рука автора и загорающаяся кнопка отмены.
   ===================================================================== */
.pw-studio--watch { position: relative; }

/* СТЕКЛО. Смотреть можно, нажать нельзя: ткнув в линейку, зритель сменил бы
   инструмент, а лента через кадр вернула бы свой — и человек решил бы, что
   интерфейс сломан. Слой держит над редактором ОБЫЧНЫЙ курсор зрителя: рука
   автора на холсте своя, и второй курсор рядом с ней читался бы как поломка.
   Вторая защита — атрибут `inert` (ставит оболочка): он снимает ещё и
   клавиатуру с фокусом, но есть не везде, поэтому слой остаётся. */
.pw-watch-veil {
    position: absolute;
    inset: 0;
    z-index: 20;
    background: transparent;
    cursor: default;
}

/* Рука автора видна на ЛЮБОМ устройстве: своего курсора на телефоне нет (там
   палец), но это чужая запись, а не палец зрителя. */
@media (hover: none) {
    .pw-cursor--watch { display: block; }
}

/* Нажатие видно: кольцо кисти твердеет, знак инструмента подсвечивается. Без
   этого не отличить «рука ведёт линию» от «рука идёт к следующему месту». */
.pw-cursor.is-down .pw-cursor__ring {
    border-color: #fff;
    box-shadow: 0 0 0 2px rgba(16, 24, 40, .75), inset 0 0 0 1px rgba(16, 24, 40, .45);
}
.pw-cursor.is-down .pw-cursor__glyph {
    filter: drop-shadow(0 1px 2px rgba(16, 24, 40, .35)) drop-shadow(0 0 4px var(--pw-accent));
}

/* Автор нажал отмену — кнопка загорается. Событие `u` в ленте есть, а нажатия
   на экране не видно, и работа «сама» теряла последний штрих. */
.pw-head__undo.is-hit,
.pw-head__redo.is-hit {
    color: var(--pw-accent);
    border-color: var(--pw-accent);
    background: var(--pw-accent-soft);
}

/* ==================================================================
   СТРАНИЦА УРОКА: показ по центру, практика — по нажатию
   Разбор `.spec/LESSON_PRACTICE_MODES.md`, заказ владельца 22.09.2026:
   «изначально урок по центру экрана; кнопка попробовать сдвигает видос
   влево и справа создается ТОЧНО ТАКОЙ ЖЕ холст — прямо один в один».
   ================================================================== */
.pw-lesson__panes {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    align-items: flex-start;
    justify-content: center;
}
.pw-lesson__pane { flex: 1 1 100%; min-width: 0; }

/* Пока практики нет, показ стоит по центру и не растягивается во всю ширину
   страницы: урок — это работа, а не панорама. */
.pw-lesson:not(.is-practice) .pw-lesson__pane--demo {
    max-width: 760px;
    margin-inline: auto;
}
.pw-lesson.is-practice .pw-lesson__pane { flex: 1 1 calc(50% - .75rem); }

.pw-lesson__cta {
    display: flex;
    justify-content: center;
    margin-top: 1.25rem;
}
.pw-lesson.is-loading .pw-lesson__cta .btn { pointer-events: none; opacity: .6; }

/* ОКНО ПОКАЗА ПРАКТИКИ — ровно той же ширины, что лист показа: число меряет
   `lesson.js` и кладёт в `--pw-sheet`. Дальше оболочка вписывает лист САМА и
   приходит ровно к тому же числу (`autoZoom` = min(ширина/W, высота/H)) —
   навязывать ей зум не нужно, и `autoFit` при движении окна посчитает то же.
   Подпись зума при этом остаётся правдой. */
.pw-lesson.is-practice .pw-canvas-host {
    /* СОДЕРЖИМОЕ окна показа, а не коробка целиком: оболочка меряет именно его
       (`Engine.hostRoom` вычитает поля), и ширина «с полями» дала лист на 42 px
       уже, чем у показа, — ровно то расхождение, из-за которого холсты
       перестали быть одинаковыми (замер 22.09.2026: 576 против 534). */
    box-sizing: content-box;
    width: var(--pw-sheet, 100%);
    /* Высота — та же ширина по пропорции холста плюс пара пикселей: лист обязан
       вписаться ПО ШИРИНЕ, иначе зум посчитается от высоты и разойдётся с
       показом. Потолок высоты снят намеренно: он считается от экрана, а показ
       рядом ограничен своим числом, и два разных потолка снова развели бы
       холсты — ширину показа мы и так меряем живьём. */
    height: calc(var(--pw-sheet, 100%) * var(--pw-ar, .75) + 2px);
    max-height: none;
    margin-inline: auto;
}

@media (max-width: 991.98px) {
    /* Две колонки на узком экране не совмещаются: показ и холст встают друг под
       друга. Телефонная раскладка (плашка плеера в углу) — следующим этапом. */
    .pw-lesson.is-practice .pw-lesson__pane { flex: 1 1 100%; }
}

/* ПРИЗРАК степ-бай-степа: калька между бумагой и рисунком ученика. Свои штрихи
   ложатся ПОВЕРХ него, нажатий он не ловит, а в опубликованный PNG попасть не
   может физически — холст не принадлежит движку (`Engine.flatten`). Силы —
   в конфиге (`editor.lesson.ghost`), здесь только место. */
.pw-ghost {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    pointer-events: none;
}

/* Вопрос на пустом холсте: «будешь типа степ бай степ или фристайлить?».
   Лист настоящий — той же ширины, что видео, — но редактора за ним ещё нет:
   способ учиться решает, каким редактор будет собран. */
.pw-lesson__sheet {
    width: var(--pw-sheet, 100%);
    aspect-ratio: 1 / var(--pw-ar, .75);
    margin-inline: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--pw-warm-paper, #fff);
    border-radius: 3px;
    box-shadow: 0 4px 18px rgba(30, 28, 20, .14);
}
.pw-lesson__ask {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    align-items: stretch;
    max-width: 16rem;
    text-align: center;
}
.pw-lesson__ask-title { margin: 0 0 .25rem; font-weight: 600; }
.pw-lesson__mode { display: flex; flex-direction: column; line-height: 1.25; }
.pw-lesson__mode-name { font-weight: 600; }
.pw-lesson__mode-hint { font-size: .78rem; opacity: .78; }

/* ВОПРОС О ЧЕРНОВИКЕ поверх листа (`Editor.askDraft`, 24.09.2026): лист закрыт,
   пока не ответили; кадр черновика бледно под вопросом — видно, что продолжать. */
.pw-draft-ask {
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px;
    background: var(--pw-warm-paper);
    cursor: default;
    touch-action: manipulation;
}
.pw-draft-ask__pic {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: .3;
    pointer-events: none;
}
.pw-draft-ask__box {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    max-width: 16rem;
    padding: 1rem 1.1rem;
    text-align: center;
    background: var(--bs-body-bg);
    border-radius: var(--pw-radius-sm);
    box-shadow: 0 4px 18px rgba(30, 28, 20, .14);
}
.pw-draft-ask__title { margin: 0 0 .15rem; font-weight: 600; }

/* Полоса шага стоит ТАМ ЖЕ, где у свободного редактора строка свойств: рука
   ищет её на одном месте. Инструмент в ней — ЗНАЧЕНИЕ, а не контрол. */
.pw-lesson__strip {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-bottom: .5rem;
}
.pw-lesson__step { font-weight: 600; margin-inline: .25rem; }
.pw-lesson__tool {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .15rem .5rem;
    border-radius: 999px;
    background: var(--pw-warm-mat, rgba(0, 0, 0, .05));
    font-size: .82rem;
}
.pw-lesson__tool img { width: 18px; height: 18px; }
.pw-lesson__tool-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .25);
}
/* Знак инструмента расталкивает полосу: «Previous» остаётся слева у номера шага,
   а «Watch again», «Redo step» и «Next» уходят к правому краю. */
.pw-lesson__tool { margin-inline-end: auto; }

/* Счёт повторённого и «всё верно»: сигнал ПОШАГОВЫЙ, а не приговор в конце шага.
   Запертых шагов в продукте нет — «дальше» доступно и без него. */
.pw-lesson__progress { font-size: .82rem; opacity: .75; }
.pw-lesson__strip.is-done .pw-lesson__progress {
    color: var(--pw-accent, #ee6046);
    font-weight: 600;
    opacity: 1;
}
.pw-lesson__strip.is-done .pw-lesson__step { color: var(--pw-accent, #ee6046); }
.pw-lesson__arrow { font-size: 1.1rem; line-height: 1; padding-inline: .6rem; }

/* Кнопка плашки существует только там, где есть сама плашка: на широком
   экране показ стоит колонкой, разворачивать нечего. */
.pw-lesson__demo-toggle { display: none; }

/* ==================================================================
   ТЕЛЕФОН: ВИДЕО — ПЛАШКОЙ В УГЛУ
   Заказ владельца 22.09.2026: «конечно, там наверное хуй совместишь на
   мобайл экране видос. Но можно видос в нижний угол сделать квадратиком.
   Почему нет? С возможностью его развернуть и смотать».
   Это не компромисс, а следствие призрака: когда шаг рисуется прямо на
   твоём холсте, видео во время рисования не нужно.
   ================================================================== */
@media (max-width: 991.98px) {
    /* Лист практики здесь равняется по ЭКРАНУ, а не по показу: показ ужат
       до плашки в углу, и подгонять холст под неё было бы дословным
       исполнением правила против его смысла. */
    .pw-lesson.is-practice .pw-canvas-host {
        box-sizing: border-box;
        width: 100%;
        height: auto;
        max-height: calc(var(--pw-canvas-cap) + 36px);
    }

    .pw-lesson.is-practice .pw-lesson__pane--demo {
        position: fixed;
        right: .75rem;
        bottom: .75rem;
        width: 42vw;
        max-width: 190px;
        margin: 0;
        z-index: 1025;          /* ниже всплывашек редактора (1080) и курсора (1090) */
        border-radius: var(--pw-radius-sm, 8px);
        box-shadow: 0 8px 26px rgba(30, 28, 20, .28);
        overflow: hidden;
        transition: opacity .15s ease;
    }
    /* Свёрнутая плашка — это КАДР, а не плеер: полоса, пресеты и знаки
       инструментов в ней не читаются и только съедают место. */
    .pw-lesson.is-practice:not(.is-demo-open) .pw-lesson__pane--demo .pw-replay-bar,
    .pw-lesson.is-practice:not(.is-demo-open) .pw-lesson__pane--demo .pw-replay-speeds,
    .pw-lesson.is-practice:not(.is-demo-open) .pw-lesson__pane--demo .pw-player__side {
        display: none;
    }
    .pw-lesson.is-practice .pw-lesson__pane--demo .pw-player { --pw-player-gutter: 0px; }

    /* Развёрнутая — во всю ширину внизу, с полосой и пресетами. */
    .pw-lesson.is-demo-open .pw-lesson__pane--demo {
        right: .5rem;
        left: .5rem;
        bottom: .5rem;
        width: auto;
        max-width: none;
        z-index: 1050;
        padding: .5rem;
        background: var(--pw-warm-mat, #fff);
    }

    /* Пока палец на холсте, плашка притухает и нажатий не ловит: она стоит
       ровно там, где рисуют, и спорить с рукой ей не за что. */
    .pw-lesson.is-drawing:not(.is-demo-open) .pw-lesson__pane--demo {
        opacity: .25;
        pointer-events: none;
    }

    .pw-lesson__demo-toggle {
        display: block;
        position: absolute;
        inset: 0;
        z-index: 2;
        width: 100%;
        border: 0;
        background: transparent;
        color: transparent;      /* подпись нужна голосу, а не глазу */
    }
    .pw-lesson.is-demo-open .pw-lesson__demo-toggle {
        /* НАВЕРХУ: внизу развёрнутой плашки стоят полоса и пресеты ускорения,
           и кнопка закрытия налезала бы прямо на них. */
        inset: .35rem .35rem auto auto;
        width: auto;
        padding: .25rem .6rem;
        border-radius: 999px;
        background: rgba(20, 18, 16, .72);
        color: #fff;
        font-size: .78rem;
    }
}
