Skip to content

alt-branding

Брендбук документации ALT в одном пакете: набор System UIcons, логотипы продуктов, иконки продуктовых плиток, палитра и дизайн-токены.

Пакет собирает то, что раньше жило вразнобой: inline-SVG в каждом компоненте, hex-значения прямо в стилях, две несвязанные системы логотипов и папки с ассетами внутри темы. Один и тот же брендинг читают тема, плагин экспорта и рендер OG-картинок.

📦 Установка

bash
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: внешний хост режется или тормозит у значительной части читателей, и брендовое начертание молча подменялось системным гротеском.

ts
import '@ampernic/alt-branding/styles/fonts.css'
import '@ampernic/alt-branding/styles/tokens.css'
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, поэтому иконка наследует цвет окружения и не требует отдельной покраски под тему.

В компоненте

Каждая иконка лежит в отдельном модуле, поэтому в бандл попадает только то, на что есть ссылка.

vue
<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 указывают, когда иконка сама является управляющим элементом.

Из фронтматтера

Когда имя приходит из фронтматтера или конфига, набор сначала регистрируют, а затем обращаются к иконке по имени.

ts
// точка входа темы
import { registerIcons } from '@ampernic/alt-branding'
import * as icons from '@ampernic/alt-branding/icons'

registerIcons(icons)
yaml
---
productLink:
  icon: chevron-right
---
vue
<AltIcon :name="frontmatter.productLink.icon" :size="20" />

Реестр намеренно пуст по умолчанию: подгружать весь набор ради одного динамического обращения означало бы обесценить раздельные модули. Незарегистрированное имя ничего не рисует и печатает предупреждение в dev, исключение не бросается.

Вне Vue

Плагин экспорта и рендер OG-картинок работают на этапе сборки и получают готовую разметку строкой.

ts
import { iconSvg } from '@ampernic/alt-branding/raw'

iconSvg('chevron-right', { size: 20 })

Эта точка входа тянет весь набор намеренно: размер бандла там не важен. В браузерном коде используйте модули отдельных иконок.

Толщина обводки

Набор нарисован в одном весе, и на маленьком боксе этот вес читается легче окружающего текста. Вес задан на обёртке, а не на путях, поэтому его можно подстроить под конкретный размер, не трогая сам набор:

css
.my-inline-icon {
  --alt-icon-stroke: 1.74; /* в единицах viewBox, по умолчанию 1.52381 */
}

Каждая отрисованная иконка несёт data-icon со своим именем - этого хватает, чтобы подстроить один глиф, не задевая соседние:

css
.my-link [data-icon="chevron-right"] {
  margin-left: -9.2px;
}

Такой сдвиг нужен нечасто: шеврон сидит по центру квадратного бокса и оставляет слева заметный отступ, тогда как большинство глифов достают до краёв.

Подмена глифов хоста

VitePress и меню читаемости Nolebase рисуют собственную обвязку - шевроны, поиск, переключатель темы - маской по CSS-переменной. Импорт готового листа переводит их на этот набор, не трогая чужие компоненты:

ts
import '@ampernic/alt-branding/styles/vitepress-icons.css'
import '@ampernic/alt-branding/styles/nolebase-icons.css'

Одна тонкость касается направленных глифов. Все четыре шеврона - и все четыре стрелки - VitePress рисует одним глифом, повёрнутым через transform. Поэтому лист отдаёт всему семейству базовое начертание и оставляет поворот хосту; подмена каждого направления по отдельности повернула бы иконку дважды.

🏷 Логотипы продуктов

Иконка вместе с начертанием названия, из общего SVG-спрайта, в полноцветном (flat) и моно-инвертированном вариантах.

vue
<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)), ширина следует за начертанием названия.

🧩 Иконки продуктовых плиток

Квадратная графика для карточек и лендингов дистрибутивов: только иконка, без названия.

vue
<AltProductIcon
  slug="alt-workstation-k"
  :family-primary="registry.productFamilyPrimary"
/>

Оба варианта темы отрисовываются сразу и переключаются в CSS: вычисляемый isDark устанавливается только после гидратации, из-за чего на первой отрисовке мелькала бы неверная графика.

Редакции без собственной графики (-e2k, -p10, -practic) разрешаются в родительский продукт через PRODUCT_ICON_ALIASES. Там же снимается расхождение в именовании: во фронтматтере встречается alt-workstation-k, а файл называется alt-kworkstation.

🎨 Палитра

ts
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, а не исключение.

🎛 Дизайн-токены

ts
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.