Design System

Все визуальные решения, токены и компоненты в одном месте. Используется дизайнерами, разработчиками и всеми, кто работает с интерфейсами oqprint.ru.

Цвета

Палитра строится на двух шкалах: Primary (синий) и Grey (нейтральный). Все цвета доступны через CSS-переменные.

Primary

100 #e2efff
200 #93cbff
300 #00a8f4
400 · base #0081bd
500 #005c89
600 #003d5e
700 #001a2b

Grey

100 #edeeee
200 #c3c7c9
300 #9ba0a3
500 #555859
600 #343637
700 #171819

Семантические токены

Токен Light Dark Использование
--bg #ffffff #171819 Фон страницы
--surface #edeeee #343637 Фон карточек, блоков
--border #c3c7c9 #555859 Границы, разделители
--text #171819 #edeeee Основной текст
--muted #555859 #9ba0a3 Второстепенный текст, подписи
--accent #0081bd #00a8f4 Ссылки, кнопки, фокус

Статусные цвета

Production Prototype In Progress Concept Error

Типографика

Шрифт — Raleway (Google Fonts). Базовый размер 16px, line-height 1.6. Все заголовки — weight 700.

Display h1 / hero
OQ Print
40px · 700 · lh 1.1
H1 page title
Заголовок страницы
32px · 700 · lh 1.2
H2 section
Раздел
24px · 700 · lh 1.2
H3 subsection
Подраздел
18.4px · 700 · lh 1.3
Body base
Основной текст интерфейса. Используется в описаниях, параграфах, формах.
16px · 400 · lh 1.6
Body sm secondary
Второстепенный текст, подписи к элементам
14px · 400 · lh 1.6
Label uppercase
Метка раздела
11.2px · 600 · ls .1em · UC
Code mono
--accent: #0081bd
14px · ui-monospace

Отступы

Шкала на базе 4px. Основные значения кратны 4 или 8.

4px
xs — иконки, зазоры внутри элементов
8px
sm — gap между inline-элементами
12px
— gap в сетках, между badge и текстом
16px
md — padding карточек, внутренние отступы
20px
— padding карточек (основной)
24px
lg — горизонтальные поля, gap секций
32px
xl — отступы внутри блоков
48px
2xl — между секциями на мобильных
64px
3xl — между секциями на десктопе
72px
— основной ритм секций
96px
4xl — крупные блоки, hero-отступы

Границы

Система без скруглений — border-radius не используется. Все границы — 1px solid.

Свойство Значение Использование
border-width 1px Единственная используемая толщина
border-style solid Всегда solid
border-color var(--border) Стандартный цвет границы
border-radius 0 Не используется — острые углы

Анимация

Минимальные, функциональные переходы. Без декоративных анимаций.

Токен Значение Использование
--duration-fast 100ms Hover опций в списке (dropdown, date-card)
--duration-base 150ms Hover кнопок, границ, триггеров — всё по умолчанию
--duration-slow 250ms Открытие/закрытие панелей, смена темы
--easing-default ease Стандартная функция — везде
--easing-in-out ease-in-out Для элементов с чётким началом и концом (chevron)
Допустимые свойства color, background, border-color, opacity, transform Только функциональные — без декоративных эффектов

Правила

Анимируй только изменения состояния (hover, focus, open, selected)
Используй transition на элементе, а не на псевдоклассе
Не используй анимации при первой загрузке страницы
Не анимируй size, width, height — дорого для браузера
Не используй bounce, elastic или длительность > 300ms для UI
/* CSS-переменные из components.css */
:root {
  --duration-fast:  100ms;
  --duration-base:  150ms;
  --duration-slow:  250ms;
  --easing-default: ease;
}

/* Применение */
.btn {
  transition: background var(--duration-base) var(--easing-default),
              border-color var(--duration-base) var(--easing-default);
}

.cd__option {
  transition: background var(--duration-fast) var(--easing-default);
}

Подключение

Все компоненты находятся в одном файле. Подключи его после base.css.

