Перейти к содержанию

CSS Custom Properties — полный список

Уровень: L3 (deep-dive) | Вверх: README.md | Раздел: ../README.md

Все дизайн-токены определены в двух файлах: - frontend/src/theme/tokens.ts — сырые токены (JavaScript) - frontend/src/theme/cssVars.css — CSS Custom Properties для использования в .module.css

Префикс всех CSS-переменных: --pl- (от «Плечики»).


Цвета

Основные

Переменная Значение Назначение
--pl-color-bg #F7F4EF Фон приложения (тёплый бежевый)
--pl-color-surface #FFFDFB Фон карточек и поверхностей
--pl-color-surface-alt #F2ECE3 Альтернативный фон (поля ввода)
--pl-color-surface-overlay rgba(255, 253, 252, 0.85) Полупрозрачный фон с backdrop-blur
--pl-color-surface-inverse #1F1B16 Инверсный фон (баннер, тост)

Акцентные

Переменная Значение Назначение
--pl-color-accent #D18A62 Основной акцент (терракотовый)
--pl-color-accent-soft rgba(209, 138, 98, 0.10) Мягкий акцент (фон выделенных элементов)
--pl-color-accent-hover #C47D56 Hover-состояние акцента

Текст

Переменная Значение Назначение
--pl-color-text #1F1B16 Основной текст
--pl-color-text-secondary rgba(31, 27, 22, 0.72) Вторичный текст
--pl-color-text-muted rgba(31, 27, 22, 0.55) Приглушённый текст (подписи, meta)
--pl-color-text-inverse #FFFDFB Текст на тёмном фоне

Границы

Переменная Значение Назначение
--pl-color-border rgba(31, 27, 22, 0.08) Границы карточек, разделители

Состояния

Переменная Значение Назначение
--pl-color-success #5B8C51 Успешные операции
--pl-color-warning #D4A12A Предупреждения
--pl-color-danger #C4483F Ошибки, удаление
--pl-color-danger-soft rgba(196, 72, 63, 0.10) Мягкий фон опасных действий

Специальные

Переменная Значение Назначение
--pl-color-chip-dot #A7B29A Точка-индикатор (sage)
--pl-color-chip-dot-soft #E4EADE Мягкая точка-индикатор

Шрифты

Переменная Значение Назначение
--pl-font-display 'Funnel Sans', sans-serif Заголовки (display, pageTitle, sectionTitle)
--pl-font-body 'Geist', sans-serif Основной текст, кнопки, подписи
--pl-font-data 'Geist Mono', monospace Данные, коды

Размеры шрифтов

Переменная Значение Элементы
--pl-font-size-display 28px AuthShell заголовки
--pl-font-size-page-title 24px PageHeader заголовки
--pl-font-size-section-title 20px Секции на страницах
--pl-font-size-body 15px Основной текст, описания
--pl-font-size-caption 13px FilterChip, подписи, OfflineBanner
--pl-font-size-meta 11px MediaCard meta, теги

Отступы (spacing)

Шкала кратна 4px с шагом через 8px:

Переменная Значение Использование
--pl-space-2 8px Минимальный внутренний отступ
--pl-space-3 12px Зазоры в сетках, gap между элементами
--pl-space-4 16px Стандартный отступ (page padding)
--pl-space-5 20px Увеличенный отступ между секциями
--pl-space-6 24px Большой отступ (AuthShell padding)
--pl-space-8 32px Максимальный отступ

Скругления (border-radius)

Переменная Значение Элементы
--pl-radius-sm 16px Изображения в карточках, thumbnail
--pl-radius-md 18px Ant Design message, inputs
--pl-radius-card 22px Карточки (SharedAccessRow)
--pl-radius-sheet 28px BottomSheet, AuthShell card
--pl-radius-pill 999px Кнопки, чипы, навигация

Высоты контролов

Переменная Значение Элементы
--pl-control-height-sm 38px FilterChip
--pl-control-height-md 52px Кнопки (PrimaryButton и др.)
--pl-control-height-input 54px Поля ввода
--pl-control-height-nav 74px Нижняя навигация (высота зоны)
--pl-control-height-status-bar 62px Status bar offset
--pl-control-height-icon 52px Круглые icon buttons
--pl-control-height-header-btn 40px Кнопка «назад» в PageHeader

Layout

Переменная Значение Назначение
--pl-page-width 390px Базовая ширина (iPhone 14)
--pl-content-max-width 768px Максимальная ширина контента
--pl-page-padding 16px Горизонтальный padding страниц
--pl-screen-top-offset env(safe-area-inset-top, 0px) Отступ от верха (notch)
--pl-screen-bottom-offset calc(var(--pl-control-height-nav) + env(safe-area-inset-bottom, 0px)) Отступ снизу (nav + safe area)

Тени

Переменная Значение Элементы
--pl-shadow-soft 0 1px 3px rgba(0,0,0,0.04) Мягкая тень (back button)
--pl-shadow-card 0 2px 8px rgba(0,0,0,0.04) Тень карточек
--pl-shadow-floating 0 4px 16px rgba(0,0,0,0.08) Floating элементы (ActionIconButton)
--pl-shadow-sheet 0 -4px 24px rgba(0,0,0,0.12) BottomSheet (тень вверх)

Z-index

Переменная Значение Элемент
--pl-z-nav 100 BottomNav
--pl-z-sheet 120 BottomSheet (Drawer)
--pl-z-modal 130 Modal, Confirm
--pl-z-toast 140 UpdateAvailableToast, messages

Полный исходный код cssVars.css

