/* ==========================================================================
   00-tokens.css — единственный источник значений дизайн-системы.
   Подключается ПЕРВЫМ: всё остальное читает эти переменные, а объявить их
   надо до того, как модуль их использует… формально — не надо (кастомные
   свойства резолвятся в момент вычисления значения, а не в момент парсинга),
   но порядок «сначала словарь, потом текст» — единственный, при котором
   правку цвета ищут в одном файле, а не гриппом по четырём.

   Внутри:
     • :root — светлая тема, «сырые» OKLCH-компоненты, --radius, шрифты;
     • :root[data-theme="dark"] / body[data-theme="dark"] — тёмная тема;
     • --console-* — консоль playground'а, НАМЕРЕННО одинаковая в обеих темах;
     • --tag-* — цвета облака тегов (их читает static/js/tag-cloud.js);
     • --prism-* — палитра подсветки кода;
     • --cat-* / --oak-* — палитры пиксельных маскотов.

   ЛЕГАСИ-МОСТА (--text-color, --bg-light, --accent-color, --border-radius,
   --shadow, …) здесь БОЛЬШЕ НЕТ: он был костылём под инлайновые <style>
   старых шаблонов и снят в конце этапа 10.3 вместе с последним из них.
   Не возвращать: два имени на одну роль — это ровно тот механизм, из-за
   которого заливка кнопки однажды взяла цвет ссылки и провалила контраст
   до 2.63:1 (см. комментарий у .tag-cloud-fallback в 03-components.css).
   Новый CSS пишется на актуальных ролевых токенах из этого файла.

   Четыре нижних блока переменных (--tag-*, --prism-*, --cat-*, --oak-*)
   раньше лежали внутри своих компонентных секций blog.css. Здесь они собраны
   вместе; правила, которые их ЧИТАЮТ, остались на прежних местах —
   в 03-components.css и 04-prose.css. Перенос безопасен: каждое из этих
   свойств объявлено ровно в двух местах (светлая + тёмная тема) и больше
   нигде в проекте, поэтому объявления не могут перебить друг друга.
   ========================================================================== */

/*
 * DevDao Blog Redesign CSS
 * Replicated from a Next.js/TailwindCSS prototype.
 * Author: Gemini
 * Date: 2025-09-25
 */

/* 1. ROOT & THEME DEFINITIONS
/* ========================================================================== */

