План разработки сайта moved.live
(дизайн-клон noviai.ai, заглушка вместо реальной AI-генерации видео)

Этот документ — техническое задание, которое можно целиком отдать Codex как контекст перед началом работы. Он описывает архитектуру, дизайн-систему, структуру страниц, логику временной заглушки для генерации видео и требования к деплою.

1. Цель и суть проекта

Сделать сайт moved.live — по визуальному стилю, "плотности" контента, композиции блоков и количеству страниц максимально похожий на noviai.ai, но с собственным контентом/текстами (без копирования чужих текстов, логотипов и торговых марок — это важно юридически: дизайн-паттерны копировать можно, а бренд, тексты, логотип и точные фото/видео — нельзя, иначе будет нарушение авторских прав и товарного знака).

Ключевая особенность текущего этапа: реальной AI-генерации видео для клиента пока нет. Вместо неё — единая "заглушка" (mock-функция), которая имитирует результат работы сервиса: клиент вводит текст/сценарий → жмёт "Сгенерировать" → сайт показывает превью-плашку с иконкой Play → под ней кнопка "Скачать ваше видео" → скачивается временный файл, названный по словам из промпта пользователя.

При этом:

Все графические и видео-ассеты для дизайна самого сайта (фоновые видео в хиро-блоке, картинки для карточек стилей, скриншоты workflow, иконки-постеры и т.д.) генерируются через fal.ai API — то есть Codex должен сам вызвать fal.ai и создать реальные изображения/видео для наполнения сайта.
Сайт должен грузиться быстро (Lighthouse Performance 90+), быть статически собираемым и легко деплоиться на обычный хостинг (не требовать выделенного сервера с бэкендом на постоянной основе — либо иметь минимальный лёгкий бэкенд только под заглушку/будущий API).
Домен: moved.live, язык — английский (весь UI/копирайт на английском).
2. Технологический стек

Рекомендация для Codex (можно скорректировать под то, что удобнее прописать в промпте):

Слой	Технология	Почему
Frontend framework	Next.js 14+ (App Router)	SSG/ISR для десятков лендингов, отличный SEO, next/image для оптимизации картинок, легко деплоить статикой (output: 'export') либо на Node-хостинг
Стилизация	Tailwind CSS + CSS-переменные для дизайн-токенов	Быстрая вёрстка, единая дизайн-система, малый CSS-бандл после purge
Анимации	Framer Motion (лёгкие, только там где нужно) + нативный CSS для скролл-эффектов	Плавность интерфейса без перегруза JS
Видео на фоне	<video> с preload="metadata", poster, lazy-init через IntersectionObserver, кодек H.264/webm, сжатие через ffmpeg	Скорость загрузки хиро-блока
Иконки	lucide-react	Готовый набор, малый вес
Формы/стейт	React state + Zustand (если нужен глобальный стор для "мастера" генерации)	Просто, без лишних зависимостей
Генерация ассетов (дизайн)	fal.ai REST API (образы — модель типа fal-ai/flux / fal-ai/nano-banana, видео — fal-ai/kling, fal-ai/pixverse и т.п. на выбор)	Пользователь предоставит API-ключ
Заглушка генерации для клиента	Node.js serverless route (/api/generate) ИЛИ полностью на клиенте (setTimeout + статичный файл)	См. раздел 6
Хостинг	Vercel / Netlify (если Next.js SSR/ISR) либо статический экспорт на любой хостинг (Nginx/Apache, S3+CloudFront)	По ТЗ — "залить готовый сайт на хостинг", поэтому лучше сразу закладывать возможность next export / статической сборки, а для заглушки — either serverless API либо чисто клиентская логика без бэкенда
CDN для картинок/видео	Cloudflare (бесплатный) перед хостингом	Кэш статики, быстрая отдача по всему миру

Важно прописать Codex явно: "собери проект так, чтобы после npm run build (или next export) получившуюся папку можно было залить на обычный shared/VPS хостинг без Node.js на сервере (чисто статика + CDN), а для функции скачивания заглушки не требовался постоянно работающий бэкенд" — это определяет архитектуру заглушки (см. ниже, вариант "полностью клиентский").

3. Карта сайта (Sitemap) — по аналогии с noviai.ai

