/* Домашний экран страницы поиска — минималистичный скин.
 *
 * URL: /nodejs/res/css/home.css (маунт search/ уже есть в dg-light.js, правок сервера не нужно).
 *
 * ВСЁ здесь живёт под классом-скином body.dg-skin-minimal и/или под состоянием
 * body.dg-state-home. Это сознательно: минималистичный стиль сейчас применяется ТОЛЬКО к
 * домашнему экрану, а выдача и ридер остаются в нынешнем оформлении — общий стиль вырабатывается
 * отдельно, по мере объединения поиска и ридера. Позже скин станет пунктом в /settings/, и тогда
 * его хватит расширить на остальные состояния, не переписывая эти правила.
 *
 * Никаких внешних шрифтов (в демке был Google Fonts — на проде внешний CDN не подключаем) и
 * никакой своей палитры: цвета те же, что уже у поиска и ридера, см. блок ниже.
 *
 * Тёмная тема здесь — body.dark, а НЕ html.dark как в демке: класс ставит themeswitch.js на
 * <body> (assets/js/themeswitch.js, bodyTag.classList.add("dark")).
 */

/* Палитра — НЕ своя. Это те же значения, которыми уже живут поиск и ридер: цвета ридера
   объявлены в reader/css/rus-multi.css (--off-white rgb(221,221,221), --light-off-white
   rgb(253,253,253), --off-black rgb(4,1,19), --dark-gray #5a5a5a, --light-gray #8f8f8f,
   --blue #3434be, в тёмной теме ссылки rgb(122,122,249)), а поверхности и границы — Bootstrap,
   как у кнопок .btn-light в ряду инструментов выдачи. Значения повторены буквально, а не через
   var(): rus-multi.css подключается лениво, только вместе с ридером, и до первого открытия
   текста её переменных на странице просто нет. Тот же приём уже применён к #language-button
   в <head> этой страницы.

   ОБНОВЛЕНО: светлая палитра переехала на землистые нейтрали и зелёный акцент (макет
   production-v4). Тёмная осталась на боевом --off-black, см. комментарий у body.dark ниже. */

/* Owner: "ширина страницы... получается неудобно, что под пальцем страница ездит" — decorative
   absolutely-positioned elements (e.g. reader/css/uiextra.css's .copyLink-start markers, which
   sit at left:-1em relative to a segment that can itself start near the viewport's left edge)
   push a few px past the viewport edge. They don't add real scrollable content, just enough
   negative overflow for mobile Safari/Chrome to treat the page as horizontally pannable — this
   guard clips exactly that kind of stray edge overflow without touching any element's OWN
   overflow-x:auto (home.css's own #dg-hero-band horizontal scrollers etc. are unaffected, they
   scroll inside their own box regardless of what the page root clips). Unscoped (not under
   body.dg-skin-minimal) — this single shell page (search/index.html) serves home/results/reader
   alike, and the bug isn't specific to the minimal skin. */
html, body { overflow-x: hidden; }

/* Owner: "текст на мобильном слишком мелкий... во всех частях... в 1.2 раза крупнее" (было 1.5 —
   owner: "слишком крупно"). Unscoped (not under body.dg-skin-minimal) on purpose, same reasoning
   as the overflow-x rule above: this one shell page serves home/results/reader/toc alike, and the
   complaint wasn't specific to the minimal skin. One rem-scale line covers ALL of it because the
   whole codebase (this file, Bootstrap utilities, --dg-* components) sizes type in rem, not px —
   rem always resolves against THIS root value, so nothing per-component needs touching.

   The chrome-specific opt-outs from this bump (icon buttons, toolbar/tab links — owner: "текст...
   не должно влиять на расстояние между иконками и текстовыми ссылками") live at the very END of
   this file, not here: they target selectors (.dg-tile, #reader-toolbar, …) that this file ALSO
   sets font-size on later at their normal spot, same specificity — same-specificity CSS is decided
   by source order, so the override has to come after, not before (this exact trap bit an earlier
   round of this file too, see the #dg-mega comment further down). */
@media (max-width: 767.98px) {
    :root { --dg-mobile-scale: 1; }
    html { font-size: calc(100% * var(--dg-mobile-scale)); }
}

body.dg-skin-minimal {
    /* Фон страницы. Отдельным токеном, а не через --bs-body-bg: тот у Bootstrap белый ВСЕГДА —
       тёмную тему на этом сайте делает body.dark из langswitch.css, до бутстраповских переменных
       она не дотягивается. Пока правило ниже брало --bs-body-bg, тёмная главная выбеливалась. */
    --dg-page: #ffffff;
    --dg-surface: #ffffff;
    --dg-surface-hover: #f5f4f1;
    --dg-surface-active: #eae8e2;
    --dg-border: #e7e5de;
    --dg-border-strong: #d7d4c9;
    --dg-text: #1b1d19;
    --dg-text-2: #5c6058;
    /* apple-design audit: was #93968c on white ≈ 3:1, fails WCAG AA (4.5:1) for text.
       Darkened to ~5:1 while keeping the same olive-gray hue. */
    --dg-text-muted: #6e716a;
    --dg-navy: #243448;
    --dg-navy-2: #1b2836;
    --dg-accent: #149c7c;
    /* Акцент для ТЕКСТА. В светлой теме совпадает с основным, в тёмной берёт более светлый тон:
       прод-зелёный для значков в подписи не читается. */
    --dg-accent-ink: #0f7c63;
    --dg-accent-dark: #0f7c63;
    --dg-accent-bg: #dff3ec;
    --dg-radius: 10px;
    --dg-font: var(--bs-body-font-family);
    --dg-ease: cubic-bezier(0.22, 0.68, 0, 1);
    /* Боковое поле страницы: столько добавляет .container-fluid вокруг .table-wrapper. Нужно
       hero-полосе, чтобы вылезти из этого поля на всю ширину экрана (margin с минусом). На
       телефоне это поле сжато до 3px — см. медиазапрос в <head> index.html. */
    --dg-gutter: 12px;
}
@media (max-width: 767.98px) {
    body.dg-skin-minimal { --dg-gutter: 3px; }
}

/* Тёмная тема отталкивается от БОЕВОГО тёмного фона: страница в тёмной теме — rgb(17,17,17),
   его задаёт [data-theme="dark"] из assets/css/extrastyles.css (замерено на живой странице; в
   langswitch.css есть ещё body.dark с --off-black, но выигрывает первое). Поверхности здесь —
   нейтральные, на пол-тона светлее фона: возьми мы оливковую основу из макета, главная встала бы
   другим цветом, чем соседние страницы, и переход между ними читался бы как переход на другой
   сайт. От макета берём только зелёный акцент — в тёмной теме он и правда звонче синего. */
body.dg-skin-minimal.dark {
    --dg-page: #111111;
    --dg-surface: #191919;
    --dg-surface-hover: #202020;
    --dg-surface-active: #2a2a2a;
    --dg-border: #2c2c2c;
    --dg-border-strong: #3b3b3b;
    --dg-text: rgb(221, 221, 221);
    --dg-text-2: #a8a8a8;
    --dg-text-muted: #7c7c7c;
    --dg-navy: #1b2836;
    --dg-navy-2: #131c26;
    /* Зелёный в тёмной теме — БОЕВОЙ, приглушённый, а не яркий из светлой: #136857 у прода стоит
       на .bg-primary и .menu-icon, #025242 на .btn-primary, #09967a на ссылках
       ([data-theme="dark"] в assets/css/extrastyles.css). Яркий #3fe3bc из макета на тёмном фоне
       бил в глаза и не совпадал ни с одной соседней страницей.
       Для значков берём ровно прод-цвет, для текста — прод-цвет ссылок: #136857 в подписи на
       тёмном фоне уже нечитаем (контраст ниже 3:1), а у прода для текста и заведён отдельный,
       более светлый тон. */
    --dg-accent: #136857;
    --dg-accent-ink: #09967a;
    --dg-accent-dark: #025242;
    --dg-accent-bg: #12241f;
}

/* ============================================================================
   Показ/скрытие домашних блоков.
   Схлопывание через max-height + opacity, а не display:none — display не анимируется, а нам
   нужно, чтобы при уходе в выдачу шапка и плитки СЖИМАЛИСЬ, поднимая инпут вверх, а не исчезали
   рывком. max-height заведомо больше реальной высоты; overflow:hidden прячет остаток во время
   перехода. Шторки живут отдельно, в конце <body>, и под это схлопывание не попадают.
   ============================================================================ */
#home-motto,
#home-hint,
#home-pane {
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition:
        max-height 0.34s var(--dg-ease),
        opacity 0.22s ease,
        transform 0.34s var(--dg-ease),
        margin 0.34s var(--dg-ease);
    margin: 0;
}

body.dg-state-home #home-motto,
body.dg-state-home #home-hint,
body.dg-state-home #home-pane {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

/* Отступ инпута от шапки — раньше держался целиком на #home-motto (девиз стоял отдельной
   строкой прямо над .hero-row, его margin и был этим воздухом). Owner: девиз переехал в
   #dg-topbar (round 3 правки выше), а инпут не должен был сдвигаться — теперь отступ здесь,
   на самой .hero-row, независимо от того, где физически стоит текст девиза. */
body.dg-state-home .hero-row { margin-top: 74px; }
body.dg-state-home #home-pane  { max-height: 2000px; margin: 22px 0 0; }
/* #home-hint — position:absolute (см. .hero-row/#home-hint в search/index.html), max-height/
   opacity/transform ниже всё ещё нужны для схлопывания при уходе с главной, margin — только
   небольшой зазор от нижнего края поля, не отступ в потоке (его больше нет в потоке). */
body.dg-state-home #home-hint { max-height: 60px; margin-top: 8px; }

/* Ширина поля по состояниям: на главной оно — центр экрана, в выдаче и чтении уступает место
   содержимому. Переход между значениями анимируется (transition на .dg-hero-form в index.html).
   width:100% обязателен: форма — flex-элемент в .hero-row, а flex-элемент по умолчанию сжимается
   до содержимого, и одного max-width мало (замерено: поле выходило 270px вместо 640px). */
/* display:block — ответ на `#form { display:flex; justify-content:center; align-items:baseline }`
   из /assets/css/langswitch.css (общий файл, его не трогаем): из-за него поле-оболочка была
   flex-элементом и сжималась до содержимого — 269px вместо 640px, и вдобавок выравнивалась по
   базовой линии. Здесь форма — простой блок, а вся раскладка внутри у .dg-input-shell. */
body.dg-skin-minimal #form.dg-hero-form { display: block; width: 100%; }
body.dg-skin-minimal.dg-state-home .dg-hero-form { max-width: 640px; }
body.dg-skin-minimal.dg-state-results .dg-hero-form,
body.dg-skin-minimal.dg-state-reader .dg-hero-form,
body.dg-skin-minimal.dg-state-toc .dg-hero-form { max-width: 520px; }

/* ============================================================================
   Фирменная hero-полоса главной.
   Тёмный сине-зелёный с переходом в зелёный — та же пара, что в шапке боевого сайта. Вывеска,
   девиз, поле и подсказка сидят НА ней: на главной это один цельный блок, а не четыре строки
   на белом. В выдаче и в чтении полоса схлопывается — фон снимается, отступы обнуляются, и
   разметка возвращается к обычной (их оформление делаем отдельно).
   ============================================================================ */
/* Переходов здесь намеренно НЕТ. Полоса появляется и исчезает вместе со сменой состояния, а
   состояние обязано примениться сразу: анимируемое свойство во вкладке, которая не рисует кадры
   (фоновая вкладка, свёрнутое окно), застревает на начальном значении — замерено, полоса
   оставалась с домашним фоном и отступом уже в выдаче. Плавность ухода даёт схлопывание
   #home-motto/#home-hint/#home-pane по max-height, этого достаточно. */
/* Полоса тянется во ВСЮ ширину окна, а не до края колонки. Отрицательного margin по полю
   контейнера не хватало: у .table-wrapper есть свой max-width 1600px, и на мониторе шире полоса
   обрывалась вертикальной границей — заливка кончалась, а страница шла дальше, и это читалось
   как недоделанный кусок. 50% — середина колонки, 50vw — половина окна; разница и есть тот
   вылет, который нужно добрать с каждой стороны. */
#dg-hero-band {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    padding: 0;
    background: none;
}
body.dg-state-home #dg-hero-band {
    /* Съедаем .mt-2 родителя: полоса должна начинаться от самого верха окна, иначе над ней
       остаётся белая щель в 8px и она перестаёт читаться как шапка. */
    margin-top: -0.5rem;
    padding-bottom: 30px;
    background: linear-gradient(165deg,
        var(--dg-navy) 0%,
        var(--dg-navy) 38%,
        var(--dg-accent-dark) 100%);
}
.dg-hero-inner {
    max-width: 700px;
    margin: 0 auto;
    padding: 0 var(--dg-gutter, 12px);
}
/* --dg-gutter сжимается до 3px на телефоне ради ПЛОТНОЙ таблицы выдачи (#search-pane, см.
   index.html) — там это осознанный выбор, каждый пиксель ширины строки на счету. Поле ввода на
   главной — не таблица, и 3px от края экрана читались как «упирается в край» (жалоба владельца).
   Отвязываем именно этот контейнер от переменной, не трогая саму переменную (другие потребители
   3px могут появиться позже и по-прежнему хотят именно 3px). */
@media (max-width: 767.98px) {
    .dg-hero-inner { padding: 0 14px; }
    /* Тот же 3px-сквоз (index.html, ради плотной таблицы выдачи) достаётся и главной — вход и
       плитки лежат в ТОМ ЖЕ .container-fluid.mt-2, что и таблица. На главной строк с колонками
       нет, экономить пиксели ширины не для чего — только на этом состоянии возвращаем воздух.
       Селектор специфичнее, чем правило в index.html (доп. класс dg-state-home), поэтому
       порядок подключения файлов не важен. */
    body.dg-state-home > .container-fluid.mt-2 { padding-left: 14px; padding-right: 14px; }
}

/* На полосе весь текст светлый — независимо от темы: подложка тёмная в обеих. */
body.dg-state-home #dg-hero-band .dg-brand-name { color: #fff; }
body.dg-state-home #dg-hero-band .dg-icon-btn { color: #eaf4ef; }
body.dg-state-home #dg-hero-band .dg-icon-btn:hover,
body.dg-state-home #dg-hero-band .dg-icon-btn:focus-visible {
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
}
/* Абрис лого нужен только на светлом фоне; на полосе логотип и так контрастен. */
body.dg-state-home #dg-hero-band .dg-brand-logo { filter: none; }

/* ============================================================================
   Шапка главной: лого с названием слева, бургер в противовес справа.
   Только на главной. В выдаче и в чтении вывеска убирается совсем — там от знака остаётся
   ракушка внутри поля, а бургер стоит правее поля (.dg-menu-btn-hero).
   ============================================================================ */
/* Сетка «1fr auto 1fr», а не flex со space-between (owner: "сделай чтобы Find the Truth был в
   центре страницы"): при space-between девиз вставал в середину ОСТАТКА между вывеской и
   бургером, а вывеска заметно шире бургера — то есть левее центра страницы. Одинаковые боковые
   колонки ставят среднюю ровно по центру полосы, независимо от ширины вывески. */
