← Портфолио

Дизайн-система

Версия 1.1 · портфолио

Дизайн-система

Единый набор токенов и компонентов сайта. Образцы собраны из тех же классов и переменных, что и сам сайт, поэтому всегда совпадают с ним.

Страница в двух частях. В первой только то, что есть на этом сайте. Во второй то, что я закладываю в системы, но здесь не использую.

Часть 1

Дизайн-система сайта

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

Основы

Цвет

Семантические роли. Тёмная и светлая тема переопределяют токены, компоненты не меняются. Распределение 60/30/10: фон, поверхности и текст, акцент.

Типографика

Две гарнитуры: Fira Sans Extra Condensed (заголовки, цифры) и Manrope (текст). Кириллица и латиница нарисованы как одна система. Все размеры в rem, заголовки текучие через clamp.

Отступы

База 4 px, ритм 8 px. Токены в rem: 1 rem = 16 px при стандартных настройках браузера. Внутреннее всегда меньше внешнего. Шкала сайта доходит до 96 px (s24); шаг 128 px вынесен во вторую часть.

Радиусы и глубина

Вложенный радиус: внешний = внутренний + отступ. Глубина сначала границей и разницей поверхностей, затем мягкой тенью.

Движение

Появление и движение только через transform и opacity; при наведении меняются заливка и цвет. Три шага длительности, один фирменный ease-out. При prefers-reduced-motion движение отключается или сводится к opacity.

Сетка и брейкпоинты

Брейкпоинты в em, чтобы макет реагировал и на размер шрифта пользователя. Поля страницы и отступ секции растут ступенями на брейкпоинтах.

Иконки и логотипы

Единая глянцевая плитка: градиент по оттенку --gh, блик сверху, цветная тень от средней точки градиента. Знаки линейные, линия 1.9, скругления round. Логотипы инструментов только официальные, без перекраски.

Анализ рынка--gh: 210
UX-гипотезы--gh: 232
Сценарии--gh: 256
Продуктовый UX/UI--gh: 282
Интерфейсы--gh: 312
Прототипы--gh: 340
Дизайн-системы--gh: 8
Разработка--gh: 34
Аргументация--gh: 168
Обратная связь--gh: 196
Команда--gh: 32
Лидерство--gh: 338
Системность--gh: 268
Процесс--gh: 214
Знак без плашки
Чёрно-белый знак на плашке

Компоненты

Кнопки

Одна главная кнопка на экран или блок. Глагол в названии, минимальная высота 44 px. Три размера.

HTML
<a class="btn" href="#">Смотреть работы <svg aria-hidden="true"><use href="#i-arrow"></use></svg></a>
<a class="btn btn--sm" href="#">Обсудить проект</a>
<a class="btn btn--xl" href="#">Написать в Telegram <svg aria-hidden="true"><use href="#i-arrow"></use></svg></a>

Состояния

У интерактивных элементов сайта три состояния: обычное, наведение и фокус; у чипа и сегмента добавляется «выбран». Кнопка белая (--ink) и при наведении заливается акцентом, стрелка сдвигается на 4 px. Состояний «нажато», «недоступно», «загрузка» и «ошибка» в интерфейсе сайта нет, их пример во второй части.

Чип

Обычное
Наведение
Выбран
Фокус

Сегмент

RU выбран, EN обычный
Фокус на EN

Иконка-кнопка

Обычное
Фокус

Ссылка

ПочтаОбычное
ПочтаНаведение: подчёркивание уходит
ПочтаФокус

Карточка инструмента

  • FigmaИнтерфейсы и прототипы
Обычное
  • FigmaИнтерфейсы и прототипы
Наведение: рамка в акцент, знак приподнимается

Состояние фокуса

Одно состояние на всю систему, второго варианта быть не должно. Кольцо 3 px цвета 20% текста (белый на тёмной теме, чёрный на светлой), отступ 4 px, повторяет форму элемента. Токены: --focus-ring, --focus-width, --focus-offset. Ряды элементов держат зазор от 32 px, чтобы кольца соседей не касались. Кольцо бледное по задаче дизайна, поэтому оно не единственный сигнал: у элементов остаётся своя подсветка.

