/**
 * pxl-accessibility-version — стили панели. Портируемый файл, ничего не
 * знает про конкретный сайт. Настройка внешнего вида — через CSS-переменные
 * на самом .pxl-a11y-panel (например, из css конкретного шаблона):
 *
 *   .pxl-a11y-panel {
 *     --pxl-a11y-width: 380px;
 *     --pxl-a11y-bg: #101820;
 *     --pxl-a11y-fg: #fff;
 *     --pxl-a11y-accent: #00ba25;
 *   }
 *
 * Каждая настройка в панели — секция .pxl-a11y-setting: заголовок
 * (.pxl-a11y-setting__title) + сам контрол ниже.
 *
 * Применение выбранной схемы ко всему сайту работает через атрибут
 * html[data-pxl-a11y-scheme] и CSS-переменные --pxl-a11y-scheme-bg/-fg,
 * которые виджет сам проставляет на <html> (см. .js) — здесь ничего
 * дополнительно подключать не нужно, one line подключения виджета уже
 * даёт этот эффект на любом сайте.
 */

/**
 * Шрифт для дислексии (OpenDyslexic, MIT) — единственный внешний ресурс
 * во всём виджете, self-hosted рядом с этим файлом (fonts/), не с CDN —
 * во время работы виджет по-прежнему никуда не ходит в сеть. url() без
 * протокола/домена — резолвится относительно этого .css-файла, поэтому
 * шрифт находится независимо от того, на какой сайт виджет поставят.
 * Название семейства с префиксом Pxl — что бы не столкнуться с другим
 * OpenDyslexic, если он вдруг уже подключён темой сайта под тем же именем.
 */
@font-face {
  font-family: 'PxlA11yOpenDyslexic';
  src: url('fonts/OpenDyslexic-Regular.woff2') format('woff2'),
       url('fonts/OpenDyslexic-Regular.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

.pxl-a11y-panel {
  --pxl-a11y-width: 360px;
  --pxl-a11y-bg: #ffffff;
  --pxl-a11y-fg: #16181d;
  --pxl-a11y-accent: #2b6cb0;
  --pxl-a11y-border: rgba(0, 0, 0, 0.08);
  --pxl-a11y-radius: 12px;
  --pxl-a11y-shadow: 0 10px 40px rgba(0, 0, 0, 0.18);
  --pxl-a11y-duration: 0.25s;
  --pxl-a11y-z: 9999;

  position: fixed;
  z-index: var(--pxl-a11y-z);
  top: 0;
  height: 100%;
  width: min(var(--pxl-a11y-width), 100vw);
  display: flex;
  flex-direction: column;
  background: var(--pxl-a11y-bg);
  color: var(--pxl-a11y-fg);
  box-shadow: var(--pxl-a11y-shadow);
  opacity: 0;
  transition: transform var(--pxl-a11y-duration) ease, opacity var(--pxl-a11y-duration) ease;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.pxl-a11y-panel[hidden] {
  display: none;
}

.pxl-a11y-panel--right {
  right: 0;
  border-radius: var(--pxl-a11y-radius) 0 0 var(--pxl-a11y-radius);
  transform: translateX(100%);
}

.pxl-a11y-panel--left {
  left: 0;
  border-radius: 0 var(--pxl-a11y-radius) var(--pxl-a11y-radius) 0;
  transform: translateX(-100%);
}

.pxl-a11y-panel--top {
  left: 0;
  height: auto;
  max-height: 80vh;
  border-radius: 0 0 var(--pxl-a11y-radius) var(--pxl-a11y-radius);
  transform: translateY(-100%);
  flex-direction: row;
}

.pxl-a11y-panel--bottom {
  left: 0;
  top: auto;
  bottom: 0;
  height: auto;
  max-height: 80vh;
  border-radius: var(--pxl-a11y-radius) var(--pxl-a11y-radius) 0 0;
  transform: translateY(100%);
  flex-direction: row;
}
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom) {
  left: 50%;
  width: max-content;
  /* Настроек стало много — без потолка ширины max-content рос бы вместе
     с их числом и вылезал за экран. flex-wrap на .pxl-a11y-panel__body
     (ниже) переносит настройки на новую строку, когда упираются в этот
     потолок, вместо горизонтального переполнения. */
  /* max-width: min(calc(100vw - 40px), 960px); */
  max-width: min(calc(100vw - 0px), 100%);
  padding-right: 200px;
  transform: translateX(-50%);
}

.pxl-a11y-panel.is-open {
  opacity: 1;
  transform: translate(0, 0);
}
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom).is-open {
  transform: translate(-50%, 0);
}

.pxl-a11y-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: none;
  padding: 16px 20px;
  border-bottom: 1px solid var(--pxl-a11y-border);
}
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom) .pxl-a11y-panel__header {
  padding-top: 0;
  padding-bottom: 0;
  margin-top: 16px;
  margin-bottom: 16px;
  border: none;
  border-right: 1px solid;
}

