Landing Magazine
Журнал — архетип «медиа»: страница продаёт привычку читать. Оба блоговых варианта в паре и в разных ролях (blog-index — свежий номер, blog-grid — архив), цифры издания, редакция и одна подписка в подвале; в сокете hero — flow-strands как издательская метафора строк.
Установка
npx shadcn@latest add https://motiva.pages.dev/r/landing-magazine.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 { NavBlend } from "@/components/nav-blend";
import { HeroCentered } from "@/components/hero-centered";
import { FlowStrands } from "@/components/flow-strands";
import { BlogIndex } from "@/components/blog-index";
import { BlogGrid } from "@/components/blog-grid";
import { StatsBand } from "@/components/stats-band";
import { TeamGrid } from "@/components/team-grid";
import { FooterCta } from "@/components/footer-cta";
/**
* Журнал — архетип «медиа»: страница продаёт не продукт, а ПРИВЫЧКУ ЧИТАТЬ.
* Оба блоговых варианта работают в паре и в разных ролях: blog-index — свежий
* номер (редакционный указатель со снимком за курсором), blog-grid — читаемое
* из архива. Подписка одна и в подвале (footer-cta): у издания CTA не должен
* перебивать чтение по дороге.
*
* В сокете hero — flow-strands: тонкие нити и есть строки, издательская
* метафора без буквальности. Акцент — красный кирпич (--ds-accent-h: 25),
* классика журнальной вёрстки.
*/
export function LandingMagazine() {
return (
<div
className="lmg ds-scope"
style={{
textAlign: "start",
["--ds-accent-h" as string]: "25",
["--ds-section-y" as string]: "clamp(48px, 7vw, 96px)",
background: "var(--ds-bg, oklch(0.14 0.02 275))",
}}
>
<NavBlend brand="тираж" links={["Свежий номер", "Архив", "Редакция"]} cta="Подписаться" />
<HeroCentered
badge="независимый журнал о городе"
title="Читаем город как текст"
accentWords={2}
sub="Раз в месяц — восемь длинных историй о том, как устроено место, где вы живёте: дворы, рынки, трамваи, люди и деньги за всем этим."
primary="Свежий номер"
secondary="Подписаться"
note="без ленты и алгоритмов — только номер"
background={
// backdrop задан явно: дефолтная подложка эффекта берёт фон ТЕМЫ, и в
// светлой теме hero с tone="dark" превращался в серую кашу. hue — НАЧАЛО
// веера (нити расходятся на ~+0.3 по кругу): 0.93 идёт через красный в охру.
<FlowStrands hue={0.93} count={5} speed={0.5} backdrop="oklch(0.13 0.02 275)" />
}
tone="dark"
scrim={0.6}
/>
<BlogIndex
eyebrow="номер 48 · сентябрь"
title="В свежем номере"
items={[
{ title: "Кому принадлежит рынок: пять семей и один прилавок", tag: "деньги", date: "№48", image: "https://motiva.pages.dev/img/1016-900x675.jpg" },
{ title: "Трамвай № 3 глазами вагоновожатой", tag: "люди", date: "№48", image: "https://motiva.pages.dev/img/1057-900x675.jpg" },
{ title: "Дворы-колодцы: почему их перестали строить", tag: "город", date: "№48", image: "https://motiva.pages.dev/img/221-900x700.jpg" },
{ title: "Ночная смена хлебозавода — репортаж до рассвета", tag: "репортаж", date: "№48", image: "https://motiva.pages.dev/img/1021-600x750.jpg" },
]}
/>
<BlogGrid
eyebrow="архив"
title="Читаемое за все номера"
sub="Истории, которые продолжают присылать друг другу спустя годы."
posts={[
{ title: "Карта запахов: чем пахнет каждый район", excerpt: "Полгода ходили с блокнотом и нюхали город — от коптилен до типографии.", date: "№31", rubric: "город", author: "Вера Штерн", readTime: "18 мин" },
{ title: "Последний часовщик на главной улице", excerpt: "Мастерской 62 года, очередь расписана на месяц. Поговорили о времени.", date: "№27", rubric: "люди", author: "Даниил Ром", readTime: "12 мин" },
{ title: "Куда уходит вода из фонтанов", excerpt: "Проследили весь путь: от насосной до легенды про подземное озеро.", date: "№40", rubric: "устройство", author: "Кира Мель", readTime: "15 мин" },
{ title: "Сколько стоит вывеска: экономика неона", excerpt: "Почему старые буквы гаснут и кто платит, когда они загораются снова.", date: "№44", rubric: "деньги", author: "Вера Штерн", readTime: "14 мин" },
{ title: "Гаражи как институция", excerpt: "Мастерские, сыроварня и репетиционная точка — экспедиция в кооператив «Луч».", date: "№36", rubric: "репортаж", author: "Даниил Ром", readTime: "20 мин" },
{ title: "Азбука подъездов: лепнина, кафель, почтовые ящики", excerpt: "Разбираем подъезд как жанр — с фотографиями и словарём.", date: "№22", rubric: "город", author: "Кира Мель", readTime: "10 мин" },
]}
/>
<StatsBand
items={[
{ value: 6, label: "лет выходим" },
{ value: 48, label: "номеров вышло" },
{ value: 120, suffix: " тыс.", label: "читателей в месяц" },
{ value: 8, label: "историй в номере" },
]}
/>
<TeamGrid
eyebrow="редакция"
title="Четыре человека и город"
sub="Пишем сами, снимаем сами, вычитываем друг друга."
items={[
{ name: "Вера Штерн", role: "главный редактор", photo: "https://motiva.pages.dev/img/1015-600x750.jpg", about: "Придумала журнал в трамвае № 3. Пишет про деньги и запахи." },
{ name: "Даниил Ром", role: "репортёр", photo: "https://motiva.pages.dev/img/1018-600x750.jpg", about: "Умеет разговорить часовщика и вагоновожатую. Ночные смены — его." },
{ name: "Кира Мель", role: "редактор и картограф", photo: "https://motiva.pages.dev/img/1022-600x750.jpg", about: "Рисует карты и словари. Знает, куда уходит вода." },
{ name: "Стёпа Гран", role: "фотограф", photo: "https://motiva.pages.dev/img/1019-600x750.jpg", about: "Снимает на плёнку, потому что город того стоит." },
]}
/>
<FooterCta
title="Номер раз в месяц — в почту"
sub="Подписка бесплатная. Печатную версию собираем дважды в год для подписчиков."
action="Подписаться"
brand="тираж"
columns={[
{ title: "Журнал", links: ["Свежий номер", "Архив", "Печатные выпуски"] },
{ title: "Редакция", links: ["Кто мы", "Предложить историю", "post@tirazh.city"] },
]}
note="Пишем раз в месяц, отписка одной кнопкой"
/>
</div>
);
}