:root {
  /* Fonts */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'JetBrains Mono', monospace;

  /* Root font scale — the single source of truth for the rem-based design.
     All font-size values in this file use rem and resolve against this root
     size. Previously `body { font-size: 20px }` made body text ~20px while
     every rem value still resolved against the browser's 16px html default,
     so body copy was larger than the rest of the UI expected. Centralising
     the scale on :root keeps body text and rem components consistent. */
  font-size: 16px;

  /* «Сырые» компоненты OKLCH — три числа `L C H` без обёртки в функцию.
     Нужны везде, где цвет берётся с альфой: `oklch(var(--primary-raw) / 0.2)`.
     Записать `oklch(var(--primary) / 0.2)` нельзя: `--primary` хранит уже
     готовый цвет, подстановка даёт вложенный вызов
     `oklch(oklch(0.7 0.15 240) / 0.2)`, недопустимый по грамматике `oklch()`,
     и браузер молча отбрасывает всё объявление целиком. Готовые токены ниже
     выражены через эти же «сырые», чтобы значение оставалось в одном месте. */
  --background-raw: 0.9731 0 0; /* точный эквивалент прежнего #F6F6F6 */
  /* Светлота подобрана по минимуму, проходящему WCAG AA (4.5:1) на ВСЕХ
     поверхностях, под которыми --primary работает цветом текста. Раньше здесь
     стояло 0.53, и учитывались только карточка (#FFF, 5.05:1) и фон страницы
     (#F6F6F6, 4.67:1). Но ссылки и счётчики лежат ещё и на --muted/--secondary
     (oklch 0.95) — они СВЕТЛЕЕ карточки, и на них 0.53 давало лишь 4.37:1,
     то есть норму не проходило. Ограничение задаёт самая светлая подложка,
     поэтому светлота опущена до 0.52: этого хватает всем трём сразу. */
  --primary-raw: 0.52 0.15 240; /* #0070B5 — 5.25:1 карточка, 4.86:1 фон, 4.55:1 --muted/--secondary */
  /* Поверхность первичной кнопки — отдельный токен, а не переиспользование
     --primary. У двух ролей взаимоисключающие требования: ссылке нужен контраст
     С ФОНОМ страницы (значит, тёмный синий в светлой теме и светлый в тёмной),
     а кнопке — контраст С ТЕКСТОМ, который лежит ПОВЕРХ неё (значит, наоборот,
     тёмный синий в обеих темах). В светлой теме оба требования сходятся в одной
     точке, поэтому здесь значение совпадает с --primary; расходятся они в тёмной
     теме — см. переопределение ниже. Токен заведён и здесь, чтобы селекторы
     ссылались на одно имя и не приходилось дублировать правила по темам.
     Светлота 0.53 (а не 0.52, как у --primary) — здесь ограничение обратное:
     считается контраст с текстом ПОВЕРХ заливки, и понижать её незачем. */
  --primary-surface-raw: 0.53 0.15 240;
  /* Ховер залитой первичной кнопки — ЗАТЕМНЕНИЕ, а не альфа. Раньше ховер
     писался как `oklch(var(--primary-surface-raw) / 0.9)`, то есть кнопка
     подмешивала под себя страницу. В тёмной теме подложка тёмная и приём
     работал (6.25:1), но в СВЕТЛОЙ он кнопку осветлял: текст поверх падал с
     4.77:1 до 4.01:1 — наведение курсора выводило главную кнопку сайта из AA.
     Отдельный непрозрачный токен убирает зависимость от подложки: контраст
     ховера фиксирован и заведомо выше базового (6.63:1 в светлой, 7.19:1
     в тёмной). Для полупрозрачных ПОДЛОЖЕК-тинтов (alert-info, tag-count)
     этот токен не нужен — там альфа по-прежнему уместна. */
  --primary-surface-hover-raw: 0.45 0.15 240;
  --primary-foreground-raw: 0.98 0.01 240;
  --destructive-raw: 0.577 0.245 27.325;
  /* Красный как ЦВЕТ ТЕКСТА (.form-errors, .btn-outline-danger). Отдельно от
     --destructive по той же причине, что и --primary-surface: --destructive
     подобран как заливка (белый текст поверх неё), и в роли текста он даёт
     ~4.4:1 на фоне страницы — норму 4.5:1 не проходит. L=0.50 опускает светлоту
     до запаса: 5.96:1 на карточке, 5.5:1 на фоне. Заливку им красить нельзя —
     белый текст на ней просядет. */
  --destructive-text: oklch(0.5 0.245 27.325);
  /* Зелёный как ЦВЕТ ТЕКСТА («Прочитано», «Задание решено», «Серия завершена»)
     и как тинт-подложка успеха. Роль полностью симметрична --destructive-text,
     поэтому и токен заведён по его образцу. Раньше вместо него по шаблонам был
     рассыпан бутстраповский хардкод #198754: на фоне страницы он давал 4.19:1
     (норма 4.5), а плашка `rgba(25,135,84,.12)` под ним — 3.89:1, то есть
     подтверждение выполненного задания читалось хуже обычного текста.
     L=0.50 даёт 5.65:1 на карточке, 5.23:1 на фоне, 4.77:1 на своём же тинте.
     «Сырой» вариант нужен для тинта: `oklch(var(--success-text-raw) / 0.12)`. */
  --success-text-raw: 0.5 0.13 150;
  --success-text: oklch(var(--success-text-raw));

  /* Зелёный как ЗАЛИВКА (.btn-success — кнопка «Прочитано» в главе курса,
     .badge--success). Отдельно от --success-text ровно по той же причине, что
     --primary-surface отделён от --primary: у текста и у подложки требования
     направлены в разные стороны. --success-text подобран так, чтобы читаться
     НА светлой карточке (L=0.50 в светлой теме, L=0.72 в тёмной); залей им
     кнопку — в тёмной теме почти белый текст поверх L=0.72 даст ~2.2:1.
     Заливке нужен контраст с текстом ПОВЕРХ неё, и он одинаков в обеих темах,
     поэтому токен объявлен ОДИН раз и в тёмном блоке не переопределяется:
     4.91:1 в светлой теме, 4.88:1 в тёмной, и при этом 3.91:1 к тёмной
     карточке — кнопку видно, она не сливается с фоном (норма 3:1, SC 1.4.11).
     Ховер — затемнение непрозрачным токеном, НЕ альфа: альфа подмешивает
     подложку и в светлой теме осветляет кнопку, роняя текст ниже AA (ровно та
     история, что описана у --primary-surface-hover-raw). 6.61:1 / 6.56:1. */
  --success-surface-raw: 0.52 0.13 150;
  --success-surface: oklch(var(--success-surface-raw));
  --success-surface-hover-raw: 0.45 0.13 150;
  --success-surface-hover: oklch(var(--success-surface-hover-raw));
  /* Текст поверх зелёной заливки. Чистый белый, а не --primary-foreground:
     тот слегка голубой (H=240) и на зелёном читается как грязный оттенок. */
  --success-foreground: oklch(1 0 0);

  /* Ховер красной заливки (.btn-danger:hover). Раньше писался как
     `oklch(var(--destructive-raw) / 0.9)` — та же альфа, что уже подвела
     --primary-surface: в СВЕТЛОЙ теме кнопка подмешивала под себя белую
     страницу и белый текст поверх падал с 4.77:1 до 3.54:1, то есть наведение
     курсора выводило кнопку «Удалить» из AA. Непрозрачное затемнение
     фиксирует контраст независимо от подложки: 5.98:1 в обеих темах
     (заливка --destructive одинакова в светлой и тёмной, поэтому и ховер
     объявлен один раз). */
  --destructive-hover-raw: 0.5 0.245 27.325;
  --destructive-hover: oklch(var(--destructive-hover-raw));

  /* Жёлтый/янтарный — предупреждение (.btn-warning, .alert-warning,
     кнопка «В избранное» на странице статьи). Раньше по 03-components.css был
     рассыпан хардкод #f39c12 / #e67e22: он не реагировал на тему и в ТЁМНОЙ
     давал 1.90:1 с текстом --foreground поверх — кнопка была нечитаема.
     Янтарь устроен иначе, чем синий и зелёный: он сам по себе светлый, поэтому
     текст на нём ТЁМНЫЙ, и это верно в обеих темах. Отсюда:
       • --warning-surface одна на обе темы (8.85:1 с --warning-foreground);
       • --warning-foreground — тёмные чернила, в тёмном блоке НЕ
         переопределяются: сделай их светлыми, и контраст рухнет;
       • --warning-text — янтарь в роли ЦВЕТА ТЕКСТА (.btn-outline-warning),
         вот он от темы зависит и переопределяется ниже.
     Отдельная оговорка про границу: янтарная заливка на белой карточке даёт
     всего 2.05:1, то есть сама по себе кнопку не очерчивает (норма 3:1).
     Поэтому у warning-кнопок рамка красится в --warning-text: в светлой теме
     это тёмный янтарь (5.14:1 к карточке) и он даёт видимый контур; в тёмной
     теме контур не нужен — там сама заливка даёт 9.88:1. */
  --warning-surface-raw: 0.78 0.16 75;
  --warning-surface: oklch(var(--warning-surface-raw));
  --warning-surface-hover-raw: 0.7 0.16 75;
  --warning-surface-hover: oklch(var(--warning-surface-hover-raw));
  --warning-foreground: oklch(0.2 0.03 75);
  --warning-text-raw: 0.54 0.13 75;
  --warning-text: oklch(var(--warning-text-raw));

  /* Фирменные цвета соцсетей в подвале (.social-link.<сеть>:hover).
     Раньше это были брендовые хардкоды #1da1f2 / #0088cc / #ff6600 / #333,
     одинаковые в обеих темах. На светлом подвале (градиент --card → --muted,
     худший стоп — белый) они давали 2.83 / 3.89 / 2.94:1 — ниже AA; чёрный
     #333 в ТЁМНОЙ теме давал 1.60:1, то есть наведение курсора ссылку почти
     гасило. Токены сохраняют узнаваемый оттенок каждой сети, но подбирают
     светлоту под тему: в светлой — тёмные версии (≥4.77:1 к обоим стопам
     градиента), в тёмной — светлые (≥9.26:1). Правила, которые их читают,
     лежат в 03-components.css (перекрывают базовые из 02-layout.css). */
  --social-github: oklch(0.3 0 0);
  --social-twitter: oklch(0.52 0.16 250);
  --social-telegram: oklch(0.5 0.14 235);
  --social-rss: oklch(0.53 0.16 50);

  /* ВКонтакте — единственная соцсеть, которая живёт не ссылкой в подвале, а
     ЗАЛИВКОЙ кнопки входа (.vk-btn на login.html / register.html). Отсюда два
     отличия от четырёх токенов выше.

     Первое: пара токенов вместо одного. У ссылки состояний нет, у кнопки есть
     покой и ховер, и обоим нужен свой замер.

     Второе — и это главное — они НЕ переопределяются в тёмном блоке, хотя
     четыре токена выше переопределяются. Причина ровно та же, по которой не
     переопределяются --success-surface / --warning-surface (см. развёрнутый
     комментарий там): у заливки требование одно — контраст с текстом ПОВЕРХ
     неё, а текст на кнопке свой собственный (--primary-foreground, светлый в
     обеих темах). Тема страницы на эту пару не влияет, поэтому и значение одно.
     Не «забыли добавить в тёмную тему» — добавлять нечего.

     Что было до токенов: хардкод #0077FF (фирменный синий VK) с белым текстом
     давал 4.13:1 при норме 4.5:1 для обычного текста, и хардкод не реагировал
     на смену темы. Шрифт кнопки 0.9375rem / 500 — это обычный текст, послабление
     для крупного (3:1) не применяется. Отдельным курьёзом ховер #005FCC давал
     5.98:1, то есть кнопка читалась ХУЖЕ в покое, чем под курсором.

     Как подобрано. Тон 258 — точный тон бренда: #0077FF в oklch это
     0.597 0.221 258. Тон и максимальная насыщенность сохранены, подвинута
     только светлота — синий остаётся узнаваемо «вэкашным».
       --social-vk       oklch(0.49 0.182 258) = #005AC4 — 6.08:1 с текстом;
       --social-vk-hover oklch(0.54 0.200 258) = #0067DF — 4.92:1 с текстом.
     Хроматы 0.182 и 0.200 — это МАКСИМУМ, влезающий в sRGB при данной светлоте
     на тоне 258 (граница гамута здесь идёт по чистому синему). Значения взяты
     внутригамутные намеренно: заявишь 0.20 при L=0.49 — браузер применит своё
     gamut mapping, и отрендерится не то, что замерено.

     Почему ховер СВЕТЛЕЕ покоя, хотя --primary-surface-hover наоборот темнее.
     На залитой кнопке со светлым текстом «темнее» означает «читабельнее».
     Затемнять на ховере — значит держать кнопку наименее читаемой ровно в том
     состоянии, в котором пользователь проводит почти всё время, и повторять
     исходный дефект в мягкой форме. Поэтому покой здесь — самый тёмный и самый
     контрастный вариант (6.08:1), а ховер делает шаг ОБРАТНО к брендовому
     #0077FF (4.92:1, запас к норме сохранён). Покой не хуже ховера — как и
     требовалось. Побочная выгода в тёмной теме: заливка ховера уходит ОТ тёмной
     карточки (3.15:1 → 3.89:1), а не к ней, то есть граница кнопки на ховере
     становится чётче, а не размывается. */
  --social-vk: oklch(0.49 0.182 258);
  --social-vk-hover: oklch(0.54 0.2 258);

  /* Консоль playground'а (.tut-pg-console) — НАМЕРЕННО тёмная в обеих темах,
     поэтому объявлена один раз и в тёмном блоке НЕ переопределяется.
     Причина не в лени: строки консоли красятся акцентами (#ffc107 warn,
     #ff6b6b error, #4dabf7 info), подобранными под тёмную плашку — на ней они
     дают 10.2:1 / 6.0:1 / 6.7:1. Сделай плашку светлой в светлой теме — те же
     акценты упадут до 1.4–2.1:1. Это терминал: он тёмный всегда, как и белый
     iframe предпросмотра рядом (там страница студента, она ожидает белый лист).
     Держать их в токенах, а не в хардкодах, нужно ради одного: чтобы правка
     цвета консоли была правкой в одном месте, а не поиском по шаблонам. */
  --console-bg: oklch(0.22 0 0);
  --console-fg: oklch(0.93 0 0);
  --console-border: oklch(0.35 0 0);

  /* Light Theme Palette (interpreted from dark theme) */
  --background: oklch(var(--background-raw));
  --foreground: oklch(0.1 0.01 240);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.1 0.01 240);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.1 0.01 240);
  --primary: oklch(var(--primary-raw));
  --primary-surface: oklch(var(--primary-surface-raw));
  /* Текст НА --primary-surface: 4.77:1 — проходит AA для основного текста;
     на --primary-surface-hover 6.63:1. */
  --primary-surface-hover: oklch(var(--primary-surface-hover-raw));
  --primary-foreground: oklch(var(--primary-foreground-raw));
  --secondary: oklch(0.95 0.01 240);
  --secondary-foreground: oklch(0.2 0.01 240);
  --muted: oklch(0.95 0.01 240);
  --muted-foreground: oklch(0.45 0.01 240);
  --accent: oklch(0.97 0.01 240);
  --accent-foreground: oklch(0.15 0.01 240);
  --destructive: oklch(var(--destructive-raw));
  --destructive-foreground: oklch(0.98 0.01 240);
  /* Декоративные разделители: контраст к карточке 1.35:1 — для линий-украшений
     это нормально, но для границ UI-компонентов норма 3:1, см.
     --border-interactive ниже. */
  --border: oklch(0.9 0.01 240);
  --input: oklch(0.9 0.01 240);
  /* Границы интерактивных элементов (поля ввода, outline-кнопки):
     контраст 3.94:1 к белой карточке — проходит WCAG 2.1 AA для non-text. */
  --border-interactive: oklch(0.6 0.01 240);
  --ring: var(--primary);
  --radius: 0.75rem;
}

