Skip to main content
Founder, Full‑stack Engineer, Architect
#Next.js 16#React 19#TypeScript#Tailwind CSS 4#shadcn/ui#FSD#PM2#MDX

django.moscow — Service Landing with Design System

Production-ready landing page with auto-generated color palettes, custom ESLint rules, and strict FSD architecture. Built a next-level design system for scalable projects.

Context

Launched a new Django support service and needed a landing page. But not just a "simple page" — a full-fledged platform for experimenting with design systems and architectural patterns. The result is a production-ready project with auto-generated color tokens, custom linters, and FSD architecture.

Live example: django.moscow

The project became a sandbox for testing advanced techniques: automatic design token generation, custom ESLint rules, strict FSD compliance. Everything that works here goes into commercial projects.

Next-Level Design System

Three-Layer Tokenization

Built a system where colors are automatically generated from config:

  1. Palettes (tokens.css) — 8 color palettes with 50-950 shades, generated from base colors via chroma-js in LCH color space
  2. Semantics (semantic.css) — contextual tokens (background, foreground, surface, text-*, link)
  3. Tailwind Mapping (theme-mapping.css) — seamless integration with utilities (bg-surface, text-foreground)
// palette.config.json
{
  "primary": { "base": "#7e102e" }
}
npm run colors:generate
# → Generates full palette: primary-50...primary-950
# → Automatically configures dark mode (reversed scale)
# → Maps to Tailwind classes

Automatic Theme Support

Themes work via data-theme attribute, not classes:

: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

Custom ESLint Plugin

Built a custom ESLint plugin to prevent hardcoded colors:

// ❌ Forbidden
<div className="bg-blue-500 text-zinc-900" />
 
// ✅ Allowed
<div className="bg-primary-500 text-foreground" />

The plugin analyzes:

  • Tailwind classes in JSX (className, class)
  • Inline styles (style)
  • CSS files via Stylelint

Result: 100% design token usage, zero "magic" colors in code.

Architecture: FSD with Boundaries

Applied strict Feature-Sliced Design with automatic boundary enforcement:

src/
├── app/         # Next.js App Router, providers, global styles
├── processes/   # Business processes (checkout, onboarding)
├── widgets/     # Large UI blocks (header, footer, hero)
├── features/    # User scenarios (theme-toggle, filters)
├── entities/    # Domain entities (user, post, order)
└── shared/      # UI primitives, utilities, config

Import Rules (enforced by ESLint):

  • features → can import entities, shared
  • featuresCANNOT import widgets, processes
  • Violation = build error

ESLint shows no mercy: trying to import a widget into a feature = red build. It's strict control, but it pays off in the long run.

Tech Stack

Next.js 16 + React 19

Used the latest versions to test new capabilities:

  • Server Components by default
  • Server Actions for forms
  • Streaming and Suspense
  • Optimized Turbopack build (in dev mode)

Tailwind CSS v4

New version with inline config directly in CSS:

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

No tailwind.config.js — everything in CSS, native and fast.

shadcn/ui Integration

Configured components.json to work with FSD:

npx shadcn@latest add button
# → Installs to src/shared/ui/
# → Integrates with design tokens
# → Ready to use

Content and SEO

MDX Blog with Validation

  • All posts in MDX with frontmatter
  • Zod schema for metadata validation
  • Automatic validation in pre-push hook
  • Separate script for CI/CD: npm run blog:validate

Full SEO Optimization

  • JSON-LD structured data (Organization, WebSite, Service)
  • Dynamic sitemap
  • robots.txt
  • Open Graph and Twitter Cards
  • Canonical URLs
const jsonLd = {
  "@context": "https://schema.org",
  "@type": "Service",
  name: "Django Support and Development",
  provider: { "@id": "https://django.moscow/#organization" },
};

Production-Ready Infrastructure

PM2 in Cluster Mode

// ecosystem.config.js
{
  name: 'django-moscow',
  instances: 'max',           // All CPU cores
  exec_mode: 'cluster',       // Cluster for zero-downtime
  autorestart: true,          // Auto-restart on crash
  max_memory_restart: '1G',   // Restart on memory limit
}

Zero-downtime deploys:

pm2 reload django-moscow  # Restart without downtime

Git Hooks for Quality

  • pre-commit: ESLint + Stylelint (blocks commit on errors)
  • pre-push: MDX posts validation (blocks push on invalid data)

Results

3 days
from idea to production
8 palettes
with auto-generated 50-950
0 hardcoded
colors in code
100%
type-safety
Typical project
django.moscow
Color management
Manual creation of each shade
Auto-generation from 1 base color
Quality control
Code review by eye
ESLint plugin + pre-commit hooks
Dark mode
Variable duplication
Automatic palette inversion
Architecture
Free structure
Strict FSD with boundaries

Lessons Learned

Token Auto-Generation = Scalability

Adding a new color to the design system is now changing 1 line in JSON and running a script. Previously — an hour of manual work.

Custom ESLint Rules Pay Off

The first 2 days I complained about the "annoying linter". A week later — appreciated the absence of questions like "why does the button have the wrong color in dark mode?".

FSD with Boundaries ≠ Bureaucracy

Strict import rules seem excessive at the start. After a month of development, you realize it's the only way to prevent the project from turning into spaghetti.

django.moscow became a testing ground for techniques I now apply in all projects: auto-generated design tokens, custom linters, strict FSD. The result is predictable, scalable, and pleasant-to-maintain code.

What's Next

  • RSS/Atom feed for blog
  • Auto-generated OG images for posts
  • Lighthouse CI in pipeline
  • A/B testing on landing
  • Design system expansion: spacing, typography, shadows