.pxl-a11y-panel__title {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.3;
}
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom) .pxl-a11y-panel__title {
  max-width: 120px;
}

.pxl-a11y-panel__actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: none;
}
/* top/bottom — панель горизонтальная, месту под кнопки внутри узкой шапки
   неоткуда взяться, поэтому группа целиком прибивается к правому краю
   панели и раскладывается в столбец (см. .pxl-a11y-panel__action-label). */
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom) .pxl-a11y-panel__actions {
  position: absolute;
  right: 20px;
  top: 16px;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}

:is(.pxl-a11y-panel__reset, .pxl-a11y-panel__close) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.pxl-a11y-panel__reset {
  color: #2b6cb0;
}
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom) :is(.pxl-a11y-panel__reset, .pxl-a11y-panel__close) {
  width: auto;
  height: auto;
  padding: 10px;
  border-radius: 6px;
  justify-content: flex-start;
}
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom) .pxl-a11y-panel__close {
  order: -1;
}

:is(.pxl-a11y-panel__reset, .pxl-a11y-panel__close):hover,
:is(.pxl-a11y-panel__reset, .pxl-a11y-panel__close):focus-visible {
  background: var(--pxl-a11y-border);
}

:is(.pxl-a11y-panel__reset, .pxl-a11y-panel__close):focus-visible {
  outline: 2px solid var(--pxl-a11y-accent);
  outline-offset: 2px;
}

.pxl-a11y-panel__action-label {
  display: none;
  font-size: 18px;
  line-height: 1;
  white-space: nowrap;
}
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom) .pxl-a11y-panel__action-label {
  display: inline;
}

.pxl-a11y-panel__body {
  flex: 1 1 auto;
  overflow: auto;
  padding: 20px;
}
:is(.pxl-a11y-panel--top, .pxl-a11y-panel--bottom) .pxl-a11y-panel__body {
  display: flex;
  flex-wrap: wrap;
  column-gap: 60px;
  row-gap: 24px;
  align-items: start;
}

:is(.pxl-a11y-panel--left, .pxl-a11y-panel--right) .pxl-a11y-setting + .pxl-a11y-setting {
  margin-top: 24px;
}

.pxl-a11y-setting__title {
  margin: 0 0 12px;
  font-size: 14px;
  font-weight: 600;
}

.pxl-a11y-schemes {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.pxl-a11y-scheme-swatch {
  position: relative;
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
}

.pxl-a11y-scheme-swatch__outer {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: var(--pxl-a11y-scheme-swatch-bg);
  border: 1px solid var(--pxl-a11y-scheme-swatch-fg, var(--pxl-a11y-border));
  outline: 3px solid transparent;
  outline-offset: 3px;
  box-sizing: border-box;
  transition: outline-color 0.15s ease;
}

.pxl-a11y-scheme-swatch__inner {
  width: 42%;
  height: 42%;
  border-radius: 50%;
  background-color: var(--pxl-a11y-scheme-swatch-fg);
}

.pxl-a11y-scheme-swatch__check {
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--pxl-a11y-accent);
  color: #fff;
  border: 2px solid var(--pxl-a11y-bg);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.pxl-a11y-scheme-swatch.is-selected .pxl-a11y-scheme-swatch__outer {
  outline-color: var(--pxl-a11y-scheme-bg, var(--pxl-a11y-accent));
}
.pxl-a11y-scheme-swatch--none.is-selected .pxl-a11y-scheme-swatch__outer {
  outline: none;
  border: 2px solid var(--pxl-a11y-accent);
}
.pxl-a11y-scheme-swatch--none.is-selected .pxl-a11y-scheme-swatch__outer svg {
  width: 25px;
  height: 25px;
}

.pxl-a11y-scheme-swatch.is-selected .pxl-a11y-scheme-swatch__check {
  opacity: 1;
  transform: scale(1);
}

.pxl-a11y-scheme-swatch:focus-visible .pxl-a11y-scheme-swatch__outer {
  outline-color: var(--pxl-a11y-scheme-bg, var(--pxl-a11y-accent));
  outline-style: dashed;
}

.pxl-a11y-font-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

.pxl-a11y-font-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding: 0 10px;
  border: 1px solid var(--pxl-a11y-border);
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font-size: 18px;
  font-weight: 600;
  cursor: pointer;
}

