diff --git a/TEMPLATE_README.md b/TEMPLATE_README.md
new file mode 100644
index 0000000..b2869b3
--- /dev/null
+++ b/TEMPLATE_README.md
@@ -0,0 +1,787 @@
+# 🚀 Универсальный шаблон лендинга TaskFlow
+
+Это профессиональный шаблон продающей страницы (лендинга), созданный по методологии **Feature-Sliced Design (FSD)**. Шаблон легко адаптируется под любой продукт, услугу или бизнес.
+
+## 📋 Содержание
+
+- [Архитектура](#архитектура)
+- [Структура проекта](#структура-проекта)
+- [Компоненты](#компоненты)
+- [Секции лендинга](#секции-лендинга)
+- [Как изменять шаблон](#как-изменять-шаблон)
+- [Стилизация](#стилизация)
+- [Анимации](#анимации)
+
+---
+
+## 🏗️ Архитектура
+
+Проект построен по **FSD (Feature-Sliced Design)** - современной методологии архитектуры фронтенд-приложений:
+
+```
+src/
+├── app/ # Слой приложения (глобальные настройки)
+├── widgets/ # Композитные секции лендинга
+├── features/ # Переиспользуемые блоки
+└── shared/ # Общий код (UI-kit, хуки, утилиты)
+```
+
+### Принципы FSD:
+
+- **Слоистая архитектура**: от общего (shared) к специфичному (app)
+- **Изолированность**: каждый компонент независим
+- **Переиспользование**: компоненты можно легко использовать в других проектах
+- **Понятность**: структура ясна для ИИ и разработчиков
+
+---
+
+## 📁 Структура проекта
+
+### Детальная структура:
+
+```
+src/
+├── app/
+│ ├── layout.tsx # Root layout с провайдерами
+│ ├── page.tsx # Главная страница (композиция widgets)
+│ └── globals.css # Глобальные стили + CSS переменные
+│
+├── widgets/ # 🎯 КОМПОЗИТНЫЕ СЕКЦИИ ЛЕНДИНГА
+│ ├── header.tsx # Header с навигацией
+│ ├── hero-section.tsx # Главная секция
+│ ├── features-section.tsx # Секция возможностей
+│ ├── stats-section.tsx # Статистика/достижения
+│ ├── how-it-works-section.tsx# Как это работает
+│ ├── comparison-section.tsx # Сравнение до/после
+│ ├── gallery-section.tsx # Галерея/портфолио
+│ ├── social-proof-section.tsx# Отзывы и логотипы
+│ ├── team-section.tsx # Команда
+│ ├── pricing-section.tsx # Тарифы
+│ ├── faq-section.tsx # Частые вопросы
+│ ├── cta-section.tsx # Призыв к действию
+│ └── footer.tsx # Подвал сайта
+│
+├── features/ # 🧩 ПЕРЕИСПОЛЬЗУЕМЫЕ БЛОКИ
+│ ├── section-container.tsx # Обертка для секций
+│ ├── section-header.tsx # Заголовок секции
+│ ├── gradient-background.tsx # Градиентный фон
+│ ├── feature-card.tsx # Карточка фичи
+│ ├── testimonial-card.tsx # Карточка отзыва
+│ ├── pricing-card.tsx # Карточка тарифа
+│ ├── stat-card.tsx # Карточка статистики
+│ ├── step-card.tsx # Карточка шага
+│ ├── team-member-card.tsx # Карточка члена команды
+│ ├── comparison-item.tsx # Элемент сравнения
+│ ├── portfolio-item.tsx # Элемент портфолио
+│ └── logo-cloud.tsx # Облако логотипов
+│
+└── shared/ # 🔧 ОБЩИЙ КОД
+ ├── ui/ # shadcn/ui компоненты
+ │ ├── button.tsx
+ │ ├── card.tsx
+ │ ├── input.tsx
+ │ └── ... (50+ компонентов)
+ ├── hooks/
+ │ ├── use-in-view.ts # Хук для viewport detection
+ │ ├── use-scroll-animation.ts # Хук для scroll анимаций
+ │ └── theme-provider.tsx # Провайдер темы
+ └── lib/
+ └── utils.ts # Утилиты
+```
+
+---
+
+## 🧩 Компоненты
+
+### Features (переиспользуемые блоки)
+
+#### 1. **SectionContainer**
+
+Универсальная обертка для всех секций.
+
+**Props:**
+
+```typescript
+{
+ children: ReactNode;
+ className?: string;
+ variant?: 'default' | 'narrow' | 'wide'; // Ширина контейнера
+ background?: 'default' | 'muted' | 'gradient'; // Фон секции
+ withPadding?: boolean; // Отступы сверху/снизу
+ id?: string; // Для якорей навигации
+}
+```
+
+**Где используется:** Во всех секциях
+
+---
+
+#### 2. **SectionHeader**
+
+Заголовок секции с subtitle и description.
+
+**Props:**
+
+```typescript
+{
+ title: string; // Основной заголовок
+ subtitle?: string; // Надзаголовок
+ description?: string; // Описание
+ align?: 'left' | 'center' | 'right'; // Выравнивание
+ withGradient?: boolean; // Gradient на заголовке
+}
+```
+
+**Где используется:** Features, Stats, Team, Pricing и др.
+
+---
+
+#### 3. **FeatureCard**
+
+Карточка возможности/преимущества.
+
+**Props:**
+
+```typescript
+{
+ icon: LucideIcon; // Иконка
+ title: string; // Название
+ description: string; // Описание
+ variant?: 'default' | 'bordered' | 'filled';
+ link?: { href: string, label: string }; // Опциональная ссылка
+}
+```
+
+**Где используется:** Features Section
+
+---
+
+#### 4. **PricingCard**
+
+Карточка тарифного плана.
+
+**Props:**
+
+```typescript
+{
+ name: string; // Название плана
+ price: number | 'custom'; // Цена в рублях
+ period?: 'month' | 'year'; // Период оплаты
+ description: string;
+ features: Array<{ // Список возможностей
+ text: string;
+ included: boolean;
+ }>;
+ ctaLabel: string; // Текст кнопки
+ ctaHref: string;
+ popular?: boolean; // Популярный план
+}
+```
+
+**Где используется:** Pricing Section
+
+---
+
+#### 5. **StatCard**
+
+Карточка статистики с анимированным счетчиком.
+
+**Props:**
+
+```typescript
+{
+ value: string | number; // Значение
+ label: string; // Подпись
+ icon?: LucideIcon;
+ animated?: boolean; // Анимация счетчика
+ trend?: { // Тренд вверх/вниз
+ value: number;
+ direction: 'up' | 'down';
+ };
+}
+```
+
+**Где используется:** Stats Section
+
+---
+
+#### 6. **TestimonialCard**
+
+Карточка отзыва клиента.
+
+**Props:**
+
+```typescript
+{
+ content: string; // Текст отзыва
+ author: {
+ name: string;
+ role: string;
+ company?: string;
+ avatar?: string;
+ };
+ rating?: number; // Рейтинг 1-5
+ variant?: 'card' | 'quote'; // Стиль отображения
+}
+```
+
+**Где используется:** Social Proof Section
+
+---
+
+### Другие компоненты
+
+- **StepCard** - для How It Works
+- **TeamMemberCard** - для Team
+- **ComparisonItem** - для Comparison
+- **PortfolioItem** - для Gallery
+- **LogoCloud** - для логотипов клиентов
+
+---
+
+## 🎨 Секции лендинга
+
+### 1. **Header** (`widgets/header.tsx`)
+
+- Sticky навигация с backdrop blur
+- Мобильное меню (Sheet)
+- Переключатель темы
+- Smooth scroll к секциям
+
+**Как изменить:**
+
+```typescript
+// Измените навигацию в массиве:
+const navigation = [
+ { name: "Ваш пункт", href: "#section-id" },
+ // ...
+];
+```
+
+---
+
+### 2. **Hero Section** (`widgets/hero-section.tsx`)
+
+Главная секция с заголовком и CTA.
+
+**Что изменить:**
+
+- Заголовок: `"Управляйте проектами быстрее и проще"`
+- Описание: `"Все инструменты для командной работы..."`
+- Кнопки CTA
+- Hero изображение (замените placeholder)
+
+---
+
+### 3. **Features Section** (`widgets/features-section.tsx`)
+
+6 карточек с возможностями.
+
+**Как изменить:**
+
+```typescript
+const features = [
+ {
+ icon: Zap, // Иконка из lucide-react
+ title: "Ваша фича",
+ description: "Описание...",
+ },
+ // ... добавьте или удалите фичи
+];
+```
+
+---
+
+### 4. **Stats Section** (`widgets/stats-section.tsx`)
+
+4 карточки со статистикой.
+
+**Как изменить:**
+
+```typescript
+const stats = [
+ {
+ value: "10000+", // Число или строка
+ label: "Ваш показатель",
+ icon: Users,
+ animated: true, // Анимация счетчика
+ },
+ // ...
+];
+```
+
+---
+
+### 5. **How It Works** (`widgets/how-it-works-section.tsx`)
+
+4 шага с описанием процесса.
+
+**Как изменить:**
+
+```typescript
+const steps = [
+ {
+ number: 1,
+ title: "Шаг 1",
+ description: "Описание...",
+ icon: YourIcon,
+ },
+ // ...
+];
+```
+
+---
+
+### 6. **Comparison Section** (`widgets/comparison-section.tsx`)
+
+Сравнение "до/после" (3 элемента).
+
+**Как изменить:**
+
+```typescript
+const comparisons = [
+ {
+ before: {
+ title: "Старый способ",
+ description: "...",
+ },
+ after: {
+ title: "Новый способ",
+ description: "...",
+ },
+ },
+ // ...
+];
+```
+
+---
+
+### 7. **Gallery Section** (`widgets/gallery-section.tsx`)
+
+6-8 примеров работ/скриншотов.
+
+**Как изменить:**
+
+- Замените `/api/placeholder/600/400` на реальные изображения
+- Измените категории и описания
+
+---
+
+### 8. **Social Proof** (`widgets/social-proof-section.tsx`)
+
+Отзывы клиентов + логотипы компаний.
+
+**Как изменить:**
+
+```typescript
+const testimonials = [
+ {
+ content: "Текст отзыва...",
+ author: {
+ name: "Имя",
+ role: "Должность",
+ company: "Компания",
+ avatar: "/path/to/avatar.jpg",
+ },
+ rating: 5,
+ },
+ // ...
+];
+
+const logos = [
+ { name: "Company", src: "/path/to/logo.png" },
+ // ...
+];
+```
+
+---
+
+### 9. **Team Section** (`widgets/team-section.tsx`)
+
+Карточки членов команды.
+
+**Как изменить:**
+
+```typescript
+const team = [
+ {
+ name: "Имя",
+ role: "Должность",
+ bio: "Краткая биография",
+ image: "/path/to/photo.jpg",
+ socials: [
+ { platform: "linkedin", url: "#" },
+ { platform: "github", url: "#" },
+ ],
+ },
+ // ...
+];
+```
+
+---
+
+### 10. **Pricing Section** (`widgets/pricing-section.tsx`)
+
+3 тарифных плана.
+
+**Как изменить:**
+
+```typescript
+const pricingPlans = [
+ {
+ name: "Название",
+ price: 2900, // В рублях
+ period: "month", // или "year"
+ description: "Описание плана",
+ features: [
+ { text: "Возможность 1", included: true },
+ { text: "Возможность 2", included: false },
+ ],
+ ctaLabel: "Купить",
+ ctaHref: "#",
+ popular: true, // Показать badge "Популярный"
+ },
+ // ...
+];
+```
+
+---
+
+### 11. **FAQ Section** (`widgets/faq-section.tsx`)
+
+8 частых вопросов с ответами.
+
+**Как изменить:**
+
+```typescript
+const faqs = [
+ {
+ question: "Ваш вопрос?",
+ answer: "Подробный ответ...",
+ },
+ // ...
+];
+```
+
+---
+
+### 12. **CTA Section** (`widgets/cta-section.tsx`)
+
+Финальный призыв к действию.
+
+**Что изменить:**
+
+- Заголовок
+- Описание
+- Текст на кнопке
+- Форма подписки (email input)
+
+---
+
+### 13. **Footer** (`widgets/footer.tsx`)
+
+Подвал с ссылками и соцсетями.
+
+**Как изменить:**
+
+```typescript
+const footerLinks = {
+ product: {
+ title: "Ваша категория",
+ links: [
+ { name: "Ссылка", href: "#" },
+ // ...
+ ],
+ },
+ // ... добавьте колонки
+};
+
+const socialLinks = [
+ { name: "GitHub", icon: Github, href: "#" },
+ // ...
+];
+```
+
+---
+
+## 🎨 Стилизация
+
+### CSS Переменные
+
+Все цвета настраиваются в `src/app/globals.css`:
+
+```css
+:root {
+ /* Градиенты для лендинга */
+ --gradient-from: oklch(0.67 0.24 252); /* Синий */
+ --gradient-via: oklch(0.62 0.23 295); /* Фиолетовый */
+ --gradient-to: oklch(0.72 0.19 345); /* Розовый */
+
+ /* Акцентный цвет */
+ --feature-accent: oklch(0.65 0.21 165); /* Бирюзовый */
+
+ /* Spacing */
+ --section-padding-y: 5rem;
+ --section-padding-y-lg: 8rem;
+}
+```
+
+### Utility классы
+
+Три готовых класса для градиентов:
+
+```css
+.text-gradient /* Градиентный текст */
+/* Градиентный текст */
+/* Градиентный текст */
+/* Градиентный текст */
+.bg-gradient-primary /* Градиентный фон */
+.border-gradient; /* Градиентная рамка */
+```
+
+**Использование:**
+
+```tsx
+
Заголовок с градиентом
+```
+
+---
+
+## ✨ Анимации
+
+### Framer Motion паттерны
+
+#### 1. Fade-in + Slide-up (для заголовков)
+
+```typescript
+initial={{ opacity: 0, y: 20 }}
+whileInView={{ opacity: 1, y: 0 }}
+viewport={{ once: true }}
+transition={{ duration: 0.5 }}
+```
+
+#### 2. Stagger (для списков)
+
+```typescript
+// Используйте готовые варианты из shared/hooks/use-scroll-animation.ts
+import {
+ staggerContainer,
+ staggerItem,
+} from "@/shared/hooks/use-scroll-animation";
+
+
+ {items.map((item) => (
+
+ {/* content */}
+
+ ))}
+ ;
+```
+
+#### 3. Hover эффекты
+
+```typescript
+whileHover={{ y: -5, scale: 1.02 }}
+transition={{ type: "spring", stiffness: 300 }}
+```
+
+#### 4. Анимированный счетчик (StatCard)
+
+Автоматически анимирует числовые значения при появлении в viewport.
+
+---
+
+## 🔧 Как изменять шаблон
+
+### Быстрый старт
+
+1. **Изменить брендинг:**
+
+ - Замените "TaskFlow" на название вашего продукта
+ - Обновите логотип в `Header` и `Footer`
+ - Измените цвета в `globals.css`
+
+2. **Изменить контент:**
+
+ - Откройте нужный widget в `src/widgets/`
+ - Найдите массив с данными (features, testimonials, etc.)
+ - Замените текст и изображения
+
+3. **Добавить/удалить секции:**
+
+ ```typescript
+ // src/app/page.tsx
+ export default function Home() {
+ return (
+ <>
+
+
+
+ {/* Добавьте или удалите секции здесь */}
+
+
+
+ >
+ );
+ }
+ ```
+
+4. **Изменить порядок секций:**
+ Просто поменяйте местами компоненты в `page.tsx`
+
+---
+
+### Создание новой секции
+
+1. Создайте файл `src/widgets/your-section.tsx`:
+
+```typescript
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+
+export function YourSection() {
+ return (
+
+
+
+ {/* Ваш контент */}
+
+ );
+}
+```
+
+2. Импортируйте в `page.tsx`:
+
+```typescript
+import { YourSection } from "@/widgets/your-section";
+```
+
+3. Добавьте в композицию:
+
+```typescript
+
+```
+
+---
+
+### Создание нового feature-компонента
+
+1. Создайте файл `src/features/your-card.tsx`:
+
+```typescript
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion } from "framer-motion";
+
+export interface YourCardProps {
+ title: string;
+ // ... ваши props
+}
+
+export function YourCard({ title }: YourCardProps) {
+ return (
+
+ {title}
+ {/* ... ваш контент */}
+
+ );
+}
+```
+
+2. Используйте в widget:
+
+```typescript
+import { YourCard } from "@/features/your-card";
+```
+
+---
+
+## 📝 Чеклист для адаптации
+
+- [ ] Изменить название продукта (TaskFlow → Ваше)
+- [ ] Обновить логотип
+- [ ] Изменить цветовую схему (globals.css)
+- [ ] Заменить все текстовые плейсхолдеры
+- [ ] Загрузить реальные изображения
+- [ ] Обновить иконки (выбрать из lucide-react)
+- [ ] Изменить количество фич/отзывов/членов команды
+- [ ] Настроить цены и тарифы
+- [ ] Обновить FAQ
+- [ ] Добавить реальные ссылки в Footer
+- [ ] Настроить соцсети
+- [ ] Проверить адаптивность на всех размерах экрана
+- [ ] Протестировать все анимации
+- [ ] Добавить реальные ссылки CTA
+
+---
+
+## 🚀 Преимущества шаблона
+
+✅ **Правильная FSD архитектура** - легко масштабировать и поддерживать
+✅ **Переиспользуемые компоненты** - DRY принцип
+✅ **Типизация TypeScript** - меньше ошибок
+✅ **Современные анимации** - Framer Motion
+✅ **Темная/светлая тема** - автоматически
+✅ **Полностью адаптивный** - от 320px до 4K
+✅ **Accessibility** - семантичный HTML, ARIA
+✅ **shadcn/ui** - 50+ готовых компонентов
+✅ **Чистый код** - комментарии и документация
+
+---
+
+## 🎯 Для ИИ-ассистентов
+
+Этот шаблон специально оптимизирован для работы с ИИ:
+
+1. **Понятная структура** - FSD методология
+2. **Изолированные компоненты** - легко заменять
+3. **Подробные props** - TypeScript интерфейсы
+4. **Комментарии в коде** - объяснения назначения
+5. **Примеры данных** - в каждом widget
+6. **Модульность** - добавляй/удаляй секции без проблем
+
+### Типичные задачи для ИИ:
+
+**"Измени цвета на зеленый"**
+→ Обнови переменные в `globals.css`
+
+**"Добавь секцию с видео"**
+→ Создай новый widget в `src/widgets/video-section.tsx`
+
+**"Убери секцию Team"**
+→ Удали ` ` из `page.tsx`
+
+**"Сделай 4 тарифа вместо 3"**
+→ Добавь объект в массив `pricingPlans` в `pricing-section.tsx`
+
+---
+
+## 📦 Технологии
+
+- **Next.js 14** - React framework
+- **TypeScript** - Type safety
+- **Tailwind CSS 4** - Utility-first CSS
+- **Framer Motion** - Анимации
+- **shadcn/ui** - UI компоненты
+- **Lucide React** - Иконки
+- **next-themes** - Темизация
+
+---
+
+## 🤝 Поддержка
+
+Этот шаблон создан как база для ИИ-генерации уникальных лендингов. Изучите структуру, измените контент под ваш продукт, и получите профессиональную продающую страницу!
+
+**Успешной адаптации! 🚀**
diff --git a/src/app/globals.css b/src/app/globals.css
index dc98be7..95e0dce 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -76,6 +76,21 @@
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
+
+ /* Gradient colors для лендинга */
+ --gradient-from: oklch(0.67 0.24 252);
+ --gradient-via: oklch(0.62 0.23 295);
+ --gradient-to: oklch(0.72 0.19 345);
+
+ /* Success/Feature accent */
+ --feature-accent: oklch(0.65 0.21 165);
+
+ /* Spacing для секций */
+ --section-padding-y: 5rem;
+ --section-padding-y-lg: 8rem;
+
+ /* Container */
+ --container-max-width: 80rem;
}
.dark {
@@ -110,6 +125,11 @@
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
+
+ --gradient-from: oklch(0.65 0.25 252);
+ --gradient-via: oklch(0.60 0.24 295);
+ --gradient-to: oklch(0.70 0.20 345);
+ --feature-accent: oklch(0.63 0.22 165);
}
@layer base {
@@ -120,3 +140,17 @@
@apply bg-background text-foreground;
}
}
+
+@layer utilities {
+ .text-gradient {
+ @apply bg-gradient-to-r from-[var(--gradient-from)] via-[var(--gradient-via)] to-[var(--gradient-to)] bg-clip-text text-transparent;
+ }
+
+ .bg-gradient-primary {
+ @apply bg-gradient-to-br from-[var(--gradient-from)]/10 via-[var(--gradient-via)]/10 to-[var(--gradient-to)]/10;
+ }
+
+ .border-gradient {
+ border-image: linear-gradient(to right, var(--gradient-from), var(--gradient-via), var(--gradient-to)) 1;
+ }
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 275318f..3367609 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,138 +1,41 @@
-"use client";
-
-import { motion } from "framer-motion";
-import { Server, Code } from "lucide-react";
+import { Header } from "@/widgets/header";
+import { HeroSection } from "@/widgets/hero-section";
+import { FeaturesSection } from "@/widgets/features-section";
+import { StatsSection } from "@/widgets/stats-section";
+import { HowItWorksSection } from "@/widgets/how-it-works-section";
+import { ComparisonSection } from "@/widgets/comparison-section";
+import { GallerySection } from "@/widgets/gallery-section";
+import { SocialProofSection } from "@/widgets/social-proof-section";
+import { TeamSection } from "@/widgets/team-section";
+import { PricingSection } from "@/widgets/pricing-section";
+import { FaqSection } from "@/widgets/faq-section";
+import { CtaSection } from "@/widgets/cta-section";
+import { Footer } from "@/widgets/footer";
+/**
+ * Главная страница - композиция всех секций лендинга
+ * Универсальный шаблон для любого продукта/бизнеса
+ */
export default function Home() {
return (
-
-
-
-
- Tungulov.space
-
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- Избавляем вас от головной боли разработки
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Давайте приступим к воплощению вашей идеи
-
-
-
-
-
-
-
- Напишите о вашем проекте
-
-
- и уже через пару мгновений протестируйте демо
-
-
-
-
-
-
-
-
-
-
-
+
+ >
);
}
diff --git a/src/features/comparison-item.tsx b/src/features/comparison-item.tsx
new file mode 100644
index 0000000..f470f18
--- /dev/null
+++ b/src/features/comparison-item.tsx
@@ -0,0 +1,115 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion } from "framer-motion";
+import { LucideIcon, X, Check } from "lucide-react";
+
+export interface ComparisonItemProps {
+ before: {
+ title: string;
+ description: string;
+ icon?: LucideIcon;
+ };
+ after: {
+ title: string;
+ description: string;
+ icon?: LucideIcon;
+ };
+ variant?: "side-by-side" | "overlay";
+ className?: string;
+}
+
+/**
+ * Элемент сравнения "до/после"
+ * Используется в Comparison Section
+ */
+export function ComparisonItem({
+ before,
+ after,
+ variant = "side-by-side",
+ className,
+}: ComparisonItemProps) {
+ if (variant === "overlay") {
+ return (
+
+
+ {/* Before */}
+
+
+
+
+
{before.title}
+
{before.description}
+
+
+ {/* After */}
+
+
+
+
+
{after.title}
+
{after.description}
+
+
+
+ );
+ }
+
+ return (
+
+ {/* Before */}
+
+
+ {before.icon && (
+
+
+
+ )}
+
+
+ {before.title}
+
+
{before.description}
+
+
+
+
+ {/* Arrow */}
+
+ →
+
+
+ {/* After */}
+
+
+ {after.icon && (
+
+ )}
+
+
+ {after.title}
+
+
{after.description}
+
+
+
+
+ );
+}
+
+
+
diff --git a/src/features/feature-card.tsx b/src/features/feature-card.tsx
new file mode 100644
index 0000000..0dacd21
--- /dev/null
+++ b/src/features/feature-card.tsx
@@ -0,0 +1,89 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion } from "framer-motion";
+import { LucideIcon } from "lucide-react";
+import Link from "next/link";
+import { ArrowRight } from "lucide-react";
+
+export interface FeatureCardProps {
+ icon: LucideIcon;
+ title: string;
+ description: string;
+ variant?: "default" | "bordered" | "filled";
+ link?: {
+ href: string;
+ label: string;
+ };
+ className?: string;
+}
+
+const variantClasses = {
+ default: "bg-card hover:bg-accent/50",
+ bordered: "bg-transparent border-2 border-border hover:border-[var(--feature-accent)]",
+ filled: "bg-gradient-primary border border-border/50",
+};
+
+/**
+ * Карточка фичи/преимущества
+ * Используется в Features Section
+ */
+export function FeatureCard({
+ icon: Icon,
+ title,
+ description,
+ variant = "default",
+ link,
+ className,
+}: FeatureCardProps) {
+ const content = (
+ <>
+
+
+
+
+ {title}
+
+ {description}
+
+ {link && (
+
+ )}
+ >
+ );
+
+ const card = (
+
+ {content}
+
+ );
+
+ if (link) {
+ return (
+
+ {card}
+
+ );
+ }
+
+ return card;
+}
+
+
+
diff --git a/src/features/gradient-background.tsx b/src/features/gradient-background.tsx
new file mode 100644
index 0000000..843a28d
--- /dev/null
+++ b/src/features/gradient-background.tsx
@@ -0,0 +1,92 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion } from "framer-motion";
+
+export interface GradientBackgroundProps {
+ variant?: "radial" | "mesh" | "animated";
+ className?: string;
+ opacity?: number;
+}
+
+/**
+ * Декоративный градиентный фон для секций
+ * Варианты: radial (радиальный), mesh (сеточный), animated (с анимацией)
+ */
+export function GradientBackground({
+ variant = "radial",
+ className,
+ opacity = 0.5,
+}: GradientBackgroundProps) {
+ if (variant === "radial") {
+ return (
+
+ );
+ }
+
+ if (variant === "mesh") {
+ return (
+
+ );
+ }
+
+ if (variant === "animated") {
+ return (
+
+
+
+
+ );
+ }
+
+ return null;
+}
+
+
diff --git a/src/features/logo-cloud.tsx b/src/features/logo-cloud.tsx
new file mode 100644
index 0000000..0241366
--- /dev/null
+++ b/src/features/logo-cloud.tsx
@@ -0,0 +1,107 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion } from "framer-motion";
+import Image from "next/image";
+import Link from "next/link";
+
+export interface LogoCloudProps {
+ logos: Array<{
+ name: string;
+ src: string;
+ url?: string;
+ }>;
+ variant?: "grid" | "marquee";
+ animated?: boolean;
+ className?: string;
+}
+
+/**
+ * Облако логотипов компаний-клиентов
+ * Используется в Social Proof Section
+ */
+export function LogoCloud({
+ logos,
+ variant = "grid",
+ animated = false,
+ className,
+}: LogoCloudProps) {
+ if (variant === "marquee") {
+ return (
+
+
+ {/* Дублируем логотипы для бесшовной прокрутки */}
+ {[...logos, ...logos].map((logo, index) => (
+
+ ))}
+
+
+ );
+ }
+
+ return (
+
+ {logos.map((logo) => (
+
+ ))}
+
+ );
+}
+
+function LogoItem({
+ logo,
+}: {
+ logo: { name: string; src: string; url?: string };
+}) {
+ const content = (
+
+
+
+ );
+
+ if (logo.url) {
+ return (
+
+ {content}
+
+ );
+ }
+
+ return {content}
;
+}
+
+
+
diff --git a/src/features/portfolio-item.tsx b/src/features/portfolio-item.tsx
new file mode 100644
index 0000000..a8666bf
--- /dev/null
+++ b/src/features/portfolio-item.tsx
@@ -0,0 +1,93 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion } from "framer-motion";
+import Image from "next/image";
+import Link from "next/link";
+import { Badge } from "@/shared/ui/badge";
+
+export interface PortfolioItemProps {
+ image: string;
+ title: string;
+ description?: string;
+ category?: string;
+ link?: string;
+ variant?: "card" | "overlay";
+ className?: string;
+}
+
+/**
+ * Элемент портфолио/галереи
+ * Используется в Gallery Section
+ */
+export function PortfolioItem({
+ image,
+ title,
+ description,
+ category,
+ link,
+ variant = "card",
+ className,
+}: PortfolioItemProps) {
+ const content = (
+
+
+
+
+ {variant === "overlay" && (
+
+ )}
+
+
+
+ {category && (
+
+ {category}
+
+ )}
+
{title}
+ {description && (
+
+ {description}
+
+ )}
+
+
+ );
+
+ if (link) {
+ return (
+
+ {content}
+
+ );
+ }
+
+ return content;
+}
+
+
+
diff --git a/src/features/pricing-card.tsx b/src/features/pricing-card.tsx
new file mode 100644
index 0000000..8f42b83
--- /dev/null
+++ b/src/features/pricing-card.tsx
@@ -0,0 +1,117 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { Card } from "@/shared/ui/card";
+import { Button } from "@/shared/ui/button";
+import { Badge } from "@/shared/ui/badge";
+import { motion } from "framer-motion";
+import { Check, X } from "lucide-react";
+import Link from "next/link";
+
+export interface PricingCardProps {
+ name: string;
+ price: number | "custom";
+ period?: "month" | "year";
+ description: string;
+ features: Array<{
+ text: string;
+ included: boolean;
+ }>;
+ ctaLabel: string;
+ ctaHref: string;
+ popular?: boolean;
+ variant?: "default" | "featured";
+ className?: string;
+}
+
+/**
+ * Карточка тарифного плана
+ * Используется в Pricing Section
+ */
+export function PricingCard({
+ name,
+ price,
+ period = "month",
+ description,
+ features,
+ ctaLabel,
+ ctaHref,
+ popular = false,
+ variant = "default",
+ className,
+}: PricingCardProps) {
+ const isFeatured = variant === "featured" || popular;
+
+ return (
+
+ {popular && (
+
+ Популярный
+
+ )}
+
+
+
+
{name}
+
{description}
+
+
+
+ {price === "custom" ? (
+
Индивидуально
+ ) : (
+
+ {price.toLocaleString('ru-RU')} ₽
+
+ /{period === "month" ? "мес" : "год"}
+
+
+ )}
+
+
+
+ {features.map((feature, index) => (
+
+ {feature.included ? (
+
+ ) : (
+
+ )}
+
+ {feature.text}
+
+
+ ))}
+
+
+
+ {ctaLabel}
+
+
+
+ );
+}
+
diff --git a/src/features/section-container.tsx b/src/features/section-container.tsx
new file mode 100644
index 0000000..93a3d96
--- /dev/null
+++ b/src/features/section-container.tsx
@@ -0,0 +1,60 @@
+import { cn } from "@/shared/lib/utils";
+import { ReactNode } from "react";
+
+export interface SectionContainerProps {
+ children: ReactNode;
+ className?: string;
+ variant?: "default" | "narrow" | "wide";
+ background?: "default" | "muted" | "gradient";
+ withPadding?: boolean;
+ id?: string;
+}
+
+const variantClasses = {
+ default: "max-w-7xl",
+ narrow: "max-w-5xl",
+ wide: "max-w-[90rem]",
+};
+
+const backgroundClasses = {
+ default: "",
+ muted: "bg-muted/50",
+ gradient: "bg-gradient-primary",
+};
+
+/**
+ * Универсальный контейнер для секций лендинга
+ * Обеспечивает единообразный spacing, ширину и padding
+ */
+export function SectionContainer({
+ children,
+ className,
+ variant = "default",
+ background = "default",
+ withPadding = true,
+ id,
+}: SectionContainerProps) {
+ return (
+
+ );
+}
+
+
+
diff --git a/src/features/section-header.tsx b/src/features/section-header.tsx
new file mode 100644
index 0000000..95d858e
--- /dev/null
+++ b/src/features/section-header.tsx
@@ -0,0 +1,87 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion } from "framer-motion";
+import { useScrollAnimation } from "@/shared/hooks/use-scroll-animation";
+
+export interface SectionHeaderProps {
+ title: string;
+ subtitle?: string;
+ description?: string;
+ align?: "left" | "center" | "right";
+ withGradient?: boolean;
+ className?: string;
+}
+
+const alignClasses = {
+ left: "text-left",
+ center: "text-center mx-auto",
+ right: "text-right ml-auto",
+};
+
+/**
+ * Переиспользуемый заголовок секции
+ * Поддерживает subtitle, description, выравнивание и gradient эффект
+ */
+export function SectionHeader({
+ title,
+ subtitle,
+ description,
+ align = "center",
+ withGradient = false,
+ className,
+}: SectionHeaderProps) {
+ const animation = useScrollAnimation({ direction: "up", duration: 0.6 });
+
+ return (
+
+ {subtitle && (
+
+ {subtitle}
+
+ )}
+
+
+ {title}
+
+
+ {description && (
+
+ {description}
+
+ )}
+
+ );
+}
+
+
+
diff --git a/src/features/stat-card.tsx b/src/features/stat-card.tsx
new file mode 100644
index 0000000..bc73d43
--- /dev/null
+++ b/src/features/stat-card.tsx
@@ -0,0 +1,113 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion, useMotionValue, useTransform, animate } from "framer-motion";
+import { LucideIcon, TrendingUp, TrendingDown } from "lucide-react";
+import { useEffect, useRef } from "react";
+import { useInView } from "@/shared/hooks/use-in-view";
+
+export interface StatCardProps {
+ value: string | number;
+ label: string;
+ description?: string;
+ icon?: LucideIcon;
+ trend?: {
+ value: number;
+ direction: "up" | "down";
+ };
+ animated?: boolean;
+ className?: string;
+}
+
+/**
+ * Карточка статистики/достижения
+ * Используется в Stats Section
+ * Поддерживает анимированный счетчик для числовых значений
+ */
+export function StatCard({
+ value,
+ label,
+ description,
+ icon: Icon,
+ trend,
+ animated = true,
+ className,
+}: StatCardProps) {
+ const { ref, isInView } = useInView({ threshold: 0.5 });
+ const count = useMotionValue(0);
+ const rounded = useTransform(count, (latest) => Math.round(latest));
+ const hasAnimated = useRef(false);
+
+ // Попытка извлечь число из строки для анимации
+ const numericValue =
+ typeof value === "number"
+ ? value
+ : parseFloat(String(value).replace(/[^0-9.]/g, ""));
+ const isNumeric = !isNaN(numericValue);
+ const prefix = typeof value === "string" ? value.replace(/[0-9.,]/g, "") : "";
+
+ useEffect(() => {
+ if (isInView && !hasAnimated.current && animated && isNumeric) {
+ hasAnimated.current = true;
+ const controls = animate(count, numericValue, {
+ duration: 2,
+ ease: "easeOut",
+ });
+ return controls.stop;
+ }
+ }, [isInView, count, numericValue, animated, isNumeric]);
+
+ return (
+
+ {Icon && (
+
+
+
+ )}
+
+
+ {animated && isNumeric ? (
+
+ {prefix}
+ {rounded}
+
+ ) : (
+
+ {value}
+
+ )}
+
+
+ {label}
+
+ {description && (
+ {description}
+ )}
+
+ {trend && (
+
+ {trend.direction === "up" ? (
+
+ ) : (
+
+ )}
+ {trend.value}%
+
+ )}
+
+ );
+}
+
+
diff --git a/src/features/step-card.tsx b/src/features/step-card.tsx
new file mode 100644
index 0000000..b5fad92
--- /dev/null
+++ b/src/features/step-card.tsx
@@ -0,0 +1,55 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { motion } from "framer-motion";
+import { LucideIcon } from "lucide-react";
+
+export interface StepCardProps {
+ number: number;
+ title: string;
+ description: string;
+ icon?: LucideIcon;
+ variant?: "numbered" | "icon";
+ className?: string;
+}
+
+/**
+ * Карточка шага
+ * Используется в How It Works Section
+ */
+export function StepCard({
+ number,
+ title,
+ description,
+ icon: Icon,
+ variant = "numbered",
+ className,
+}: StepCardProps) {
+ return (
+
+
+ {variant === "numbered" ? (
+
+ {number}
+
+ ) : Icon ? (
+
+
+
+ ) : null}
+
+
{title}
+
{description}
+
+
+ );
+}
+
+
+
diff --git a/src/features/team-member-card.tsx b/src/features/team-member-card.tsx
new file mode 100644
index 0000000..e5bd7af
--- /dev/null
+++ b/src/features/team-member-card.tsx
@@ -0,0 +1,91 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { Card } from "@/shared/ui/card";
+import { motion } from "framer-motion";
+import Image from "next/image";
+import Link from "next/link";
+import { Github, Linkedin, Twitter } from "lucide-react";
+
+export interface TeamMemberCardProps {
+ name: string;
+ role: string;
+ bio?: string;
+ image: string;
+ socials?: Array<{
+ platform: "github" | "linkedin" | "twitter";
+ url: string;
+ }>;
+ className?: string;
+}
+
+const socialIcons = {
+ github: Github,
+ linkedin: Linkedin,
+ twitter: Twitter,
+};
+
+/**
+ * Карточка члена команды
+ * Используется в Team Section
+ */
+export function TeamMemberCard({
+ name,
+ role,
+ bio,
+ image,
+ socials,
+ className,
+}: TeamMemberCardProps) {
+ return (
+
+
+
+
+
+
+
+
{name}
+
+ {role}
+
+
+ {bio &&
{bio}
}
+
+ {socials && socials.length > 0 && (
+
+ {socials.map((social) => {
+ const Icon = socialIcons[social.platform];
+ return (
+
+
+
+ );
+ })}
+
+ )}
+
+
+
+ );
+}
+
+
+
diff --git a/src/features/testimonial-card.tsx b/src/features/testimonial-card.tsx
new file mode 100644
index 0000000..60c2d63
--- /dev/null
+++ b/src/features/testimonial-card.tsx
@@ -0,0 +1,116 @@
+"use client";
+
+import { cn } from "@/shared/lib/utils";
+import { Card } from "@/shared/ui/card";
+import { Avatar, AvatarFallback, AvatarImage } from "@/shared/ui/avatar";
+import { motion } from "framer-motion";
+import { Star, Quote } from "lucide-react";
+
+export interface TestimonialCardProps {
+ content: string;
+ author: {
+ name: string;
+ role: string;
+ company?: string;
+ avatar?: string;
+ };
+ rating?: number;
+ variant?: "card" | "quote";
+ className?: string;
+}
+
+/**
+ * Карточка отзыва клиента
+ * Используется в Social Proof Section
+ */
+export function TestimonialCard({
+ content,
+ author,
+ rating,
+ variant = "card",
+ className,
+}: TestimonialCardProps) {
+ const getInitials = (name: string) => {
+ return name
+ .split(" ")
+ .map((n) => n[0])
+ .join("")
+ .toUpperCase()
+ .slice(0, 2);
+ };
+
+ if (variant === "quote") {
+ return (
+
+
+
+ {content}
+
+
+
+ {getInitials(author.name)}
+
+
+
{author.name}
+
+ {author.role}
+ {author.company && ` @ ${author.company}`}
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+ {rating && (
+
+ {Array.from({ length: 5 }).map((_, i) => (
+
+ ))}
+
+ )}
+
+ {content}
+
+
+
+
+ {getInitials(author.name)}
+
+
+
{author.name}
+
+ {author.role}
+ {author.company && ` @ ${author.company}`}
+
+
+
+
+
+ );
+}
+
+
diff --git a/src/shared/hooks/use-in-view.ts b/src/shared/hooks/use-in-view.ts
new file mode 100644
index 0000000..9db4acf
--- /dev/null
+++ b/src/shared/hooks/use-in-view.ts
@@ -0,0 +1,54 @@
+import { useEffect, useRef, useState, RefObject } from "react";
+
+export interface UseInViewOptions {
+ threshold?: number;
+ rootMargin?: string;
+ triggerOnce?: boolean;
+}
+
+export interface UseInViewReturn {
+ ref: RefObject;
+ isInView: boolean;
+}
+
+/**
+ * Hook для определения когда элемент появляется в viewport
+ * @param options - настройки Intersection Observer
+ * @returns ref для элемента и статус видимости
+ */
+export function useInView(
+ options: UseInViewOptions = {}
+): UseInViewReturn {
+ const { threshold = 0.1, rootMargin = "0px", triggerOnce = true } = options;
+ const ref = useRef(null);
+ const [isInView, setIsInView] = useState(false);
+
+ useEffect(() => {
+ const element = ref.current;
+ if (!element) return;
+
+ const observer = new IntersectionObserver(
+ ([entry]) => {
+ const inView = entry.isIntersecting;
+ setIsInView(inView);
+
+ // Если triggerOnce, отключаем observer после первого срабатывания
+ if (inView && triggerOnce) {
+ observer.unobserve(element);
+ }
+ },
+ {
+ threshold,
+ rootMargin,
+ }
+ );
+
+ observer.observe(element);
+
+ return () => {
+ observer.disconnect();
+ };
+ }, [threshold, rootMargin, triggerOnce]);
+
+ return { ref, isInView };
+}
diff --git a/src/shared/hooks/use-scroll-animation.ts b/src/shared/hooks/use-scroll-animation.ts
new file mode 100644
index 0000000..8f63a38
--- /dev/null
+++ b/src/shared/hooks/use-scroll-animation.ts
@@ -0,0 +1,121 @@
+import { Variants } from "framer-motion";
+
+export interface ScrollAnimationConfig {
+ direction?: "up" | "down" | "left" | "right";
+ delay?: number;
+ duration?: number;
+ distance?: number;
+}
+
+/**
+ * Хук для генерации настроек scroll-triggered анимаций
+ * @param config - конфигурация анимации
+ * @returns объект с вариантами анимации и настройками viewport
+ */
+export function useScrollAnimation(config: ScrollAnimationConfig = {}) {
+ const {
+ direction = "up",
+ delay = 0,
+ duration = 0.5,
+ distance = 20,
+ } = config;
+
+ const getInitialPosition = () => {
+ switch (direction) {
+ case "up":
+ return { y: distance, x: 0 };
+ case "down":
+ return { y: -distance, x: 0 };
+ case "left":
+ return { y: 0, x: distance };
+ case "right":
+ return { y: 0, x: -distance };
+ default:
+ return { y: distance, x: 0 };
+ }
+ };
+
+ const position = getInitialPosition();
+
+ return {
+ initial: {
+ opacity: 0,
+ ...position,
+ },
+ whileInView: {
+ opacity: 1,
+ x: 0,
+ y: 0,
+ },
+ viewport: {
+ once: true,
+ margin: "-50px",
+ },
+ transition: {
+ duration,
+ delay,
+ ease: "easeOut",
+ },
+ };
+}
+
+/**
+ * Варианты для stagger анимации списков/сеток
+ */
+export const staggerContainer: Variants = {
+ hidden: { opacity: 0 },
+ show: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ delayChildren: 0.1,
+ },
+ },
+};
+
+export const staggerItem: Variants = {
+ hidden: { opacity: 0, y: 20 },
+ show: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ duration: 0.5,
+ ease: "easeOut",
+ },
+ },
+};
+
+/**
+ * Варианты для hover эффектов на карточках
+ */
+export const cardHover = {
+ rest: {
+ scale: 1,
+ y: 0,
+ },
+ hover: {
+ scale: 1.02,
+ y: -5,
+ transition: {
+ type: "spring",
+ stiffness: 300,
+ damping: 20,
+ },
+ },
+};
+
+/**
+ * Варианты для fade-in анимации
+ */
+export const fadeIn: Variants = {
+ hidden: { opacity: 0 },
+ show: {
+ opacity: 1,
+ transition: {
+ duration: 0.5,
+ },
+ },
+};
+
+
+
diff --git a/src/widgets/comparison-section.tsx b/src/widgets/comparison-section.tsx
new file mode 100644
index 0000000..b2bb6aa
--- /dev/null
+++ b/src/widgets/comparison-section.tsx
@@ -0,0 +1,71 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+import { ComparisonItem } from "@/features/comparison-item";
+import { FileText, Workflow, Mail } from "lucide-react";
+
+const comparisons = [
+ {
+ before: {
+ title: "Ручное управление",
+ description: "Потеря времени на рутинные задачи и отслеживание статусов",
+ icon: FileText,
+ },
+ after: {
+ title: "Автоматизация",
+ description: "Автоматические уведомления, дедлайны и распределение задач",
+ icon: Workflow,
+ },
+ },
+ {
+ before: {
+ title: "Хаос в задачах",
+ description: "Задачи разбросаны по разным инструментам и чатам",
+ },
+ after: {
+ title: "Структурированный процесс",
+ description: "Все задачи в одном месте с четкой структурой и приоритетами",
+ },
+ },
+ {
+ before: {
+ title: "Email-цепочки",
+ description: "Потерянные сообщения и долгие согласования",
+ icon: Mail,
+ },
+ after: {
+ title: "Централизованное общение",
+ description: "Вся коммуникация по проекту в контексте задач",
+ },
+ },
+];
+
+/**
+ * Comparison Section - секция сравнения "до/после"
+ */
+export function ComparisonSection() {
+ return (
+
+
+
+
+ {comparisons.map((comparison, index) => (
+
+ ))}
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/cta-section.tsx b/src/widgets/cta-section.tsx
new file mode 100644
index 0000000..9798fc6
--- /dev/null
+++ b/src/widgets/cta-section.tsx
@@ -0,0 +1,80 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { GradientBackground } from "@/features/gradient-background";
+import { Button } from "@/shared/ui/button";
+import { Input } from "@/shared/ui/input";
+import { motion } from "framer-motion";
+import { ArrowRight, Sparkles } from "lucide-react";
+import Link from "next/link";
+
+/**
+ * CTA Section - финальный призыв к действию
+ */
+export function CtaSection() {
+ return (
+
+
+
+
+
+
+
+
+ Начните работать эффективнее уже сегодня
+
+
+
+
+ Готовы{" "}
+ трансформировать
+
+ работу вашей команды?
+
+
+
+ Присоединяйтесь к тысячам команд, которые уже используют TaskFlow
+ для достижения своих целей быстрее и эффективнее.
+
+
+
+
+
+ Попробовать бесплатно
+
+
+
+
+
+ 14 дней бесплатно • Кредитная карта не требуется • Отмените в любое время
+
+
+
+
+ ✓ Настройка за 5 минут
+
+
+ ✓ Поддержка 24/7
+
+
+ ✓ Безопасность данных
+
+
+
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/faq-section.tsx b/src/widgets/faq-section.tsx
new file mode 100644
index 0000000..8cf52a9
--- /dev/null
+++ b/src/widgets/faq-section.tsx
@@ -0,0 +1,99 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+import {
+ Accordion,
+ AccordionContent,
+ AccordionItem,
+ AccordionTrigger,
+} from "@/shared/ui/accordion";
+
+const faqs = [
+ {
+ question: "Как начать работу с TaskFlow?",
+ answer:
+ "Просто зарегистрируйтесь на сайте, создайте свой первый проект и пригласите команду. Настройка займет не более 5 минут. Мы предлагаем 14-дневный бесплатный пробный период для всех планов.",
+ },
+ {
+ question: "Могу ли я изменить тариф в любое время?",
+ answer:
+ "Да, вы можете повысить или понизить свой тариф в любое время. При повышении тарифа вы сразу получите доступ к новым функциям. При понижении изменения вступят в силу со следующего платежного периода.",
+ },
+ {
+ question: "Есть ли бесплатный период?",
+ answer:
+ "Да! Мы предлагаем 14-дневную бесплатную пробную версию для всех платных планов. Кредитная карта не требуется для начала пробного периода. План Free доступен всегда без ограничений по времени.",
+ },
+ {
+ question: "Как работает поддержка?",
+ answer:
+ "Для пользователей Free доступна поддержка по email. Пользователи Pro получают приоритетную поддержку по email и чату. Клиенты Enterprise имеют доступ к выделенному менеджеру и поддержке 24/7.",
+ },
+ {
+ question: "Безопасны ли мои данные?",
+ answer:
+ "Абсолютно! Мы используем шифрование на уровне банков (SSL/TLS), регулярно делаем резервные копии и храним данные в защищенных дата-центрах. Мы соответствуем стандартам GDPR и SOC 2.",
+ },
+ {
+ question: "Можно ли интегрировать TaskFlow с другими сервисами?",
+ answer:
+ "Да! TaskFlow интегрируется с более чем 50 популярными сервисами, включая Slack, GitHub, Jira, Google Calendar и многими другими. Пользователи Enterprise также получают доступ к API для создания собственных интеграций.",
+ },
+ {
+ question: "Доступно ли мобильное приложение?",
+ answer:
+ "Да, у нас есть нативные приложения для iOS и Android. Все функции доступны на мобильных устройствах, и данные синхронизируются в реальном времени между всеми платформами.",
+ },
+ {
+ question: "Как отменить подписку?",
+ answer:
+ "Вы можете отменить подписку в любое время через настройки аккаунта. При отмене вы сохраните доступ ко всем функциям до конца оплаченного периода. Никаких штрафов за отмену подписки нет.",
+ },
+];
+
+/**
+ * FAQ Section - секция с частыми вопросами
+ */
+export function FaqSection() {
+ return (
+
+
+
+
+
+ {faqs.map((faq, index) => (
+
+
+ {faq.question}
+
+
+ {faq.answer}
+
+
+ ))}
+
+
+
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/features-section.tsx b/src/widgets/features-section.tsx
new file mode 100644
index 0000000..ccc515b
--- /dev/null
+++ b/src/widgets/features-section.tsx
@@ -0,0 +1,87 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+import { FeatureCard } from "@/features/feature-card";
+import { motion } from "framer-motion";
+import { staggerContainer, staggerItem } from "@/shared/hooks/use-scroll-animation";
+import {
+ Zap,
+ Users,
+ BarChart3,
+ Puzzle,
+ Shield,
+ Headphones,
+} from "lucide-react";
+
+const features = [
+ {
+ icon: Zap,
+ title: "Быстрый старт",
+ description:
+ "Начните работу за 5 минут. Интуитивный интерфейс и простая настройка.",
+ },
+ {
+ icon: Users,
+ title: "Командная работа",
+ description:
+ "Пригласите коллег и работайте вместе в реальном времени над проектами.",
+ },
+ {
+ icon: BarChart3,
+ title: "Аналитика",
+ description:
+ "Отслеживайте прогресс в реальном времени с подробными отчетами и дашбордами.",
+ },
+ {
+ icon: Puzzle,
+ title: "Интеграции",
+ description:
+ "Подключите любимые инструменты: Slack, GitHub, Jira и еще более 50 сервисов.",
+ },
+ {
+ icon: Shield,
+ title: "Безопасность",
+ description:
+ "Защита данных на уровне банков с шифрованием и регулярными бэкапами.",
+ },
+ {
+ icon: Headphones,
+ title: "Поддержка 24/7",
+ description:
+ "Наша команда всегда готова помочь вам в любое время дня и ночи.",
+ },
+];
+
+/**
+ * Features Section - секция с возможностями/преимуществами
+ */
+export function FeaturesSection() {
+ return (
+
+
+
+
+ {features.map((feature) => (
+
+
+
+ ))}
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/footer.tsx b/src/widgets/footer.tsx
new file mode 100644
index 0000000..ba9d32d
--- /dev/null
+++ b/src/widgets/footer.tsx
@@ -0,0 +1,132 @@
+"use client";
+
+import Link from "next/link";
+import { Separator } from "@/shared/ui/separator";
+import { Github, Twitter, Linkedin, Youtube } from "lucide-react";
+
+const footerLinks = {
+ product: {
+ title: "Продукт",
+ links: [
+ { name: "Возможности", href: "#features" },
+ { name: "Тарифы", href: "#pricing" },
+ { name: "Обновления", href: "#" },
+ { name: "Roadmap", href: "#" },
+ ],
+ },
+ company: {
+ title: "Компания",
+ links: [
+ { name: "О нас", href: "#team" },
+ { name: "Блог", href: "#" },
+ { name: "Карьера", href: "#" },
+ { name: "Пресс-кит", href: "#" },
+ ],
+ },
+ resources: {
+ title: "Ресурсы",
+ links: [
+ { name: "Документация", href: "#" },
+ { name: "Помощь", href: "#faq" },
+ { name: "API", href: "#" },
+ { name: "Статус", href: "#" },
+ ],
+ },
+ support: {
+ title: "Поддержка",
+ links: [
+ { name: "Контакты", href: "#" },
+ { name: "FAQ", href: "#faq" },
+ { name: "Чат", href: "#" },
+ { name: "Email", href: "mailto:support@taskflow.com" },
+ ],
+ },
+};
+
+const socialLinks = [
+ { name: "GitHub", icon: Github, href: "#" },
+ { name: "Twitter", icon: Twitter, href: "#" },
+ { name: "LinkedIn", icon: Linkedin, href: "#" },
+ { name: "YouTube", icon: Youtube, href: "#" },
+];
+
+/**
+ * Footer - подвал сайта
+ */
+export function Footer() {
+ return (
+
+ );
+}
+
+
+
diff --git a/src/widgets/gallery-section.tsx b/src/widgets/gallery-section.tsx
new file mode 100644
index 0000000..f118ee6
--- /dev/null
+++ b/src/widgets/gallery-section.tsx
@@ -0,0 +1,69 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+import { PortfolioItem } from "@/features/portfolio-item";
+
+const portfolioItems = [
+ {
+ image: "/api/placeholder/600/400",
+ title: "Dashboard",
+ description: "Полная аналитика проектов",
+ category: "Интерфейс",
+ },
+ {
+ image: "/api/placeholder/600/400",
+ title: "Kanban Board",
+ description: "Визуальное управление задачами",
+ category: "Функции",
+ },
+ {
+ image: "/api/placeholder/600/400",
+ title: "Team Collaboration",
+ description: "Совместная работа в реальном времени",
+ category: "Команда",
+ },
+ {
+ image: "/api/placeholder/600/400",
+ title: "Reports",
+ description: "Детальные отчеты о прогрессе",
+ category: "Аналитика",
+ },
+ {
+ image: "/api/placeholder/600/400",
+ title: "Mobile App",
+ description: "Работайте из любой точки мира",
+ category: "Мобайл",
+ },
+ {
+ image: "/api/placeholder/600/400",
+ title: "Integrations",
+ description: "Подключение к любимым сервисам",
+ category: "Интеграции",
+ },
+];
+
+/**
+ * Gallery Section - секция с примерами/скриншотами
+ */
+export function GallerySection() {
+ return (
+
+
+
+
+ {portfolioItems.map((item) => (
+
+ ))}
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/header.tsx b/src/widgets/header.tsx
new file mode 100644
index 0000000..a411347
--- /dev/null
+++ b/src/widgets/header.tsx
@@ -0,0 +1,146 @@
+"use client";
+
+import { useState, useEffect } from "react";
+import { cn } from "@/shared/lib/utils";
+import { Button } from "@/shared/ui/button";
+import { Sheet, SheetContent, SheetTrigger } from "@/shared/ui/sheet";
+import { Menu, X } from "lucide-react";
+import Link from "next/link";
+import { useTheme } from "next-themes";
+import { Moon, Sun } from "lucide-react";
+
+const navigation = [
+ { name: "Возможности", href: "#features" },
+ { name: "Преимущества", href: "#stats" },
+ { name: "Как работает", href: "#how-it-works" },
+ { name: "Тарифы", href: "#pricing" },
+ { name: "FAQ", href: "#faq" },
+];
+
+/**
+ * Header с навигацией
+ * Sticky header с backdrop blur, мобильное меню, theme toggle
+ */
+export function Header() {
+ const [scrolled, setScrolled] = useState(false);
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+ const { theme, setTheme } = useTheme();
+
+ useEffect(() => {
+ const handleScroll = () => {
+ setScrolled(window.scrollY > 20);
+ };
+
+ window.addEventListener("scroll", handleScroll);
+ return () => window.removeEventListener("scroll", handleScroll);
+ }, []);
+
+ const scrollToSection = (href: string) => {
+ const element = document.querySelector(href);
+ if (element) {
+ element.scrollIntoView({ behavior: "smooth" });
+ setMobileMenuOpen(false);
+ }
+ };
+
+ return (
+
+
+
+ {/* Logo */}
+
+
TaskFlow
+
+
+ {/* Desktop Navigation */}
+
+ {navigation.map((item) => (
+ scrollToSection(item.href)}
+ className="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors"
+ >
+ {item.name}
+
+ ))}
+
+
+ {/* Desktop Actions */}
+
+ setTheme(theme === "dark" ? "light" : "dark")}
+ >
+
+
+ Toggle theme
+
+
+ Войти
+
+
+ Начать бесплатно
+
+
+
+ {/* Mobile Menu */}
+
+
setTheme(theme === "dark" ? "light" : "dark")}
+ >
+
+
+ Toggle theme
+
+
+
+
+
+ {mobileMenuOpen ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ {navigation.map((item) => (
+ scrollToSection(item.href)}
+ className="text-lg font-medium text-left py-2 hover:text-[var(--feature-accent)] transition-colors"
+ >
+ {item.name}
+
+ ))}
+
+
+ Войти
+
+
+ Начать бесплатно
+
+
+
+
+
+
+
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/hero-section.tsx b/src/widgets/hero-section.tsx
new file mode 100644
index 0000000..33bd722
--- /dev/null
+++ b/src/widgets/hero-section.tsx
@@ -0,0 +1,167 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { GradientBackground } from "@/features/gradient-background";
+import { Button } from "@/shared/ui/button";
+import { motion } from "framer-motion";
+import { ArrowRight, Play } from "lucide-react";
+import Link from "next/link";
+
+/**
+ * Hero Section - главная секция лендинга
+ * Варианты: centered, split (текст слева, визуал справа)
+ */
+export function HeroSection() {
+ return (
+
+
+
+
+ {/* Content */}
+
+
+
+
+
+ Новый способ управления проектами
+
+
+
+
+
+ Управляйте проектами{" "}
+ быстрее и проще
+
+
+
+ Все инструменты для командной работы в одном месте. Начните работать
+ эффективнее уже сегодня.
+
+
+
+
+
+ Начать бесплатно
+
+
+
+
+
+
+ Посмотреть демо
+
+
+
+
+
+
+
10,000+
+
Пользователей
+
+
+
+
+
+
+
+
+ {/* Visual */}
+
+
+
+
+
+
+ {/* Placeholder для мокапа/скриншота */}
+
+
+ [Hero Image / Product Mockup]
+
+
+
+
+ {/* Floating elements */}
+
+
+
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/how-it-works-section.tsx b/src/widgets/how-it-works-section.tsx
new file mode 100644
index 0000000..ae49577
--- /dev/null
+++ b/src/widgets/how-it-works-section.tsx
@@ -0,0 +1,64 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+import { StepCard } from "@/features/step-card";
+import { motion } from "framer-motion";
+import { UserPlus, FolderPlus, Users as UsersIcon, Rocket } from "lucide-react";
+
+const steps = [
+ {
+ number: 1,
+ title: "Зарегистрируйтесь",
+ description: "Создайте аккаунт за 30 секунд. Кредитная карта не требуется.",
+ icon: UserPlus,
+ },
+ {
+ number: 2,
+ title: "Создайте проект",
+ description: "Настройте свой первый проект и добавьте задачи.",
+ icon: FolderPlus,
+ },
+ {
+ number: 3,
+ title: "Пригласите команду",
+ description: "Добавьте коллег и назначьте роли для совместной работы.",
+ icon: UsersIcon,
+ },
+ {
+ number: 4,
+ title: "Начните работать",
+ description: "Отслеживайте прогресс и достигайте целей быстрее.",
+ icon: Rocket,
+ },
+];
+
+/**
+ * How It Works Section - секция "Как это работает"
+ */
+export function HowItWorksSection() {
+ return (
+
+
+
+
+ {/* Connection line */}
+
+
+
+ {steps.map((step) => (
+
+ ))}
+
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/pricing-section.tsx b/src/widgets/pricing-section.tsx
new file mode 100644
index 0000000..660c8b6
--- /dev/null
+++ b/src/widgets/pricing-section.tsx
@@ -0,0 +1,90 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+import { PricingCard } from "@/features/pricing-card";
+
+const pricingPlans = [
+ {
+ name: "Free",
+ price: 0,
+ description: "Для начала работы и малых команд",
+ features: [
+ { text: "До 5 участников команды", included: true },
+ { text: "До 10 проектов", included: true },
+ { text: "Базовые отчеты", included: true },
+ { text: "Email поддержка", included: true },
+ { text: "Интеграции", included: false },
+ { text: "Приоритетная поддержка", included: false },
+ { text: "Кастомные роли", included: false },
+ ],
+ ctaLabel: "Начать бесплатно",
+ ctaHref: "#",
+ },
+ {
+ name: "Pro",
+ price: 2900,
+ description: "Для растущих команд",
+ features: [
+ { text: "До 50 участников команды", included: true },
+ { text: "Неограниченные проекты", included: true },
+ { text: "Расширенная аналитика", included: true },
+ { text: "Email и чат поддержка", included: true },
+ { text: "Все интеграции", included: true },
+ { text: "Приоритетная поддержка", included: true },
+ { text: "Кастомные роли", included: false },
+ ],
+ ctaLabel: "Попробовать Pro",
+ ctaHref: "#",
+ popular: true,
+ variant: "featured" as const,
+ },
+ {
+ name: "Enterprise",
+ price: "custom",
+ description: "Для крупного бизнеса",
+ features: [
+ { text: "Неограниченные участники", included: true },
+ { text: "Неограниченные проекты", included: true },
+ { text: "Кастомная аналитика", included: true },
+ { text: "Выделенный менеджер", included: true },
+ { text: "Все интеграции + API", included: true },
+ { text: "24/7 поддержка", included: true },
+ { text: "Кастомные роли и права", included: true },
+ ],
+ ctaLabel: "Связаться с нами",
+ ctaHref: "#",
+ },
+];
+
+/**
+ * Pricing Section - секция с тарифами
+ */
+export function PricingSection() {
+ return (
+
+
+
+
+ {pricingPlans.map((plan) => (
+
+ ))}
+
+
+
+
+ );
+}
+
diff --git a/src/widgets/social-proof-section.tsx b/src/widgets/social-proof-section.tsx
new file mode 100644
index 0000000..d91b020
--- /dev/null
+++ b/src/widgets/social-proof-section.tsx
@@ -0,0 +1,105 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+import { TestimonialCard } from "@/features/testimonial-card";
+import { LogoCloud } from "@/features/logo-cloud";
+import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/shared/ui/carousel";
+
+const testimonials = [
+ {
+ content:
+ "TaskFlow полностью изменил то, как мы работаем. Теперь все задачи под контролем, и команда работает намного эффективнее.",
+ author: {
+ name: "Алексей Иванов",
+ role: "CTO",
+ company: "TechStart",
+ avatar: "/api/placeholder/100/100",
+ },
+ rating: 5,
+ },
+ {
+ content:
+ "Интуитивный интерфейс и мощные функции. За первую неделю наша продуктивность выросла на 40%.",
+ author: {
+ name: "Мария Петрова",
+ role: "Product Manager",
+ company: "InnovateCo",
+ avatar: "/api/placeholder/100/100",
+ },
+ rating: 5,
+ },
+ {
+ content:
+ "Лучший инструмент для управления проектами, который я использовал. Поддержка на высшем уровне!",
+ author: {
+ name: "Дмитрий Сидоров",
+ role: "Team Lead",
+ company: "DevStudio",
+ avatar: "/api/placeholder/100/100",
+ },
+ rating: 5,
+ },
+ {
+ content:
+ "Отличная альтернатива дорогим решениям. Все что нужно для команды из 20 человек.",
+ author: {
+ name: "Екатерина Волкова",
+ role: "Operations Director",
+ company: "GrowthLab",
+ avatar: "/api/placeholder/100/100",
+ },
+ rating: 4,
+ },
+];
+
+const logos = [
+ { name: "Company 1", src: "/api/placeholder/150/50" },
+ { name: "Company 2", src: "/api/placeholder/150/50" },
+ { name: "Company 3", src: "/api/placeholder/150/50" },
+ { name: "Company 4", src: "/api/placeholder/150/50" },
+ { name: "Company 5", src: "/api/placeholder/150/50" },
+ { name: "Company 6", src: "/api/placeholder/150/50" },
+ { name: "Company 7", src: "/api/placeholder/150/50" },
+ { name: "Company 8", src: "/api/placeholder/150/50" },
+];
+
+/**
+ * Social Proof Section - секция с отзывами и логотипами клиентов
+ */
+export function SocialProofSection() {
+ return (
+
+
+
+
+
+ {testimonials.map((testimonial, index) => (
+
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+ Нам доверяют лучшие компании
+
+
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/stats-section.tsx b/src/widgets/stats-section.tsx
new file mode 100644
index 0000000..e6b9b43
--- /dev/null
+++ b/src/widgets/stats-section.tsx
@@ -0,0 +1,47 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { StatCard } from "@/features/stat-card";
+import { Users, TrendingUp, Star, Puzzle } from "lucide-react";
+
+const stats = [
+ {
+ value: "10000+",
+ label: "Активных пользователей",
+ icon: Users,
+ },
+ {
+ value: "99.9%",
+ label: "Uptime",
+ icon: TrendingUp,
+ trend: { value: 12, direction: "up" as const },
+ },
+ {
+ value: "4.9",
+ label: "Средняя оценка",
+ icon: Star,
+ },
+ {
+ value: "50+",
+ label: "Интеграций",
+ icon: Puzzle,
+ },
+];
+
+/**
+ * Stats Section - секция с цифрами/достижениями
+ */
+export function StatsSection() {
+ return (
+
+
+ {stats.map((stat) => (
+
+ ))}
+
+
+ );
+}
+
+
+
diff --git a/src/widgets/team-section.tsx b/src/widgets/team-section.tsx
new file mode 100644
index 0000000..20b8c4a
--- /dev/null
+++ b/src/widgets/team-section.tsx
@@ -0,0 +1,73 @@
+"use client";
+
+import { SectionContainer } from "@/features/section-container";
+import { SectionHeader } from "@/features/section-header";
+import { TeamMemberCard } from "@/features/team-member-card";
+
+const team = [
+ {
+ name: "Иван Петров",
+ role: "CEO & Founder",
+ bio: "10+ лет опыта в разработке SaaS продуктов",
+ image: "/api/placeholder/400/400",
+ socials: [
+ { platform: "linkedin" as const, url: "#" },
+ { platform: "twitter" as const, url: "#" },
+ ],
+ },
+ {
+ name: "Анна Смирнова",
+ role: "CTO",
+ bio: "Архитектор enterprise-решений с опытом в Google",
+ image: "/api/placeholder/400/400",
+ socials: [
+ { platform: "github" as const, url: "#" },
+ { platform: "linkedin" as const, url: "#" },
+ ],
+ },
+ {
+ name: "Михаил Козлов",
+ role: "Head of Product",
+ bio: "Создал продукты, используемые миллионами пользователей",
+ image: "/api/placeholder/400/400",
+ socials: [
+ { platform: "linkedin" as const, url: "#" },
+ { platform: "twitter" as const, url: "#" },
+ ],
+ },
+ {
+ name: "Елена Новикова",
+ role: "Head of Design",
+ bio: "Award-winning UX/UI дизайнер с 8-летним опытом",
+ image: "/api/placeholder/400/400",
+ socials: [
+ { platform: "twitter" as const, url: "#" },
+ { platform: "linkedin" as const, url: "#" },
+ ],
+ },
+];
+
+/**
+ * Team Section - секция с командой
+ */
+export function TeamSection() {
+ return (
+
+
+
+
+ {team.map((member) => (
+
+ ))}
+
+
+ );
+}
+
+
+