alt-branding
Брендбук документации ALT в одном пакете: набор System UIcons, логотипы продуктов, иконки продуктовых плиток, палитра и дизайн-токены.
Пакет собирает то, что раньше жило вразнобой: inline-SVG в каждом компоненте, hex-значения прямо в стилях, две несвязанные системы логотипов и папки с ассетами внутри темы. Один и тот же брендинг читают тема, плагин экспорта и рендер OG-картинок.
📦 Установка
pnpm add @ampernic/alt-brandingПакет доступен во внутреннем Forgejo-реестре:
@ampernic:registry=https://altlinux.space/api/packages/ampernic/npm/Node >= 18. Vue - опциональный peer: палитра, резолверы логотипов и строковое API иконок работают и без него.
🎨 Точки входа
Подпути разделены так, чтобы потребитель платил только за то, чем пользуется.
| Импорт | Что внутри |
|---|---|
@ampernic/alt-branding | палитра, логотипы, composables, компоненты |
@ampernic/alt-branding/icons | модули отдельных иконок, tree-shaking |
@ampernic/alt-branding/raw | строковое API всего набора, для кода вне Vue |
@ampernic/alt-branding/colors | только палитра, без Vue |
@ampernic/alt-branding/logos | спрайт логотипов и резолверы |
@ampernic/alt-branding/components | только Vue-компоненты |
@ampernic/alt-branding/styles/fonts.css | @font-face брендового шрифта |
@ampernic/alt-branding/styles/tokens.css | дизайн-токены как CSS-переменные |
@ampernic/alt-branding/styles/vitepress-icons.css | подмена собственных глифов VitePress |
@ampernic/alt-branding/styles/nolebase-icons.css | подмена глифов меню Nolebase |
🔤 Шрифт
Montserrat, начертания 400/500/600/700. Пакет везёт шрифт с собой, а не тянет его с Google Fonts: внешний хост режется или тормозит у значительной части читателей, и брендовое начертание молча подменялось системным гротеском.
import '@ampernic/alt-branding/styles/fonts.css'
import '@ampernic/alt-branding/styles/tokens.css'font-family: var(--altb-font-sans);Вариативный файл покрывает весь диапазон весов, а сабсеты разделены по unicode-range, поэтому русская страница забирает ~24 КБ кириллицы и подхватывает латиницу только там, где в тексте есть команды или листинги.
Семейство регистрируется под именем Montserrat, а не Montserrat Variable: так установленная в системе копия не может перебить пакетную и увести метрики.
Файлы шрифта - Montserrat 5.3.0 под SIL Open Font License 1.1; лицензия лежит рядом с ними в assets/fonts/OFL.txt.
🔣 Иконки
430 иконок 32×32, штриховые. Обводка рисуется currentColor, поэтому иконка наследует цвет окружения и не требует отдельной покраски под тему.
В компоненте
Каждая иконка лежит в отдельном модуле, поэтому в бандл попадает только то, на что есть ссылка.
<script setup lang="ts">
import { AltIcon } from '@ampernic/alt-branding'
import { ChevronRight, Download } from '@ampernic/alt-branding/icons'
</script>
<template>
<AltIcon :icon="ChevronRight" :size="20" />
<AltIcon :icon="Download" :size="16" label="Скачать" />
</template>Иконка без label помечается aria-hidden. Это верно для глифа рядом с собственной подписью; label указывают, когда иконка сама является управляющим элементом.
Из фронтматтера
Когда имя приходит из фронтматтера или конфига, набор сначала регистрируют, а затем обращаются к иконке по имени.
// точка входа темы
import { registerIcons } from '@ampernic/alt-branding'
import * as icons from '@ampernic/alt-branding/icons'
registerIcons(icons)---
productLink:
icon: chevron-right
---<AltIcon :name="frontmatter.productLink.icon" :size="20" />Реестр намеренно пуст по умолчанию: подгружать весь набор ради одного динамического обращения означало бы обесценить раздельные модули. Незарегистрированное имя ничего не рисует и печатает предупреждение в dev, исключение не бросается.
Вне Vue
Плагин экспорта и рендер OG-картинок работают на этапе сборки и получают готовую разметку строкой.
import { iconSvg } from '@ampernic/alt-branding/raw'
iconSvg('chevron-right', { size: 20 })Эта точка входа тянет весь набор намеренно: размер бандла там не важен. В браузерном коде используйте модули отдельных иконок.
Толщина обводки
Набор нарисован в одном весе, и на маленьком боксе этот вес читается легче окружающего текста. Вес задан на обёртке, а не на путях, поэтому его можно подстроить под конкретный размер, не трогая сам набор:
.my-inline-icon {
--alt-icon-stroke: 1.74; /* в единицах viewBox, по умолчанию 1.52381 */
}Каждая отрисованная иконка несёт data-icon со своим именем - этого хватает, чтобы подстроить один глиф, не задевая соседние:
.my-link [data-icon="chevron-right"] {
margin-left: -9.2px;
}Такой сдвиг нужен нечасто: шеврон сидит по центру квадратного бокса и оставляет слева заметный отступ, тогда как большинство глифов достают до краёв.
Подмена глифов хоста
VitePress и меню читаемости Nolebase рисуют собственную обвязку - шевроны, поиск, переключатель темы - маской по CSS-переменной. Импорт готового листа переводит их на этот набор, не трогая чужие компоненты:
import '@ampernic/alt-branding/styles/vitepress-icons.css'
import '@ampernic/alt-branding/styles/nolebase-icons.css'Одна тонкость касается направленных глифов. Все четыре шеврона - и все четыре стрелки - VitePress рисует одним глифом, повёрнутым через transform. Поэтому лист отдаёт всему семейству базовое начертание и оставляет поворот хосту; подмена каждого направления по отдельности повернула бы иконку дважды.
🏷 Логотипы продуктов
Иконка вместе с начертанием названия, из общего SVG-спрайта, в полноцветном (flat) и моно-инвертированном вариантах.
<AltLogo logo="alt-server" />
<AltLogo logo="alt-workstation-k" :aliases="registry.productBrandingKeys" />
<AltLogo logo="alt-server" force-light />Вариант выбирается по текущей теме; force-light нужен для печати и экспорта в PDF, где моно-инвертированный логотип вышел бы белым по белому. Продукты без собственного логотипа получают логотип BaseALT.
Высота задаётся через --alt-logo-height (по умолчанию clamp(76px, 14vh, 128px)), ширина следует за начертанием названия.
🧩 Иконки продуктовых плиток
Квадратная графика для карточек и лендингов дистрибутивов: только иконка, без названия.
<AltProductIcon
slug="alt-workstation-k"
:family-primary="registry.productFamilyPrimary"
/>Оба варианта темы отрисовываются сразу и переключаются в CSS: вычисляемый isDark устанавливается только после гидратации, из-за чего на первой отрисовке мелькала бы неверная графика.
Редакции без собственной графики (-e2k, -p10, -practic) разрешаются в родительский продукт через PRODUCT_ICON_ALIASES. Там же снимается расхождение в именовании: во фронтматтере встречается alt-workstation-k, а файл называется alt-kworkstation.
🎨 Палитра
import {
BASEALT_COLORS,
productColor,
productColorRgb,
} from '@ampernic/alt-branding/colors'
BASEALT_COLORS.orange // '#ff8000'
productColor('alt-orchestra') // '#664ae3'
productColorRgb('alt-orchestra') // '102, 74, 227'productColorRgb возвращает тройку без обёртки rgb(), чтобы её можно было подставить в rgba(var(--accent-rgb), .12) для полупрозрачных подложек. Неизвестный слаг возвращает оранжевый BaseALT, а не исключение.
🎛 Дизайн-токены
import '@ampernic/alt-branding/styles/tokens.css'Объявляет базовые бренд-переменные --altb-* и токены раскладки и поверхностей --ds-*, с переопределениями для тёмной темы под .dark.
Имена --ds-* сохранены как были, чтобы существующий CSS темы продолжал работать без правок. В новом коде читайте примитивы --altb-*.
Шрифтовые токены --altb-font-sans и --altb-font-mono объявляются там же; семейства для веса - --altb-weight-regular … --altb-weight-bold.