.pxl-a11y-font-btn:hover:not(:disabled) {
  background: var(--pxl-a11y-border);
}

.pxl-a11y-font-btn:focus-visible {
  outline: 2px solid var(--pxl-a11y-accent);
  outline-offset: 2px;
}

.pxl-a11y-font-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.pxl-a11y-font-value {
  /* Самый широкий вариант текста — "Обычный" (когда значение = null,
     "как на сайте"), заметно шире чисел вроде "0.02em"/"200%" — фиксируем
     ширину под него, что бы кнопки по бокам не сдвигались при смене
     значения. */
  display: inline-block;
  min-width: 72px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  white-space: nowrap;
}

.pxl-a11y-images-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.pxl-a11y-images-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--pxl-a11y-border);
  border-radius: 8px;
  background: transparent;
  cursor: pointer;
}

.pxl-a11y-images-btn:hover {
  background: var(--pxl-a11y-border);
}

.pxl-a11y-images-btn:focus-visible {
  outline: 2px solid var(--pxl-a11y-accent);
  outline-offset: 2px;
}

.pxl-a11y-images-btn svg {
  width: 30px;
  height: 30px;
  transition: width .25s, height .25s;
}

.pxl-a11y-images-btn.is-selected {
  border: 2px solid var(--pxl-a11y-accent);
}
.pxl-a11y-images-btn.is-selected svg {
  width: 100%;
  height: 100%;
}

/*
 * Ряд кнопок-переключателей — по кнопке на каждое положение (выравнивание/
 * подчёркивание/курсор/линейка/чтение с экрана), не одна кнопка с
 * несколькими состояниями. Тот же визуальный язык и структура, что и у
 * .pxl-a11y-images-row/.pxl-a11y-fontfamily-row: строка кнопок, рамка
 * var(--pxl-a11y-border) в покое, подсветка фона на hover, акцентная рамка
 * у выбранной (.is-selected) — единообразно с остальными радио-группами
 * панели (цветовая схема, изображения, шрифт).
 */
.pxl-a11y-toggle-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.pxl-a11y-toggle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--pxl-a11y-border);
  border-radius: 8px;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.pxl-a11y-toggle-btn:hover {
  background: var(--pxl-a11y-border);
}

.pxl-a11y-toggle-btn:focus-visible {
  outline: 2px solid var(--pxl-a11y-accent);
  outline-offset: 2px;
}

.pxl-a11y-toggle-btn.is-selected {
  border: 2px solid var(--pxl-a11y-accent);
}

.pxl-a11y-toggle-btn:disabled {
  opacity: 0.4;
  cursor: default;
}
.pxl-a11y-toggle-btn:disabled:hover {
  background: transparent;
}

/**
 * Окошко ассистента — Play/Pause/Стоп/Повтор рядом с выделенным текстом
 * (не в панели настроек, см. buildAssistantPopupEl() в .js). position:
 * absolute (не fixed) — координаты из getBoundingClientRect() + scrollX/
 * scrollY (см. positionAssistantPopup() в .js), окошко остаётся рядом с
 * текстом при прокрутке страницы (пересчитывается на scroll), а не висит
 * прибитым к экрану/пропадает. z-index выше самой панели (--pxl-a11y-z:
 * 9999) — окошко должно быть кликабельно поверх всего, включая панель,
 * если выделение оказалось рядом с её краем. Свой, не унаследованный от
 * .pxl-a11y-panel набор переменных фона/тени/радиуса (панель — не предок
 * этого элемента, он в <html>, а не в ней, см. её же докблок про это) —
 * с теми же значениями по умолчанию, что и у самой панели.
 */
