diff --git a/_blueprint/plan-draft.md b/_blueprint/plan-draft.md
new file mode 100644
index 0000000..dbe34b7
--- /dev/null
+++ b/_blueprint/plan-draft.md
@@ -0,0 +1,510 @@
+# План: Django микросайт для генерации гипно-SVG
+
+## Стек
+- **Django 5.x** — бэкенд
+- **HTMX** — интерактивность без перезагрузки
+- **Pillow** — обработка изображений, color clustering
+- **scikit-learn** — k-means для дуотон/трейтон/квантование
+- **numpy** — векторизованные вычисления
+- **Gunicorn** — WSGI-сервер
+- **Poetry** — управление зависимостями
+
+## Структура проекта (как в cadpoint-ru)
+
+```
+2026-hypn0-site/
+├── pyproject.toml # Poetry — общие зависимости
+├── poetry.lock
+├── .env.sample # Переменные окружения
+├── .env # Локальные секреты (не в VCS)
+├── Dockerfile # Многостадийная сборка
+├── docker-compose.local.yml # Dev: bind-mount, --reload
+├── docker-compose.prod.yml # Prod: образ из registry
+│
+├── config/
+│ └── nginx/ # Nginx-конфиги (хост, не в Docker)
+│ └── hypn0-app--external-nginx.conf
+│
+├── public/ # Статика + медиа (shared dev/prod)
+│ ├── static/
+│ │ ├── css/
+│ │ │ └── site.css # Tailwind CDN + кастомные стили
+│ │ └── js/
+│ │ └── site.js # Alpine/минимальный JS
+│ └── media/
+│ ├── temp/ # Публичные SVG (TTL 14 дней)
+│ └── gallery/ # Отфильтрованные лучшие
+│
+├── database/ # SQLite БД
+│ └── .gitignore
+│
+├── hypn0/ # Django project root
+│ ├── manage.py
+│ ├── hypn0/ # Settings package
+│ │ ├── __init__.py
+│ │ ├── settings.py # django-environ для конфига
+│ │ ├── urls.py
+│ │ ├── wsgi.py
+│ │ └── templates/
+│ │ ├── base.html
+│ │ └── errors/
+│ │ ├── 404.html
+│ │ └── 500.html
+│ │
+│ └── halftone/ # Django app
+│ ├── __init__.py
+│ ├── urls.py
+│ ├── views.py # главная + генерация
+│ ├── forms.py # формы параметров
+│ ├── models.py # FeaturedSVG + votes
+│ ├── services/
+│ │ ├── __init__.py
+│ │ └── halftone.py # ядро из main.py
+│ ├── templates/
+│ │ └── halftone/
+│ │ └── index.html
+│ └── management/
+│ └── commands/
+│ ├── cleanup_temp.py # очистка temp (14 дней)
+│ └── cleanup_reports.py # удаление по жалобам
+│
+├── .gitea/workflows/ # CI/CD
+│ └── docker-publish.yaml
+│
+└── main.py # [удаляем]
+```
+
+## Ключевые принципы (перенос из cadpoint-ru)
+
+| Принцип | Реализация |
+|---------------|------------------------------------------|
+| Django-проект | `hypn0/` — подкаталог в корне |
+| Статика/медиа | `public/static/` и `public/media/` |
+| БД | `database/db.sqlite3` |
+| Конфиги | `config/nginx/` — внешний nginx |
+| Docker | многостадийный, bind-mount для dev |
+| Зависимости | Poetry, `pyproject.toml` в корне |
+| Env | `django-environ`, `.env.sample` → `.env` |
+
+## Архитектура приложения
+
+### 1. Рефакторинг ядра (`hypn0/halftone/services/halftone.py`)
+
+Извлечь из `main.py` чистую функцию:
+
+```python
+def generate_halftone_svg(
+ image: Image.Image,
+ *,
+ cols: int = 80,
+ max_radius: int = 8,
+ color: str = "#800000",
+ opacity: str = "90", # hex alpha для CSS
+ animation_variants: int = 12,
+) -> str: # возвращает SVG-строку
+```
+
+**Что убираем из CLI-версии:**
+- Аргументы `image_path` / `output_path`
+- Форматирование чисел для CSS-переменных
+- Запись в файл
+- `print()`
+
+### 2. View-слой (`hypn0/halftone/views.py`)
+
+```python
+# Главная — GET → рендерим index.html
+# Генерация — POST (HTMX) → возвращаем SVG фрагмент
+# Скачивание — GET /download/{temp_id} → отдаём файл + удаляем исходник
+# Просмотр публичного — GET /view/{hash} → отдаём SVG из temp/
+# Галерея — GET /gallery → список FeaturedSVG
+# Просмотр в галерее — GET /gallery/{hash}
+# Report — POST /report/{hash} → increment reports_count
+# Promote (admin) — админ переносит SVG из temp → gallery
+```
+
+### 3. Фронтенд (`hypn0/halftone/templates/halftone/index.html`)
+
+```
+┌──────────────────────────────────────────────┐
+│ 📷 [Загрузить изображение] │
+│ hx-post="/generate" │
+│ hx-target="#preview" │
+├──────────────────────────────────────────────┤
+│ Ширина колонок: [80] │
+│ Макс. размер: [8] │
+│ Цвет: [#800000] │
+│ Анимация: [✓] │
+│ Опубликовать: [ ] — показать ссылку │
+├──────────────────────────────────────────────┤
+│ [Сгенерировать] │
+├──────────────────────────────────────────────┤
+│
│
+│ │
+└──────────────────────────────────────────────┘
+```
+
+Важно: данная форма -- черновик. Настроек генерации будет больше:
+- Фигуры (не только кружки, но и квадратики, кольца, треугольники, буквы-цифры, линии (переменной толщины), волнистые линии.
+- Наклон сетки (угол)
+- Цветовые модели (дуотон/трейтон с разным наклоном сетки для каждого цвета как в полиграфии, полноцвет)
+- Возможно разные настройки анимации (групп)
+
+Рядом с панелью настроек, превью ("на лету") и кнопка скачать.
+Галерея отобранных изображений. Под картинками в галере кнопки "понравилось" и "подаваться"
+
+## СЕКЦИЯ B: Алгоритмы и фигуры
+
+### F: Типы фигур
+
+| ID | Фигура | Параметры | SVG-реализация |
+|------------|------------------------|------------------------------|-------------------------------------------------|
+| `circle` | Круг | `max_radius` | `` |
+| `square` | Квадрат | `max_size` | `` |
+| `ring` | Кольцо | `max_radius`, `stroke_width` | `` |
+| `diamond` | Ромб | `max_size` | `` |
+| `star` | Звезда 5-лучевая | `outer_r`, `inner_r` | `` |
+| `cross` | Крест | `max_size`, `arm_width` | `` |
+| `line-h` | Горизонтальная полоска | `max_width`, `thickness` | `` |
+| `line-v` | Вертикальная полоска | `max_height`, `thickness` | `` |
+| `line-d` | Диагональная полоска | `max_length`, `thickness` | Повернутый `` на angle |
+| `wave` | Волна | `amplitude`, `frequency` | `` |
+| `hex` | Шестигранник | `max_radius` | `` (6 вершин) |
+| `triangle` | Треугольник | `max_size` | `` |
+| `typeface` | Буква/цифра | `font_family`, `font_size` | `...` |
+
+**Сложность реализации:**
+- **Быстро** (фигура по центру, один параметр масштаба): circle, square, ring, diamond, hex, triangle
+- **Средне** (дополнительные параметры): line-h/v/d, cross, star, wave
+- **Сложно** (загрузка шрифта): typeface
+
+### G: Типы сеток
+
+| ID | Описание | Параметры | Сложность |
+|-------------|-----------------------------------|---------------------|-----------|
+| `grid` | Прямая прямоугольная (как сейчас) | `cols`, `rows` | — |
+| `rotated` | Прямая сетка с наклоном | `cols`, `angle_deg` | Низкая |
+| `hex_grid` | Шестиугольная сетка | `cols`, `radius` | Средняя |
+| `isometric` | Изометрическая проекция 60° | `cols` | Средняя |
+| `polar` | Полярные координаты | `rings`, `spokes` | Высокая |
+| `bend` | Изогнутая сетка | `cols`, `curve` | Высокая |
+
+**Реализация `rotated`:**
+```python
+angle = math.radians(angle_deg)
+cos_a, sin_a = math.cos(angle), math.sin(angle)
+rotated_x = x * cos_a - y * sin_a
+rotated_y = x * sin_a + y * cos_a
+```
+
+### P: Цветовые модели
+
+| ID | Описание | Параметры | Сложность |
+|----------------|-----------------------|-------------------------------|-----------|
+| `single` | Один цвет | `color_hex`, `opacity` | — |
+| `duotone` | 2 цвета | `color_a`, `color_b`, `blend` | Средняя |
+| `tritone` | 3 цвета | `colors[3]`, `blend` | Средняя |
+| `quad` | 4 цвета | `colors[4]`, `blend` | Средняя |
+| `palette_auto` | Авто-палитра n цветов | `palette_name`, `n` | Низкая |
+| `fullcolor` | Квантование цветов | `quantization_levels` | Высокая |
+
+**Реализация `duotone/tritone/quad`:**
+```python
+from sklearn.cluster import KMeans
+pixels = image.convert('RGB').resize((100, 100)).getdata()
+kmeans = KMeans(n_clusters=n, random_state=42, n_init=1)
+kmeans.fit(pixels)
+centers = kmeans.cluster_centers_ # RGB-координаты кластеров
+# Каждый пиксель маппим на ближайший кластер
+```
+
+**Реализация `fullcolor`:**
+```python
+# Median-cut квантование
+pixels = image.quantize(colors=256) # или custom median-cut
+```
+
+### Q: Анимации
+
+| ID | Описание | Параметры |
+|-----------|----------------------------------|-----------------------------------------------|
+| `pulse` | Пульсация (как сейчас) | `speed`, `variants`, `scale_min`, `scale_max` |
+| `rotate` | Медленное вращение (покачивание) | `speed`, `direction` (cw/ccw) |
+| `wave` | Волна по вертикали (покачивание) | `amplitude`, `frequency`, `speed` |
+| `sparkle` | Мерцание fade in/out | `variants`, `speed_range` |
+| `flow` | Поток в направлении | `direction`, `speed` |
+| `breathe` | Всё вместе "дышит" | `speed`, `scale_range` |
+| `static` | Без анимации | — |
+
+**Реализация:**
+- Каждая группа (CSS-класс) получает свой `@keyframes` + `animation-delay`
+- N ключевых кадров в ` │ │
+│ │ │ │ │
+│ ─── Стиль ───── │ │ │ │
+│ ┌─┐┌─┐┌─┐┌─┐ │ │ [♥ liked] [Скачать] │ │
+│ │●│┌─┐┌─┐┌─┐ │ └─────────────────────────────┘ │
+│ └─┘└─┘└─┘└─┘ │ [Поделиться] 🔗 │
+│ circle │ │
+│ │ │
+│ ─── Сетка ───── │ │
+│ ┌─┐┌─┐┌─┐┌─┐ │ │
+│ │●│┌─┐┌─┐┌─┐ │ │
+│ └─┘└─┘└─┘└─┘ │ │
+│ grid │ │
+│ │ │
+│ ─── Цвет ────── │ │
+│ ┌─┐┌─┐┌─┐┌─┐ │ │
+│ │●│┌─┐┌─┐┌─┐ │ │
+│ └─┘└─┘└─┘└─┘ │ │
+│ single │ │
+│ │ │
+│ ─── Параметры ─ │ │
+│ Колонки: [80]│ │
+│ Макс. размер: [8]│ │
+│ Цвет: #[800000]│ │
+│ Прозрачность:[.5]│ │
+│ Угол сетки: [0°]│ │
+│ Анимация:[▼pulse]│ │
+│ │ │
+│ ───────────────── │ │
+│ │ │
+│ [Сгенерировать] │ │
+│ │ │
+├───────────────────┴───────────────────────────────────┤
+│ ───────────── Галерея ───────────── │
+│ [thumb] [thumb] [thumb] [thumb] ... │
+│ [♥ 12] [♥ 8] [♥ 23] [♥ 5] │
+└───────────────────────────────────────────────────────┘
+```
+
+### Табы настроек
+
+- На десктопе: 2 колонки — слева настройки, справа превью
+- На мобильном: вертикально — превью сверху, настройки снизу
+- Табы переключают секции: "Стиль / Сетка / Цвет / Параметры"
+- HTMX: `hx-trigger="change"` на контролах → превью обновляется без перезагрузки
+
+### Галерея
+
+- `GET /gallery` — CSS Grid сетка миниатюр (3-4 колонки)
+- Каждая карточка: SVG-превью (inline), кнопка ♥ (HTMX vote), кнопка поделиться
+- `POST /gallery/{hash}/vote` — HTMX запрос, обновляет ♥ счётчик
+- Пагинация: 24 карточки на странице
+- `GET /gallery/{hash}` — полноэкранный просмотр SVG с кнопками "Скачать" и "Поделиться"
+
+**CSS:**
+- Dev: Tailwind CDN (``) + Purge content в конфиге
+- Prod: `collectstatic` → `whitenoise` обслуживает скомпилированную статику
+
+HTMX: форма с `hx-post`, `hx-encoding="multipart/form-data"` → SVG вставляется в `#preview`.
+
+### 4. Политика хранения
+
+**Исходные изображения:** удаляются сразу после генерации (не хранятся вообще).
+
+**Публичные SVG (опционально, по желанию пользователя):**
+```
+public/media/temp/{hash_16символов}.svg
+```
+- TTL: **14 дней**
+- URL: `/view/{hash}` — прямая ссылка, без индексации
+- Автоматическая очистка: `manage.py cleanup_temp --older-than 1209600` → crontab
+
+**Галерея (FeaturedSVG):**
+- Администратор/promote: лучшие SVG переезжают из `temp/` в `gallery/`
+- Хранятся вечно (лучшая коллекция халфтонов)
+- Прямая ссылка: `/gallery/{hash}`
+- `/gallery` — страница галереи со всеми (пагинация)
+
+**Модель `FeaturedSVG`:**
+```python
+class FeaturedSVG(models.Model):
+ svg_hash = models.CharField(max_length=16, unique=True)
+ original_temp_path = models.CharField(max_length=512)
+ gallery_path = models.CharField(max_length=512)
+ params_json = models.JSONField(default=dict)
+ votes = models.PositiveIntegerField(default=0)
+ promoted_at = models.DateTimeField(auto_now_add=True)
+ promoted_by = models.ForeignKey('auth.User', null=True, blank=True)
+ reports_count = models.PositiveIntegerField(default=0)
+```
+
+**Report / жалоба:**
+- `/report/{hash}` — кнопка "Пожаловаться" на странице просмотра
+- Просто счётчик `reports_count` в модели (или просто scan для ручного удаления)
+- После жалобы — админ проверяет и удаляет вручную
+
+**Публичный режим:**
+Все генерации публичны:
+- Любой SVG доступен к скачиванию
+- SVG показываются в браузере по `temp/` или `/gallery`, но доступны только `/hypn0/` с hash-именем
+- В браузере, показывается "Поделиться ссылкой"
+
+## Шаги реализации
+
+### Шаг 1. Структура каталогов
+
+Создать:
+- `hypn0/` — Django project root
+- `hypn0/hypn0/` — settings package
+- `hypn0/halftone/` — Django app
+- `public/` — static + media
+- `public/media/temp/` — публичные SVG (TTL 14 дней)
+- `public/media/gallery/` — лучшие SVG
+- `database/` — БД
+- `config/nginx/` — nginx config
+- `.gitea/workflows/` — CI/CD
+
+### Шаг 2. Зависимости в `pyproject.toml`
+
+Добавить:
+```toml
+[tool.poetry.dependencies]
+django = "^5.2"
+django-environ = "^0.13"
+gunicorn = "^25.3"
+whitenoise = "^6.12"
+django-htmx = "^1.21"
+```
+
+### Шаг 3. Django settings (`hypn0/hypn0/settings.py`)
+
+```python
+import environ
+env = environ.Env(DEBUG=(bool, False))
+environ.Env.read_env(os.path.join(BASE_DIR.parent, '.env'))
+
+DEBUG = env('DEBUG')
+SECRET_KEY = env('SECRET_KEY')
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR.parent / 'database' / 'db.sqlite3',
+ }
+}
+
+STATIC_ROOT = BASE_DIR.parent / 'public' / 'static'
+MEDIA_ROOT = BASE_DIR.parent / 'public' / 'media'
+MEDIA_URL = '/media/'
+
+STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
+
+INSTALLED_APPS += ['halftone']
+ROOT_URLCONF = 'hypn0.urls'
+```
+
+### Шаг 4. Docker
+
+**Dockerfile** (многостадийный, как в cadpoint-ru):
+- Stage 1 (builder): Poetry → export → pip install
+- Stage 2 (runtime): gunicorn, non-root user 1000:1000, `collectstatic`
+
+**docker-compose.local.yml**:
+- Bind-mount: `./hypn0`, `./public`, `./database`
+- Gunicorn `--reload`
+- Port `8051:8000`
+
+**docker-compose.prod.yml**:
+- Образ из Gitea registry
+- Host port: `127.0.0.1:8051:8000`
+- Watchtower для автообновления
+
+### Шаг 5. Nginx-конфиг (`config/nginx/hypn0-app--external-nginx.conf`)
+
+Reverse proxy: `hypn0.local` → `127.0.0.1:8051`
+- Static/media раздается через Nginx (не Django)
+- GZip, HTTPS (если есть cert)
+
+### Шаг 6. CI/CD (`.gitea/workflows/docker-publish.yaml`)
+
+Trigger: tags `v*` → build → push to Gitea registry.
+Паттерн как в cadpoint-ru.
+
+### Шаг 7. Удаление `main.py`
+
+CLI больше не нужен.
+
+## Файлы для создания (итого)
+
+| Файл | Назначение |
+|---------------------------------------------------------|------------------------|
+| `hypn0/manage.py` | Django CLI |
+| `hypn0/hypn0/__init__.py` | Settings pkg |
+| `hypn0/hypn0/settings.py` | Конфиг |
+| `hypn0/hypn0/urls.py` | URL routing |
+| `hypn0/hypn0/wsgi.py` | WSGI entry |
+| `hypn0/hypn0/templates/base.html` | Базовый шаблон |
+| `hypn0/halftone/__init__.py` | App pkg |
+| `hypn0/halftone/urls.py` | URL app |
+| `hypn0/halftone/views.py` | Views |
+| `hypn0/halftone/forms.py` | Forms |
+| `hypn0/halftone/models.py` | FeaturedSVG |
+| `hypn0/halftone/services/halftone.py` | Ядро |
+| `hypn0/halftone/templates/halftone/index.html` | Главная |
+| `hypn0/halftone/management/commands/cleanup_temp.py` | Очистка temp (14 дней) |
+| `hypn0/halftone/management/commands/cleanup_reports.py` | Очистка по жалобам |
+| `public/static/css/site.css` | Стили |
+| `public/static/js/site.js` | JS |
+| `.env.sample` | Env template |
+| `Dockerfile` | Сборка |
+| `docker-compose.local.yml` | Dev |
+| `docker-compose.prod.yml` | Prod |
+| `config/nginx/hypn0-app--external-nginx.conf` | Nginx |
+| `.gitea/workflows/docker-publish.yaml` | CI/CD |
+| `database/.gitignore` | Игнор БД |
+
+## Файлы для модификации
+
+1. `pyproject.toml` — новые зависимости
+2. `poetry.lock` — после `poetry lock`
+
+## Файлы для удаления
+
+1. `main.py` — CLI заменён микросайтом
+
+## Верификация
+
+1. `docker compose -f docker-compose.local.yml up` → сайт открывается
+2. Загрузка картинки → параметризация → генерация SVG через HTMX
+3. SVG отображается в preview с анимацией
+4. Скачивание SVG работает
+5. `docker compose -f docker-compose.prod.yml` → prod деплой работает
+6. CI/CD: тег `v0.1.0` → сборка образа → push
+
+## Производительность: 1 CPU / 1 GB RAM / 10 GB disk
+
+**Storage:**
+- Один SVG: ~50–200 КБ (зависит от cols/max_radius)
+- 500 публичных SVG в день × 14 дней = ~700 МБ
+- 10 ГБ — более чем достаточно (галерея + кэш + ОС)
+
+**CPU:**
+- Генерация SVG: Pillow + цикл по пикселям (~6400 точек при cols=80)
+- Python: ~0.1–0.5 сек на генерацию
+- Gunicorn: 2–4 воркера → ~10–30 req/min на генерацию
+- Просмотры галереи: Nginx раздает статику напрямую (минимум нагрузки)
+
+**Трафик:**
+- 100–200 пользователей/день на генерацию — без проблем
+- Сотни просмотров галереи — без проблем
+- 500+ генераций/день → вертикальное масштабирование (2 CPU / 2 GB)