Тематизация книг на Radix Colors и CSS Tokens
Подробное руководство по системе темизации книг в проекте: Radix-шкалы 1..12, семантические токены, scoped-темы и практический workflow.
Зачем нужна отдельная система темизации книг
Когда книг становится несколько, у каждой появляется собственный визуальный характер:
- у одной акцент на «технический» холодный стиль,
- у другой — тёплый «редакционный» стиль,
- у третьей — более нейтральная учебная палитра.
Если управлять этим через точечные правки CSS-компонентов, система быстро разваливается: появляются случайные цвета, дублирование и поломки контраста.
Поэтому в проекте используется token-first подход:
- У каждой книги есть свой
theme.css. - В
theme.cssнастраиваются только переменные. - Компоненты (
prose, sidebar, TOC, header) читают только семантические токены.
Архитектура темизации в проекте
1. Где лежит тема книги
Файл темы находится рядом с контентом книги:
src/content/books/<book-id>/theme.css
Примеры:
src/content/books/effect/theme.csssrc/content/books/hexagonal-architecture/theme.css
2. Где тема применяется
На страницах книги корневой контейнер получает атрибуты:
<div data-page-kind="book" data-book-id="effect">...</div>
Тема книги навешивается через селектор:
[data-page-kind='book'][data-book-id='effect'] {
/* book tokens */
}
Это важно: тема привязана к конкретной книге и не протекает на другие разделы.
3. Как тема подключается
BaseLayout автоматически подключает theme.css книги через bookThemeHref.
Итог: при открытии страницы книги в DOM присутствуют:
- CSS-файл именно этой книги,
- корректный
data-book-idна корневом контейнере, - переменные темы доступны всем дочерним компонентам.
Профили тем в этом проекте
Чтобы книги не выглядели одинаково, у них должны быть разные профили уже на уровне шкал:
effect: холоднаяslate + cyanпалитра, более компактный ритм чтения, UI выглядит «технически».hexagonal-architecture: тёплаяsand + amberпалитра, чуть более «книжная» типографика и увеличенный вертикальный ритм.
Технически это означает, что в theme.css каждой книги отличаются минимум:
--book-gray-1..12,--book-accent-1..12,- хотя бы часть typography/layout токенов.
Почему именно Radix Colors
Radix использует шкалы 1..12:
1..2— самые фоновые значения,3..6— поверхности и границы,7..9— активные/интерактивные состояния,10..12— контрастные тексты и выделения.
Такой формат делает тему предсказуемой. Вместо «подбора отдельных hex по месту» ты настраиваешь две шкалы:
gray— нейтральная система,accent— акцентная система.
Слой 1: Scale Tokens
В теме книги задаются только шкалы:
[data-page-kind='book'][data-book-id='effect'] {
--book-gray-1: #0c1118;
--book-gray-2: #121924;
/* ... */
--book-gray-12: #e7f1ff;
--book-accent-1: #09141a;
--book-accent-2: #0d1b24;
/* ... */
--book-accent-12: #b9ecf7;
}
Слой 2: Semantic Tokens
В global.css семантика выводится из шкал:
--book-color-bg-primary: var(--book-gray-1);
--book-color-bg-secondary: var(--book-gray-2);
--book-color-bg-tertiary: var(--book-gray-3);
--book-color-bg-hover: var(--book-gray-4);
--book-color-text-primary: var(--book-gray-12);
--book-color-text-secondary: var(--book-gray-11);
--book-color-text-muted: var(--book-gray-10);
--book-color-accent: var(--book-accent-9);
--book-color-accent-hover: var(--book-accent-10);
--book-color-accent-muted: var(--book-accent-8);
--book-color-border: var(--book-gray-6);
--book-color-border-hover: var(--book-gray-7);
Плюс есть отдельные токены для типографики и layout.
Слой 3: Component Consumption
Компоненты не знают про gray-7 или accent-10.
Они используют только семантику:
--color-bg-*--color-text-*--color-accent*--color-border*
Это позволяет менять визуальный язык книги без переписывания компонентов.
Что можно настраивать кроме цветов
Система поддерживает не только палитру.
Типографика чтения
--book-prose-font-size--book-prose-line-height--book-prose-paragraph-spacing--book-prose-heading-h1-size--book-prose-heading-h2-size--book-content-title-size
Макет
--book-layout-sidebar-width--book-layout-toc-width--book-layout-header-height
Шрифты
--book-font-sans--book-font-mono
То есть у книги можно поменять не только цвет, но и «ритм» чтения.
Практический workflow для новой темы
- Скопируй существующий
theme.cssиз ближайшей по стилю книги. - Подбери
gray 1..12(сначала фон/текст, потом промежуточные ступени). - Подбери
accent 1..12(ориентируйся на link/hover/active). - Пройди страницу главы и проверь:
- sidebar,
- TOC,
- кодовые блоки,
- таблицы,
- blockquote,
- навигацию предыдущая/следующая.
- Донастрой типографику (
font-size,line-height,h1/h2).
Как проверить, что темы книг действительно разные
Минимальная проверка:
diff -u src/content/books/effect/theme.css src/content/books/hexagonal-architecture/theme.css
Если diff пустой, книги визуально будут практически одинаковыми.
Дополнительно проверь в браузере:
- Страницы двух книг должны иметь разный
data-book-idна корневом контейнере. - У каждой книги должен подгружаться свой
theme.css. - В DevTools значения
--book-accent-9и--book-gray-1должны отличаться.
Чеклист качества темы
- Текст
gray-12читается на фонеgray-1без напряжения. gray-11иgray-10различимы как secondary/muted.- Акцент
accent-9хорошо читается в inline-ссылках. - Hover (
accent-10) визуально отличается, но не «кричит». - Границы (
gray-6,gray-7) видимы, но не перегружают интерфейс. - Кодовые блоки и таблицы остаются читаемыми.
Типичные ошибки
Ошибка 1: Настройка только accent, без нейтральной шкалы
Результат: цвета «красивые», но UI остаётся случайным.
Ошибка 2: Слишком близкие gray-10/11/12
Результат: исчезает иерархия текста.
Ошибка 3: Слишком яркий accent-9
Результат: ссылки и активные элементы доминируют над контентом.
Ошибка 4: Тема определяется вне scoped-селектора книги
Результат: тема протекает на другие страницы.
Ошибка 5: theme.css у разных книг скопирован без изменений
Результат: формально файлов несколько, но визуально тема одна и та же.
Минимальный шаблон theme.css
[data-page-kind='book'][data-book-id='my-book'] {
--book-gray-1: #111113;
--book-gray-2: #18191b;
--book-gray-3: #212225;
--book-gray-4: #272a2d;
--book-gray-5: #2e3135;
--book-gray-6: #363a3f;
--book-gray-7: #43484e;
--book-gray-8: #5a6169;
--book-gray-9: #696e77;
--book-gray-10: #777b84;
--book-gray-11: #b0b4ba;
--book-gray-12: #edeef0;
--book-accent-1: #0d1520;
--book-accent-2: #111927;
--book-accent-3: #0d2847;
--book-accent-4: #003362;
--book-accent-5: #004074;
--book-accent-6: #104d87;
--book-accent-7: #205d9e;
--book-accent-8: #2870bd;
--book-accent-9: #0090ff;
--book-accent-10: #3b9eff;
--book-accent-11: #70b8ff;
--book-accent-12: #c2e6ff;
--book-prose-font-size: 16px;
--book-prose-line-height: 1.8;
--book-layout-sidebar-width: 272px;
--book-layout-toc-width: 232px;
}
Итог
Тематизация книг должна быть не «набором случайных цветов», а устойчивой системой:
- Scale tokens (Radix 1..12),
- semantic aliases,
- component-level consumption,
- scoped application по книге.
Так можно быстро создавать визуально разные книги без регрессий в читабельности и без ручного переписывания компонентов.