.pxl-a11y-assistant-popup {
  position: absolute;
  z-index: 10001;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  background: var(--pxl-a11y-bg, #ffffff);
  color: var(--pxl-a11y-fg, #16181d);
  border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.22);
}
.pxl-a11y-assistant-popup[hidden] {
  display: none;
}
/* Кнопки друг под другом, с текстом справа от иконки — не квадратные
   38×38, как раньше (когда были в ряд, без подписи), а во всю ширину
   окошка. */
.pxl-a11y-assistant-popup .pxl-a11y-toggle-btn.pxl-a11y-assistant-popup__btn {
  width: auto;
  height: auto;
  justify-content: flex-start;
  gap: 10px;
  padding: 8px 14px 8px 10px;
  white-space: nowrap;
}
.pxl-a11y-assistant-popup__label {
  font-size: 14px;
}

/* Кнопки "Подчёркивание" — буква "А", сама подчёркнутая или нет (см.
   UNDERLINE_MODES в .js) — состояние видно по самой кнопке, не только по
   рамке is-selected. */
.pxl-a11y-toggle-btn--letter {
  font-size: 18px;
  font-weight: 600;
}

/*
 * Ряд кнопок «Шрифт»/«Засечки» — превью «Аа» каждым в своём font-family
 * (проставлен инлайн-стилем в .js), что бы было видно, что выбираешь.
 */
.pxl-a11y-fontfamily-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.pxl-a11y-fontfamily-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding: 0 10px;
  border: 1px solid var(--pxl-a11y-border);
  border-radius: 8px;
  background: transparent;
  color: inherit;
  font-size: 16px;
  cursor: pointer;
}

.pxl-a11y-fontfamily-btn:hover {
  background: var(--pxl-a11y-border);
}

.pxl-a11y-fontfamily-btn:focus-visible {
  outline: 2px solid var(--pxl-a11y-accent);
  outline-offset: 2px;
}

.pxl-a11y-fontfamily-btn.is-selected {
  border: 2px solid var(--pxl-a11y-accent);
}

/*
 * Отключение transition на время применения настройки (см. applyWithoutTransition
 * в .js) — один кадр, до/после все transition, включая цветовые, работают
 * штатно. Здесь именно blanket transition: none, а не точечно для
 * color/background — сайты часто вешают "transition: all", и погасить
 * в нём только пару свойств средствами CSS нельзя, не задев остальные.
 */
.pxl-a11y-no-transition,
.pxl-a11y-no-transition * {
  transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .pxl-a11y-panel {
    transition: none;
  }
}

@media (max-width: 480px) {
  .pxl-a11y-panel--left,
  .pxl-a11y-panel--right {
    width: 100vw;
    border-radius: 0;
  }
}

/**
 * Применение выбранной цветовой схемы ко всему сайту. --pxl-a11y-scheme-bg/
 * -fg и атрибут data-pxl-a11y-scheme на <html> проставляет сам виджет
 * (см. .js) при выборе схемы и при загрузке, если схема уже была выбрана
 * раньше (localStorage). body * — самый простой надёжный способ перекрасить
 * произвольный сайт без знания его разметки/классов. Панель сюда не попадает
 * в принципе — она добавляется в <html>, а не в <body> (см. buildPanel() в
 * .js), поэтому никаких исключений/защитных правил для неё здесь не нужно.
 */
html[data-pxl-a11y-scheme] body,
html[data-pxl-a11y-scheme] body * {
  background-color: var(--pxl-a11y-scheme-bg) !important;
  color: var(--pxl-a11y-scheme-fg) !important;
  border-color: var(--pxl-a11y-scheme-fg) !important;
}

html[data-pxl-a11y-scheme] a,
html[data-pxl-a11y-scheme] a * {
  color: var(--pxl-a11y-scheme-fg) !important;
}

/**
 * Подчёркивание ссылок — самостоятельная настройка (кнопка «Подчёркивание»),
 * не жёстко привязанная к цветовой схеме. Схема лишь включает разумное
 * значение по умолчанию при выборе (см. setScheme() в .js — однонаправленно,
 * без обратной связи), а дальше это обычный независимый тумблер: можно
 * выключить, не трогая саму схему, и наоборот.
 */
html.pxl-a11y-underline body a,
html.pxl-a11y-underline body a * {
  text-decoration: underline !important;
}
html.pxl-a11y-underline body a:hover,
html.pxl-a11y-underline body a:hover * {
  text-decoration: none !important;
}