<!-- 1. Токены и базовые стили -->
<link rel="stylesheet" href="/shared/base.css">

<!-- 2. Компоненты -->
<link rel="stylesheet" href="/shared/components.css">

<!-- 3. Шрифты -->
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@400;500;600;700&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">

Кнопки

Три варианта (Primary, Secondary, Ghost) + Danger. Три размера. Нет скруглений.

Варианты

Размеры

<!-- Primary -->
<button class="btn btn--primary">Оформить заказ</button>

<!-- Secondary -->
<button class="btn btn--secondary">Подробнее</button>

<!-- Ghost -->
<button class="btn btn--ghost">Отмена</button>

<!-- Danger -->
<button class="btn btn--danger">Удалить</button>

<!-- Размеры: добавь btn--sm или btn--lg -->
<button class="btn btn--primary btn--sm">Маленькая</button>
<button class="btn btn--primary btn--lg">Большая</button>

<!-- Ширина 100% -->
<button class="btn btn--primary btn--full">Рассчитать стоимость</button>

Статусы

Используются для маркировки состояния задач, проектов, заказов.

Production Prototype In Progress Concept Error
КлассКонтекст
.badge--productionЗапущено, работает в продакшне
.badge--prototypeПрототип, тестирование
.badge--wipВ работе, ещё не завершено
.badge--conceptКонцепт, идея, не утверждено
.badge--errorОшибка, требует внимания
<span class="badge badge--production">Production</span>
<span class="badge badge--prototype">Prototype</span>
<span class="badge badge--wip">In Progress</span>
<span class="badge badge--concept">Concept</span>
<span class="badge badge--error">Error</span>

Формы

Input, Select, Label. Фокус — accent-border. Ошибки — красная граница.

Введите корректный email
До 200 символов
<!-- Поле с лейблом -->
<div class="field">
  <label class="field__label">Тираж</label>
  <input class="input" type="text" placeholder="Например, 500 шт.">
  <span class="field__hint">Минимум 50 штук</span>
</div>

<!-- Select -->
<div class="field">
  <label class="field__label">Формат</label>
  <select class="select">
    <option>A4 (210 × 297 мм)</option>
    <option>A5 (148 × 210 мм)</option>
  </select>
</div>

<!-- Ошибка -->
<div class="field">
  <label class="field__label">Email</label>
  <input class="input input--error" type="email">
  <span class="field__hint field__hint--error">Введите корректный email</span>
</div>

Карточки

Базовый блок для каталога, сервисов, списков проектов. Hover: border → accent, bg → surface.

Визитки
Офсетная печать, мелованная бумага, любой тираж от 50 шт.
Листовки
Цифровая и офсетная печать, форматы A4–A6, от 100 шт.

Правая карточка — hover-состояние

<div class="card">
  <div class="card__name">Визитки</div>
  <div class="card__desc">Офсетная печать, от 50 шт.</div>
  <div class="card__footer">
    <span class="badge badge--production">В наличии</span>
  </div>
</div>

Калькуляторы на сайте

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

Структура

БлокОписание
.calcКорневой контейнер калькулятора
.calc__titleЗаголовок — название услуги
.calc__fieldsГруппа полей выбора параметров
.calc__fieldОдно поле: лейбл + контрол
.calc__resultБлок итоговой стоимости
.calc__priceЦена — крупный акцентный текст
.calc__actionКнопка перехода к заказу

Order Form · живой прототип

Исходник: experiments/order-form/

Допустимые контролы в полях

ТипКогда использовать
selectФиксированный список значений (тираж, формат, бумага)
input[type=number]Произвольное число (тираж вручную, размер)
radio-группа2–4 варианта, нужна визуальная ясность (ламинация)
checkboxДобавочные опции (скругление, пробивка)

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

Используется для выбора даты готовности заказа. Шрифт — Roboto. Три карточки в ряд (Atom → Molecule). Цена + срок + опциональная скидка.

Состояния