#dg-topbar {
    display: none;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 0.75rem;
    padding: 16px 0 0;
    font-family: var(--dg-font);
}
body.dg-state-home #dg-topbar { display: grid; }
/* Вывеска и бургер — по краям своих боковых колонок (по умолчанию grid растянул бы их на всю
   колонку, и бургер уехал бы от правого края). */
#dg-topbar > #dg-brand { justify-self: start; }
#dg-topbar > .dg-menu-btn { justify-self: end; }
/* На телефоне — как было до центрирования, flex со space-between (owner: "откати про Find the
   Truth на мобильном, слишком близко стало к логотипу"). Там лого крупное и на всю ширину места
   мало: центр страницы приходится почти вплотную к нему, и девиз слипался с вывеской. Ширина
   экрана решает больше, чем формальная симметрия. */
@media (max-width: 767.98px) {
    body.dg-state-home #dg-topbar { display: flex; justify-content: space-between; }
}

/* Бургеров в разметке два — в шапке и рядом с полем: перенести один элемент между строками
   средствами CSS нельзя, а состояния требуют разных мест. Оба открывают одно и то же меню. */
/* Селектор с body — намеренно: .dg-icon-btn ниже в этом же файле задаёт display:inline-flex той
   же специфичностью и выигрывал бы по порядку (замерено: бургер оставался виден и на главной). */
body .dg-menu-btn-hero { display: none; }
body.dg-state-results .dg-menu-btn-hero,
body.dg-state-reader .dg-menu-btn-hero,
body.dg-state-toc .dg-menu-btn-hero { display: inline-flex; }

#dg-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    text-decoration: none;
    color: var(--dg-text);
}
#dg-brand:hover { color: var(--dg-text); }

/* Лого в шапке. Картинка почти белая (см. /assets/img/dgsanhkalogo.png: раскрытая книга серая,
   а лепестки-страницы и раковина — почти #fff), и на светлом фоне верх логотипа пропадал.
   Кружок-подложка эту беду решал, но выглядел наклейкой; вместо него — тонкий абрис ПО КОНТУРУ
   самой картинки: четыре drop-shadow по сторонам света дают ровную обводку в 1px (у filter нет
   своего «обводящего» примитива, это обычный приём для png с прозрачностью).
   В тёмной теме логотип и так виден на тёмном фоне — обводка там только пачкала бы края. */
.dg-brand-logo {
    width: 34px;
    height: 34px;
    flex: none;
    object-fit: contain;
    display: block;
    filter:
        drop-shadow(1px 0 0 rgba(4, 1, 19, 0.45))
        drop-shadow(-1px 0 0 rgba(4, 1, 19, 0.45))
        drop-shadow(0 1px 0 rgba(4, 1, 19, 0.45))
        drop-shadow(0 -1px 0 rgba(4, 1, 19, 0.45));
}
body.dark .dg-brand-logo { filter: none; }

/* Главный логотип на главной странице — на 10% крупнее базового 34px (34*1.1≈37, владелец:
   "мелко"). #dg-brand — единственный полный лого+название лок-ап, показывается только на
   главной (в выдаче/чтении остаётся только ракушка внутри поля, другая картинка) — точечный
   override, не трогает базовый размер, которым пользуются другие места (боковое меню ниже). */
/* Owner: "ещё крупнее на 30%" — 37px × 1.3 ≈ 48px. Owner: "покрупнее на 50%" — 48px × 1.5 = 72px. */
#dg-brand .dg-brand-logo { width: 72px; height: 72px; }
/* Owner: "на мобильной вёрстке только лого ещё крупнее, размером как на проде" — matches the
   legacy PHP site's actual header logo (measured live, dhamma.gift/read.php: rendered
   width:100px, height auto ≈58px — same source image, its own natural ratio 688:399, not
   letterboxed into a square like the 72×72 box above). */
@media (max-width: 767px) {
    #dg-brand .dg-brand-logo { width: 100px; height: 58px; }
    /* Owner: "на мобильном вообще не должно быть надписи Dhamma gift только крупное лого" —
       drop the wordmark text entirely on mobile, logo alone carries the brand there. */
    #dg-brand .dg-brand-name { display: none; }
}

/* Маленькая копия лого в шапке бокового меню — там та же история со светлыми лепестками. */
.dg-drawer-head .dg-brand-logo { width: 26px; height: 26px; }

.dg-brand-name {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--dg-text);
}
/* Owner: "Dhamma.Gift с больших букв". text-transform вместо переписывания текста: "." рвёт
   слово для capitalize так же, как пробел ("dhamma.gift" -> "Dhamma.Gift"), поэтому одно правило
   вместо второй захардкоженной строки.
   БЕЗ медиазапроса (было `min-width: 768px`, owner: "на планшетах тоже с большой, а то разнобой"):
   надпись в принципе показывается только там, где ей место (на главной ниже 768px её прячет
   правило выше, остаётся одно лого), так что ограничивать ЕЩЁ и регистр было незачем — ровно это
   и давало строчные буквы у той же надписи в шапке бокового меню, где она видна на любой ширине,
   включая узкие планшеты и телефоны. */
.dg-brand-name { text-transform: capitalize; }

/* Кнопка-иконка шапки (бургер, крестик в меню) — без рамки и заливки. */
.dg-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex: none;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--dg-text-2);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.dg-icon-btn:hover,
.dg-icon-btn:focus-visible { background: var(--dg-surface-hover); color: var(--dg-text); }

/* Ряд с полем: само поле тянется, бургер стоит рядом и не сжимается. Ширину на главной держит
   .dg-hero-inner, поэтому своего max-width здесь больше нет. */
body.dg-skin-minimal .hero-row {
    max-width: 700px;
    margin-left: auto;
    margin-right: auto;
    flex-wrap: nowrap;
}
body.dg-state-home .hero-row { max-width: none; margin-bottom: 0 !important; }
body.dg-skin-minimal #form.dg-hero-form { flex: 1 1 auto; min-width: 0; }

/* ============================================================================
   Поле ввода: знак сайта + поле + очистить + быстрые настройки + лупа, всё в одной рамке
   ============================================================================ */
.dg-input-shell {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 6px 8px 6px 10px;
    background: var(--dg-surface);
    border: 1px solid var(--dg-border);
    border-radius: 28px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.dg-input-shell:hover { border-color: var(--dg-border-strong); }
.dg-input-shell:focus-within {
    background: var(--dg-surface);
    border-color: var(--dg-border-strong);
    box-shadow: 0 0 0 3px var(--dg-accent-bg);
}
/* В выдаче/чтении --dg-surface (фон поля) и --dg-border (рамка) почти совпадают с фоном
   страницы (--dg-page) — поле и кнопки в нём читались как "почти невидимые" что в светлой,
   что в тёмной теме (владелец, со скриншотом). На главной то же поле — светлая карточка
   поверх ТЁМНОЙ полосы (правило выше, .dg-state-home), там контраст и так есть, не трогаем.
   Цвета — не новые: те же, что уже у #paliauto/#language-button/#scrollToTopBtn на проде и в
   reader-template.html (reader/css/index.css: --off-white/--dark-gray/--dark-blue) — владелец
   явно попросил взять оттуда. */
/* Заодно — владелец: поле "стало слишком большим" (50px высотой, замерено) рядом с рядом
   компактных 19px-иконок ниже (#results-toolbar/#reader-toolbar) — непропорционально. Паддинг
   потоньше, сами кнопки (32-34px) не трогаем — они те же, что и в остальной шапке. */
body.dg-state-results .dg-input-shell,
body.dg-state-reader .dg-input-shell,
body.dg-state-toc .dg-input-shell {
    padding: 4px 6px 4px 8px;
    background: rgb(221, 221, 221);
    border-color: #5a5a5a;
}
body.dg-state-results .dg-input-shell .dg-shell-btn,
body.dg-state-reader .dg-input-shell .dg-shell-btn,
body.dg-state-toc .dg-input-shell .dg-shell-btn {
    color: #5a5a5a;
}
body.dg-state-results #form #paliauto.searchinput,
body.dg-state-reader #form #paliauto.searchinput,
body.dg-state-toc #form #paliauto.searchinput {
    color: #2b2b2b;
}
body.dg-state-results #form #paliauto.searchinput::placeholder,
body.dg-state-reader #form #paliauto.searchinput::placeholder,
body.dg-state-toc #form #paliauto.searchinput::placeholder {
    color: #5a5a5a;
}
body.dark.dg-state-results .dg-input-shell,
body.dark.dg-state-reader .dg-input-shell,
body.dark.dg-state-toc .dg-input-shell {
    background: #42426a;
    border-color: #42426a;
}
body.dark.dg-state-results .dg-input-shell .dg-shell-btn,
body.dark.dg-state-reader .dg-input-shell .dg-shell-btn,
body.dark.dg-state-toc .dg-input-shell .dg-shell-btn {
    color: rgb(221, 221, 221);
}
body.dark.dg-state-results #form #paliauto.searchinput,
body.dark.dg-state-reader #form #paliauto.searchinput,
body.dark.dg-state-toc #form #paliauto.searchinput {
    color: rgb(221, 221, 221);
}
/* apple-design audit: .dg-input-shell:focus-within's ring uses --dg-accent-bg (#12241f in
   dark) — nearly invisible against both the dark page and this pill's own #42426a fill
   (confirmed live: box-shadow computed but not perceptible). Brighter ring for these
   dark-theme states specifically. */
body.dark.dg-state-results .dg-input-shell:focus-within,
body.dark.dg-state-reader .dg-input-shell:focus-within,
body.dark.dg-state-toc .dg-input-shell:focus-within {
    box-shadow: 0 0 0 3px rgba(122, 122, 249, 0.6);
}

/* На полосе поле — светлая карточка, лежащая ПОВЕРХ тёмного фона: не пилюля, а прямоугольник со
   скруглением 10px и заметной тенью (так в макете). Тень обязательна: без неё карточка сливается
   с нижним, уже позеленевшим краем градиента. */
/* Скругление — то же, что у поля в выдаче и в чтении (28px у .dg-input-shell выше): прямоугольник
   с радиусом 10 из макета рядом с остальным сайтом смотрелся чужим. На главной поле только крупнее
   и с тенью — оно лежит поверх тёмной полосы и должно от неё отделяться. */
body.dg-state-home .dg-input-shell {
    padding: 11px 11px 11px 16px;
    border-color: transparent;
    box-shadow: 0 6px 18px rgba(15, 20, 15, 0.18);
}
body.dg-state-home .dg-input-shell:focus-within {
    border-color: transparent;
    box-shadow: 0 6px 18px rgba(15, 20, 15, 0.22), 0 0 0 3px rgba(255, 255, 255, 0.28);
}

/* Порядок справа: сперва быстрые настройки, потом лупа. Лупа — последняя кнопка строки, у самого
   края: это действие «искать», и оно завершает ввод. Разделитель между «очистить» и парой кнопок
   на главной не нужен — там и так просторно. */
body.dg-state-home .dg-shell-sep { display: none; }

/* Ракушка внутри поля — только в выдаче и в чтении: на главной знак и название уже стоят
   в шапке. Она же кнопка «домой». */
body .dg-shell-logo { display: none; flex: none; line-height: 0; text-decoration: none; }
body.dg-state-results .dg-shell-logo,
body.dg-state-reader .dg-shell-logo,
body.dg-state-toc .dg-shell-logo { display: inline-flex; }
.dg-shell-logo img { width: 26px; height: 26px; object-fit: contain; display: block; }
/* Разделитель перед блоком кнопок справа — как в строке поиска у поисковиков. */
.dg-shell-sep {
    width: 1px;
    height: 22px;
    flex: none;
    margin: 0 2px;
    background: var(--dg-border);
}

/* Спиннер ожидания живёт ВНУТРИ кнопки-лупы и подменяет саму иконку. Отдельным элементом в
   строке он раздвигал соседей, и на каждый запрос кнопки успевали дёрнуться туда и обратно
   (шестерёнка-лупа → спиннер-шестерёнка → шестерёнка-лупа). Теперь меняется только картинка
   внутри кнопки, геометрия строки неподвижна. */
.dg-shell-spinner {
    display: none;
    width: 17px;
    height: 17px;
    /* Owner: still invisible on the home page — border was a hardcoded teal (--dg-accent)
       sitting on the search button's own dark navy fill (body.dg-state-home .dg-shell-go,
       color:#fff), near-zero contrast between two dark/teal tones. Real Bootstrap
       .spinner-border uses `currentColor`, not a fixed color, precisely so it always matches
       whatever text/icon color its button already has — white on the home button, muted
       grey on results/reader, near-white in dark theme (all already set via .dg-shell-btn's
       own `color`, see above) — no per-state override needed here at all. */
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: dg-spin 0.7s linear infinite;
}
body.dg-busy .dg-shell-spinner { display: block; }
body.dg-busy #searchbtn .dg-search-icon { display: none; }
@keyframes dg-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .dg-shell-spinner { animation-duration: 2s; }
}

/* Тот же спиннер, но НЕ внутри поля — на случай, когда сама шапка (и вместе с ней
   .dg-shell-spinner) уехала за экран автоскрытием (autoHideHeader). Показывается только когда
   ОБА условия разом: идёт запрос И шапка спрятана — когда шапка видна, свой спиннер в поле уже
   всё показывает, дублировать незачем. z-index выше стека шапки (850/849), чтобы не потеряться
   под подложкой (#dg-header-backdrop), но ниже дровера. */
#dg-busy-indicator {
    display: none;
    position: fixed;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 900;
}
body.dg-busy.dg-header-hidden #dg-busy-indicator { display: block; }
#dg-busy-indicator .spinner-border {
    width: 22px;
    height: 22px;
    border-width: 3px;
    border-color: var(--dg-accent);
    border-right-color: transparent;
    border-radius: 50%;
    border-style: solid;
    animation: dg-spin 0.7s linear infinite;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
@media (prefers-reduced-motion: reduce) {
    #dg-busy-indicator .spinner-border { animation-duration: 2s; }
}

/* Инпут внутри оболочки — без своей рамки, фона и «пилюли»: рамка теперь у оболочки.
   Специфичность (0,2,1) намеренная: reader/css/uiextra.css задаёт `#form.ui-widget #paliauto,
   #paliauto { padding-left:10px !important }` (ДВА id), и она подключается лениво, ПОСЛЕ этого
   файла — обычным правилом её не перебить (см. docs/SPA_HANDOVER.md §4). */
body #form #paliauto.searchinput,
body #form #paliauto.form-control {
    flex: 1 1 auto;
    min-width: 0;
    height: auto;
    padding: 6px 4px !important;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    color: var(--dg-text);
    font-family: var(--dg-font);
    font-size: 1rem;
    outline: none;
}
body.dg-state-home #form #paliauto.searchinput { font-size: 1.12rem; }
body #form #paliauto.searchinput::placeholder { color: var(--dg-text-muted); }
/* Родной крестик type="search" (только webkit) — вместо него своя кнопка #dg-clear-btn: родной
   не поддаётся оформлению и вставал бы вплотную к нашим кнопкам. */
