Landing Hotel
Отель/загородный дом — архетип гостеприимства: продают фотографии и прямые цены. Витрина пространств, прайс номеров на menu-list (вторая реальная роль вида pricing), бронь формой contact-split и первое применение footer-reveal — подвал открывается из-под страницы.
Установка
npx shadcn@latest add https://motiva.pages.dev/r/landing-hotel.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 { HeroCentered } from "@/components/hero-centered";
import { ShowcaseGallery } from "@/components/showcase-gallery";
import { FeaturesColumns } from "@/components/features-columns";
import { MenuList } from "@/components/menu-list";
import { TestimonialsGrid } from "@/components/testimonials-grid";
import { FaqAccordion } from "@/components/faq-accordion";
import { ContactSplit } from "@/components/contact-split";
import { FooterReveal } from "@/components/footer-reveal";
/**
* Отель/загородный дом — четырнадцатый архетип. Гостиницу продают фотографии
* и прямота цен, поэтому середина страницы — витрина пространств и ПРАЙС
* НА MENU-LIST: секция меню с точечной отбивкой переиспользована как
* тариф номеров (вид pricing и есть роль «что и почём» — вторая реальная
* сборка подтверждает решение). Бронь — форма contact-split: у маленького
* дома нет booking-движка, есть человек, который отвечает на письма.
*
* Подвал — ПЕРВОЕ применение footer-reveal на странице: дом «стоит на земле»,
* и подвал, открывающийся из-под страницы, дословно про это. Живых фонов
* нет — фотографии главнее. Акцент хвойный (--ds-accent-h: 150).
*/
export function LandingHotel() {
return (
<div
className="lht ds-scope"
style={{
textAlign: "start",
["--ds-accent-h" as string]: "150",
["--ds-section-y" as string]: "clamp(48px, 7vw, 96px)",
background: "var(--ds-bg, oklch(0.14 0.02 275))",
}}
>
<NavSticky brand="сосны" links={["Номера", "Дом", "Цены", "Дорога"]} cta="Забронировать" />
<HeroCentered
badge="загородный дом на дюнах"
title="Десять номеров и очень тихо"
accentWords={3}
sub="Сосны, море в четырёхстах метрах и никакой анимации у ресепшена — её тут нет, как и самого ресепшена. Завтрак включён, вай-фай есть, но вы приехали не за ним."
primary="Выбрать номер"
secondary="Посмотреть дом"
note="10 номеров · завтрак включён · с собаками можно"
/>
<ShowcaseGallery
eyebrow="вокруг дома"
title="Место, ради которого едут"
items={[
{ src: "https://motiva.pages.dev/img/1015-800x600.jpg", title: "Вид с дюны", tag: "море в четырёхстах метрах", wide: true },
{ src: "https://motiva.pages.dev/img/1018-600x750.jpg", title: "Дорога к дому", tag: "последний поворот" },
{ src: "https://motiva.pages.dev/img/1019-600x750.jpg", title: "Вечер у воды", tag: "после сауны — сюда" },
{ src: "https://motiva.pages.dev/img/1039-900x700.jpg", title: "Ручей в лесу", tag: "полчаса пешком", wide: true },
{ src: "https://motiva.pages.dev/img/1050-600x750.jpg", title: "Наш берег", tag: "бухта за дюной" },
{ src: "https://motiva.pages.dev/img/1057-900x675.jpg", title: "Закат с террасы", tag: "каждый день другой" },
]}
/>
<FeaturesColumns
eyebrow="почему у нас"
title="Три вещи, ради которых едут"
sub="Остальное — как везде: чисто, тепло, вкусно."
items={[
{ title: "Тишина по-настоящему", text: "Ни трассы, ни соседей, ни музыки у бассейна — бассейна тоже нет, есть море" },
{ title: "Завтрак до полудня", text: "Свой хлеб, яйца от соседей, сырники по записи. Проспали — не пропустили" },
{ title: "Сауна на дровах", text: "У кромки леса, топим к вашему часу. После — купель под открытым небом" },
]}
/>
<MenuList
eyebrow="цены"
title="За ночь, без мелкого шрифта"
sub="Завтрак и парковка включены. Дети до пяти — бесплатно."
items={[
{ group: "Номера", name: "«Дюна» с видом на море", price: "9 800 ₽", note: "двое · балкон · до +1 места" },
{ group: "Номера", name: "«Сосна», мансарда", price: "7 400 ₽", note: "двое · окно в кронах" },
{ group: "Номера", name: "«Вереск», у сада", price: "6 200 ₽", note: "двое · первый этаж" },
{ group: "Дополнительно", name: "Сауна на дровах, 2 часа", price: "3 000 ₽", note: "к вашему часу, по записи" },
{ group: "Дополнительно", name: "Завтрак в номер", price: "600 ₽" },
{ group: "Дополнительно", name: "Трансфер от станции", price: "1 200 ₽", note: "20 минут, встретим с табличкой" },
]}
note="В межсезонье (ноябрь—март) номера дешевле на 25 %. Предоплата — одна ночь."
/>
<TestimonialsGrid
eyebrow="гости"
title="Что пишут после выходных"
items={[
{ text: "Приехали на две ночи, остались на пять. Работает только одно правило: телефон ловит на террасе, и слава богу.", name: "Марина В.", featured: true },
{ text: "Сауна к девяти вечера, купель со звёздами — как заказывали. Дрова пахнут правильно.", name: "Сергей и Оля", role: "приезжают третий год" },
{ text: "С собакой пустили без вздохов и доплат, выдали плед и миску. Запомнили её имя раньше моего.", name: "Антон Л.", role: "с ретривером Кноп" },
{ text: "Завтрак до полудня — это не маркетинг, мы проверили в 11:58.", name: "Даша К." },
]}
/>
<FaqAccordion
eyebrow="частые вопросы"
title="Что спрашивают до брони"
items={[
{ q: "Когда заезд и выезд?", a: "Заезд с 15:00, выезд до 12:00. Ранний заезд — если номер готов, бесплатно; про поздний выезд договоримся, если нет заезда следом." },
{ q: "Можно с детьми и животными?", a: "Да. Дети до пяти лет — бесплатно, кроватку поставим. Собаки живут бесплатно, для них есть пледы и миски; кошек тоже пустим." },
{ q: "Как добраться без машины?", a: "Электричка до станции, дальше двадцать минут: закажите трансфер при брони — встретим. Такси на месте почти не ловится." },
{ q: "Что с отменой?", a: "Бесплатно за семь дней. Позже — удерживаем предоплату (одна ночь), но её можно перенести на другие даты в течение года." },
]}
/>
<ContactSplit
eyebrow="бронь"
title="Спросите про даты"
sub="Отвечает хозяйка дома, обычно в течение пары часов. Напишите даты и состав — предложим номер."
/>
<FooterReveal
brand="сосны"
tagline="Загородный дом на дюнах. Десять номеров, море в четырёхстах метрах."
columns={[
{ title: "Дом", links: ["Номера", "Цены", "Дорога"] },
{ title: "Связь", links: ["+7 900 000-00-00", "stay@sosny.house"] },
]}
note="Работаем круглый год"
/>
</div>
);
}