/**
 * Режим "Изображения" — выключение/обесцвечивание любых медиа и фоновых
 * картинок. "Изображения" — img/picture/svg, "видео" — video/embed/iframe
 * (произвольная встроенная страница/плеер — не только <video>). Классы на
 * <html> проставляет виджет (applyImagesMode() в .js) при выборе кнопки и
 * при загрузке, если режим уже был выбран раньше. Как и у цветовой схемы,
 * скоуп body/body * — панель добавлена в <html>, а не в <body>, так что
 * дополнительно исключать её тут не нужно (и, соответственно, не нужно
 * никак пробрасывать исключение внутрь этих правил — сам виджет их не
 * увидит в принципе, а не потому что где-то стоит :not()).
 *
 * Фоновые картинки CSS не умеет находить сам (нет селектора "у элемента
 * есть background-image") — элементы с реальным фоном помечены атрибутом
 * [data-pxl-a11y-bg] один раз в JS (markBackgroundImageElements()), здесь
 * это уже просто ещё один селектор.
 *
 * OFF прячет медиа через visibility (не display/opacity) — так они
 * по-прежнему занимают место в вёрстке, просто не отрисовываются: верстка
 * не "плывёт" без своих изображений. Для фоновых картинок аналог того же
 * принципа — не сам элемент прячем (внутри него может быть текст), а только
 * его background-image, элемент и его размеры остаются как есть.
 *
 * Известное ограничение: у <iframe>/<embed> мы не управляем их содержимым
 * (это чужой документ/плагин) — CSS visibility прячет их с экрана, но не
 * гарантирует, что внутри что-то перестало играть/звучать (в отличие от
 * <video>, который виджет явно ставит на паузу, см. pauseAllVideos() в
 * .js) — общего кросс-доменного способа остановить произвольный iframe
 * (плеер YouTube, Vimeo и т.п.) не существует без интеграции с конкретным
 * провайдером, а это уже не задача портируемого зависимостей-независимого
 * виджета.
 *
 * Исключение: svg внутри <a>/<button> сюда не попадает —
 * :not(:is(a, button) *) отсекает именно такие svg (проверяется наличие
 * предка a/button у самого svg, а не у его содержимого). Это служебные
 * иконки навигации/действий (бургер, шеврон, соцсети, кнопки виджета и
 * т.п.), а не декоративный/контентный визуал вроде логотипа или картинки
 * в тексте — и у них уже есть собственная, отдельная логика перекраски:
 * цветовая схема красит body * через `color`, а иконки внутри интерактивных
 * элементов обычно рисуются `fill/stroke="currentColor"`, то есть уже
 * следуют за цветом ссылки/кнопки. Трогать их здесь ещё раз — конфликтовать
 * с этой логикой, а не дополнять её.
 */
html.pxl-a11y-images-off body img,
html.pxl-a11y-images-off body picture,
html.pxl-a11y-images-off body svg:not(:is(a, button) *),
html.pxl-a11y-images-off body video,
html.pxl-a11y-images-off body embed,
html.pxl-a11y-images-off body iframe {
  visibility: hidden;
}
html.pxl-a11y-images-off body [data-pxl-a11y-bg] {
  background-image: none !important;
}

html.pxl-a11y-images-grey body img,
html.pxl-a11y-images-grey body picture,
html.pxl-a11y-images-grey body svg:not(:is(a, button) *),
html.pxl-a11y-images-grey body video,
html.pxl-a11y-images-grey body embed,
html.pxl-a11y-images-grey body iframe,
html.pxl-a11y-images-grey body [data-pxl-a11y-bg] {
  filter: grayscale(1);
}

/**
 * Межбуквенный/межстрочный интервал — абсолютные значения (не "плюс к
 * тому, что было" — для произвольного сайта с разными line-height на
 * разных элементах это не выразить одним global-правилом), !important на
 * body * по тому же принципу, что и цветовая схема: иначе конкретные
 * правила сайта (у заголовков часто свой line-height) перебьют это по
 * специфичности. Классы включаются только когда значение не null ("как на
 * сайте") — что бы не тащить !important туда, где он не нужен.
 */
html.pxl-a11y-letter-spacing body,
html.pxl-a11y-letter-spacing body * {
  letter-spacing: var(--pxl-a11y-letter-spacing) !important;
}
html.pxl-a11y-line-height body,
html.pxl-a11y-line-height body * {
  line-height: var(--pxl-a11y-line-height) !important;
}