/*
 * Dark theme variables are scoped to the document element (:root === <html>)
 * instead of <body>. The anti-flicker inline script in <head> sets
 * data-theme on documentElement synchronously before first paint, so the
 * dark palette is in place before <body> is rendered. Scoping to <body>
 * caused a white->black flash on navigation because document.body is null
 * while the script runs in <head>, so the attribute only landed at
 * DOMContentLoaded (after the deferred scripts at the end of <body>).
 * body[data-theme="dark"] is kept as a redundant fallback.
 */
:root[data-theme="dark"],
body[data-theme="dark"] {
  /* «Сырые» компоненты тёмной темы. Светлота --primary здесь не менялась:
     на тёмной карточке этот синий даёт 7.73:1 и уже проходит AA. */
  --background-raw: 0.08 0 0;
  --primary-raw: 0.7 0.15 240;
  /* Здесь роли ссылки и кнопки расходятся, и одним значением их не покрыть.
     Светлый --primary (L=0.70) отлично читается как ссылка на тёмном фоне
     (7.73:1), но если залить им кнопку, почти белый --primary-foreground
     поверх даёт всего 2.27:1 при норме 4.5:1 — грубый провал. Поэтому у
     заливки своя, более тёмная светлота: #006AAF даёт 5.38:1 белому тексту
     поверх и при этом сам остаётся отличим от карточки (3.56:1 — норма 3:1
     для границ UI-компонентов), то есть кнопка не сливается с фоном. */
  --primary-surface-raw: 0.5 0.15 240;
  /* Ховер и здесь через затемнение — тем же токеном, что и в светлой теме,
     чтобы правила не пришлось дублировать по темам. 0.43 даёт тексту поверх
     7.19:1. Оговорка: сама ховер-поверхность отличается от тёмной карточки
     лишь на 2.66:1, то есть ниже 3:1 из SC 1.4.11. Это осознанно: норма 3:1
     нужна, чтобы компонент можно было НАЙТИ на фоне, а в покое кнопка даёт
     3.56:1 и находится; ховер — производное состояние под уже наведённым
     курсором, и его задача только быть заметно отличимым от покоя. */
  --primary-surface-hover-raw: 0.43 0.15 240;
  /* Поднято с 0.95: на --primary-surface нужен максимум светлоты, чтобы выйти
     на 5.38:1. Используется и с альфой (подложка счётчика в тегах). */
  --primary-foreground-raw: 0.98 0 0;
  --destructive-raw: 0.577 0.245 27.325;

  /* Dark Theme Palette (from redesign file) */
  --background: oklch(var(--background-raw));
  --foreground: oklch(0.95 0 0);
  --card: oklch(0.12 0 0);
  --card-foreground: oklch(0.95 0 0);
  --popover: oklch(0.12 0 0);
  --popover-foreground: oklch(0.95 0 0);
  --primary: oklch(var(--primary-raw));
  --primary-surface: oklch(var(--primary-surface-raw));
  --primary-surface-hover: oklch(var(--primary-surface-hover-raw));
  --primary-foreground: oklch(var(--primary-foreground-raw));
  --secondary: oklch(0.18 0 0);
  --secondary-foreground: oklch(0.85 0 0);
  --muted: oklch(0.15 0 0);
  --muted-foreground: oklch(0.65 0 0);
  --accent: oklch(0.2 0 0);
  --accent-foreground: oklch(0.95 0 0);
  --destructive: oklch(var(--destructive-raw));
  /* Поднято с 0.95: на --destructive тот давал ~4.2:1 — ниже нормы 4.5:1.
     0.99 выводит на 4.63:1. Выше поднимать некуда: 1.0 — уже чистый белый. */
  --destructive-foreground: oklch(0.99 0 0);
  /* Тёмная тема требует более СВЕТЛОГО красного для текста, чем светлая (там
     0.50), — направление контраста обратное. Отсюда переопределение:
     5.36:1 на карточке, 5.49:1 на фоне. */
  --destructive-text: oklch(0.64 0.245 27.325);
  /* Зелёный текста — по той же логике, что и красный выше: в тёмной теме он
     должен быть СВЕТЛЕЕ, чем в светлой (0.50), иначе контраст идёт в минус.
     0.72 даёт 8.69:1 на карточке и 7.53:1 на собственном тинте.
     --console-* здесь намеренно НЕ переопределяются: см. комментарий в :root. */
  --success-text-raw: 0.72 0.15 150;
  --success-text: oklch(var(--success-text-raw));
  /* --success-surface / --warning-surface / --destructive-hover здесь
     НЕ переопределяются намеренно: это заливки, а у заливки требование одно —
     контраст с текстом ПОВЕРХ неё, и оно не зависит от темы страницы.
     См. развёрнутое объяснение в :root. Переопределяется только янтарь
     в роли текста — у него направление контраста, как у --success-text. */
  --warning-text-raw: 0.78 0.14 75;
  --warning-text: oklch(var(--warning-text-raw));
  /* Соцсети: на тёмном подвале нужны СВЕТЛЫЕ версии брендовых оттенков.
     --social-vk / --social-vk-hover здесь НАМЕРЕННО отсутствуют: это не цвет
     ссылки на подвале, а заливка кнопки со своим светлым текстом поверх, и от
     темы страницы она не зависит — см. объяснение в :root. */
  --social-github: oklch(0.92 0 0);
  --social-twitter: oklch(0.78 0.13 250);
  --social-telegram: oklch(0.78 0.12 235);
  --social-rss: oklch(0.78 0.15 50);
  --border: oklch(0.2 0 0);
  --input: oklch(0.15 0 0);
  /* 3.4:1 к тёмной карточке oklch(0.12) — норма 3:1 для UI-компонентов. */
  --border-interactive: oklch(0.5 0 0);
  --ring: var(--primary);

  /* Keep native UI (scrollbars, form controls) consistent with the theme
     so they don't flash a light style before the body attribute lands. */
  color-scheme: dark;
}