Главная кнопка
Кнопка
Чип
Чип
Иконка-кнопка
Ссылка
Ссылка
CSS
:root { --focus-ring: color-mix(in srgb, var(--ink) 20%, transparent); --focus-width: 3px; --focus-offset: 4px; }
:focus-visible { outline: var(--focus-width) solid var(--focus-ring); outline-offset: var(--focus-offset); }
.toggle:focus-visible { outline: 0; } .toggle:focus-visible i { /* то же кольцо на дорожку */ }

Чипы, сегмент, иконка-кнопка, ссылка

Чип: фильтр работ (aria-pressed), выбранный инвертируется. Сегмент: выбор из двух (язык). Иконка-кнопка 44×44: тема. Все с видимым фокусом.

Ссылка с подчёркиванием
HTML
<button class="chip" aria-pressed="true">Все</button>
<div class="seg"><button aria-pressed="true">RU</button><button aria-pressed="false">EN</button></div>
<button class="icon-btn" aria-label="Сменить тему">…</button>
<a class="link" href="#">Почта</a>

Карточки навыка и инструмента

Карточка навыка: плитка-иконка, контурный номер, подпись. Стрелка между карточками показывает путь. Карточка инструмента: официальный знак, название, роль. При наведении рамка окрашивается акцентом на 45%, плитка и знак приподнимаются.

  • 01Анализ рынка и конкурентов
  • 02UX-гипотезы
  • FigmaИнтерфейсы и прототипы
  • MidjourneyРеференсы и арт
HTML
<li class="scard" data-dir="r">
  <span class="gt" style="--gh:210"><svg><use href="#i-search"/></svg></span>
  <span class="scard__n">01</span><span class="scard__t">Название</span>
  <span class="scard__go"><svg><use href="#i-arrow"/></svg></span>
</li>
<li class="tool"><span class="logo"><img src="…"></span><span class="tool__n">Figma</span><span class="tool__r">Роль</span></li>

Карточка работы

Обложка одного размера: 16:11 на десктопе, 4:3 на планшете и телефоне, в горизонтальной ленте на низких экранах 16:9 или 2:1, экраны нарисованы в коде и масштабируются контейнерными единицами. Вся карточка кликабельна, у курсора метка «Открыть кейс».

HTML
<article class="wcard glass" style="--h:262">
  <div class="wcard__cover"><!-- .mock --><span class="wcard__tag">iGaming</span><span class="wcard__go">Открыть кейс →</span></div>
  <div class="wcard__body"><p class="wcard__meta"><span class="wcard__ds">Дизайн-система</span></p><h3 class="wcard__title">Lumen Live</h3><p class="wcard__sum">…</p></div>
  <button class="wcard__open" data-cursor-label="Открыть кейс"></button>
</article>

Факты, путь, шаги

Крупные цифры с линией, вертикальный путь с точками и шаги процесса. Линия рисуется слева направо, шаги заполняются по мере скролла.

  • 8+лет в дизайне интерфейсов
  • 14+игр с моим участием
  1. 08.2022 – 12.2024iGaming-платформа: интерфейсы 14+ игр
  2. 02.2025 – сейчасОнлайн-беттинг: дизайн-система
  1. Уточняю задачу и ограничения
  2. Прорабатываю сценарии
  3. Собираю прототип
HTML
<ul class="metrics"><li class="metrics__line"></li><li class="metric"><span class="metric__n">8+</span><span class="metric__l">…</span></li></ul>
<ol class="timeline"><li><b>Период</b><span>Описание</span></li></ol>
<ol class="steps"><li class="step is-on">…</li></ol> <!-- is-on включается по скроллу -->

Шапка

Закреплённая, матовое стекло (blur) после 60 px скролла. Прячется при скролле вниз и возвращается при скролле вверх или при наведении к верхнему краю.

Бургер-меню

Ниже 1100 px ссылки шапки уходят в меню на весь экран. Кнопка превращается в крест, пункты выезжают по очереди, Esc закрывает, страница под меню не прокручивается. Выше 1100 px возвращаются обычные ссылки. Тема и язык остаются в шапке рядом с кнопкой.