/**
 * Шрифт (Базовый/Arial/для дислексии) и засечки — одна CSS-переменная на
 * оба состояния сразу (computeFontFamilyValue() в .js считает, что из
 * двух побеждает: Arial/дислексия — сами по себе, засечки — только когда
 * выбран "Базовый", см. докблок в .js). Класс включается, только когда
 * итоговое значение не null ("как на сайте") — тот же принцип, что и у
 * интервалов.
 */
html.pxl-a11y-font-family body,
html.pxl-a11y-font-family body * {
  font-family: var(--pxl-a11y-font-family) !important;
}

/**
 * Выравнивание по ширине — 4 состояния (по умолчанию/лево/по ширине/право),
 * та же блочная модель, что и у интервалов/шрифта: абсолютное значение
 * !important на body * (иначе конкретные правила сайта по специфичности
 * победили бы), класс включается только когда выбрано не "по умолчанию".
 */
html.pxl-a11y-text-align body,
html.pxl-a11y-text-align body * {
  text-align: var(--pxl-a11y-text-align) !important;
}

/**
 * «Фокусирование» — усиленная обводка у элемента в фокусе с клавиатуры.
 * :focus-visible, не :focus — иначе кольцо появлялось бы при любом клике
 * мышью, а не только при Tab (тот случай, для которого эта настройка и
 * нужна: у сайта может не быть видимого фокуса вообще, ниже он просто
 * убран через outline: none). !important перебивает такие сайтовые правила
 * тем же способом, что и остальные настройки этой панели — известное
 * ограничение то же: сайтовое правило с ещё большей специфичностью и
 * тоже !important теоретически может победить, на практике редкость.
 *
 * var(--pxl-a11y-accent, #2b6cb0) — обязательно с фолбэком: сама переменная
 * объявлена на .pxl-a11y-panel, а панель вне <body> (в другой ветке дерева
 * от элементов сайта), так что без фолбэка здесь она была бы не унаследована,
 * весь outline стал бы невалидным значением и браузер отбросил бы объявление
 * целиком — обводка тихо не появлялась бы вообще. Значение фолбэка — тот же
 * дефолт, что и у самой переменной в .pxl-a11y-panel.
 */
html.pxl-a11y-enhanced-focus body :focus-visible {
  outline: 3px solid var(--pxl-a11y-accent, #2b6cb0) !important;
  outline-offset: 2px !important;
}

/**
 * «Чтение с экрана» — подсветка элемента, который сейчас озвучивается
 * (см. speakText()/handleScreenReadingClick() в .js). Снимается сама по
 * завершении/ошибке речи (onend/onerror у SpeechSynthesisUtterance) или
 * сразу же, если начали читать что-то новое / выключили режим. Тот же
 * фолбэк у --pxl-a11y-accent и по той же причине, см. блок выше.
 */
.pxl-a11y-reading {
  outline: 3px solid var(--pxl-a11y-accent, #2b6cb0) !important;
  outline-offset: 2px !important;
}

/**
 * Крупный курсор — --pxl-a11y-cursor ставит/снимает сам виджет (см.
 * applyCursorLarge() в .js), body { cursor: auto } — дефолт, когда
 * переменная не задана (обычный курсор ОС, ничего не переопределено).
 */
body {
  cursor: var(--pxl-a11y-cursor, auto);
}

/**
 * Читающая линейка — горизонтальная полупрозрачная полоса, следует за
 * курсором по вертикали (top выставляет JS на mousemove, см. applyRuler()).
 * pointer-events: none — что бы не перехватывала клики по контенту под
 * собой. Добавлена в <html>, не в <body> (как и сама панель), поэтому
 * настройки вроде "Изображения"/цветовой схемы её не задевают.
 */
.pxl-a11y-ruler {
  position: fixed;
  left: 0;
  right: 0;
  height: 40px;
  transform: translateY(-50%);
  background: rgba(255, 235, 59, 0.35);
  border-top: 2px solid rgba(255, 193, 7, 0.9);
  border-bottom: 2px solid rgba(255, 193, 7, 0.9);
  pointer-events: none;
  z-index: 10000;
}
.pxl-a11y-ruler[hidden] {
  display: none;
}

/**
 * Масштаб шрифта сайта. zoom (а не transform: scale) — не создаёт новый
 * containing block для потомков с position: fixed, поэтому не ломает,
 * например, фиксированную шапку сайта. Панель эта переменная не задевает —
 * она объявлена только на body, а панель вне <body> (см. выше).
 */
body {
  zoom: var(--pxl-a11y-font-scale, 1);
}