Все URL — на английском, без привязки к бренду "Novi". Структура должна повторять глубину и логику оригинала.

3.1 Главные разделы
/                          — Главная (Home)
/pricing/                  — Тарифы
/about-us/                 — О нас
/faqs/                     — FAQ
/support/                  — Поддержка
/blog/                     — Блог (листинг статей)
/blog/[slug]/              — Отдельная статья
/privacy-policy/
/terms-conditions/
/cookie-policy/
/refund-policy/
/dmca-policy/
/disclaimer/
3.2 "Продуктовые" инструменты (Tools) — каждая своя лендинг-страница

Все ведут на один и тот же "мастер генерации" (wizard), но с разным заголовком/визуалом/примерами под нишу:

/tools/                              — каталог всех инструментов
/tools/script-to-video/
/tools/text-to-video/
/tools/image-to-video/
/tools/text-to-image/
/tools/image-to-image/
/tools/story-to-video/
/tools/animation-story-maker/
/tools/horror-story-video-generator/
/tools/love-story-video-generator/
/tools/bible-story-video-generator/
/tools/kids-bedtime-story-generator/
/tools/cat-story-video-generator/
/tools/reddit-story-video-generator/
/tools/youtube-shorts-generator/
/tools/faceless-youtube-video-maker/
/tools/animated-explainer-video-maker/
/tools/logo-animator/

(Список можно сократить до 10–15 на первом этапе, остальные добавлять позже — главное показать Codex шаблон "1 генератор страницы = 1 конфиг", см. раздел 7).

3.3 Приложение / мастер генерации
/app/create/                — сам мастер (wizard) генерации видео
/app/dashboard/             — "Мои видео" (список сгенерированных заглушек пользователя, localStorage/DB)
3.4 Модели (опционально, для плотности контента)
/models/                    — список AI-моделей (карточки "как у noviai": Seedance, PixVerse, Veo, Kling...)
/models/[model-slug]/

Итого: ~35–45 страниц для первого релиза — это и создаёт ощущение "заполненности" сайта, как у оригинала.

4. Дизайн-система
4.1 Общий стиль (референс noviai.ai)
Тёмная/светлая шапка с крупным логотипом слева, растянутое меню посередине с dropdown-мега-меню (несколько колонок с подзаголовками и иконками "Hot"/"New").
Хиро-секция: 3 автоплей-видео в ряд (без звука, loop muted playsinline) + крупный H1 в 2 строки + сабтайтл + большая CTA-кнопка + горизонтальная бегущая строка логотипов "поддерживаемых моделей".
Блок "What story will you tell" — карусель карточек-примеров с фоновым видео/картинкой и оверлей-текстом.
4-шаговый workflow (Paste → Storyboard → Preview → Export) с номерными карточками и скриншотами.
Блок "Capabilities" — чередующиеся секции текст/картинка (zig-zag layout).
Блок соцдоказательств — логотипы медиа (Yahoo, PR Web, Product Hunt...) + счётчик пользователей + карусель отзывов с аватарками и звёздами.
Блок "Create for every creator" — табы (Filmmakers / Studios / Authors / Creators / Marketers) переключающие картинку и описание.
FAQ — аккордеон.
Блок последних статей блога — сетка карточек 4 в ряд.
Финальный CTA-блок на тёмном фоне с крупной кнопкой.
Футер — 6 колонок ссылок + соцсети + copyright.
Всплывающий поп-ап (welcome offer) при первом визите — "Get free credits", с крестиком закрытия, показывать один раз через localStorage.
4.2 Токены дизайна

Прописать в tailwind.config.js / CSS variables:

Цвета: primary (акцентный, напр. фиолетово-синий градиент), background dark/light, текстовые оттенки (primary/secondary/muted), success/error.
Радиусы: крупные скругления карточек (16–24px), кнопок (пилюли/rounded-full).
Тени: мягкие цветные glow-тени под CTA-кнопками.
Шрифты: один "display" шрифт с чуть увеличенным трекингом для заголовков (напр. Inter/Sora/Manrope), моноширинный не нужен.
Сетка: контейнер max-width ~1280–1320px, отступы секций 96–140px по вертикали.
Градиенты: фоновые "aurora"/"blob" градиенты за хиро-блоком (можно сделать SVG/CSS, не через AI).
4.3 Генерация визуальных ассетов через fal.ai