body #form #paliauto.searchinput::-webkit-search-cancel-button { display: none; }

/* Лупа-сабмит. Раньше лежала ПОВЕРХ поля (position:absolute + z-index:12 из-за
   .searchinput{z-index:9}) — теперь это обычный элемент flex-строки, накладок больше нет. */
.dg-input-shell .dg-shell-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex: none;
    padding: 0;
    border: 0;
    /* Круглые, а не скруглённые квадраты. Заливки у них нет, пока на кнопку не навели, — но при
       наведении подсветка вылезала прямоугольником посреди круглого поля с круглыми соседями. */
    border-radius: 50%;
    background: transparent;
    color: var(--dg-text-muted);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.dg-input-shell .dg-shell-btn:hover,
.dg-input-shell .dg-shell-btn:focus-visible { background: var(--dg-surface-hover); color: var(--dg-text); }

/* Слайдеры (fa-sliders) — быстрые настройки. Раньше была шестерёнка с молнией-прорезью, но с
   гером (полные настройки) и словарной шестерёнкой в компасе получалось три шестерёнки подряд —
   путали, какая для чего (просьба владельца). Иконку сменили в home.js (quickButtonHtml), сам
   диск-молния (.dg-qs-bolt) был частью именно гексагонной композиции гера и с ней вместе убран.
   Кнопка круглая, а не скруглённый квадрат: в поле ввода круглое уже всё остальное — и само
   поле, и «очистить», и лупа, — и один квадрат посреди них выбивался. */
.dg-qs-btn {
    /* Прозрачно, пока не навели — как остальные кнопки поля (.dg-shell-btn), не отдельный кружок
       на виду всегда: слайдеры второстепенное действие, не должны тянуть взгляд. */
    --dg-qs-bg: transparent;
    --dg-qs-fg: var(--dg-text-2);
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex: none;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--dg-qs-bg);
    color: var(--dg-qs-fg);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.dg-qs-btn:hover,
.dg-qs-btn:focus-visible { --dg-qs-bg: var(--dg-border); --dg-qs-fg: var(--dg-text); }
/* Повёрнута на 90° и увеличена — владелец: горизонтальные слайдеры (fa-sliders) на маленьком
   размере читались почти как бургер (тоже три горизонтальные линии), путали. Вертикальные
   слайдеры — стандартная альтернативная ориентация той же иконки, однозначно другой силуэт.
   Центровка — сама .dg-qs-btn уже flex/center (см. выше), rotate() крутит вокруг центра иконки
   по умолчанию, так что положение не съезжает. */
/* 26px оказался БОЛЬШЕ бургера — перебор. Владелец задал точный ориентир: не крупнее лупы
   (#searchbtn .dg-search-icon, index.html — 17×17, тот же ряд той же формы поля). 17px, без
   попытки сравнять зрительный вес на глаз ещё раз — на этот раз просто взял чужой размер
   буквально. */
.dg-qs-btn .dg-qs-gear { width: 17px; height: 17px; display: block; transform: rotate(90deg); }

/* Тёмный кружок — на лупе (главное, кликабельное действие поля), не на шестерёнке (второстепенная
   настройка). Раньше было наоборот, и тёмное пятно тянуло взгляд/палец не туда — шестерёнку
   хотелось нажать, а не лупу (жалоба владельца). Шестерёнка теперь просто шестерёнка — тот же
   приглушённый стиль, что у остальных кнопок поля (.dg-shell-btn: прозрачно, подсветка только
   по наведению).
   transition:none по той же причине, что и у полосы: цвет здесь меняет СОСТОЯНИЕ страницы, а не
   наведение, и не должен зависеть от того, рисует ли вкладка кадры. */
body.dg-state-home .dg-shell-go,
body:not(.dg-state-home) .dg-shell-go { transition: none; }
body.dg-state-home .dg-shell-go {
    background: var(--dg-navy);
    color: #fff;
    width: 34px;
    height: 34px;
}
body.dg-state-home .dg-shell-go:hover,
body.dg-state-home .dg-shell-go:focus-visible { background: var(--dg-navy-2); color: #fff; }
body.dg-state-home .dg-shell-go .dg-search-icon { width: 19px; height: 19px; }

/* Ожидание ответа поиска: пока крутится спиннер, выдачи (даже пустой) быть не должно — ради
   этого весь класс и заведён. Домашние блоки при этом НЕ прячем: смысл в том, чтобы человек
   остался на главной, а не смотрел в пустоту. */
body.dg-busy #results-toolbar,
body.dg-busy #results-divider,
body.dg-busy #search-pane,
body.dg-busy #reader-pane {
    display: none;
}
body.dg-busy #variants-hint { display: none !important; }

#dg-loading {
    display: flex;
    justify-content: center;
    padding: 2.5rem 0;
}
#dg-loading[hidden] { display: none; }
/* .spinner-border есть и в Bootstrap (подключён здесь), и в reader/css/rus-multi.css — размеры
   и цвет задаём сами, чтобы вид не зависел от того, догружен ли уже ридер. */
#dg-loading .spinner-border {
    width: 1.75rem;
    height: 1.75rem;
    border-width: 0.2em;
    color: var(--dg-text-muted);
}

/* Всё, что относится к выдаче, на главной не нужно: пустая таблица с шапкой колонок, ряд кнопок
   выдачи, подсказка о вариантах, плавающие кнопки языка и "наверх". Модалки (#settings,
   #SearchResultHelp) НЕ трогаем — у них свой display, которым управляет Bootstrap. */
body.dg-state-home #results-toolbar,
body.dg-state-home #results-divider,
body.dg-state-home #search-pane,
body.dg-state-home #reader-pane,
body.dg-state-home #language-button,
body.dg-state-home #scrollToTopBtn {
    display: none;
}
/* ============================================================================
   Совместимость с таблицами стилей ридера
   Они подключаются в рантайме (при первом открытии текста), то есть ПОСЛЕ всех остальных, и
   выигрывают по порядку. Здесь — точечные ответы на конкретные конфликты.
   ============================================================================ */

/* Ответ на `#form.ui-widget #paliauto, #paliauto { padding-left:10px !important }` из
   reader/css/uiextra.css — выше, вместе с остальными правилами инпута (.dg-input-shell). */

/* И index.css, и rus-multi.css задают глобальное `body { margin:1rem 3rem; background-color;
   font-family:"Robto Serif" }`. Пока ридер был отдельной страницей, это никого не задевало;
   теперь, один раз открыв текст, выдача до конца сессии съезжала на 3rem и меняла шрифт.
   Возвращаем ей своё оформление везде, КРОМЕ состояния ридера — там правила ридера как раз
   нужны. Специфичность (0,1,1) против (0,0,1) у голого `body`, поэтому побеждаем и без
   !important. */
body:not(.dg-state-reader):not(.dg-state-toc) {
    margin: 0;
    font-family: var(--bs-body-font-family);
    background-color: var(--dg-page);
}

/* Панель ридера видна только в своём состоянии. В разметке у неё раньше стоял bootstrap-овский
   d-none (display:none !important) — его перебить состоянием было нельзя, поэтому класс снят, а
   видимость целиком здесь. */
#reader-pane { display: none; }
/* Owner: "toc и фильтр переводчиков разлетались в свои стороны... в центре была бы сутта уже
   ридер режим" — сутта "вырастает" из центра, пока TOC/фильтр разлетаются по бокам (см.
   .dg-toc-leaving ниже). Анимация переигрывается только при ПЕРЕХОДЕ в ридер (display:none →
   block снимает и заново вешает CSS-анимацию), а не при переключении между суттами внутри уже
   открытого ридера — dgSetState() рано выходит, если dg-state-reader уже стоял (search/index.html),
   так что #reader-pane всё это время остаётся block и анимация не перезапускается. */
@keyframes dg-reader-enter {
    from { opacity: 0; transform: scale(.96); }
    to { opacity: 1; transform: scale(1); }
}
body.dg-state-reader #reader-pane { display: block; animation: dg-reader-enter .28s var(--dg-ease); }
@media (prefers-reduced-motion: reduce) {
    body.dg-state-reader #reader-pane { animation: none; }
}

/* Панель TOC/навигатора — тот же приём, что #reader-pane выше. Первая, минимальная версия
   разметки: подробная стилизация (тема шапки/тулбара и т.п.) при желании донастраивается позже,
   как и весь остальной визуал ридера когда-то дорабатывался постепенно. */
#toc-pane { display: none; }
body.dg-state-toc #toc-pane { display: block; }
body.dg-state-toc #search-pane,
body.dg-state-toc #results-toolbar,
body.dg-state-toc #results-divider,
body.dg-state-toc #dynamicHeader,
body.dg-state-toc #language-button {
    display: none;
}

/* Layout: tree on the left (this is a Dhamma site, not a translation-comparison site — owner),
   translator filter as a right-hand aside when there's room; on narrow screens the aside moves
   ABOVE the tree instead (order:-1) and stays compact via the per-language <details> "ещё". */
/* Palette: not new — reuses the site's own production-v4 tokens (--dg-surface/--dg-border/
   --dg-text/--dg-accent etc.), already defined on body.dg-skin-minimal above and already
   theme-aware (body.dark redefines them) since they drive the home screen and reader toolbar.
   The old version of this block used bare Bootstrap vars (--bs-border-color etc.), which this
   site's dark theme never touches — that's why it looked like an unstyled draft in dark mode. */
#toc-pane { max-width: 1100px; margin: 0 auto; color: var(--dg-text); }
/* Safety net: every link in this pane is the same accent green, full stop (owner: "цвета ссылок
   должны быть тогда уже все зелёные, а не только зелёные какие-то фиолетовые" — repeated after
   the :visited-only fix, because the REAL cause wasn't :visited at all). Once the reader has been
   opened anywhere in this SPA session, reader/css/index.css + rus-multi.css stay loaded and carry
   a bare ".dark a{color:rgb(122,122,249)}" — class+type beats this file's plain ".toc-mark"/
   ".toc-leaf-link" classes (both are single-class selectors), so links quietly turned lilac the
   moment reader CSS entered the page, :visited or not. #toc-pane is an ID selector — it outranks
   any class-based rule regardless of load order, so this one line pins every link in the pane. */
#toc-pane a,
#toc-pane a:visited { color: var(--dg-accent-ink, var(--dg-accent)); }
.toc-layout { display: flex; gap: 2rem; align-items: flex-start; }
.toc-main { flex: 1 1 auto; min-width: 0; }
.toc-aside {
    flex: 0 0 260px;
    position: sticky; top: 1rem;
    border: 1px solid var(--dg-border); border-radius: var(--dg-radius, 10px);
    padding: .75rem .9rem;
    background: var(--dg-surface);
}
/* Owner: "toc и фильтр переводчиков разлетались в свои стороны" — played by toc.js right before
   navigating to a sutta (window.dgNavigateInternal), timed to finish before dg-state-toc→reader
   switches #toc-pane to display:none (which would otherwise cut the animation off mid-flight —
   see .dg-toc-leaving's duration mirrored in toc.js's setTimeout). Skipped when reduced motion is
   requested — toc.js checks prefers-reduced-motion itself and navigates immediately instead of
   adding this class. */
.toc-main, .toc-aside {
    transition: transform .28s var(--dg-ease), opacity .28s ease;
}
.toc-layout.dg-toc-leaving .toc-main { transform: translateX(-40px); opacity: 0; }
.toc-layout.dg-toc-leaving .toc-aside { transform: translateX(40px); opacity: 0; }
.toc-aside-title { font-size: .95rem; margin: 0 0 .5rem; color: var(--dg-text-2); }
/* Same button-reset + "+/-" affordance as the category expand-all toggle — collapsible on
   phones so arriving at /toc lands on the Pali contents, not this panel (owner: "на мобильном
   когда пришёл в оглавление, он пришёл в оглавление пали, а не в список переводчиков"). */
.toc-aside-toggle {
    display: flex; align-items: center; gap: .4rem;
    width: 100%; background: none; border: none; padding: 0; cursor: pointer;
    text-align: left; font: inherit;
}
.toc-aside-toggle .toc-toggle { flex: none; }
.toc-filter-reset { font-size: .8rem; margin-bottom: .6rem; }
.toc-filter-reset a,
.toc-filter-reset a:visited { color: var(--dg-accent-ink, var(--dg-accent)); }
/* Stack to one column only on phones — tablets have plenty of room for the two-column layout
   too (owner: "на планшетах же много места... в одну колонку только на мобильных"). 640px keeps
   portrait tablets (iPad-class, ≥768px) two-column; only narrower phone widths collapse. */
@media (max-width: 640px) {
    .toc-layout { flex-direction: column; }
    .toc-aside { order: -1; flex-basis: auto; width: 100%; position: static; }
}

.toc-category { margin-bottom: 1.75rem; }
.toc-category-header { display: flex; align-items: center; gap: .75rem; margin-bottom: .35rem; }
.toc-category-header h3 { margin: 0; font-size: 1.15rem; color: var(--dg-text); }
/* Chunky square toggle — prod's own look for its one top-level collapse-all control
   (read.php #collapseAll: filled accent square, bold "+"). */
.toc-expand-all-btn {
    width: 1.9rem; height: 1.9rem; flex: none;
    border: none; border-radius: 6px; background: var(--dg-accent); color: #fff;
    font-size: 1.2rem; font-weight: 700; line-height: 1; cursor: pointer;
}
.toc-expand-all-btn:hover { background: var(--dg-accent-dark, var(--dg-accent-ink, var(--dg-accent))); }
.toc-books { display: flex; flex-direction: column; }
.toc-book { border-top: 1px solid var(--dg-border); padding: .5rem 0; }
.toc-book:first-child { border-top: none; }
.toc-book-header,
.toc-book-header:visited {
    display: block; width: 100%; text-align: left;
    background: none; border: none; padding: .3rem .1rem; cursor: pointer;
    color: var(--dg-accent-ink, var(--dg-accent)); font-size: 1.3rem; font-weight: 700;
    text-decoration: underline; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
}
.toc-book-header:hover { text-decoration-color: currentColor; }
/* The "(N)" count (and, for Khuddaka, the "*" partial-collection mark) is its own muted span, not
   part of the bold name — it's metadata about the row, not the title itself (owner: "отдели
   счётчик от названия чтобы он был серым... это к имени не относится"). */
.toc-count {
    color: var(--dg-text-muted); font-weight: 400; font-size: 1rem;
    text-decoration: none;
}
.toc-count-star { cursor: help; }
.toc-book-body { padding: .25rem 0 .5rem .7rem; }
.toc-empty { padding: .35rem 0; color: var(--dg-text-muted); font-size: .9rem; }

/* Explicit hierarchy: "Переводчики" (aside title, h4) → language name (level 2 — bigger, bold,
   its own underline) → each translator (level 3 — small checkbox row). Owner: "у тебя всё
   одинакового размера... это же для того, чтобы было удобно понимать, это первый уровень, это
   там опция, это второй уровень" — same size everywhere read as one flat blob. */