:root[data-theme="light"],
body[data-theme="light"] {
  color-scheme: light;
}

/* --------------------------------------------------------------------------
   Цвета облака тегов. Переехали сюда из компонентной секции «Tag cloud»
   (blog.css:2356). Их читает не только CSS, но и static/js/tag-cloud.js —
   через getComputedStyle(document.body), поэтому объявления обязаны остаться
   на body/:root и меняться вместе с data-theme.
   -------------------------------------------------------------------------- */
/* Tag cloud colors for different themes */
body[data-theme="light"] {
  --tag-text-color: #3498db;
  --tag-outline-color: #2c3e50;
}

body[data-theme="dark"] {
  --tag-text-color: #2ecc71;
  --tag-outline-color: #34495e;
}

/* --------------------------------------------------------------------------
   Палитра Prism, привязанная к теме сайта. Переехала сюда из секции
   «CODE SYNTAX HIGHLIGHTING» (blog.css:2637). Сами правила, которые эти
   переменные читают (:root .token.*), остались в 04-prose.css — там же
   лежит развёрнутое объяснение, почему у них префикс :root.
   Светлые значения совпадают с дефолтной темой Prism 1.29.0, тёмные —
   собственные; ОС-медиазапрос prefers-color-scheme здесь не используется
   намеренно: тема сайта живёт в localStorage и выражена data-theme.
   -------------------------------------------------------------------------- */