Всё, что на оригинале является фото/видео контентом (примеры историй, превью стилей, картинки workflow, аватарки отзывов, иконки карточек творцов) — Codex должен сгенерировать сам через fal.ai, а не скачивать/копировать с noviai.ai. Прописать Codex список нужных ассетов и промптов, например:

/assets-generation/
  images.config.json   — список: {id, prompt, model, size, destination}
  videos.config.json   — список: {id, prompt, model, duration, destination}
  generate-images.mjs  — скрипт: читает config, вызывает fal.ai image API, сохраняет в /public/generated/images/
  generate-videos.mjs  — скрипт: читает config, вызывает fal.ai video API, сохраняет в /public/generated/videos/

Пример содержимого images.config.json (структура, не финальный текст):

json
[
  { "id": "hero-bg-1", "prompt": "cinematic film still, romance drama story scene, warm lighting, 16:9", "model": "fal-ai/flux/dev", "size": "1920x1080" },
  { "id": "style-cyberpunk", "prompt": "cyberpunk city character portrait, neon, cinematic", "model": "fal-ai/flux/dev", "size": "1024x1024" }
]

Скрипты запускаются один раз на этапе сборки контента (не во время работы сайта у реального пользователя!), результат — обычные статичные файлы в /public, которые дальше отдаются через CDN. Это критично для скорости: сайт не должен дергать fal.ai при каждом визите пользователя.

Сжатие после генерации:

Картинки → .webp/.avif через sharp, несколько размеров (responsive srcset).
Видео → пережать ffmpeg в H.264 mp4 + webm, обрезать длительность (6–10 сек, бесшовный loop), убрать звук.
5. Раздел "мастер генерации" (то, что видит пользователь)
5.1 UX-флоу
Пользователь заходит на /app/create/ (или на страницу конкретного инструмента и жмёт "Try for Free" → редирект в мастер с предзаполненным типом).
Экран 1 — ввод: textarea "Paste your script or story", выбор стиля (карточки: Cinematic, Anime, Ghibli, Pixar...), выбор соотношения сторон (16:9 / 9:16 / 1:1), кол-во сцен (слайдер).
Экран 2 — "Storyboard preview": сетка из N карточек-сцен, у каждой — статичная превью-картинка (тоже можно взять из заранее сгенерированного fal.ai пула "нейтральных" превью, либо просто заглушка-постер) и текст сцены.
Кнопка "Generate Video" → показывается прогресс-бар/лоадер (имитация, 5–15 секунд с фейковым процентом) → результат.
Экран результата: центрированная карточка-плеер:
Постер (картинка) с центральной круглой кнопкой ▶️ поверх.
Клик по кнопке ничего не делает технически (или показывает toast "Video preview coming soon" / просто визуально "нажимается", но видео не воспроизводится) — как и просил заказчик.
Под плеером кнопка "Download your video".
Клик на Download скачивает временный файл (см. раздел 6) с динамическим именем на основе введённого пользователем текста.
5.2 Компоненты UI мастера
/components/wizard/
  ScriptInput.tsx
  StyleSelector.tsx
  AspectRatioSelector.tsx
  ScenePreviewGrid.tsx
  GeneratingLoader.tsx      — фейковый прогресс (анимация 0→100%, случайные "статусы": "Analyzing script...", "Rendering scene 3/6...", "Syncing voiceover...")
  ResultPlayerCard.tsx      — постер + fake play button + Download CTA
  DownloadButton.tsx

GeneratingLoader стоит сделать реалистичным — со сменой текстовых статусов, т.к. это создаёт у клиента ощущение "настоящей" работы AI, при этом ничего реального не считается.

6. Логика временной заглушки (mock video generation)

Это ключевая техническая часть, которую нужно прописать Codex максимально буквально.

6.1 Структура папки заглушки в проекте
/mock-video/                      ← отдельная папка в корне проекта, как просил заказчик
  ├── template.mp4                ← один "эталонный" временный видеофайл (или несколько шаблонов на выбор)
  ├── template-poster.jpg         ← постер/превью с иконкой Play, который показывается ДО скачивания
  ├── behavior.config.js          ← ЕДИНЫЙ файл, где прописывается ВСЯ логика поведения заглушки
  └── README.md                   ← пояснение для себя/заказчика, как менять поведение