.toc-filter-search {
    width: 100%; box-sizing: border-box; margin-bottom: .85rem;
    padding: .4rem .55rem; font-size: .85rem;
    background: var(--dg-page); color: var(--dg-text);
    border: 1px solid var(--dg-border-strong); border-radius: 6px;
}
.toc-filter-group { margin-bottom: 1.1rem; padding-top: .6rem; border-top: 1px solid var(--dg-border); }
.toc-filter-group:first-child { padding-top: 0; border-top: none; }
/* Named ...-hdr/-title, deliberately NOT ...-lang-row/...-lang: reader/css/uiextra.css has its own
   "[class*='-lang']{display:block}" (targets .pli-lang/.eng-lang/etc.) — any class of ours that
   happens to contain that substring gets silently forced to display:block too (same specificity,
   uiextra.css loads later so it wins), which is exactly what broke the checkbox+language-name row
   here (owner: screenshot showed the checkbox stacked above "English" — that CSS rule, not the
   active-word JS bug from before, which was a separate collision on the same "-lang" substring). */
.toc-filter-hdr { display: flex; align-items: center; gap: .5rem; margin-bottom: .4rem; }
.toc-filter-title { font-weight: 700; font-size: 1rem; color: var(--dg-text); }
.toc-filter-item { display: flex; align-items: baseline; gap: .5rem; font-size: .85rem; padding: .2rem 0; color: var(--dg-text-2); }
/* Real, visible checkboxes — not text-sized-to-invisibility (owner: "это же не просто какие-то
   ссылки, это должны быть чекбоксы... непонятно как это работает"). They were rendering
   display:none: extrastyles.css has a global "label input[type=checkbox]{display:none}" (its own
   custom-checkbox hack elsewhere on the site) that swallows every checkbox nested in a <label> —
   same issue already solved once for .dg-scope/.dg-check below; same fix here, a selector with
   enough classes to outrank it. accent-color tints the checked state green in both themes. */
.toc-filter-item input.toc-filter-checkbox {
    display: inline-block;
    width: 16px; height: 16px; flex: none; margin: 0; cursor: pointer;
    accent-color: var(--dg-accent);
    border: 1px solid var(--dg-border-strong); border-radius: 3px;
}
/* The language master checkbox lives in a plain div, not a <label> — extrastyles.css's
   display:none hack only targets checkboxes inside a <label>, so this one just needs sizing. */
.toc-filter-master {
    width: 16px; height: 16px; flex: none; margin: 0; cursor: pointer;
    accent-color: var(--dg-accent);
    border: 1px solid var(--dg-border-strong); border-radius: 3px;
}
.toc-filter-more { margin-top: .3rem; }
.toc-filter-more summary { font-size: .8rem; cursor: pointer; color: var(--dg-accent-ink, var(--dg-accent)); list-style: none; }
.toc-filter-more summary::-webkit-details-marker { display: none; }

/* Small per-level step, not 1.4rem — SN nests up to 5 deep (group>samyutta>paññāsaka>vagga>leaf
   list), and since this stacks cumulatively at every level, 1.4rem there pushed the leaf/
   translator list ~7rem off the left edge, squeezing it into the middle of the page (owner:
   "слишком большие отступы... список сутт оказывается в центре экрана"). */
.toc-tree, .toc-children { list-style: none; margin: 0; padding-left: .35rem; }
/* Second nesting level and deeper step in at HALF the first level's indent, not another full
   step each time — cumulative width still adds up on a narrow phone once you're 4-5 levels deep
   (owner: repeated "отступы всё ещё гигантские" even after the first halving — halved again). */
.toc-children .toc-children,
.toc-children .toc-children .toc-children,
.toc-children .toc-children .toc-children .toc-children { padding-left: .18rem; }
/* Only the OUTERMOST list (straight under .toc-book-body, never anyone's "children" container)
   starts flush — every nested level below it (buildTreeChildren always stamps .toc-tree on the
   node it returns, then renderBranch ALSO adds .toc-children onto that SAME element for anything
   nested) needs to keep its indent. A bare ".toc-tree{padding-left:0}" matched every level alike
   and cancelled the indent everywhere, not just at the root (owner: "они должны отличаться
   отступами тоже" — depth should read in the indent, not only font size/weight). */
.toc-book-body > .toc-tree { padding-left: 0; }
/* Vagga/chapter heading — prod shows this as a plain bold static subheading, not another
   collapsible row; kept collapsible here (large books like SN/AN genuinely need it lazy), but
   styled like a heading, not a list item, to match. */
.toc-branch-header { display: flex; align-items: baseline; gap: .4rem; cursor: pointer; padding: .5rem 0 .3rem; }
.toc-branch-title { color: var(--dg-text-2); font-weight: 700; font-size: 1.05rem; }
/* Depth reads two ways at once: size/weight taper (unchanged) plus a black/green color
   alternation, one step smaller AND a swapped color per level, so hierarchy is visible at a
   glance instead of every branch looking the same (owner: "уровни у тебя не отличаются", then
   "саньютты зелёный поменять... вагги чёрным оставить" — vagga black, samyutta green, and the
   same alternation continues for any book with more levels, not just SN). */
.toc-children .toc-branch-title { color: var(--dg-accent-ink, var(--dg-accent)); font-weight: 600; font-size: .95rem; }
.toc-children .toc-children .toc-branch-title { color: var(--dg-text-2); font-weight: 500; font-size: .88rem; }
.toc-children .toc-children .toc-children .toc-branch-title { color: var(--dg-accent-ink, var(--dg-accent)); font-weight: 400; font-size: .84rem; }
.toc-toggle {
    background: none; border: none; cursor: pointer; padding: 0;
    width: 1.3em; height: 1.3em; line-height: 1.3em; text-align: center;
    font-weight: 700; color: var(--dg-text-muted); flex: none;
}
/* padding-left was a flat 1.75rem (28px) on EVERY leaf row regardless of depth — on top of the
   UL nesting indent above, that alone was nearly half the total indent a leaf sat at, and it
   didn't scale down the way the rest of the tree just got tuned to (owner: "отступы всё ещё
   гигантские"). The UL nesting already carries the depth signal; the leaf only needs a small
   step of its own. */
.toc-leaf { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; padding: .6rem 0 .6rem .5rem; border-bottom: 1px solid var(--dg-border); }
.toc-leaf:last-child { border-bottom: none; }
.toc-leaf-link,
.toc-leaf-link:visited { text-decoration: underline; color: var(--dg-accent-ink, var(--dg-accent)); font-weight: 600; }
/* One language's tag + its own translator marks wrap together as a single unit — without this,
   wrapping split the tag from its marks, landing "EN" wherever the wrap fell, disconnected from
   its own translator list (owner: "переводы... переносится на разные строчки"). */
.toc-src-group { display: inline-flex; align-items: baseline; flex-wrap: wrap; gap: .45rem; }
.toc-src-tag { font-size: .68rem; text-transform: uppercase; color: var(--dg-text-muted); }
/* Phones: a wrapping flex row of id + title + N language groups reads as a jumble at this width —
   stack it instead, one clear line per thing (owner: "посмотри как ужасно выглядят переводы...
   на мобильном"). Tablet/desktop keep the denser inline row, there's room for it. */
@media (max-width: 640px) {
    .toc-leaf { flex-direction: column; align-items: flex-start; gap: .3rem; }
}
/* Translator marks — plain small text, like prod's muted "TB"/"BS" initials, not chip/badge
   boxes: a box reads as tooling chrome, plain text reads as part of the same page. All the same
   accent green as every other link here (owner: "почему одни зеленые одни сиреневые, делай все
   зелёными") — the lilac was the browser's default :visited color leaking through; explicit
   :visited rules on every link class in this pane pin the color regardless of visited state. */
.toc-mark,
.toc-mark:visited {
    font-size: .78rem; color: var(--dg-accent-ink, var(--dg-accent)); text-decoration: none;
}
.toc-mark:hover { text-decoration: underline; }
.toc-mark-primary,
.toc-mark-primary:visited { color: var(--dg-accent-ink, var(--dg-accent)); font-weight: 600; }
.toc-more { display: inline-block; }
.toc-more summary { font-size: .78rem; cursor: pointer; color: var(--dg-text-muted); list-style: none; }
.toc-more summary::-webkit-details-marker { display: none; }
.toc-more .toc-mark { margin-right: .5rem; }
.toc-loading, .toc-error { padding: .5rem 0; color: var(--dg-text-muted); }
.toc-book-link { text-decoration: underline; }

/* Bhikkhu/Bhikkhuni Pātimokkha fragment (reader/{bu,bi}-pm-fragment.html, injected by toc.js's
   renderBookRow) carries legacy styles.css-scale headings/text — that stylesheet isn't loaded
   here (this page uses its own toc-* typography), so left unscoped the fragment renders with
   browser-default h3 sizing (much bigger than everything else in the panel) and, depending on
   ancestor flex context, can end up centered instead of left-aligned like the rest of the toc.
   Scale it down to the same rhythm as a tree branch (.toc-branch-title) and force left/block. */
.toc-patimokkha-body .level1,
.toc-patimokkha-body .level2,
.toc-patimokkha-body .level3,
.toc-patimokkha-body .level4,
.toc-patimokkha-body .level5 { text-align: left; }
/* h3 = section (Pārājikuddeso...), h4 = nested vagga sub-group inside Nissaggiya/Pācittiya/
   Sekhiya (Pādukavaggo...) — one step deeper than a section, so one step smaller, same as
   .toc-children .toc-branch-title vs .toc-branch-title for a normal tree branch. */
.toc-patimokkha-body h3,
.toc-patimokkha-body h4 {
    margin: 0; font-weight: 700; color: var(--dg-text); text-align: left;
}
.toc-patimokkha-body h3 { font-size: 1.05rem; }
.toc-patimokkha-body h4 { font-size: .95rem; }
/* Each section/vagga toggle row (.level2/.level3.d-flex) has no vertical margin of its own in
   extrastyles.css — one after another they sit flush, the "+" squares touching like a caterpillar
   (owner: "они как гусеница слиплись"). Gap between the button and its own heading stays as-is
   (align-items-center row), only space BETWEEN rows is added. */
.toc-patimokkha-body .level2.d-flex,
.toc-patimokkha-body .level3.d-flex { margin-bottom: .5rem; }
.toc-patimokkha-body .pli-lang { font-size: .92rem; line-height: 1.5; }
.toc-patimokkha-body a.setReader { font-size: .85rem; font-weight: 600; }
/* extrastyles.css (legacy) overrides .btn-primary's background-color directly (green, matching
   this site's palette) but never touches Bootstrap's own :hover/:focus/:active states — those
   still come from Bootstrap's --bs-btn-hover-bg variable, precomputed from ITS default blue
   --bs-primary, not from the overridden background-color. Result: the "+"/"−" toggle squares
   here read green at rest and flash bootstrap-blue on hover (owner: "делай тёмно зелёными как в
   стилях"). Fixed with an explicit hover/focus/active shade of the same green instead of editing
   the shared legacy file (see CLAUDE.md symlink policy) — darker in light mode (standard hover
   treatment), lighter in dark mode (dark surfaces read hover as "lighter", not "darker"). */
.toc-patimokkha-body .btn-primary:hover,
.toc-patimokkha-body .btn-primary:focus,
.toc-patimokkha-body .btn-primary:active {
    background-color: #128a72 !important;
    border-color: #159c81 !important;
}
[data-theme="dark"] .toc-patimokkha-body .btn-primary:hover,
[data-theme="dark"] .toc-patimokkha-body .btn-primary:focus,
[data-theme="dark"] .toc-patimokkha-body .btn-primary:active {
    background-color: #036b57 !important;
    border-color: #6b7d79 !important;
}

/* В ридере выдача остаётся в DOM (возврат по "назад" мгновенный), но не показывается. Раньше
   здесь прятались только ОТДЕЛЬНЫЕ кнопки внутри #results-toolbar (разворачивание строк,
   отметки "прочитано", переключатель "Тексты/Слова", заголовок результатов), а сам
   #results-toolbar оставался в потоке — по мысли того времени, часть его кнопок (тема, словарь,
   компас, настройки, помощь) должна была использоваться и при чтении. С тех пор в ридере
   появился свой ПОЛНЫЙ #reader-toolbar с тем же набором функций — оставшийся #results-toolbar не
   удалялся из потока (display не задан ни в одном правиле), стоял пустой полосой ~41px высотой
   ПЕРЕД самим reader-pane и просто отодвигал текст сутты вниз без всякой видимой причины
   (владелец, скриншот: "огромный чёрный отступ"). Заодно теперь и #toggle-mode-results (кнопка
   режима колонок ИМЕННО для выдачи, соседствует в этом же ряду) не дублируется в ридере поверх
   его собственной #toggle-mode. #language-button сюда НЕ входит — он физически вынесен из
   #results-toolbar в разметке (search/index.html) именно потому, что ему нужна ОБРАТНАЯ
   видимость (скрыт в выдаче — там нечего переключать, показан в чтении — см. правило ниже), а
   display:none на родителе полностью скрыл бы потомка независимо от любых его собственных
   правил — быть внутри этого списком он не мог бы в принципе. */
body.dg-state-reader #search-pane,
body.dg-state-reader #results-toolbar,
body.dg-state-reader #results-divider,
body.dg-state-reader #dynamicHeader,
body.dg-state-reader #btn-show-all-children,
body.dg-state-reader #btn-read-marks,
body.dg-state-reader .forshellscript {
    display: none;
}
/* Pāḷi/translation toggle used to be hidden on the results LISTING (comment here used to claim
   it was a "fake button that doesn't work" there) — that was true at the time, but is stale now:
   search-render.js/langswitch.css later wired up .dg-title-lang + .quote so hide-pali/hide-english
   on #sutta DOES affect titles and quotes in the results table too. Owner asked for the button
   back on results, same as in the reader — #dg-state-home still hides it above (no results table
   there at all, nothing to toggle). */
body.dg-state-reader #variants-hint,
body.dg-state-toc #variants-hint { display: none !important; }

/* #variants-hint — отдельно и с !important: скрипт выдачи показывает его ИНЛАЙНОВЫМ
   style="display:block" (см. renderResultHeader в index.html), а инлайн бьёт любой селектор
   таблицы стилей. Без этого подсказка "у слова есть варианты" оставалась висеть на главной
   после возврата из выдачи по кнопке "назад". */
body.dg-state-home #variants-hint { display: none !important; }

@media (prefers-reduced-motion: reduce) {
    #home-motto, #home-hint, #home-pane,
    .hero-row, .dg-hero-form {
        transition: none;
    }
}

/* Первый кадр загрузки: состояние уже проставлено инлайновым скриптом в начале <body>, и без
   этого главная каждый раз "въезжала" бы анимацией. Снимается через два requestAnimationFrame. */
body.dg-no-anim,
body.dg-no-anim * {
    transition: none !important;
    animation: none !important;
}

/* ============================================================================
   Девиз — на месте подписи из макета, прямо над полем
   ============================================================================ */
/* Девиз — обращение к читателю НА полосе, слева над полем, а не крупный заголовок по центру:
   вывеска в этом экране одна, и вторая крупная строка спорила бы с ней. */