HTML
<button class="burger" aria-expanded="false" aria-controls="menu"><span></span><span></span></button>
<div class="menu" id="menu" inert><nav class="menu__nav"><a href="#work">…</a></nav><div class="menu__foot">…</div></div>
<!-- открыто: .menu.is-open, html.menu-open блокирует прокрутку -->

Крупные заголовки

Размер = меньшее из двух: расчётный размер секции (rem + vw) и ширина колонки ÷ ширина самого длинного неразрывного слова. Слово не ломается ни на какой ширине между брейкпоинтами; ширину слова (--k) скрипт измеряет один раз при смене языка и загрузке шрифта.

Как работаю

колонка 11 rem

Как работаю

колонка 18 rem

Как работаю

колонка 28 rem: потолок 4,5 rem
CSS
.display { --h: var(--h-display); --avail: calc(100vw - 2 * var(--gutter) - 1rem);
  font-size: min(var(--h), calc(var(--avail) / var(--k, 6))); }
/* двухколоночный блок: --avail = ширина колонки */

Hero: подсказка, лента, карточки

Подсказка «Листайте»: линия растёт к слову и втягивается в него, на телефоне симметрично с двух сторон. Бегущая строка и карточки ленты в hero. Слово-заголовок обрамлено уголками видоискателя: они заданы в em от размера слова (толщина max(1px, 0.012em), длина 0.16em), поэтому следуют ему на любой ширине; при наведении сжимаются на 3% и сдвигаются за курсором. Бесконечные анимации ставятся на паузу вне экрана и отключаются при reduced motion.

Листайте

Десктоп, справа

Листайте

Телефон, по центру
8+лет в дизайне интерфейсов

Портрет

Вырезанная фигура без карточки. Три слоя. Сзади полупрозрачный дубль с сильным глитчем: рябь и вертикальное размытие. Лицо и шея резкие. Ниже шеи на одежде тот же глитч, что у дубля, но слабее: лёгкий вертикальный смаз (кожа в него не попадает). Внизу плавный уход в прозрачность по радиусу. Уголки видоискателя и векторные детали справа (линейка, пунктир, кольцо) из токенов --muted и --accent. При наведении слои сдвигаются навстречу курсору, видоискатель сжимается, кольцо растёт. На сайте показывается с 1100 px.

Артур Валеев
Артур Валеев
  • Слои: глитч-дубль (z 1, прозрачность 55%), резкая фигура (z 2), смаз на одежде (z 3, прозрачность 20%), свечение позади.
  • Глитч и смаз используют один SVG-фильтр #reeded; без поддержки остаётся плавное затухание.
  • Интерактив только для мыши, при reduced motion отключён.

Контакт, подвал, прелоадер

Крупная кнопка действия, подвал с водяным знаком (размер подгоняется под ширину) и прелоадер: имя, счётчик и линия прогресса.

Написать в Telegram

Product / UI/UX-дизайнер

62

Эффекты

Glass и курсор: все состояния

Параметры из Figma: Light −32° / 80%, Refraction 80, Depth 64, Dispersion 60, Frost 2, Splay 0. Преломление и дисперсия через SVG-фильтр (Chromium), в остальных браузерах лёгкое размытие. Один стеклянный объект на экран. Состояния курсора собраны из тех же классов, что и настоящий курсор; ниже ими можно управлять мышью. Режим выбирается по тому, что под курсором.

Попробуйте сами: проведите мышью по зонам, нажмите. Режим: наведите курсор

Пустое местоСсылка
Карточка с подписью
Кнопка

Поле точек

Сетка 2 rem, при наведении точки загораются акцентным цветом по радиусу 115–170 px (12% ширины экрана). Только в секциях с классом patterned, только для мыши.

Проведите курсором

HTML
<section class="patterned">…</section> <!-- --mx / --my выставляются из JS, подсветка в ::after -->

Слои процесса (3D)

Раздвигающиеся слои: экран, состояния, компоненты, токены. Раздвижение и поворот задаются переменной --p, слои загораются по шагам. Здесь управляется ползунком.

Правила

