From 1e2fd40c9f1d781305b0d7af4198fdd69e42b1f6 Mon Sep 17 00:00:00 2001 From: StanisLove Date: Thu, 18 Jun 2026 21:38:39 +0300 Subject: [PATCH] feat: update for agent --- AGENTS.md | 51 ++++++++++++++++++++++++ src/features/feature-card.tsx | 3 +- src/shared/hooks/use-scroll-animation.ts | 4 +- src/widgets/cta-section.tsx | 1 - src/widgets/header.tsx | 3 +- src/widgets/how-it-works-section.tsx | 1 - src/widgets/pricing-section.tsx | 2 +- 7 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..abaef15 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,51 @@ +# AGENTS.md + +Универсальный одностраничный лендинг-шаблон (shadcn + Payload-ready) для любого продукта/бизнеса. Композиция секций собрана в `src/app/page.tsx`; каждая секция — отдельный widget. + +## Project Specifics + +- `src/app/page.tsx` — только композиция: `Header` + секции в `
` + `Footer`. Не превращай его в монолит, добавляй/убирай секции, а не код блоков. +- Каждая секция лендинга — самостоятельный widget в `src/widgets/*-section.tsx`; правь нужную секцию точечно. +- Базовые UI-примитивы shadcn — в `src/shared/ui/*` (vendored, не переписывай). +- Проверка после правок: `pnpm lint` и `pnpm build`. + +## Design System + +Источник токенов — `src/app/globals.css` (`@theme` + `:root`/`.dark`). Шрифт — Roboto Flex (`--font-roboto-flex`). Работай через семантические классы Tailwind (`bg-primary`, `text-muted-foreground`, `border`), не хардкодь hex/oklch. + +**Важно — это нейтральная база.** Токены сейчас grayscale (монохром, `--radius` 0.625rem) — дефолтная shadcn-тема без характера. Это значит главный риск шаблона — **дженерик «AI-лендинг»**, который выглядит как все остальные. Поэтому: + +- **Сначала задай направление.** Под конкретный продукт выбери осознанную эстетику и зашей её в **токены** `globals.css` (`--primary`, `--secondary`, `--accent`, `--radius`, типографику) — а не точечными классами по секциям. Тогда все секции автоматически становятся on-brand. +- **Расширяй личность, а не сбрасывай в дефолт.** Если у проекта уже задан характер — держи его консистентно во всех секциях. + +| Роль | База (neutral) | Назначение | +|---|---|---| +| `background` / `foreground` | white / near-black | фон и текст | +| `primary` | near-black | основные CTA, акценты | +| `secondary` / `muted` | light gray | вторичные поверхности, приглушённый текст | +| `accent` | light gray | подсветки (задай ярче под бренд) | +| `border` / `ring` | gray | границы, фокус | + +Do / Don't: +- **Do:** определять тему через токены; держать единый ритм отступов/типографики между секциями; контент-first (оффер, доказательства, цена). +- **Don't:** оставлять монохром-дефолт «как есть» под реальный продукт; хардкодить цвета мимо токенов; стакать секции без выбранного направления — это и есть «одинаковый AI-лендинг». + +## File Map + +Композиция: `src/app/page.tsx` → `Header` + секции + `Footer`. + +| Блок | Widget | +|---|---| +| Шапка | `src/widgets/header.tsx` | +| Hero | `src/widgets/hero-section.tsx` | +| Features | `src/widgets/features-section.tsx` | +| Stats | `src/widgets/stats-section.tsx` | +| How it works | `src/widgets/how-it-works-section.tsx` | +| Comparison | `src/widgets/comparison-section.tsx` | +| Gallery | `src/widgets/gallery-section.tsx` | +| Social proof | `src/widgets/social-proof-section.tsx` | +| Team | `src/widgets/team-section.tsx` | +| Pricing | `src/widgets/pricing-section.tsx` | +| FAQ | `src/widgets/faq-section.tsx` | +| CTA | `src/widgets/cta-section.tsx` | +| Footer | `src/widgets/footer.tsx` | diff --git a/src/features/feature-card.tsx b/src/features/feature-card.tsx index 0dacd21..e0dc894 100644 --- a/src/features/feature-card.tsx +++ b/src/features/feature-card.tsx @@ -2,9 +2,8 @@ import { cn } from "@/shared/lib/utils"; import { motion } from "framer-motion"; -import { LucideIcon } from "lucide-react"; +import { ArrowRight, LucideIcon } from "lucide-react"; import Link from "next/link"; -import { ArrowRight } from "lucide-react"; export interface FeatureCardProps { icon: LucideIcon; diff --git a/src/shared/hooks/use-scroll-animation.ts b/src/shared/hooks/use-scroll-animation.ts index 8f63a38..75e915e 100644 --- a/src/shared/hooks/use-scroll-animation.ts +++ b/src/shared/hooks/use-scroll-animation.ts @@ -54,7 +54,7 @@ export function useScrollAnimation(config: ScrollAnimationConfig = {}) { transition: { duration, delay, - ease: "easeOut", + ease: "easeOut" as const, }, }; } @@ -97,7 +97,7 @@ export const cardHover = { scale: 1.02, y: -5, transition: { - type: "spring", + type: "spring" as const, stiffness: 300, damping: 20, }, diff --git a/src/widgets/cta-section.tsx b/src/widgets/cta-section.tsx index 9798fc6..c259cc4 100644 --- a/src/widgets/cta-section.tsx +++ b/src/widgets/cta-section.tsx @@ -6,7 +6,6 @@ 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 - финальный призыв к действию diff --git a/src/widgets/header.tsx b/src/widgets/header.tsx index a411347..046df68 100644 --- a/src/widgets/header.tsx +++ b/src/widgets/header.tsx @@ -4,10 +4,9 @@ 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 { Menu, Moon, Sun, 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" }, diff --git a/src/widgets/how-it-works-section.tsx b/src/widgets/how-it-works-section.tsx index ae49577..e64c502 100644 --- a/src/widgets/how-it-works-section.tsx +++ b/src/widgets/how-it-works-section.tsx @@ -3,7 +3,6 @@ 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 = [ diff --git a/src/widgets/pricing-section.tsx b/src/widgets/pricing-section.tsx index 660c8b6..a7adae6 100644 --- a/src/widgets/pricing-section.tsx +++ b/src/widgets/pricing-section.tsx @@ -41,7 +41,7 @@ const pricingPlans = [ }, { name: "Enterprise", - price: "custom", + price: "custom" as const, description: "Для крупного бизнеса", features: [ { text: "Неограниченные участники", included: true },