:root {
  /* ── colours ── */
  --pl-color-bg: #F7F4EF;
  --pl-color-surface: #FFFDFB;
  --pl-color-surface-alt: #F2ECE3;
  --pl-color-surface-overlay: rgba(255, 253, 252, 0.85);
  --pl-color-surface-inverse: #1F1B16;

  --pl-color-accent: #D18A62;
  --pl-color-accent-soft: rgba(209, 138, 98, 0.10);
  --pl-color-accent-hover: #C47D56;

  --pl-color-text: #1F1B16;
  --pl-color-text-secondary: rgba(31, 27, 22, 0.72);
  --pl-color-text-muted: rgba(31, 27, 22, 0.55);
  --pl-color-text-inverse: #FFFDFB;

  --pl-color-border: rgba(31, 27, 22, 0.08);

  --pl-color-success: #5B8C51;
  --pl-color-warning: #D4A12A;
  --pl-color-danger: #C4483F;
  --pl-color-danger-soft: rgba(196, 72, 63, 0.10);

  --pl-color-chip-dot: #A7B29A;
  --pl-color-chip-dot-soft: #E4EADE;

  /* ── fonts ── */
  --pl-font-display: 'Funnel Sans', sans-serif;
  --pl-font-body: 'Geist', sans-serif;
  --pl-font-data: 'Geist Mono', monospace;

  --pl-font-size-display: 28px;
  --pl-font-size-page-title: 24px;
  --pl-font-size-section-title: 20px;
  --pl-font-size-body: 15px;
  --pl-font-size-caption: 13px;
  --pl-font-size-meta: 11px;

  /* ── spacing ── */
  --pl-space-2: 8px;
  --pl-space-3: 12px;
  --pl-space-4: 16px;
  --pl-space-5: 20px;
  --pl-space-6: 24px;
  --pl-space-8: 32px;

  /* ── radius ── */
  --pl-radius-sm: 16px;
  --pl-radius-md: 18px;
  --pl-radius-card: 22px;
  --pl-radius-sheet: 28px;
  --pl-radius-pill: 999px;

  /* ── control heights ── */
  --pl-control-height-sm: 38px;
  --pl-control-height-md: 52px;
  --pl-control-height-input: 54px;
  --pl-control-height-nav: 74px;
  --pl-control-height-status-bar: 62px;
  --pl-control-height-icon: 52px;
  --pl-control-height-header-btn: 40px;

  /* ── layout ── */
  --pl-page-width: 390px;
  --pl-content-max-width: 768px;
  --pl-page-padding: 16px;
  --pl-screen-top-offset: env(safe-area-inset-top, 0px);
  --pl-screen-bottom-offset: calc(var(--pl-control-height-nav) + env(safe-area-inset-bottom, 0px));

  /* ── shadows ── */
  --pl-shadow-soft: 0 1px 3px rgba(0, 0, 0, 0.04);
  --pl-shadow-card: 0 2px 8px rgba(0, 0, 0, 0.04);
  --pl-shadow-floating: 0 4px 16px rgba(0, 0, 0, 0.08);
  --pl-shadow-sheet: 0 -4px 24px rgba(0, 0, 0, 0.12);

  /* ── z-index ── */
  --pl-z-nav: 100;
  --pl-z-sheet: 120;
  --pl-z-modal: 130;
  --pl-z-toast: 140;
}

html {
  background: var(--pl-color-bg);
}

body {
  font-family: var(--pl-font-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

Полный исходный код tokens.ts

export const tokens = {
  color: {
    accent: '#D18A62',
    accentSoft: 'rgba(209, 138, 98, 0.10)',
    accentHover: '#C47D56',
    bg: '#F7F4EF',
    surface: '#FFFDFB',
    surfaceAlt: '#F2ECE3',
    surfaceOverlay: 'rgba(255, 253, 252, 0.85)',
    surfaceInverse: '#1F1B16',
    border: 'rgba(31, 27, 22, 0.08)',
    text: '#1F1B16',
    textSecondary: 'rgba(31, 27, 22, 0.72)',
    textMuted: 'rgba(31, 27, 22, 0.55)',
    textInverse: '#FFFDFB',
    success: '#5B8C51',
    warning: '#D4A12A',
    danger: '#C4483F',
    dangerSoft: 'rgba(196, 72, 63, 0.10)',
  },
  font: {
    display: "'Funnel Sans', sans-serif",
    body: "'Geist', sans-serif",
    data: "'Geist Mono', monospace",
  },
  fontSize: {
    display: '28px',
    pageTitle: '24px',
    sectionTitle: '20px',
    body: '15px',
    caption: '13px',
    meta: '11px',
  },
  fontWeight: {
    regular: 400,
    medium: 500,
    semibold: 600,
    bold: 700,
  },
  lineHeight: {
    display: 1.1,
    title: 1.15,
    body: 1.4,
    caption: 1.25,
  },
  space: {
    2: '8px',
    3: '12px',
    4: '16px',
    5: '20px',
    6: '24px',
    8: '32px',
  },
  radius: {
    sm: '16px',
    md: '18px',
    card: '22px',
    sheet: '28px',
    pill: '999px',
  },
  control: {
    sm: '38px',
    md: '52px',
    input: '54px',
    nav: '74px',
    statusBar: '62px',
    icon: '52px',
    headerButton: '40px',
  },
  layout: {
    pageWidth: '390px',
    contentMaxWidth: '768px',
    pagePadding: '16px',
  },
  shadow: {
    soft: '0 1px 3px rgba(0, 0, 0, 0.04)',
    card: '0 2px 8px rgba(0, 0, 0, 0.04)',
    floating: '0 4px 16px rgba(0, 0, 0, 0.08)',
    sheet: '0 -4px 24px rgba(0, 0, 0, 0.12)',
  },
  z: {
    nav: 100,
    sheet: 120,
    modal: 130,
    toast: 140,
  },
};