Перейти к содержимому
Основатель, Full‑stack Engineer, Архитектор
#Next.js 16#React 19#TypeScript#Tailwind CSS 4#shadcn/ui#FSD#PM2#MDX

django.moscow — Сервисный лендинг с дизайн-системой

Production-ready лендинг с автогенерацией цветовых палитр, кастомными ESLint-правилами и строгой FSD-архитектурой. Создал дизайн-систему нового уровня для масштабируемых проектов.

Контекст

Запустил новый сервис по поддержке Django-проектов и нужен был лендинг. Но не просто «страничка», а полноценная платформа для экспериментов с дизайн-системами и архитектурными паттернами. Результат — production-ready проект с автогенерацией цветовых токенов, кастомными линтерами и FSD-архитектурой.

Живой пример: django.moscow

Проект стал sandbox'ом для отработки продвинутых техник: автоматическая генерация дизайн-токенов, кастомные ESLint-правила, строгое соблюдение FSD. Всё, что работает здесь, переношу в коммерческие проекты.

Дизайн-система нового уровня

Трёхслойная токенизация

Создал систему, где цвета генерируются автоматически из конфига:

  1. Палитры (tokens.css) — 8 цветовых палитр с оттенками 50-950, генерируются из базовых цветов через chroma-js в LCH-пространстве
  2. Семантика (semantic.css) — контекстные токены (background, foreground, surface, text-*, link)
  3. Tailwind-маппинг (theme-mapping.css) — прозрачная интеграция с утилитами (bg-surface, text-foreground)
// palette.config.json
{
  "primary": { "base": "#7e102e" }
}
npm run colors:generate
# → Генерирует полную палитру: primary-50...primary-950
# → Автоматически настраивает dark-режим (инверсия шкалы)
# → Мапит на Tailwind-классы

Автоматическая поддержка тем

Темы работают через data-theme атрибут, а не классы:

:root {
  --background: var(--color-gray-50);
  --foreground: var(--color-gray-900);
}
 
[data-theme="dark"] {
  --background: var(--color-gray-950);
  --foreground: var(--color-gray-50);
}
Next.js 16React 19TypeScriptTailwind CSS 4shadcn/uichroma-jsFSD

Кастомный ESLint плагин

Написал собственный ESLint-плагин для запрета хардкод-цветов:

// ❌ Запрещено
<div className="bg-blue-500 text-zinc-900" />
 
// ✅ Разрешено
<div className="bg-primary-500 text-foreground" />

Плагин анализирует:

  • Tailwind-классы в JSX (className, class)
  • Встроенные стили (style)
  • CSS-файлы через Stylelint

Результат: 100% использование дизайн-токенов, ноль «магических» цветов в коде.

Архитектура: FSD с границами

Применил строгое Feature-Sliced Design с автоматической проверкой границ:

src/
├── app/         # Next.js App Router, провайдеры, глобальные стили
├── processes/   # Бизнес-процессы (checkout, onboarding)
├── widgets/     # Крупные UI-блоки (header, footer, hero)
├── features/    # Пользовательские сценарии (theme-toggle, filters)
├── entities/    # Доменные сущности (user, post, order)
└── shared/      # UI-примитивы, утилиты, конфиг

Правила импортов (enforced by ESLint):

  • features → может импортить entities, shared
  • featuresНЕ может импортить widgets, processes
  • Нарушение = ошибка сборки

ESLint не прощает ошибок: попытка импортировать виджет в фичу = красная сборка. Это жёсткий контроль, но он окупается в долгосрочной перспективе.

Технологический стек

Next.js 16 + React 19

Использовал самые свежие версии для тестирования новых возможностей:

  • Server Components по умолчанию
  • Server Actions для форм
  • Streaming и Suspense
  • Оптимизированная сборка Turbopack (в dev-режиме)

Tailwind CSS v4

Новая версия с inline-конфигом прямо в CSS:

@theme inline {
  --color-primary: var(--primary);
  --color-foreground: var(--foreground);
}

Никаких tailwind.config.js — всё в CSS, нативно и быстро.

shadcn/ui интеграция