#home-motto {
    text-align: left;
    font-family: var(--dg-font);
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.35;
    color: rgba(255, 255, 255, 0.82);
}

/* Owner: "Find the Truth между лого и бургером" — now a flex child of #dg-topbar itself
   (between #dg-brand and the menu button), not its own line below with the old
   collapse-on-state-change spacing (margin/max-height from the shared #home-motto/#home-hint/
   #home-pane block above). #dg-topbar #home-motto (2 IDs) outranks the old
   `body.dg-state-home #home-motto` rule (1 ID) regardless of source order. */
#dg-topbar #home-motto {
    margin: 0;
    max-height: none;
    white-space: nowrap;
    flex: none;
}

/* Подсказка под полем: "искать «…»" / "похоже на ссылку на текст". На полосе — светлая плашка
   поверх тёмного фона; акцентная заливка там нечитаема.
   Owner (round 3): справа, под полем — не в потоке (иначе снова толкала бы плитки вниз), а
   position:absolute от .hero-row (position:relative там же, search/index.html), правым краем
   вровень с полем. Автодополнение (.ui-autocomplete, uiextra.css) висит у ЛЕВОГО края поля и
   не шире 274px — справа под широким полем места достаточно, не пересекаются. */
#home-hint {
    text-align: right;
    position: absolute;
    top: 100%;
    right: 0;
}
#home-hint .dg-hint {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    font-weight: 600;
    color: #fff;
    background: rgba(255, 255, 255, 0.16);
    padding: 5px 10px;
    border-radius: 7px;
}

/* ============================================================================
   Объявление над полем поиска (#dg-announce, см. hero-row в search/index.html)
   ============================================================================ */
/* Вне потока (owner: "без сдвига интерфейса"): лежит в уже существующем пустом отступе над полем
   — body.dg-state-home .hero-row { margin-top: 74px } — поэтому и появление, и закрытие не
   двигают ни поле, ни плитки под ним. Тот же приём, что у #home-hint выше, только сверху.
   Только на главной: в выдаче и в чтении полосы нет, а поле переезжает наверх. */
#dg-announce {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    margin-bottom: 12px;
    display: flex;
    justify-content: center;
    /* Плавное появление (плашку показывает home.js через несколько секунд после загрузки).
       Двигается только она сама — соседи стоят на месте: элемент вне потока. */
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity 0.35s ease, transform 0.35s ease;
}
#dg-announce.dg-announce-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
    #dg-announce { transition: none; transform: none; }
}
body:not(.dg-state-home) #dg-announce { display: none; }
.dg-announce-box {
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: 100%;
    padding: 7px 8px 7px 12px;
    border-radius: 10px;
    /* Светлая плашка поверх тёмной полосы — как у #home-hint: акцентная заливка там нечитаема. */
    background: rgba(255, 255, 255, 0.16);
    color: #fff;
    font-family: var(--dg-font);
    font-size: 0.82rem;
    line-height: 1.3;
}
.dg-announce-box a { color: #fff; text-decoration: underline; }
.dg-announce-close {
    flex: none;
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: inherit;
    opacity: 0.7;
    cursor: pointer;
}
.dg-announce-close:hover, .dg-announce-close:focus-visible { opacity: 1; background: rgba(255, 255, 255, 0.18); }
/* На узком экране отступ над полем тот же, но текст переносится в две строки — прижимаем плашку
   к низу отступа, чтобы она не наезжала на шапку. */
@media (max-width: 767.98px) {
    .dg-announce-box { font-size: 0.78rem; padding: 6px 6px 6px 10px; }
}

/* ============================================================================
   Плитки
   ============================================================================ */
.dg-tiles {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    max-width: 560px;
    margin: 0 auto;
    /* Reserve space for the tiles home.js fills in after its menu-links.json fetch resolves —
       without this the empty grid collapses to 0 height and everything below (footer etc.)
       jumps down once tiles pop in. Sized for the default 8 tiles at 2 cols (4 rows); narrower
       at >=576px below since it switches to 4 cols (2 rows). Approximate on purpose — tile count
       is user-customizable (hidden/custom tiles), an exact height isn't possible anyway. */
    min-height: 460px;
}
.dg-tiles:empty {
    background: linear-gradient(90deg, var(--dg-surface) 25%, var(--dg-surface-hover) 50%, var(--dg-surface) 75%);
    background-size: 200% 100%;
    border-radius: 12px;
    animation: dg-tiles-skeleton 1.4s ease-in-out infinite;
}
@keyframes dg-tiles-skeleton {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
@media (min-width: 576px) {
    .dg-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); max-width: 720px; min-height: 226px; }
}

.dg-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 16px 6px;
    background: var(--dg-surface);
    border: 1px solid var(--dg-border);
    border-radius: 12px;
    font-family: var(--dg-font);
    font-size: 0.92rem;
    line-height: 1.3;
    color: var(--dg-text-2);
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.dg-tile:hover,
.dg-tile:focus-visible {
    background: var(--dg-surface-hover);
    border-color: var(--dg-border-strong);
    color: var(--dg-text);
}
.dg-tile:active { transform: scale(0.985); }

/* Иконка — в кружке из акцентного фона, сама иконка акцентного цвета. Кружок и есть то, что
   делает плитку значком, а не строкой списка в рамке. */
.dg-tile-ic {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    flex: none;
    border-radius: 50%;
    background: var(--dg-accent-bg);
}
.dg-tile svg {
    width: 24px;
    height: 24px;
    display: block;
    color: var(--dg-accent);
}

/* ============================================================================
   Нижняя шторка со ссылками
   position:fixed — она вне схлопывающегося #home-pane и живёт в конце <body>, иначе
   overflow:hidden родителя обрезал бы её.
   ============================================================================ */
#dg-sheet-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(20, 18, 10, 0.4);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease;
    z-index: 1080;
}
#dg-sheet-backdrop.show { opacity: 1; pointer-events: auto; }
/* Под выпадашкой быстрых настроек подложка невидима, но клики по странице всё так же ловит:
   затемнять весь экран ради маленького меню — перебор, а закрывать по клику мимо нужно. */
#dg-sheet-backdrop.dg-transparent { background: transparent; }

.dg-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1081;
    display: flex;
    flex-direction: column;
    max-height: 82vh;
    background: var(--dg-surface);
    color: var(--dg-text);
    font-family: var(--dg-font);
    border-top: 1px solid var(--dg-border-strong);
    border-radius: 16px 16px 0 0;
    transform: translateY(100%);
    transition: transform 0.3s var(--dg-ease);
}
.dg-sheet.show { transform: translateY(0); }
@media (min-width: 768px) {
    .dg-sheet {
        left: 50%;
        right: auto;
        bottom: 20px;
        width: 560px;
        max-height: 74vh;
        border: 1px solid var(--dg-border-strong);
        border-radius: 16px;
        transform: translate(-50%, calc(100% + 20px));
    }
    .dg-sheet.show { transform: translate(-50%, 0); }
}

/* Быстрые настройки — выпадашка ПОД шестерёнкой, на любой ширине. Нижняя шторка выглядела как
   отдельный раздел страницы и уводила взгляд от поля, к которому эти настройки относятся.
   Правило вне медиазапроса намеренно: на узком экране home.js сам сужает выпадашку до ширины
   экрана за вычетом полей (см. placeAnchored). Координаты приходят инлайном. */
.dg-sheet.dg-anchored {
    left: auto;
    right: auto;
    bottom: auto;
    max-height: 70vh;
    border: 1px solid var(--dg-border-strong);
    border-radius: 14px;
    box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.35);
    transform: translateY(-8px);
    opacity: 0;
    transition: transform 0.16s var(--dg-ease), opacity 0.16s ease;
}
.dg-sheet.dg-anchored.show { transform: translateY(0); opacity: 1; }
/* У выпадашки ручки-«потяни вниз» быть не должно: тянуть её некуда. */
.dg-sheet.dg-anchored .dg-sheet-handle { display: none; }

/* Мега-меню (External/AI & Dicts/Materials/Tools/Русские) — тот же анкоренный попап, что у
   быстрых настроек, но .dg-sheet-body раскладывается в колонки вместо вкладок+списка.
   Ширину/позицию считает placeMegaAnchored() (home.js) инлайном.
   position: absolute (не fixed, как у .dg-sheet/.dg-anchored) — координаты, которые считает
   placeMegaAnchored(), уже document-relative (учитывают scrollX/scrollY), так что попап скроллится
   ВМЕСТЕ со страницей, а не остаётся приклеенным к вьюпорту. max-height/overflow — none/visible:
   owner явно просил убрать СВОЙ скролл попапа ("не должно быть скролла... за счёт общего сдвига
   экрана его нужно прокручивать, а не за счёт какого-то своего отдельного скроллбара") — если
   колонки не помещаются в высоту вьюпорта, страница просто скроллится ниже, как у обычного
   мега-меню; scrollForMega() (home.js) заранее подтягивает страницу так, чтобы поле поиска
   оказалось у верха экрана (плюс сжимает зазоры над плитками, body.dg-mega-compact ниже), чтобы
   места обычно хватало без скролла вовсе.
   Открытие — не translateY, как у .dg-anchored выше, а scale от transform-origin, который
   выставляет placeMegaAnchored() инлайном (X — под серединой открывшей кнопки): owner: "анимацию
   как будто мегаменю расширяется/растягивается из соответствующей кнопки". */
.dg-sheet.dg-anchored.dg-mega {
    position: absolute;
    max-height: none;
    transform: scale(0.35);
    transition: transform 0.22s var(--dg-ease), opacity 0.16s ease;
}
.dg-sheet.dg-anchored.dg-mega.show { transform: scale(1); }
.dg-mega .dg-sheet-body {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0 28px;
    align-items: start;
}
/* #dg-mega (id), not .dg-mega (class): .dg-sheet .dg-sheet-body (overflow-y:auto, further down
   this file) has the SAME class-only specificity and comes AFTER this rule in source order, so a
   same-specificity .dg-mega override here would silently lose (same trap as the comment on
   #dg-mega .dg-sheet-row above) — bumped to an id selector to win for real. */
#dg-mega .dg-sheet-body {
    overflow-y: visible;
    max-height: none;
}
/* A later un-headed cluster inside a "blocks" group (owner: "не выделяй suttacentral в
   отдельный" — SC/Vinaya/Voice/Legacy etc. share the Collections header, split from the block
   above them by a quiet rule only, never a made-up sub-title). */
.dg-mega-block-divider { margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--dg-border); }
.dg-mega-col { min-width: 0; }
/* Owner: "скролл не нужен был по максимуму" — Patimokkha+Prātimokṣa (10 пунктов с описаниями,
   владелец явно просил их держать в одной колонке) остаются самой высокой колонкой независимо
   от числа колонок в сетке; единственный оставшийся рычаг — плотность самой строки. Сужаем
   только внутри мега-меню (.dg-sheet-row/.dg-group-title — общие классы с нижней шторкой, её
   не трогаем). :first-child здесь переопределяет общее .dg-group-title:first-child (метит
   первый заголовок ВСЕЙ шторки) — в колонках первый заголовок должен быть без верхнего отступа
   у КАЖДОЙ колонки, а не только у первой. */
/* #dg-mega (id), not .dg-mega (class): the generic .dg-sheet-row/.dg-row-desc/.dg-group-title
   rules a bit further down this file have the SAME class-only specificity and come AFTER these
   in source order, so a same-specificity .dg-mega override here was silently losing the
   cascade (measured live: padding stayed 11px, not 7px) — the id bumps specificity past that,
   no reordering needed. */
#dg-mega .dg-sheet-row { padding: 7px 0; }
/* Owner: "описание идёт отдельной строчкой снизу... всё удлиняется чуть ли не в два раза" —
   desc back to inline (its default as a <small>, before the generic .dg-sheet rule below forces
   it to its own line) with a quiet separator, same row, no line break — label stays bright
   (inherits the row's normal text color), desc stays dim (--dg-text-2 further down). Cuts most
   rows back to one line, which also does more for "скролл не нужен был по максимуму" than the
   padding trim above ever could. */
#dg-mega .dg-row-desc {
    display: inline;
    margin-top: 0;
}
#dg-mega .dg-row-desc::before { content: " \00b7 "; color: var(--dg-text-muted); }
#dg-mega .dg-group-title { margin: 1.4em 0 0.6em; }
.dg-mega-col .dg-group-title:first-child { margin-top: 0; }

@media (prefers-reduced-motion: reduce) {
    .dg-sheet, #dg-sheet-backdrop { transition: none; }
}

.dg-sheet .dg-sheet-handle {
    width: 34px;
    height: 3.5px;
    border-radius: 3px;
    background: var(--dg-border-strong);
    margin: 9px auto 2px;
    flex: none;
}
@media (min-width: 768px) { .dg-sheet .dg-sheet-handle { display: none; } }

.dg-sheet .dg-sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 8px 18px 4px;
    flex: none;
}
.dg-sheet .dg-sheet-head h2 {
    font-size: 0.95rem;
    font-weight: 700;
    margin: 0;
    color: var(--dg-text);
}
.dg-sheet .dg-sheet-close {
    border: none;
    background: transparent;
    color: var(--dg-text-2);
    font-size: 1.3rem;
    line-height: 1;
    padding: 0.2rem 0.4rem;
    cursor: pointer;
}

.dg-sheet .dg-sheet-tabs {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    padding: 6px 18px 10px;
    border-bottom: 1px solid var(--dg-border);
    flex: none;
}
.dg-sheet .dg-sheet-tabs button {
    flex: none;
    font-size: 0.74rem;
    font-weight: 600;
    padding: 6px 11px;
    border-radius: 7px;
    border: 1px solid var(--dg-border);
    color: var(--dg-text-2);
    background: var(--dg-surface);
    cursor: pointer;
}
.dg-sheet .dg-sheet-tabs button.on {
    background: var(--dg-accent-bg);
    border-color: var(--dg-accent);
    color: var(--dg-accent);
}

.dg-sheet .dg-sheet-body {
    overflow-y: auto;
    padding: 4px 18px 22px;
    flex: 1 1 auto;
}
/* Заголовок набора отбит пустой строкой сверху и снизу — до правки он прилипал к предыдущему
   пункту и читался как его продолжение, а не как начало нового набора. */
.dg-sheet .dg-group-title {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--dg-text-muted);
    margin: 2em 0 1em;
}
.dg-sheet .dg-group-title:first-child { margin-top: 0.8em; }
.dg-sheet .dg-sheet-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 0;
    font-size: 0.95rem;
    color: var(--dg-text);
    text-decoration: none;
    border-bottom: 1px solid var(--dg-border);
    cursor: pointer;
}
.dg-sheet .dg-sheet-row:last-child { border-bottom: none; }
.dg-sheet .dg-sheet-row:hover { color: var(--dg-accent-ink); }
.dg-sheet .dg-sheet-row .dg-row-icon {
    width: 17px;
    height: 17px;
    flex: none;
    color: var(--dg-text-muted);
}
.dg-sheet .dg-sheet-row .dg-row-label { flex: 1; min-width: 0; }
.dg-sheet .dg-sheet-empty {
    font-size: 0.82rem;
    color: var(--dg-text-muted);
    padding: 14px 0;
}

