# design/llms.txt — правила вёрстки opopa.top Этот файл читается перед любой работой с `src/`. Если правила нет здесь — его нет. Источник значений: `design/design.md`. Механический перенос: `src/styles/tokens.css`. ## Жёсткие запреты 1. **Ни одного литерального цвета** в `src/components`, `src/layouts`, `src/pages`. Запрещено: `#0b0c0e`, `rgb(...)`, `hsl(...)`, `white`, `black`, `slate-800`, `blue-500`. Разрешено: утилиты по нашим токенам (`bg-canvas`, `text-text-muted`, `border-border`). 2. **Ни одного магического размера.** Запрещено: `p-[13px]`, `mt-[37px]`, `text-[19px]`, `w-[420px]`, любые произвольные значения в квадратных скобках для отступов, кеглей и радиусов. Разрешено: `p-5`, `mt-7`, `text-body`, `rounded-card` — только шаги нашей шкалы. 3. **Никаких inline-стилей** (`style="..."`) кроме одного исключения: динамическая ширина полосы прогресса чтения. 4. **Никаких новых цветов.** Палитра закрыта: 4 поверхности, 3 уровня текста, iris, ember, 2 границы. Нужен новый цвет — сначала правка `design.md`, потом `tokens.css`, потом код. 5. **Никакой светлой темы и никакого переключателя тем.** Система dark-only. 6. **Белый текст на заливке-акценте запрещён.** На `iris-deep` и `ember` текст только `text-canvas`. Контраст белого там 3.71 и 2.33 — это провал WCAG AA. 7. **`font-display` ниже 28px запрещён.** Тело, навигация, подписи, кнопки — только `font-body`. 8. **`outline: none` без замены запрещён.** Фокус всегда виден: `shadow-focus`. 9. **Тени для разделения карточек запрещены.** Разделяем поверхностью и границей. 10. **Аврорная полоса** — только на главной, горизонтальной полосой 3px под навигацией, один раз на страницу. Не как заливка фона, не на странице поста. 11. **Третий акцентный цвет запрещён.** Пара iris/ember — весь словарь. 12. **Текст тише `--color-text-subtle` (`#8d929b`) запрещён.** 13. **Ссылка на `/en/` без реального перевода запрещена.** Переключатель языка и `hreflang` появляются только там, где перевод существует, иначе читатель попадает в 404. ## Как писать значения Токены объявлены один раз в `@theme static` внутри `src/styles/tokens.css`. **Принятый способ вёрстки — scoped ` ``` Tailwind-утилиты не запрещены, но в проекте не используются. Если берёте их — только по нашим токенам (`bg-card`, `text-body`), никогда чужую палитру. Единственное место с `!important` — `Prose.astro`, перекрытие фона Shiki. ## Карта: что нужно → какой токен | Нужно | Токен | |---|---| | фон страницы | `var(--color-canvas)` | | фон секции, шапки, подвала | `var(--color-surface)` | | фон карточки, врезки | `var(--color-card)` | | фон блока кода | `var(--color-code)` | | основной текст | `var(--color-text)` | | вторичный текст, лид | `var(--color-text-muted)` | | дата, метаданные, подпись | `var(--color-text-subtle)` | | ссылка, активный пункт | `var(--color-iris)` | | заливка primary-кнопки | `var(--color-iris-deep)` + текст `var(--color-canvas)` | | «Артефакт», цифры, наш вывод | `var(--color-ember)` | | подложка пилюли-тега | `var(--color-iris-wash)` / `var(--color-ember-wash)` | | декоративная граница | `var(--color-border)` | | граница кликабельного | `var(--color-border-strong)` | | скругление кнопки/тега | `var(--radius-pill)` | | скругление карточки | `var(--radius-card)` | | скругление кода/инпута | `var(--radius-code)` | | кегль текста | `var(--text-body)` + `var(--text-body--line-height)` | | кегль лида | `var(--text-lead)` | | заголовки | `var(--text-h1)`…`var(--text-h4)`, `var(--text-display)` | | шаг отступа | `var(--spacing-1)`…`var(--spacing-10)` (4/8/12/16/24/32/48/64/96/144px) | | ширина колонки текста | `var(--max-prose)` (68ch) | | ширина страницы | `var(--max-page)` (1200px) | Каждый кегль идёт в паре со своим `--text-*--line-height` и `--text-*--letter-spacing`. ## Компоненты Список закрыт. Нужен новый — сначала описать в `design.md` → Components, потом верстать. `Primary Button` · `Ghost Button` · `Post Row` · `Prose` · `Code Block` · `Artifact Block` · `Callout` · `Tag Pill` · `Header` · `Footer` · `Aurora Strip` · `Reading Progress` · `Table of Contents` · `Subscribe` · `Intent Nav` · `Month Group` · `Search` · `Feed Filter` · `Related` · `FileStat` ## Хорошо / плохо **Плохо** ```astro

{title}

{description}

``` Почему плохо: литеральные цвета, inline-стиль, магические размеры, чужая палитра Tailwind, белый текст вместо токена, кегль мимо шкалы. ## Самопроверка перед коммитом ```bash # 1. Литеральные цвета и магические px в компонентах — должно быть пусто grep -rnE '#[0-9a-fA-F]{3,8}|rgb\(|hsl\(|\[[0-9]+px\]' src/components src/layouts src/pages # 2. Inline-стили — должно быть пусто (кроме Reading Progress) grep -rn 'style="' src/components src/layouts src/pages # 3. Классы чужой палитры Tailwind — должно быть пусто grep -rnE '(bg|text|border)-(slate|gray|zinc|neutral|stone|blue|indigo|red|green)-[0-9]' src/ # 4. Сборка npm run build ``` ## Приложения - `design/design.md` — источник правды по токенам и компонентам. - `design/donors/huly-DESIGN.md` — стиль-донор (палитра, ритм, pill-геометрия). - `design/references/intercom-onboarding/` — структурный референс (композиция, микрокопирайт). Палитру оттуда НЕ брать: он light-first. - shadcn/ui llms.txt: https://ui.shadcn.com/llms.txt — берём паттерны примитивов (composition, `data-*` состояния, слоты), ставим только те React-примитивы, которые реально нужны; стили всегда переопределяются нашими токенами.