Настроил components.json для работы с FSD:

npx shadcn@latest add button
# → Устанавливается в src/shared/ui/
# → Интегрируется с дизайн-токенами
# → Готов к использованию

Контент и SEO

MDX-блог с валидацией

  • Все посты в MDX с frontmatter
  • Zod-схема для валидации метаданных
  • Автоматическая проверка в pre-push hook
  • Отдельный скрипт для CI/CD: npm run blog:validate

Полная SEO-оптимизация

  • JSON-LD structured data (Organization, WebSite, Service)
  • Динамический sitemap
  • robots.txt
  • Open Graph и Twitter Cards
  • Canonical URLs
const jsonLd = {
  "@context": "https://schema.org",
  "@type": "Service",
  name: "Поддержка и разработка Django",
  provider: { "@id": "https://django.moscow/#organization" },
};

Production-ready инфраструктура

PM2 в кластерном режиме

// ecosystem.config.js
{
  name: 'django-moscow',
  instances: 'max',           // Все CPU-ядра
  exec_mode: 'cluster',       // Кластер для zero-downtime
  autorestart: true,          // Авто-рестарт при падении
  max_memory_restart: '1G',   // Рестарт при превышении памяти
}

Zero-downtime deploys:

pm2 reload django-moscow  # Рестарт без простоя

Git hooks для качества

  • pre-commit: ESLint + Stylelint (блокирует коммит при ошибках)
  • pre-push: Валидация MDX-постов (блокирует push при невалидных данных)

Результаты

3 дня
от идеи до production
8 палитр
с авто-генерацией 50-950
0 хардкода
цветов в коде
100%
type-safety
Типичный проект
django.moscow
Управление цветами
Ручное создание каждого оттенка
Автогенерация из 1 базового цвета
Контроль качества
Code review на глаз
ESLint плагин + pre-commit hooks
Dark mode
Дублирование переменных
Автоматическая инверсия палитр
Архитектура
Свободная структура
Строгий FSD с границами

Уроки и находки

Автогенерация токенов = масштабируемость

Добавить новый цвет в дизайн-систему теперь — это изменить 1 строку в JSON и запустить скрипт. Раньше — ручная работа на час.

Кастомные ESLint-правила окупаются

Первые 2 дня ругался на «назойливый линтер». Через неделю — радовался отсутствию вопросов типа «почему у кнопки не тот цвет в dark mode?».

FSD с границами ≠ бюрократия

Строгие правила импортов кажутся избыточными на старте. Через месяц разработки понимаешь, что это единственный способ не превратить проект в спагетти.

django.moscow стал полигоном для техник, которые теперь применяю во всех проектах: автогенерация дизайн-токенов, кастомные линтеры, строгий FSD. Результат — предсказуемый, масштабируемый и приятный в поддержке код.

Что дальше

  • RSS/Atom feed для блога
  • Автогенерация OG-изображений для постов
  • Lighthouse CI в pipeline
  • A/B тесты на лендинге
  • Расширение дизайн-системы: spacing, typography, shadows

Похожие материалы

Проекты с похожими технологиями и задачами

PassWave — Генератор и хранилище паролей

Основатель, Full‑stack Engineer • 2025

Минималистичный PWA: генерирует крепкие пароли, шифрует всё на клиенте, синхронизируется по желанию. Сделал MVP за 2 недели — и оставил как есть: быстро, безопасно, без излишеств.

  • Next.js 16
  • React 19
  • TypeScript
  • Supabase
  • PWA
  • +1
Читать детальный кейс →

Slot-Me.ru — Платформа бронирования встреч

Основатель, Principal Engineer • 2025

Cal.com для русского рынка: от архитектуры до production. FastAPI + React, FSD, OAuth, календари, email, 196 тестов.

  • FastAPI
  • React
  • PostgreSQL
  • Redis
  • TypeScript
  • +3
Читать детальный кейс →

Система управления Евразийским экономическим форумом молодежи (ШОС)

Team Lead, Project Manager • 2014

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

  • Python
  • Django
  • PostgreSQL
  • JavaScript
  • jQuery
  • +1
Читать детальный кейс →