/* Пояснение под названием ссылки — «что это вообще такое». Проставлено пока не всем пунктам, а
   первым в каждом наборе (поле desc в menu-links.json): по ним и видно, чем набор занимается. */
.dg-sheet .dg-sheet-row { align-items: flex-start; }
.dg-sheet .dg-sheet-row .dg-row-icon { margin-top: 2px; }
/* Пояснение — второй по важности текст строки, а не сноска: мелким его просто не читали.
   Цвет тоже подняли до --dg-text-2: muted на светлом фоне давал слишком блёклую строку. */
.dg-sheet .dg-row-desc {
    display: block;
    margin-top: 3px;
    font-size: 0.84rem;
    line-height: 1.45;
    color: var(--dg-text-2);
}

/* Вкладка-ссылка в шапке шторки: те плитки, у которых нет своего списка (Читать Pāḷi, История).
   Это НЕ переключение набора, а прямое действие — помечаем стрелкой и не даём состояние "on". */
.dg-sheet .dg-sheet-tabs button.dg-tab-link::after {
    content: " ↗";
    font-size: 0.68rem;
    opacity: 0.7;
}

/* ============================================================================
   Быстрые настройки (шестерёнка-молния). Отдельная шторка: наполнение зависит от состояния
   страницы, поэтому она перерисовывается при каждом открытии.
   ============================================================================ */
.dg-sheet .dg-qs-note {
    margin: 6px 0 0;
    font-size: 0.72rem;
    line-height: 1.4;
    color: var(--dg-text-muted);
}
.dg-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    padding: 9px 0;
    border: 0;
    border-bottom: 1px solid var(--dg-border);
    background: transparent;
    color: var(--dg-text);
    font-family: var(--dg-font);
    font-size: 0.85rem;
    text-align: left;
    cursor: pointer;
}
.dg-toggle-row:last-child { border-bottom: none; }
.dg-toggle-row .dg-toggle-label { flex: 1; min-width: 0; }
.dg-toggle-row .dg-toggle-label small {
    display: block;
    font-size: 0.72rem;
    color: var(--dg-text-muted);
}
/* Owner: "нужно чтобы это было видимо пользователю что есть горячие клавиши" — inline next to
   the label, not its own line (unlike .dg-toggle-label small above, that's a sub-description). */
.dg-toggle-hotkey {
    font-size: 0.7rem;
    font-weight: 400;
    color: var(--dg-text-muted);
}
/* Переключатель — свой, а не .form-switch Bootstrap: тот тянет за собой свою палитру и
   размеры, которые в шторке смотрятся крупнее всего остального. */
.dg-tgl {
    position: relative;
    width: 34px;
    height: 20px;
    flex: none;
    border-radius: 10px;
    background: var(--dg-surface-hover);
    border: 1px solid var(--dg-border-strong);
    transition: background-color 0.18s ease, border-color 0.18s ease;
}
.dg-tgl::after {
    content: "";
    position: absolute;
    top: 1px;
    left: 1px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--dg-surface);
    border: 1px solid var(--dg-border-strong);
    transition: transform 0.18s var(--dg-ease);
}
.dg-toggle-row[aria-pressed="true"] .dg-tgl {
    background: var(--dg-accent);
    border-color: var(--dg-accent);
}
.dg-toggle-row[aria-pressed="true"] .dg-tgl::after {
    transform: translateX(14px);
    border-color: transparent;
}

/* Переключатель «одно из нескольких». Размеры по макету: кнопки крупнее прежних — в них
   попадают пальцем, а не курсором. Выбранное — нейтральной заливкой, не акцентной: акцент в
   этом экране закреплён за действиями, а выбранный пункт действием не является. */
.dg-segmented {
    display: flex;
    margin: 8px 0 2px;
    border: 1px solid var(--dg-border);
    border-radius: var(--dg-radius);
    overflow: hidden;
}
.dg-segmented button {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex: 1;
    min-width: 0;
    padding: 10px 6px;
    border: 0;
    background: var(--dg-surface);
    color: var(--dg-text-2);
    font-family: var(--dg-font);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}
/* Подпись рядом со значком на узком экране может не помещаться — сжимается она, а значок
   остаётся целым: по нему вариант и узнают. */
.dg-segmented button > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dg-seg-ic { width: 14px; height: 14px; flex: none; }
.dg-segmented button[aria-pressed="true"] .dg-seg-ic { color: var(--dg-accent-ink); }
/* На узком экране трети переключателя не хватало на «Light» рядом со значком — подпись
   обрезалась многоточием (замерено на 375px). Ужимаем отступы и кегль, а не значок. */
@media (max-width: 420px) {
    .dg-segmented button { gap: 5px; padding: 10px 3px; font-size: 0.76rem; }
}
.dg-segmented button:hover { background: var(--dg-surface-hover); }
.dg-segmented button[aria-pressed="true"] {
    background: var(--dg-surface-active);
    color: var(--dg-text);
}

/* ============================================================================
   Область поиска — раскрывающийся список с галочками
   Восемь переключателей подряд занимали пол-экрана и открывались на каждый запрос. Переключатель
   вообще про «включить режим»; здесь же выбирают из набора, где обычно отмечено почти всё, —
   а это галочки. Свёрнутая строка показывает выбранное («DN, MN, SN, AN, KN»), и чаще всего
   разворачивать не приходится вовсе.
   ============================================================================ */
.dg-scope {
    margin: 8px 0 2px;
    border: 1px solid var(--dg-border);
    border-radius: var(--dg-radius);
    background: var(--dg-surface);
    overflow: hidden;
}
.dg-scope-group + .dg-scope-group { border-top: 1px solid var(--dg-border); }

/* Строка группы: галка, название, счётчик «сколько из скольких», кнопка раскрытия. Счётчик тут
   вместо перечисления — он и сообщает, выбрана группа целиком, частично или вовсе нет. */
.dg-scope-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 12px;
    font-family: var(--dg-font);
    font-size: 0.92rem;
    color: var(--dg-text);
}
/* font-size: inherit — assets/css/extrastyles.css (legacy, shared) sets a global `label {
   font-size: 20px }` that otherwise wins over inheriting .dg-scope-head's 0.92rem, since an
   explicit rule on the element itself beats inheritance regardless of specificity. Same trap as
   .dg-check-row below, which already has its own font-size for the same reason. */
.dg-scope-label { flex: 1; min-width: 0; cursor: pointer; font-size: inherit; }
.dg-scope-count {
    flex: none;
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    color: var(--dg-text-muted);
}
.dg-scope-group.dg-some .dg-scope-count { color: var(--dg-accent-ink); }
.dg-scope-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    flex: none;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--dg-text-muted);
    cursor: pointer;
}
.dg-scope-toggle:hover { background: var(--dg-surface-hover); color: var(--dg-text); }
.dg-scope-chev { transition: transform 0.18s var(--dg-ease); }
.dg-scope-group.dg-open .dg-scope-chev { transform: rotate(180deg); }

/* Под-пункты с отступом — видно, что они принадлежат группе, а не идут с ней вровень. */
.dg-scope-list { padding: 0 12px 8px 34px; }
.dg-scope-list[hidden] { display: none; }

.dg-check-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 0;
    font-size: 0.92rem;
    color: var(--dg-text);
    cursor: pointer;
}
/* Галочка — родная, только перекрашенная в акцент: свои квадратики пришлось бы отдельно учить
   доступности (фокус, клавиатура, screen reader), а accent-color даёт всё это даром.
   Селектор с двумя классами и элементом — ответ на `label input[type="checkbox"] {display:none}`
   из assets/css/extrastyles.css (общий файл, его не трогаем). Из-за него галки под-пунктов, а они
   лежат ВНУТРИ <label>, не рисовались вовсе: была видна одна родительская, и список читался как
   набор простых строк. */
.dg-scope input.dg-check {
    display: inline-block;
    width: 18px;
    height: 18px;
    flex: none;
    margin: 0;
    accent-color: var(--dg-accent);
    cursor: pointer;
}

/* Диакритика: набрать ā/ṁ/ñ без своей раскладки. Символ уходит в позицию курсора, поле фокус
   не теряет — набор продолжается с того же места. */
.dg-diac {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 6px;
    margin-top: 8px;
}
.dg-diac button {
    padding: 8px 0;
    border: 1px solid var(--dg-border);
    border-radius: var(--dg-radius);
    background: var(--dg-surface);
    color: var(--dg-text);
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}
.dg-diac button:hover { background: var(--dg-surface-hover); border-color: var(--dg-border-strong); }

/* ============================================================================
   Боковое меню — выезжает СПРАВА, с той стороны, где стоит бургер: выезд слева от кнопки
   справа читался как чужое движение.
   ============================================================================ */
#dg-drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1082;
    background: rgba(20, 18, 10, 0.4);
    /* Bleeds the dimming color far past the actual viewport edges via box-shadow (paints extra
       area without touching layout/scroll at all) — a defensive backstop for mobile rubber-band
       overscroll, on top of the real fix below (body scroll lock + overscroll-behavior on the
       drawer itself): owner, live device, dragging the open drawer: "граница белая всё ещё
       торчит" (a white edge still pokes through). */
    box-shadow: 0 0 0 100vmax rgba(20, 18, 10, 0.4);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease;
}
#dg-drawer-backdrop.show { opacity: 1; pointer-events: auto; }
#dg-drawer-backdrop[hidden] { display: none; }

#dg-drawer {
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    z-index: 1083;
    display: flex;
    flex-direction: column;
    width: 82%;
    max-width: 320px;
    background: var(--dg-surface);
    color: var(--dg-text);
    font-family: var(--dg-font);
    border-left: 1px solid var(--dg-border-strong);
    box-shadow: -8px 0 30px rgba(0, 0, 0, 0.14);
    transform: translateX(100%);
    transition: transform 0.3s var(--dg-ease);
    overflow-y: auto;
    /* Real fix for the mobile "white edge" bug (see #dg-drawer-backdrop above): scrolling the
       drawer's own list to its end used to chain into scrolling the page BODY behind it (body
       scroll wasn't locked either — see body.dg-drawer-open below), and that body-level
       rubber-band bounce is what briefly shifted the fixed backdrop/drawer and revealed page
       background at an edge. contain stops the drawer's scroll from ever handing off to body. */
    overscroll-behavior: contain;
}
/* Locked while the drawer is open (openDrawer()/closeDrawer(), home.js) — the other half of the
   white-edge fix: with body itself unable to scroll/bounce, there's nothing left for the fixed
   backdrop/drawer to visually lag behind during a drag. */
body.dg-drawer-open {
    overflow: hidden;
}
/* apple-design audit: menu drawer was a flat opaque fill — no depth/material feel over the
   dimmed content behind it. Falls back to the solid fill above where backdrop-filter is
   unsupported. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    #dg-drawer {
        background: color-mix(in srgb, var(--dg-surface) 88%, transparent);
        -webkit-backdrop-filter: blur(20px) saturate(180%);
        backdrop-filter: blur(20px) saturate(180%);
    }
}
#dg-drawer.show { transform: translateX(0); }
#dg-drawer[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
    #dg-drawer, #dg-drawer-backdrop { transition: none; }
}

.dg-drawer-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 14px 12px 10px 16px;
    border-bottom: 1px solid var(--dg-border);
}
.dg-drawer-head .dg-brand-name { flex: 1; min-width: 0; }
.dg-drawer-body { padding: 8px 18px 24px; }
.dg-drawer-body .dg-group-title {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--dg-text-muted);
    margin: 18px 0 2px;
}
.dg-drawer-body .dg-group-title:first-child { margin-top: 2px; }
/* Пункты меню — со значками: без них список ссылок читается сплошной серой простынёй, и глазом
   не за что зацепиться. Значки те же, что у плиток (Font Awesome, см. paintDrawerIcons). */
.dg-drawer-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 0;
    font-size: 0.95rem;
    color: var(--dg-text);
    text-decoration: none;
    border-bottom: 1px solid var(--dg-border);
}
.dg-drawer-row:last-child { border-bottom: none; }
.dg-drawer-row:hover { color: var(--dg-accent-ink); }
.dg-drawer-row .dg-row-ic {
    width: 17px;
    height: 17px;
    flex: none;
    color: var(--dg-text-muted);
}
.dg-drawer-row:hover .dg-row-ic { color: var(--dg-accent-ink); }
/* Значок-картинка (ракушка у «Главной»). object-fit — иначе картинка растянется в квадрат и
   потеряет пропорции. Коробка РОВНО как у соседних svg (17px), иначе подпись «Главная» съезжает
   вправо относительно остальных строк (замерено: при коробке 22px — 1013px против 1008px у
   соседей, owner: "выбивается"). Крупнее соседей ракушка становится через transform, который
   на раскладку не влияет: её рисунок узкий и с большими полями по бокам (замерено по пикселям
   картинки: 117×188 краски в холсте 206×206), поэтому в общей коробке 17px она выходит заметно
   мельче круглых значков рядом. */
.dg-drawer-row .dg-row-ic-img { width: 17px; height: 17px; object-fit: contain; transform: scale(1.6); }
/* Значок у заголовка раздела — того же роста, что и сама подпись раздела. */
.dg-drawer-body .dg-group-title {
    display: flex;
    align-items: center;
    gap: 8px;
}
.dg-drawer-body .dg-group-title .dg-row-ic { width: 13px; height: 13px; flex: none; }

/* Сворачиваемый раздел меню (<details>, см. "Навигация" в search/index.html) — summary
   переиспользует .dg-group-title один в один, только добавляет кликабельность и свой
   индикатор вместо браузерного треугольника (тот не темизируется единообразно между
   движками). */
.dg-drawer-group summary.dg-group-title {
    cursor: pointer;
    list-style: none;
}
.dg-drawer-group summary.dg-group-title::-webkit-details-marker { display: none; }
.dg-drawer-group summary.dg-group-title::after {
    content: '';
    width: 8px;
    height: 8px;
    margin-left: auto;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
    transition: transform 0.15s ease;
}
.dg-drawer-group:not([open]) summary.dg-group-title::after { transform: rotate(-45deg); }

/* Список режимов чтения в бургере — тот же паттерн, что у .dg-drawer-row, плюс вторая строка
   описания под подписью. Owner: "не нужны радио кнопки" — was a radio-style filled/empty
   circle per row; dropped, active row is just bold + accent color, same convention as an
   active nav item elsewhere in this file. */
.dg-mode-row {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 0;
    border-bottom: 1px solid var(--dg-border);
    cursor: pointer;
    background: none;
    border-left: none; border-right: none; border-top: none;
    width: 100%;
    text-align: left;
    color: var(--dg-text);
}
.dg-mode-row:last-child { border-bottom: none; }
.dg-mode-row:hover { color: var(--dg-accent-ink); }
.dg-mode-row-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 0.95rem; }
.dg-mode-row-desc { font-size: 0.78rem; color: var(--dg-text-muted); }
/* Owner: "нужно чтобы это было видимо пользователю что есть горячие клавиши" — Alt+N next to
   the row it actually triggers (window.MODE_HOTKEY_DIGITS, settings.js). */
