Landing Course
Лендинг онлайн-курса — образовательный архетип: продаёт путь (программа шагами) и человека (автор прожектором team-spotlight), честное сравнение карточками, тумблер цены «помесячно/сразу» как рассрочка. Одиннадцать секций, две новые встали в страницу в день рождения. Тёплая охра одним числом --ds-accent-h.
Установка
npx shadcn@latest add https://motiva.pages.dev/r/landing-course.jsonЧто нужно в проекте до установки
Файл
components.jsonв корнеИз него CLI узнаёт, куда класть файлы. Алиасы — в такой форме:
"aliases": { "components": "@/components", "lib": "@/lib" }Нет файла — установка не начнётся вовсе.
Алиас
@объявлен дваждыВ корневом
tsconfig.jsonи в конфиге сборщика. В Vite корневой tsconfig часто содержит толькоreferences— этого мало."paths": { "@/*": ["./src/*"] } // tsconfig.json resolve.alias = { "@": "/src" } // vite.config.tsБез
pathsCLI молча создаёт папку с именем@.Токены подключены один раз на приложение
Они приезжают вместе с записью — достаточно импортировать их в точке входа:
import "@/styles/motiva-tokens.css";Без них блок потеряет цвета, ритм и тему.
Своя типографика не спорит с блоком
Наследуемые свойства протекают внутрь:
text-align: centerна обёртке отцентрует содержимое секции. То же касаетсяfont-familyиline-height.Проект без TypeScript? всё равно нужен tsconfig
CLI грузит
tsconfig.jsonбезусловно, а при"tsx": falseидёт заjsconfig.jsonи падает так же. Минимум — файл сpathsи"tsx": trueвcomponents.json.Приехавший рядом
.tsxможно не трогать — вам нужен.vanilla.js.
Экспорт
Код
import { NavSticky } from "@/components/nav-sticky";
import { HeroSplit } from "@/components/hero-split";
import { LogosStrip } from "@/components/logos-strip";
import { StepsFlow } from "@/components/steps-flow";
import { TeamSpotlight } from "@/components/team-spotlight";
import { TestimonialsGrid } from "@/components/testimonials-grid";
import { ComparisonCards } from "@/components/comparison-cards";
import { PricingToggle } from "@/components/pricing-toggle";
import { FaqColumns } from "@/components/faq-columns";
import { CtaGlow } from "@/components/cta-glow";
import { FooterMinimal } from "@/components/footer-minimal";
/**
* Лендинг онлайн-курса — «образовательный» архетип: продаёт не функции, а ПУТЬ
* (программа шагами) и ЧЕЛОВЕКА (автор прожектором). Две новые секции — прожектор
* автора и честное сравнение карточками — встали в страницу в день рождения.
*
* Характер — тёплая охра (--ds-accent-h: 80): учебное должно выглядеть спокойным,
* а не неоновым. Плотный ритм: страница читается сверху вниз как оглавление.
*/
export function LandingCourse() {
return (
<div
className="lcr ds-scope"
style={{
textAlign: "start",
["--ds-accent-h" as string]: "80",
["--ds-section-y" as string]: "clamp(44px, 6vw, 84px)",
background: "var(--ds-bg, oklch(0.14 0.02 275))",
}}
>
<NavSticky brand="плавно" links={["Программа", "Автор", "Отзывы", "Цена"]} cta="Записаться" />
<HeroSplit
eyebrow="курс · 6 недель"
lines={["Интерфейсы, которые"]}
accentLine="не дёргаются"
sub="Практический курс о движении в интерфейсах: скролл, пружины, переходы. Каждую неделю — разбор вашей работы, а не тест с галочками."
primary="Записаться на поток"
secondary="Смотреть программу"
/>
<LogosStrip caption="выпускники работают в" items={["NORDWIND", "KERNEL", "LUMA", "VERTEX", "OKAPI", "SOLARIS"]} />
<StepsFlow
eyebrow="программа"
title="Шесть недель — шесть слоёв"
sub="Каждый модуль заканчивается работой в ваш портфель, а не сертификатом ради сертификата."
items={[
{ title: "Каркас", note: "неделя 1", text: "Раскладка, которая не ломается контентом: сетки, subgrid, честные минимумы." },
{ title: "Движение", note: "неделя 2", text: "Твины против пружин, композитор против раскладки — что анимировать можно, а что дорого." },
{ title: "Скролл", note: "недели 3–4", text: "Прокруточные таймлайны без скриптов, липкие сцены, производная скорости." },
{ title: "Отклик", note: "неделя 5", text: "Курсорные приёмы по шаблону: запомнил координату, разбудил цикл, заснул в покое." },
{ title: "Диплом", note: "неделя 6", text: "Собираете живую страницу целиком; лучшие работы разбираем в прямом эфире." },
]}
/>
<TeamSpotlight
eyebrow="кто ведёт"
name="Jane Doe"
role="продуктовый дизайнер, 12 лет в интерфейсах"
bio="Вела дизайн-системы, на которых живут десятки продуктов, и команды, которые их не боятся менять. Курс — всё, что сама хотела бы услышать десять лет назад: без теории ради теории, с кодом и замерами."
photo="https://motiva.pages.dev/img/1027-400x400.jpg"
facts={[
{ value: "12 лет", label: "в продуктовой разработке" },
{ value: "40+", label: "запущенных интерфейсов" },
{ value: "900", label: "выпускников трёх потоков" },
]}
/>
<TestimonialsGrid
eyebrow="отзывы"
title="Что говорят выпускники"
items={[
{ text: "Первый курс, где домашку разбирают руками, а не ботом. После третьей недели переписала весь онбординг у нас в продукте — и его наконец перестали ругать.", name: "Mary M.", role: "дизайнер, финтех", featured: true },
{ text: "Понял, почему мои анимации тормозили. Спойлер: раскладка.", name: "John R.", role: "фронтенд" },
{ text: "Шаблон курсорного цикла из пятой недели уехал прямиком в прод.", name: "Alex P.", role: "инди-разработчик" },
{ text: "Стоил как месяц кофе, окупился первым же собеседованием.", name: "Sam D.", role: "джуниор" },
]}
/>
<ComparisonCards
eyebrow="честно"
title="Курс — не единственный путь"
sub="Сравните сами. Мы за любой вариант, где вы правда учитесь."
items={[
{
name: "Статьи и видео",
note: "бесплатно",
points: ["+ Ничего не стоит", "+ Свой темп", "− Никто не смотрит вашу работу", "− Половина советов устарела"],
verdict: "Хватает сильным одиночкам",
},
{
name: "Этот курс",
note: "6 недель с разборами",
points: ["+ Разбор каждой домашки", "+ Свежий материал с замерами", "+ Портфель к финалу", "− Требует 6–8 часов в неделю"],
verdict: "Быстрее всего с обратной связью",
featured: true,
},
{
name: "Университет",
note: "годы и диплом",
points: ["+ Фундамент и корочка", "− Интерфейсам почти не учат", "− Годы и другой бюджет"],
verdict: "Про другое, не про ремесло",
},
]}
/>
<PricingToggle
eyebrow="цена"
title="Помесячно или сразу"
currency="$"
saveLabel="−20% при оплате сразу"
plans={[
{
name: "Сам",
monthly: 39,
yearly: 31,
note: "материалы без разборов",
features: ["Все модули и обновления", "Чат потока", "Сертификат"],
cta: "Начать",
},
{
name: "С разборами",
monthly: 89,
yearly: 71,
note: "как задумано",
features: ["Всё из «Сам»", "Разбор каждой домашки", "Две личные сессии", "Диплом с разбором в эфире"],
cta: "Записаться",
featured: true,
},
]}
/>
<FaqColumns
eyebrow="вопросы"
title="Перед записью спрашивают"
sub="Если вашего вопроса нет — напишите, отвечаем в тот же день."
contact="Спросить про курс"
items={[
{ q: "Я дизайнер, не разработчик. Потяну?", a: "Да: код даётся с объяснением каждой строки, а половина приёмов вообще без JS." },
{ q: "Сколько времени нужно?", a: "6–8 часов в неделю. Меньше — можно, но разборы ценнее, когда есть что разбирать." },
{ q: "Что, если не успеваю?", a: "Доступ бессрочный, к следующему потоку можно присоединиться бесплатно." },
{ q: "Есть ли рассрочка?", a: "Помесячный тариф и есть рассрочка: платите, пока учитесь." },
{ q: "Вернёте деньги?", a: "Две недели без вопросов — если поняли, что не ваше." },
{ q: "Будет ли поток ещё?", a: "Дважды в год. Но материал стареет быстрее, чем вы думаете." },
]}
/>
<CtaGlow
title="Поток стартует в понедельник"
sub="Дальше — только следующий, через полгода. Материалы откроются в день старта."
cta="Занять место"
note="осталось 14 мест с разборами"
/>
<FooterMinimal
brand="плавно"
tagline="Курс о движении в интерфейсах"
columns={[
{ title: "Курс", links: ["Программа", "Автор", "Отзывы", "Цена"] },
{ title: "Помощь", links: ["Вопросы", "Рассрочка", "Для компаний"] },
{ title: "Связь", links: ["hello@plavno.dev", "Телеграм"] },
]}
/>
</div>
);
}