:root {
  /* Значения светлой темы совпадают с дефолтной темой Prism 1.29.0 —
     светлый вид кода не меняется. */
  --prism-bg: #f5f2f0;
  --prism-fg: oklch(0.1 0.01 240);
  --prism-text-shadow: 0 1px white;
  --prism-comment: slategray;
  --prism-punctuation: #999;
  --prism-property: #905;
  --prism-string: #690;
  --prism-operator: #9a6e3a;
  --prism-operator-bg: hsla(0, 0%, 100%, 0.5);
  --prism-keyword: #07a;
  --prism-function: #dd4a68;
  --prism-variable: #e90;
  --prism-selection-bg: #b3d4fc;
}

:root[data-theme="dark"],
body[data-theme="dark"] {
  --prism-bg: var(--muted);
  --prism-fg: oklch(0.85 0 0);
  --prism-text-shadow: none;
  --prism-comment: #7c7c7c;
  --prism-punctuation: #ccc;
  --prism-property: #f08d49;
  --prism-string: #7ec699;
  --prism-operator: #67cdcc;
  --prism-operator-bg: transparent;
  --prism-keyword: #cc99cd;
  --prism-function: #f8c555;
  --prism-variable: #e2777a;
  --prism-selection-bg: oklch(0.3 0.05 240);
}