.dg-mode-row-hotkey {
    flex: none;
    font-size: 0.7rem;
    font-weight: 400;
    color: var(--dg-text-muted);
    font-variant-numeric: tabular-nums;
}
.dg-mode-row.active .dg-mode-row-top { color: var(--dg-accent-ink); font-weight: 600; }

/* ============================================================================
   Перетаскивание плиток
   Порядок хранится в localStorage.dgTileOrder и переживает перезагрузку. Реализация — на
   pointer-событиях, а не на HTML5 drag-and-drop: тот на мобильных браузерах не работает вовсе,
   а плитки нужны в первую очередь именно там.
   ============================================================================ */
/* Deliberately NOT touch-action:none, even though that is the usual drag-and-drop recipe: tiles
   cover most of the mobile home screen, and "none" would kill page scrolling from all of it. The
   finger drag is unblocked in JS instead, only once the drag actually starts — see the
   passive:false touchmove handler in wireTileDrag() (search/js/home.js). */
.dg-tile { touch-action: manipulation; }
/* Пока идёт перетаскивание — гасим переходы у соседей, иначе они «догоняют» палец, и целиться
   в позицию становится невозможно. */
body.dg-tiles-dragging .dg-tile { transition: none; }
body.dg-tiles-dragging { user-select: none; -webkit-user-select: none; }
.dg-tile.dg-dragging {
    position: fixed;
    z-index: 1090;
    margin: 0;
    pointer-events: none;
    opacity: 0.95;
    box-shadow: 0 10px 26px -8px rgba(0, 0, 0, 0.45);
    transform: scale(1.03);
}
/* Место, куда плитка встанет. Тот же размер, что у неё самой — сетка не перестраивается. */
.dg-tile-placeholder {
    border: 1px dashed var(--dg-border-strong);
    border-radius: 12px;
    background: var(--dg-surface-hover);
    opacity: 0.6;
}

/* z-index выше #dg-sheet-backdrop (1080, home.css) намеренно — owner: "кликая по иконкам
   мультитула, они бы переключались сразу... сейчас нужно два тапа, если открыто мегаменю: один
   уходит на закрытие активного, второй — на открытие другого". Причина — общая подложка шторок/
   мега-меню на z-index:1080 закрывает весь экран (pointer-events:auto, пока показана), в том
   числе плитки, которые сами по себе ниже неё; первый клик всегда попадал в подложку, а не в
   плитку под ней. Приподнимаем ТОЛЬКО саму кнопку (не весь #home-tiles) — клик по зазору между
   плитками по-прежнему бьёт в подложку и корректно закрывает открытое, а клик по самой плитке
   идёт напрямую в её обработчик (renderTiles() → runTile()), который сам переключает/закрывает
   через openMega()/openSheet() — тем же кликом, без второго тапа. */
.dg-tile { position: relative; z-index: 1081; }
/* Полный стек z-index этой страницы (снизу вверх): 900 #dg-busy-indicator, 1080 #dg-sheet-
   backdrop, 1081 .dg-sheet/.dg-tile, 1082 #dg-drawer-backdrop, 1083 #dg-drawer, 1084 autocomplete,
   1090 плитка во время drag. Bootstrap-модалка (#SearchResultHelp — "Помощь", вызывается через
   runTile()) была НИЖЕ всего этого — bootstrap 5 по умолчанию кладёт .modal-backdrop/.modal в
   районе 1050-1060, скроен под страницы БЕЗ своего конкурирующего оверлей-стека. Раньше не
   всплывало: до фикса .dg-tile выше двумя пунктами модалка открывалась только вторым кликом,
   когда мега/шторка/дровер уже гарантированно закрыты первым. Теперь модалку можно открыть, пока
   что-то из стека ещё видимо (та же причина, что и починенный runTile() ниже) — owner
   (скриншот): "плитки поверх Помощи, z-index". Модалка — единственная НАСТОЯЩАЯ модальная
   штора (блокирует весь остальной интерфейс), поэтому кладём её однозначно выше ЛЮБОГО пункта
   этого стека, а не подбираем число под текущий максимум (1090) — если стек когда-то вырастет
   ещё, модалка не должна снова оказываться потерянной под новым слоем. */
.modal-backdrop { z-index: 1095 !important; }
.modal { z-index: 1096 !important; }
/* Owner: "странное поведение — при хувере появляется крестик закрыть, случайно можно удалить
   мегаменю... давай уберём" — .dg-tile-remove (inline ✕, appeared on hover AND on drag-start,
   both easy to trigger by accident) removed entirely, both the CSS here and its creation in
   renderTiles() (search/js/home.js). Show/hide now lives ONLY in "Изменить кнопки"
   (openEditList(), same file) as an explicit checkbox per row — a deliberate action in a
   dedicated list, not a stray button that shows up mid-interaction. */

/* ============================================================================
   Плитки на широком экране — компактнее, но В ДВА РЯДА
   Все восемь в одну строку вытягивались через весь экран «колбасой»: подписи расходились так
   далеко друг от друга, что набор переставал читаться как набор. Четыре в ряд — привычная сетка
   значков, и восьмая плитка просто уходит во второй ряд.
   ============================================================================ */
/* ============================================================================
   Воздух на широком экране.
   Отступы, подобранные под телефон, на десктопе сбивают всё в кучу: вывеска, девиз, поле и
   плитки стоят одной плотной пачкой, хотя места вокруг полно. Растягиваем по вертикали именно
   здесь, а не в общих правилах: на телефоне эта же прибавка увела бы плитки за нижний край.
   ============================================================================ */
@media (min-width: 992px) {
    body.dg-state-home #dg-hero-band { padding-bottom: 54px; }
    body.dg-state-home #dg-topbar { padding-top: 26px; }
    /* Restores the desktop-specific gap the old standalone #home-motto (64px margin + its own
       text height) used to hold before it moved into #dg-topbar — same reasoning as the base
       .hero-row margin-top above, just the wider desktop value. */
    body.dg-state-home .hero-row { margin-top: 107px; }
    body.dg-state-home #home-pane { margin-top: 40px; }
    /* Поле на десктопе крупнее: оно — центр экрана, а не строка в ряду. */
    body.dg-state-home .dg-input-shell { padding: 14px 14px 14px 20px; }
    body.dg-state-home #form #paliauto.searchinput { font-size: 1.2rem; }
    body.dg-skin-minimal.dg-state-home .dg-hero-form { max-width: 720px; }
    .dg-hero-inner { max-width: 760px; }
    #home-slides { margin-top: 46px; }
    #dg-footer { margin-top: 56px; }
}

@media (min-width: 992px) {
    .dg-tiles {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 14px;
        max-width: 680px;
    }
    .dg-tile {
        gap: 7px;
        padding: 14px 6px;
        font-size: 0.82rem;
        border-radius: 10px;
    }
    .dg-tile-ic { width: 38px; height: 38px; }
    .dg-tile svg { width: 20px; height: 20px; }
}

/* Owner: "инпут оказывался у верха страницы, расстояние... сужалось... мега меню открывалось
   максимально без скролла" — toggled by scrollForMega() (home.js) right before a mega tile opens
   (desktop-only, mega tiles only). Shrinks the two gaps ABOVE the tile row (hero-band's own
   bottom padding, then #home-pane's margin before the tiles) so the row sits higher, leaving
   more viewport height below it for the mega panel (placeMegaAnchored sizes it off that gap).
   Two classes outrank the plain "body.dg-state-home ..." rules above without !important. */
body.dg-mega-compact.dg-state-home #dg-hero-band { padding-bottom: 20px; }
body.dg-mega-compact.dg-state-home #home-pane { margin-top: 14px; }

/* ============================================================================
   Строки списка: звёздочка и «чипсы»
   ============================================================================ */
/* Звезда у важных пунктов ($iconimportant в легаси-меню + личные отметки поверх, см. isStarred()
   в home.js). Раньше рисовался знак ✦ — но ромбик на этом сайте уже занят: им помечены скрытые
   ссылки-якоря на цитаты (.quoteLink-start), и два разных смысла одним значком путали. Здесь
   настоящая звезда (контур fa-star).
   Стоит СЛЕВА, на месте обычного значка строки — и ТОГО ЖЕ размера, что .dg-row-icon (17px):
   раньше была мельче (12px) соседних значков строки, из-за чего звёздный пункт визуально терял
   вес, а не подчёркивал важность (просьба владельца — «как иконка ссылки»). Золотая, а не
   акцентным цветом темы — так же, как остальное «избранное» на сайте. */
.dg-sheet .dg-sheet-row .dg-row-star {
    width: 17px;
    height: 17px;
    flex: none;
    margin-top: 2px;
    color: #f39c12;
}

/* Группы, где подписи короткие и говорят сами за себя (ИИ, переводчики, коды изданий), рисуются
   не столбцом строк, а вплотную — «чипсами» в одну-две строки: четыре имени вроде Gemini или
   DeepSeek не заслуживают четырёх полноразмерных строк (просьба владельца). Задаётся в
   menu-links.json полем группы "layout": "chips". */
.dg-sheet .dg-chip-group {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 6px 0 10px;
}
.dg-sheet .dg-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 6px 11px;
    border: 1px solid var(--dg-border);
    border-radius: 999px;
    background: var(--dg-surface);
    color: var(--dg-text);
    font-size: 0.8rem;
    text-decoration: none;
}
.dg-sheet .dg-chip:hover {
    border-color: var(--dg-accent);
    color: var(--dg-accent);
    background: var(--dg-accent-bg);
}
.dg-sheet .dg-chip .dg-row-star { margin-top: 0; width: 11px; height: 11px; }

/* ============================================================================
   «Интересные запросы» — перенос слайд-шоу с боевой главной

   Разметка повторяет index.php один-в-один (#carouselWithCaptions в <div class="max-w-450
   container-lg my-5">), и на проде у этой карусели НЕТ ни одного своего правила в CSS — всё
   оформление бутстраповское. Поэтому здесь только то, чего у Bootstrap нет: ширина колонки,
   поля под боковые стрелки и цвет значков этих стрелок. Ни рамки, ни подложки, ни своих кнопок
   в шапке — от них наш вариант и выглядел хуже оригинала.
   ============================================================================ */
#home-slides { margin-top: 26px; }
#home-slides[hidden] { display: none; }

/* max-width 450 и центрирование — те самые .max-w-450 и .container-lg с прода. Текст по центру:
   на боевой главной карусель стоит внутри .container.text-center. */
.dg-slides {
    max-width: 450px;
    margin: 0 auto;
    font-family: var(--dg-font);
    text-align: center;
}

/* Боковые стрелки Bootstrap занимают полосу поверх содержимого. Даём слайду поля, чтобы длинный
   заголовок не заезжал под них. */
#dg-carousel .carousel-item { padding: 0 44px; }
#dg-carousel h5 {
    margin: 0 0 6px;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--dg-text);
}
#dg-carousel span { font-size: 0.88rem; line-height: 1.5; color: var(--dg-text-2); }
#dg-carousel a {
    display: inline-block;
    margin-top: 8px;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--dg-accent-ink);
    text-decoration: none;
}
#dg-carousel a:hover { text-decoration: underline; }

/* Значок стрелки у Bootstrap белый — он рассчитан на фотографию во всю карточку. На светлом фоне
   его не видно, поэтому инвертируем, как это делает штатный вариант .carousel-dark. В тёмной
   теме белый как раз к месту, там инверсия снимается. */
#dg-carousel .carousel-control-prev,
#dg-carousel .carousel-control-next { width: 40px; opacity: 0.45; }
#dg-carousel .carousel-control-prev:hover,
#dg-carousel .carousel-control-next:hover { opacity: 0.9; }
#dg-carousel .carousel-control-prev-icon,
#dg-carousel .carousel-control-next-icon {
    width: 1.4rem;
    height: 1.4rem;
    filter: invert(1) grayscale(100);
}
body.dark #dg-carousel .carousel-control-prev-icon,
body.dark #dg-carousel .carousel-control-next-icon { filter: none; }

/* «Показать все» — внизу справа, приглушённой мелочью: как .text-end.mt-2 с .text-muted.small
   на проде.
   Отрицательный margin-top — owner: "показать все стоит слишком далеко от слайд-шоу, подними
   ссылку вверх". Причина отрыва: lockCarouselHeight() (home.js) фиксирует min-height карусели по
   САМОМУ ВЫСОКОМУ слайду, чтобы переключение не дёргало страницу — под коротким слайдом остаётся
   пустая полоса (замерено по всем 18 слайдам: от 2px под самым длинным до 88px под самым
   коротким), и ссылка висела под ней. Саму карусель НЕ трогаем (owner: "не трогай ничего по
   слайд шоу" — попытки двигать .carousel-item ломали анимацию Bootstrap и съезжала «Читать»),
   поднимаем только сам футер — он вне карусели. Наезда нет даже на самом длинном слайде:
   «Показать все» прижата вправо, а «Читать»/текст слайда отцентрованы — по горизонтали не
   пересекаются (проверено по всем слайдам). */
.dg-slides-foot { margin-top: 8px; text-align: right; }
/* Подъём футера — ТОЛЬКО на мобильной (owner: "на десктопе было и так хорошо, стало плохо;
   проблема была только на мобильных"): на широком экране слайд занимает всю коробку карусели,
   пустой полосы под ним нет, и -34px просто ставили «Показать все» вплотную к стрелке, на одну
   строку с «Читать». z-index здесь же — плата за отрицательный margin: подняв футер, мы заводим
   его под правую стрелку (.carousel-control-next — absolute, во всю высоту, z-index:1 у
   bootstrap), и она перехватывала клики (owner: "ссылка больше не работает"). */
@media (max-width: 767.98px) {
    .dg-slides-foot { margin-top: -34px; position: relative; z-index: 2; }
}
.dg-slides-all {
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--dg-text-muted);
    font-family: var(--dg-font);
    font-size: 0.78rem;
    cursor: pointer;
}
.dg-slides-all:hover { color: var(--dg-text-2); text-decoration: underline; }

/* Пункты в списке «показать все» (шторка). Стрелка справа — знак того, что строку можно открыть:
   без неё список читался справочником с описаниями, а не набором ссылок. */
.dg-sheet .dg-slide-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 0;
}
.dg-sheet .dg-slide-row-body { flex: 1; min-width: 0; }
.dg-sheet .dg-slide-go-ic { flex: none; color: var(--dg-text-muted); }
.dg-sheet .dg-slide-row:hover .dg-slide-go-ic { color: var(--dg-accent-ink); }
.dg-sheet .dg-slide-row .dg-slide-title {
    display: block;
    margin: 0 0 2px;
    font-size: 0.95rem;
    color: var(--dg-text);
    text-decoration: none;
}
.dg-sheet .dg-slide-row .dg-slide-title:hover { color: var(--dg-accent-ink); }
.dg-sheet .dg-slide-row .dg-slide-desc {
    margin: 0;
    font-size: 0.84rem;
    line-height: 1.45;
    color: var(--dg-text-2);
}
/* Подсказка "Чего-то не хватает?" внизу полного списка — перенос с multiTool.html. */
.dg-slides-contacts-note {
    margin: 14px 0 2px;
    padding-top: 12px;
    border-top: 1px solid var(--dg-border);
    font-size: 0.82rem;
    color: var(--dg-text-muted);
}
.dg-slides-contacts-note a { color: var(--dg-accent-ink); }