6.2 Файл behavior.config.js — что в нём должно быть настраиваемо

Это тот самый "js в котором можно указывать, как именно временный файл будет выдаваться клиенту", о котором просил заказчик. Он должен экспортировать конфиг-объект, который читает фронтенд, например:

js
// /mock-video/behavior.config.js
export const mockVideoBehavior = {
  // какой шаблон видео отдавать (можно расширить до массива и рандомизировать/чередовать)
  sourceFile: "/mock-video/template.mp4",
  posterImage: "/mock-video/template-poster.jpg",

  // имитация задержки генерации (мс) — диапазон, чтобы не было каждый раз одинаково
  fakeProcessingTimeMs: { min: 6000, max: 14000 },

  // текстовые статусы, которые сменяются во время "генерации"
  fakeStatusMessages: [
    "Analyzing your script...",
    "Building storyboard...",
    "Generating scenes...",
    "Syncing voiceover & subtitles...",
    "Finalizing your video...",
  ],

  // работает ли клик по кнопке Play (сейчас — нет, просто визуальный клик/анимация)
  playButtonEnabled: false,

  // правило генерации имени скачиваемого файла
  fileNaming: {
    prefix: "video_",
    // сколько слов брать из пользовательского текста для имени файла
    wordsFromUserInput: 3,
    // как чистить текст перед вставкой в имя файла (убрать спецсимволы, привести к kebab-case)
    slugify: true,
    // fallback, если пользователь ничего не ввёл
    fallback: "untitled-story",
    extension: ".mp4",
  },
};
6.3 Логика генерации имени файла

Пример правила (реализуется в утилите lib/mockVideo.ts, использующей конфиг выше):

Взять текст, который ввёл пользователь на первом шаге (сценарий/описание).
Убрать всё, что не буквы/цифры/пробелы.
Взять первые wordsFromUserInput слов.
Привести к нижнему регистру, пробелы → _.
Итоговое имя: video_ + слова + .mp4.

Пример: пользователь ввёл "A lonely astronaut discovers a garden on Mars" → итоговый файл: video_a_lonely_astronaut.mp4.

Если несколько видео генерируются подряд с одинаковым началом текста — добавлять короткий суффикс (timestamp/random 4 символа), чтобы не перезаписывались одинаковые файлы: video_a_lonely_astronaut_x93k.mp4.

6.4 Как физически происходит "скачивание"

Раз сайт должен быть статическим и быстрым, без обязательного постоянно работающего бэкенда — лучший вариант:

template.mp4 лежит в /public/mock-video/template.mp4 (тот же файл, что и в /mock-video/, либо копируется туда сборочным скриптом).
По клику на "Download your video" — фронтенд:
Через fetch() получает template.mp4 как Blob.
Создаёт URL.createObjectURL(blob).
Программно кликает по скрытому <a download="video_a_lonely_astronaut.mp4" href="...">.
Освобождает URL после скачивания.
Никакого бэкенда для самого скачивания не нужно — это чисто клиентская операция, значит сайт спокойно живёт на статическом хостинге.

Если в будущем понадобится разный временный файл для разных инструментов (например, для "Horror Story" — один плейсхолдер, для "Kids Story" — другой, более "дружелюбный"), то в behavior.config.js можно расширить sourceFile до объекта по типу инструмента:

js
sourceFile: {
  default: "/mock-video/template.mp4",
  horror: "/mock-video/template-horror.mp4",
  kids: "/mock-video/template-kids.mp4",
},

— и в компоненте выбирать нужный файл по типу текущей страницы/инструмента.

6.5 Экран "постер с кнопкой Play"
template-poster.jpg — статичная картинка (можно сгенерировать через fal.ai — "cinematic movie still frame placeholder" под тематику), поверх — полупрозрачный тёмный оверлей + большая круглая белая/акцентная кнопка Play по центру (SVG-иконка, не картинка — для чёткости на любом экране).
По клику — лёгкая анимация нажатия (scale 0.95 → 1, ripple-эффект), можно показать тултип "Video playback will be available soon" — по желанию заказчика (сейчас: просто ничего не делает технически, воспроизведения нет).
Сразу под карточкой — заметная кнопка Download your video.
7. Как унифицировать ~20 разных лендингов инструментов