/* --------------------------------------------------------------------------
   Палитра пиксельного кота-маскота. Переехала сюда из секции «Pixel cat
   mascot» (blog.css:3203); сами .pixel-cat / .pc-* остались в
   03-components.css.
   -------------------------------------------------------------------------- */
:root {
  --cat-fur: #f0a868;   /* ginger body            */
  --cat-ear: #ffc0cf;   /* inner ears + nose      */
  --cat-eye: #2b2b3a;   /* accessories (Zzz, ?, magnifier) */
  --cat-iris: #2e7d32;  /* green irises           */
  --cat-blush: #ff9aa8; /* cheeks                 */
}

body[data-theme="dark"] {
  --cat-fur: #c98a4a;   /* deep ginger — toned down for dark bg */
  --cat-ear: #d98aa0;   /* muted inner ears + nose */
  --cat-eye: #f4f4f8;   /* light accessories so they read on dark fur */
  --cat-iris: #4a9d4a;  /* toned green irises (less neon than #5cb85c) */
  --cat-blush: #e07a8c; /* muted cheeks */
}

/* --------------------------------------------------------------------------
   Палитра пиксельного дуба — напарника кота в шапке. Переехала сюда из
   секции «Pixel oak tree» (blog.css:3239); правила .pixel-oak / .po-*
   остались в 03-components.css. Тёмная тема поднимает зелёный, иначе крона
   сливается с тёмным фоном.
   -------------------------------------------------------------------------- */
:root {
  --oak-leaf:   #4a8a3a; /* deep green canopy        */
  --oak-leaf2:  #5fa84a; /* canopy highlight         */
  --oak-trunk:  #7a5230; /* brown trunk + roots      */
  --oak-trunk2: #9a6a40; /* trunk highlight          */
}

body[data-theme="dark"] {
  --oak-leaf:   #5fa84a; /* lifted green for dark bg */
  --oak-leaf2:  #74c25c;
  --oak-trunk:  #9a6a40;
  --oak-trunk2: #b58658;
}