/* ============================================================================
   Форма «своя кнопка» (в шторке, вызывается из бокового меню)
   ============================================================================ */
.dg-add-form { padding: 6px 0 4px; }
.dg-field { display: block; margin-bottom: 14px; }
.dg-field-label {
    display: block;
    margin-bottom: 5px;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--dg-text-2);
}
.dg-field-input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--dg-border-strong);
    border-radius: var(--dg-radius);
    background: var(--dg-surface);
    color: var(--dg-text);
    font-family: var(--dg-font);
    font-size: 0.95rem;
}
.dg-field-input:focus {
    outline: none;
    border-color: var(--dg-accent);
    box-shadow: 0 0 0 3px var(--dg-accent-bg);
}
.dg-field-textarea { resize: vertical; min-height: 44px; font-family: var(--dg-font); }
.dg-field-hint {
    margin: -8px 0 14px;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--dg-text-muted);
}
.dg-field-error {
    margin: 10px 0 0;
    font-size: 0.82rem;
    color: #b3261e;
}
body.dark .dg-field-error { color: #ff8a80; }

/* Выбор значка — из готового набора. Свои картинки не грузим: пришлось бы думать про их
   хранение, размер и то, как они переживут смену темы. */
.dg-icon-pick {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 6px 0 4px;
}
.dg-icon-opt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid var(--dg-border);
    border-radius: 50%;
    background: var(--dg-surface);
    color: var(--dg-text-2);
    cursor: pointer;
}
.dg-icon-opt svg { width: 18px; height: 18px; }
.dg-icon-opt:hover { border-color: var(--dg-border-strong); }
.dg-icon-opt.on {
    border-color: var(--dg-accent);
    background: var(--dg-accent-bg);
    color: var(--dg-accent);
}
.dg-add-submit {
    width: 100%;
    margin-top: 16px;
    padding: 12px;
    border: 0;
    border-radius: var(--dg-radius);
    background: var(--dg-accent);
    color: #fff;
    font-family: var(--dg-font);
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}
.dg-add-submit:hover { background: var(--dg-accent-dark); }
.dg-add-reset {
    width: 100%;
    margin-top: 10px;
    padding: 11px;
    border: 1px solid var(--dg-border-strong);
    border-radius: var(--dg-radius);
    background: transparent;
    color: var(--dg-text-2);
    font-family: var(--dg-font);
    font-size: 0.9rem;
    cursor: pointer;
}
.dg-add-reset:hover { color: var(--dg-text); border-color: var(--dg-text-muted); }

/* Свой значок — эмодзи. Красим ОДНИМ цветом с остальными значками: цветная картинка среди
   одноцветных контуров выбивается из ряда, а плитки должны читаться как один набор.
   Приём стандартный: обесцвечиваем эмодзи и закрашиваем текущим цветом через фон с обрезкой по
   тексту. Если браузер не умеет background-clip:text, останется обычное цветное эмодзи —
   значок при этом виден, просто не одноцветный. */
.dg-emoji-ic {
    display: inline-block;
    font-size: 20px;
    line-height: 1;
    font-style: normal;
    color: transparent;
    background-color: currentColor;
    background-image: none;
    -webkit-background-clip: text;
    background-clip: text;
    filter: grayscale(1) contrast(0);
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .dg-emoji-ic { color: inherit; background: none; filter: none; }
}
.dg-tile-ic .dg-emoji-ic { font-size: 22px; color: transparent; background-color: var(--dg-accent); }
.dg-edit-ic .dg-emoji-ic { font-size: 15px; background-color: var(--dg-text-muted); }

.dg-emoji-input { margin-top: 4px; }

/* Строка списка «изменить кнопки» — .dg-edit-row теперь просто <div> (общий .dg-sheet-row даёт
   flex/gap/padding/border-bottom), внутри — чекбокс показа (owner: "добавь чекбоксы, по
   умолчанию включенные, чтобы можно было скрыть" — заменяет крестик, всплывавший на самой
   плитке) и .dg-edit-row-main — настоящая кнопка, открывающая форму правки по клику где угодно
   в строке, кроме самого чекбокса (там его click — свой stopPropagation, home.js). */
.dg-sheet .dg-edit-visible-cb {
    flex: none;
    width: 17px;
    height: 17px;
    margin: 0;
    accent-color: var(--dg-accent);
    cursor: pointer;
}
.dg-sheet .dg-edit-row-main {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    border: 0;
    background: transparent;
    padding: 0;
    font: inherit;
    font-family: var(--dg-font);
    color: inherit;
    text-align: left;
    cursor: pointer;
}
.dg-sheet .dg-edit-row-main .dg-edit-ic {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ============================================================================
   Подсказки автодополнения (jQuery UI, autopali.js)
   Виджет приходит со своим оформлением jQuery UI — светлые уголки, свой шрифт, синяя подсветка.
   Рядом с новым полем это выглядело деталью с другого сайта. Приводим к виду самого поля: та же
   рамка, то же скругление, те же цвета и та же тень.
   ============================================================================ */
body.dg-skin-minimal .ui-autocomplete {
    padding: 6px;
    border: 1px solid var(--dg-border-strong);
    border-radius: var(--dg-radius);
    background: var(--dg-surface);
    box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.35);
    font-family: var(--dg-font);
    font-size: 0.95rem;
    z-index: 1084;
}
/* Строку подсказки autopali.js рисует своим шаблоном: <li><div class="autopali-dropdown-item">
   (см. _renderItem в /assets/js/autopali.js), а jQuery UI вешает подсветку через .ui-state-active
   на обёртку. Красим оба варианта — какой именно окажется в разметке, зависит от версии виджета. */
body.dg-skin-minimal .ui-autocomplete .autopali-dropdown-item,
body.dg-skin-minimal .ui-autocomplete .ui-menu-item-wrapper {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 10px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--dg-text);
}
body.dg-skin-minimal .ui-autocomplete .ui-state-active,
body.dg-skin-minimal .ui-autocomplete .ui-state-active .autopali-dropdown-item,
body.dg-skin-minimal .ui-autocomplete .autopali-dropdown-item:hover,
body.dg-skin-minimal .ui-autocomplete .ui-menu-item-wrapper.ui-state-active {
    margin: 0;
    border: 0;
    background: var(--dg-accent-bg);
    color: var(--dg-accent-ink);
}
/* Часы у строк из истории — приглушаем: это пометка, а не содержание подсказки. */
/* Значок часов у строк из истории — это <img> с тёмным SVG (autopali.js подставляет
   /assets/svg/clock-rotate-left.svg), а не иконочный шрифт: currentColor на него не действует, и
   в тёмной теме он сливался с фоном. Инвертируем картинку — другого способа перекрасить внешний
   SVG, вставленный через <img>, у CSS нет. */
body.dg-skin-minimal .ui-autocomplete .autocomplete-history-icon {
    width: 13px;
    height: 13px;
    flex: none;
    opacity: 0.55;
}
body.dark .ui-autocomplete .autocomplete-history-icon { filter: invert(1); opacity: 0.7; }

/* ============================================================================
   Подвал — виден всегда (мобильный браузер, десктоп, установленное PWA-приложение): владелец
   явно попросил копирайт видимым везде, скрывать в приложении раньше было ошибкой.
   ============================================================================ */
#dg-footer {
    margin: 34px 0 6px;
    padding-top: 16px;
    border-top: 1px solid var(--dg-border);
    font-family: var(--dg-font);
    font-size: 0.78rem;
    color: var(--dg-text-muted);
    text-align: center;
}
.dg-footer-link { color: var(--dg-text-2); text-decoration: none; }
.dg-footer-link:hover { color: var(--dg-accent-ink); text-decoration: underline; }

/* Owner: same fixed bottom-right cluster (#language-button + #scrollToTopBtn, uiextra.css) that
   needed a mobile safe zone below the reader's footer links (reader/css/uiextra.css,
   .links-area) also covers #dg-footer's terms/privacy links at the bottom of the RESULTS page —
   #dg-footer is shown on results too (see comment above), just without the reserved space.
   Home doesn't need this: both buttons are display:none there (body.dg-state-home rule above). */
@media (max-width: 600px) {
    body.dg-state-results #dg-footer {
        padding-bottom: 96px;
    }
}
.dg-terms-text {
    margin: 8px 0 4px;
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--dg-text);
}
.dg-terms-text a { color: var(--dg-accent-ink); }

/* ============================================================================
   «Как искать» + памятка о переводах — перенос блоков боевой главной.
   На широком экране всегда видно. На узком — свёрнуто по умолчанию (владелец: главная и так
   длинная на телефоне), но НЕ display:none навсегда — якорь из бургера/списка "Show all" должен
   до него доводить. .dg-anchor-revealed добавляет revealAnchorSection() (home.js) при переходе
   по хешу внутрь блока — тем же классом раскрывается и #home-extra ниже.
   ============================================================================ */
#home-howto { max-width: 640px; margin: 0 auto; }
body.dg-state-home #home-howto:not([hidden]) { display: block; }
@media (max-width: 991.98px) {
    body.dg-state-home #home-howto:not(.dg-anchor-revealed) { display: none; }
}
.dg-howto-quote {
    margin: 46px 0 0;
    padding: 20px 24px;
    border: 1px solid var(--dg-border);
    border-radius: 12px;
    text-align: center;
}
.dg-howto-quote .pli-lang {
    font-style: italic;
    font-size: 0.98rem;
    line-height: 1.6;
    color: var(--dg-text);
    margin: 0 0 12px;
}
#dg-howto-body {
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--dg-text-2);
    margin: 0 0 10px;
}
.dg-howto-refs { margin: 0; font-size: 0.85rem; }
.dg-howto-refs a {
    color: var(--dg-accent-ink);
    text-decoration: none;
    margin: 0 6px;
}
.dg-howto-refs a:hover { text-decoration: underline; }

.dg-howto-warn {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    margin: 18px 0 0;
    padding: 16px 20px;
    border-radius: 12px;
    background: var(--dg-accent-bg);
    color: var(--dg-text);
}
.dg-howto-warn svg { flex: none; margin-top: 2px; color: var(--dg-accent-ink); }
.dg-howto-warn strong { display: block; font-size: 0.95rem; margin-bottom: 6px; }
.dg-howto-warn p {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--dg-text-2);
    white-space: pre-line;
}

/* ============================================================================
   Приложения, расширения и контакты — нижние блоки боевой главной.
   Widescreen: всегда видно. Узкий экран: свёрнуто по умолчанию (владелец: главная и так длинная
   на телефоне), раскрывается тем же .dg-anchor-revealed, что и #home-howto выше — переход по
   якорю из бургера или из списка "Show all" доводит до цели вместо второй отдельной страницы.
   ============================================================================ */
body.dg-state-home #home-extra:not([hidden]) { display: block; }
@media (max-width: 991.98px) {
    body.dg-state-home #home-extra:not(.dg-anchor-revealed) { display: none; }
}
.dg-extra-title {
    margin: 46px 0 18px;
    font-family: var(--dg-font);
    font-size: 0.82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--dg-text-muted);
    text-align: center;
}
.dg-cta {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    max-width: 820px;
    margin: 0 auto;
}
.dg-cta-btn { display: inline-flex; line-height: 0; border-radius: 8px; }
.dg-cta-btn img { height: 44px; width: auto; display: block; border-radius: 8px; }
.dg-cta-btn:hover img { opacity: 0.85; }

.dg-contacts-motto {
    margin: 0 0 18px;
    font-family: var(--dg-font);
    font-size: 1rem;
    color: var(--dg-text-2);
    text-align: center;
}
.dg-contacts {
    display: flex;
    justify-content: center;
    gap: 12px;
}
.dg-contact-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--dg-border-strong);
    border-radius: 50%;
    color: var(--dg-text-2);
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.dg-contact-btn svg { width: 18px; height: 18px; }
.dg-contact-btn:hover {
    background: var(--dg-accent-bg);
    border-color: var(--dg-accent);
    color: var(--dg-accent-ink);
}

/* Prod: <p class="lead mt-4">$poweredby ... *</p> right under the contact icons. */
.dg-powered-by {
    margin: 18px 0 0;
    font-family: var(--dg-font);
    font-size: 1.1rem;
    color: var(--dg-text-2);
    text-align: center;
}

/* apple-design audit — #pali/#pali-words carry DataTables' "responsive" class but the
   Responsive extension itself is never loaded, so it does nothing: columns keep their
   auto-calculated desktop widths and long words in the Title column get torn mid-word
   on narrow screens. Give Title room and let it wrap on spaces instead. Also reserve a
   bottom safe zone so the fixed Pāli/Eng toggle (bottom:30px, ~38-48px tall) never
   permanently covers the last table row. */
@media (max-width: 480px) {
    #pali td:nth-child(2),
    #pali-words td:nth-child(2) {
        word-break: normal;
        overflow-wrap: anywhere;
        min-width: 45vw;
    }
    /* #search-pane specifically, not the bare .table-wrapper class — that class is ALSO reused
       (search/index.html:913, deliberately, for matching max-width/centering) by the page-wide
       header wrapper present in every state (home/results/reader/toc), so the un-scoped
       selector was adding this same 90px trailing gap after the search heading, after the
       reader's prev/next row, and after the TOC input — everywhere, not just after the results
       table it was meant for (owner: "бессмысленный отступ" in all three places). */
    #search-pane.table-wrapper {
        padding-bottom: 90px;
    }
}

/* Owner: "верхние ссылки и кнопки слишком широко... увеличение шрифта не должно влиять на
   расстояние между иконками и текстовыми ссылками в ридере и в других частях сайта" — the mobile
   html{font-size} bump above (--dg-mobile-scale) is meant for PROSE (headings, paragraphs, table
   cells, TOC entries); growing icon-button/toolbar-link CHROME too was collateral damage — bigger
   link/tab labels wrapped onto extra lines (.dg-reader-toolbar's DPR/BJT/Voice/… row, "TBW" bumped
   to its own line) and read as "spaced too far apart", even though the row's own gap/min-width
   were already fixed px and never moved. Each selector below divides its OWN normal rem size back
   by --dg-mobile-scale — not a flat 1rem/scale for all of them, that would make .dg-icon-btn (0.8rem)
   and .dg-tile (0.92rem) suddenly render at the SAME size as everything else instead of their
   usual distinct ones. Must be the LAST block in the file: same specificity as each selector's own
   rule earlier up top, and same-specificity CSS is decided by source order. */
@media (max-width: 767.98px) {
    .dg-icon-btn,
    #smart-toc-btn { font-size: calc(0.8rem / var(--dg-mobile-scale)); }
    .dg-tile,
    .dg-tile-label { font-size: calc(0.92rem / var(--dg-mobile-scale)); }
    p.sc-link a { font-size: calc(1.1rem / var(--dg-mobile-scale)); }
    .dg-reader-toolbar,
    .dg-reader-toolbar a,
    #results-toolbar,
    #reader-toolbar { font-size: calc(1rem / var(--dg-mobile-scale)); }
}