Чтобы не писать 20 раз одну и ту же страницу руками, прописать Codex шаблонизацию:

/content/tools/
  script-to-video.json
  text-to-video.json
  horror-story-video-generator.json
  ...
/app/tools/[slug]/page.tsx   ← один шаблон страницы, рендерит данные из /content/tools/{slug}.json

Каждый JSON содержит: title, metaDescription, heroHeadline, heroSubtext, heroVideoAssetId (ссылка на ассет, сгенерированный fal.ai), exampleCards (массив примеров с картинками), faq (массив вопрос/ответ), ctaText, а также опционально mockVideoOverride (какой шаблон-заглушку показывать именно для этого инструмента, ссылаясь на behavior.config.js).

Так каждая страница выглядит и оформлена по-своему (разные картинки/видео/тексты/акценты — как и просил заказчик "может даже для клиента оформлять по-разному"), но технически все ведут в один и тот же мастер /app/create/ с параметром ?tool=horror-story, который влияет только на: (а) визуальные примеры на экране ввода, (б) какой файл-заглушка отдаётся при скачивании, (в) какие статусы показываются в лоадере.

8. SEO и контент
Каждая страница — свои <title>, meta description, og:image (сгенерированный через fal.ai уникальный превью-баннер 1200×630).
sitemap.xml и robots.txt генерируются автоматически (next-sitemap).
Разметка Schema.org: Organization, FAQPage (для блока FAQ), Article (для блога), BreadcrumbList.
Блог: минимум 10–15 стартовых статей (SEO-тексты про "AI video generator", "script to video" и т.п., собственный уникальный копирайт, не копировать с noviai.ai — там это тоже сгенерированный/уникальный контент, и копирование текстов = риск DMCA).
Семантическая структура заголовков (один h1 на страницу, логичная иерархия h2/h3).
9. Производительность ("шустрый" сайт)
Next.js Image Optimization / sharp, форматы AVIF/WEBP, loading="lazy" везде кроме хиро.
Видео в хиро — сжаты до минимально приемлемого битрейта, preload="none" + запуск по IntersectionObserver, либо статичный постер + видео подгружается только когда блок появляется в вьюпорте.
Разбивка JS по маршрутам (Next.js делает это автоматически), отказ от тяжёлых библиотек (не тащить полный lodash/moment — использовать нативные методы/dayjs).
Критический CSS инлайнится, Tailwind — с purge/JIT (только использованные классы).
Шрифты — next/font с font-display: swap, subset только нужных символов (латиница).
Кэширование статики на уровне хостинга/CDN: Cache-Control: public, max-age=31536000, immutable для сгенерированных ассетов с хэшами в именах.
Цель: LCP < 2.0s, CLS < 0.1, TBT < 150ms на mobile 4G (Lighthouse).
10. Структура проекта (репозиторий)
moved-live/
├── app/                          # Next.js App Router
│   ├── (marketing)/
│   │   ├── page.tsx              # главная
│   │   ├── pricing/page.tsx
│   │   ├── about-us/page.tsx
│   │   ├── faqs/page.tsx
│   │   ├── support/page.tsx
│   │   ├── blog/
│   │   │   ├── page.tsx
│   │   │   └── [slug]/page.tsx
│   │   ├── tools/
│   │   │   ├── page.tsx
│   │   │   └── [slug]/page.tsx
│   │   ├── models/
│   │   │   ├── page.tsx
│   │   │   └── [slug]/page.tsx
│   │   ├── privacy-policy/page.tsx
│   │   ├── terms-conditions/page.tsx
│   │   ├── cookie-policy/page.tsx
│   │   ├── refund-policy/page.tsx
│   │   └── dmca-policy/page.tsx
│   └── app/
│       ├── create/page.tsx       # мастер генерации
│       └── dashboard/page.tsx
├── components/
│   ├── layout/ (Header, MegaMenu, Footer, PromoPopup)
│   ├── home/ (Hero, WorkflowSteps, CapabilitiesSection, SocialProof, Testimonials, CreatorTabs, FAQAccordion, BlogGrid, FinalCTA)
│   ├── wizard/ (см. раздел 5.2)
│   └── ui/ (Button, Card, Badge, Tabs, Accordion — переиспользуемые примитивы)
├── content/
│   ├── tools/*.json
│   ├── models/*.json
│   └── blog/*.mdx
├── mock-video/
│   ├── template.mp4
│   ├── template-poster.jpg
│   └── behavior.config.js
├── lib/
│   ├── mockVideo.ts               # логика имени файла + скачивания
│   └── seo.ts
├── scripts/
│   ├── generate-images.mjs        # вызовы fal.ai для картинок
│   └── generate-videos.mjs        # вызовы fal.ai для видео
├── public/
│   ├── generated/images/
│   ├── generated/videos/
│   └── mock-video/template.mp4    # копия для клиентского скачивания
├── .env.local                     # FAL_KEY=...
├── next.config.js
├── tailwind.config.ts
└── package.json
11. Этапы разработки (порядок для Codex)
Инициализация проекта — Next.js + TypeScript + Tailwind, базовый конфиг, деплой "hello world" на хостинг для проверки пайплайна.
Дизайн-система — токены, базовые UI-компоненты (Button, Card, Badge, Accordion, Tabs).
Генерация ассетов через fal.ai — написать и прогнать generate-images.mjs / generate-videos.mjs, наполнить /public/generated.
Layout — Header с мега-меню, Footer, промо-попап.
Главная страница — все секции по разделу 4.1, с реальными сгенерированными ассетами.
Мастер генерации (/app/create) — весь UX-флоу из раздела 5, включая GeneratingLoader и ResultPlayerCard.
Логика заглушки (mock-video/) — behavior.config.js, lib/mockVideo.ts, тест скачивания с динамическим именем.
Шаблон страниц инструментов — /tools/[slug], JSON-конфиги для 10–20 инструментов, связка с параметром для мастера.
Второстепенные страницы — Pricing, About, FAQ, Support, юридические страницы, Models.
Блог — листинг + шаблон статьи + 10–15 стартовых статей.
SEO — sitemap, meta, schema.org, og-картинки.
Оптимизация производительности — аудит Lighthouse, сжатие видео/картинок, code splitting.
Адаптивность — полная проверка мобильной версии (мега-меню → бургер, хиро-видео → 1 колонка, карусели → свайп).
Финальная сборка и деплой — сборка приложения, загрузка на хостинг, проверка на реальном домене moved.live, настройка CDN/кэша, SSL.
12. Что обязательно прописать Codex текстом в самом промпте (чек-лист для тебя)
 Технологии: Next.js + TypeScript + Tailwind (или уточнить свои предпочтения).
 Домен и язык: moved.live, весь контент на английском.
 Дать API-ключ fal.ai и явно указать: "используй его только на этапе генерации ассетов дизайна (скрипты в /scripts), НЕ вызывай fal.ai в рантайме на проде для обычных пользователей".
 Список страниц (взять из раздела 3, сократить/дополнить по желанию).
 Точное описание UX мастера генерации (раздел 5).
 Дословно передать структуру и содержимое mock-video/behavior.config.js (раздел 6.2) — это то самое "ТЗ по заглушке", которое просил заказчик.
 Требование: "кнопка Play визуально кликабельна, но воспроизведения не запускает".
 Требование к имени скачиваемого файла: video_ + первые 3 слова из ввода пользователя, slugify, fallback на untitled-story.
 Требование к производительности: статическая сборка, оптимизированные медиа, Lighthouse 90+.
 Требование к деплою: собранный проект должен запускаться на обычном хостинге без необходимости постоянно работающего Node-сервера (либо — если бэкенд всё же нужен на будущее — минимальный serverless API, который можно выключить/не разворачивать на этом этапе).
13. На будущее (не делать сейчас, но заложить в архитектуре)
Замена заглушки в /mock-video/behavior.config.js на реальный вызов fal.ai video API (интерфейс lib/mockVideo.ts уже будет спроектирован так, что реальную генерацию можно подставить, не переписывая UI).
Личный кабинет с реальной авторизацией и историей видео (сейчас — можно ограничиться localStorage-имитацией "Моих видео").
Биллинг/подписки (страница Pricing уже будет свёрстана, оплата подключается позже).