4 500 За 1 час
Default
4 500 Завтра
Hover
4 500 За 1 час
Selected
3 800 11 марта −15%
With discount

Date Selection Grid — organism

4 500 За 1 час
3 800 Завтра −15%
2 900 18 марта
3 варианта
КлассОписание
.dates-gridGrid-контейнер, 3 колонки, gap: 8px
.date-cardКарточка: border 1px grey-200, flex col
.date-card.selectedВыбранная: border-color primary-400
.priceЦена: 14px, font-weight 600, grey-700
.whenСрок: 11px, grey-400
.dc-badgeСкидка: absolute, top-right, red #ef4444
<!-- Grid из 3 карточек -->
<div class="dates-grid">
  <div class="date-card selected">
    <span class="date-card__price">4 500 <span class="date-card__price-curr">₽</span></span>
    <span class="date-card__when">За 1 час</span>
  </div>
  <div class="date-card">
    <span class="date-card__price">3 800 <span class="date-card__price-curr">₽</span></span>
    <span class="date-card__when">Завтра</span>
    <span class="date-card__badge">−15%</span>
  </div>
  <div class="date-card">
    <span class="date-card__price">2 900 <span class="date-card__price-curr">₽</span></span>
    <span class="date-card__when">18 марта</span>
  </div>
</div>

Stepper

Счётчик для ручного ввода тиража. Используется когда нет фиксированных вариантов или нужен точный ввод числа.

Демо

КлассОписание
.stepperОбёртка: inline-flex, border 1px grey-200
.stepper__btnКнопки − и +, 36×36px. Hover: primary-100
.stepper__valЧисловой input, 56px, border по бокам
<div class="stepper">
  <button class="stepper__btn" onclick="this.nextElementSibling.stepDown()">−</button>
  <input class="stepper__val" type="number" value="500" min="1">
  <button class="stepper__btn" onclick="this.previousElementSibling.stepUp()">+</button>
</div>

Addon Toggle

Добавление/удаление опциональных услуг к заказу. Четыре состояния: недоступно, доступно, добавлено, удаление.

Состояния

Скругление углов недоступно
+ Ламинация матовая +320 ₽
Пробивка отверстий +180 ₽
× Пробивка отверстий Удалить

Последний — hover-состояние активного аддона

КлассСостояниеОписание
.addon--emptyНедоступноСерый фон, курсор default
.addon--addДоступноБелый фон, hover: border primary
.addon--activeДобавленоBorder primary, фон primary-50
.addon--active:hoverУдалениеBorder red, фон #fff5f5
<div class="addon addon--add">
  <span class="addon__icon">+</span>
  <span class="addon__label">Ламинация матовая</span>
  <span class="addon__price">+320 ₽</span>
</div>

<!-- Добавлено -->
<div class="addon addon--active">
  <span class="addon__icon">✓</span>
  <span class="addon__label">Ламинация матовая</span>
  <span class="addon__price">+320 ₽</span>
</div>

Сетка

CSS Grid с auto-fill. Gap — 12px стандартный, 8px плотный.

2 колонки

3 колонки

4 колонки

/* Адаптивная сетка — базовый паттерн */ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }

Контейнеры

Ширина контента ограничивается по контексту. Нет единого универсального контейнера — ширина зависит от задачи.

Имяmax-widthКонтекст
.page (demo) 900px Индексные страницы прототипов
.ds-main 880px Документация дизайн-системы
.case-container 800px Кейс-страницы портфолио
.container 1200px Основной сайт oqprint.ru / copy.spb.ru
Мобильные поля padding: 0 24px Горизонтальный padding до 600px

Changelog

История изменений дизайн-системы.

Версия Дата Изменения
1.0.0 Март 2026 Первый релиз. Foundation: цвета, типографика, отступы, границы, анимация. Components: Button, Badge, Form, Card, Custom Dropdown (5 вариантов), Date Card, Stepper, Addon Toggle. shared/components.css — единый CSS-файл.