Доступность

  • Фокус. Кольцо 3 px цвета 20% текста, отступ 4 px, на всех интерактивных элементах (:focus-visible).
  • Цели касания. Не меньше 44×44 px: кнопки 44–48, иконка-кнопка 44, чипы 44.
  • Контраст. Основной текст ≥ 4.5:1, крупный ≥ 3:1 (проверка в таблице цвета).
  • Состояния не только цветом. Наведение меняет заливку и сдвигает стрелку, выбранный чип и сегмент инвертируются, фокус обводится кольцом.
  • Движение. Анимации под prefers-reduced-motion: no-preference (gsap.matchMedia), иначе мгновенно или только opacity.
  • Клавиатура. Skip-ссылка, диалог кейса с возвратом фокуса, Esc закрывает.

Контент

  • Висячие предлоги запрещены. Слова до трёх букв склеиваются со следующим через NBSP (функция tidy), тире не переносится. Пример ниже уже обработан функцией.
  • Два языка. Все тексты в data/i18n.json, язык в URL (?lang=) и localStorage.
  • Только реальные цифры. Факты берутся из резюме и макетов.
  • NDA. Проекты обезличены: свои названия, замена фирменной графики.

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

Лицензии

  • Шрифты: Fira Sans Extra Condensed и Manrope (Google Fonts, SIL OFL).
  • Логотипы инструментов: gilbarbara/logos и Simple Icons (CC0), товарные знаки остаются за владельцами.
  • Анимация: GSAP и ScrollTrigger. Код карточек и макетов собственный.
  • Файлы: assets/official/SOURCES.md.

Часть 2

Вне этого сайта

Примеры того, что я учитываю при разработке систем, но чего нет на страницах этого сайта. Здесь они показаны на образцах, а в первой части не значатся.

Крупный шаг отступа: 128 px

Токен --s32 есть в шкале, но на этом сайте не применяется: самый большой отступ здесь 96 px (--s24). В системе я оставляю шаг для hero и акцентных секций на высоких экранах, где нужно больше воздуха.

s2496 px · 6 rem
s32128 px · 8 rem

Колонки и ширина текста

Страницы сайта собраны из отдельных сеток под каждый блок (метрики, путь, карточки) и не держатся на единой колоночной сетке. Для плотных интерфейсов с таблицами и дашбордами я задаю одну сетку: 4 колонки на телефоне, 8 на планшете, 12 на десктопе, gutter 1 и 1.5 rem. Строка текста не шире 65 символов.

4 колонки, телефон
8 колонок, планшет
12 колонок, десктоп

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

Подсказка прокрутки: слева

Третий вариант подсказки «Листайте»: текст слева, линия справа. На сайте используются два: справа на десктопе и по центру на телефоне и планшете. Этот вариант я держу для макетов с выравниванием по левому краю.

Листайте

Слева: текст слева, линия справа

Полная матрица состояний кнопки

Пример проверки компонента из блока «Лаборатория состояний» на сайте: три характера (основная, контурная, опасная) на пять состояний, включая «недоступно» и «загрузка». Кнопки самого сайта устроены проще: они белые и при наведении заливаются акцентом.

Обычное
Наведение
Фокус
Недоступно
Загрузка
Обычное
Наведение
Фокус
Недоступно
Загрузка
Обычное
Наведение
Фокус
Недоступно
Загрузка
HTML
<button type="button" class="demo" data-state="default"><svg class="demo__lock">…</svg><span>Подтвердить</span></button>
<!-- data-state: default | hover | focus | disabled | loading -->
<!-- модификаторы: demo--ghost, demo--danger; цвет и скругление из --a и --r родителя -->

Поле и переключатель

На сайте нет полей ввода и переключателей, эти образцы показаны в «Лаборатории состояний» как пример. Фокус у поля: кольцо плюс акцентная граница. У переключателя кольцо только вокруг дорожки. Подпись у поля всегда видна, ошибка не только цветом.

Поле: кольцо и акцентная граница
Уведомления
Переключатель: только дорожка
HTML
<label class="demo-field" data-state="default"><span class="demo-field__l">Сумма депозита</span><input value="50.00"></label>
<button class="demo-toggle" role="switch" aria-checked="true" data-state="default"><i></i><span>Уведомления</span></button>