content: тексты лендинга — черновик ИИ, вычитка автора, slopotron
site.ts: все блоки страницы только из фактов ТЗ. form.ts: правки, принятые автором (без «помола», понятнее успех, уточнение и 429). slopotron: убраны повторы «обжариваем по четвергам» и «пока обжарка свежая» между первым экраном и блоком свежести.
This commit is contained in:
+57
@@ -0,0 +1,57 @@
|
|||||||
|
# Product
|
||||||
|
|
||||||
|
<!-- impeccable:product-schema 1 -->
|
||||||
|
|
||||||
|
> Записано по брифу автора и `docs/plan.md` без интервью: все решения приняты автором заранее. Источник фактов — `docs/plan.md`, раздел «Факты из ТЗ».
|
||||||
|
|
||||||
|
## Platform
|
||||||
|
|
||||||
|
web
|
||||||
|
|
||||||
|
## Users
|
||||||
|
|
||||||
|
Жители Минска 25–45 лет, приходят с телефона из Instagram и Яндекса. Задача: понять, чем эта обжарка лучше пачки из магазина, выбрать сорт или подписку и оставить заявку. Менеджер перезванивает.
|
||||||
|
|
||||||
|
## Product Purpose
|
||||||
|
|
||||||
|
Одностраничный лендинг обжарки «Кварта». Успех — отправленная **заявка** (имя, телефон, интерес, комментарий), которая доходит до менеджера в Telegram с источником визита.
|
||||||
|
|
||||||
|
## Positioning
|
||||||
|
|
||||||
|
Свежесть по расписанию: обжарка по четвергам партиями по 5 кг, развоз по Минску в пятницу, зерно у клиента на 1–3 день после обжарки. «Кварта» — «четвёртая», четверг — четвёртый день недели. У соседей по рынку такого расписания нет.
|
||||||
|
|
||||||
|
## Operating Context
|
||||||
|
|
||||||
|
- Обжарка с 2019 года, основатели Аня и Дмитрий, бывшие бариста.
|
||||||
|
- Ассортимент: Эфиопия Иргачеффе (цветочный, бергамот, светлая обжарка) 250 г — 32 BYN; Колумбия Уила (карамель, красное яблоко) 250 г — 29 BYN; Бразилия Серрадо (орех, шоколад, под эспрессо) 250 г — 26 BYN; дрип-пакеты ассорти, 10 шт — 18 BYN.
|
||||||
|
- Подписка: 2 пачки по 250 г раз в месяц, доставка бесплатно — 54 BYN/мес.
|
||||||
|
- Самовывоз: Минск, ул. Короля, 9. Пн–пт 8:00–20:00, сб–вс 10:00–18:00.
|
||||||
|
- Доставка по Минску в пятницу, от 50 BYN бесплатно; дешевле — «стоимость уточнит менеджер».
|
||||||
|
- Телефон вымышленный: +375 29 000-00-00.
|
||||||
|
|
||||||
|
## Capabilities and Constraints
|
||||||
|
|
||||||
|
- Next.js 16 App Router, Tailwind 4 (CSS-first `@theme`), next/font, next/og. Без UI-китов.
|
||||||
|
- Форма и логика уже есть (`apps/landing/src/components/LeadForm.tsx`, `CtaButton.tsx`, `lib/leadPrefill.ts`); вёрстка ложится на них, логика не меняется.
|
||||||
|
- Все тексты — в `apps/landing/src/content/site.ts` и `content/form.ts`.
|
||||||
|
- Термины — `GLOSSARY.md`: заявка, уточнение, интерес, посетитель, менеджер.
|
||||||
|
|
||||||
|
## Brand Commitments
|
||||||
|
|
||||||
|
Тон тёплый, простой, без пафоса. Название «Кварта» = «четвёртая», обжарка по четвергам.
|
||||||
|
|
||||||
|
## Evidence on Hand
|
||||||
|
|
||||||
|
- Фото (Unsplash License, без людей): зерно крупным планом — Mona Jain; открытый мешок с зерном на тёмном — Tina Guina; охладитель ростера — Scott Soltys-Curry. Это не фото самой «Кварты», подписи не должны выдавать их за её цех.
|
||||||
|
- Отзывов, клиентов, наград, цифр продаж, соцсетей, логотипа нет. Не выдумывать.
|
||||||
|
|
||||||
|
## Product Principles
|
||||||
|
|
||||||
|
1. Свежесть показываем датой, а не прилагательным.
|
||||||
|
2. Каждая цена и условие из ТЗ видны без клика.
|
||||||
|
3. От любой CTA до отправленной заявки — один экран формы, без лишних шагов.
|
||||||
|
4. Ничего сверх фактов ТЗ.
|
||||||
|
|
||||||
|
## Accessibility & Inclusion
|
||||||
|
|
||||||
|
WCAG 2.2 AA: контраст, видимый фокус, тач-цели ≥ 44px, `prefers-reduced-motion`. Мобильный трафик: проверка на 390 и 1440.
|
||||||
@@ -44,12 +44,9 @@ function Notice({ notice }: { notice: SubmitNotice | null }) {
|
|||||||
return <p>{FORM_TEXT.clarified}</p>;
|
return <p>{FORM_TEXT.clarified}</p>;
|
||||||
case 'rate_limited':
|
case 'rate_limited':
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-1">
|
<p>
|
||||||
<p>{FORM_TEXT.rateLimited}</p>
|
{FORM_TEXT.rateLimited} <PhoneLink />
|
||||||
<p>
|
</p>
|
||||||
{FORM_TEXT.callUs} <PhoneLink />
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
case 'failed':
|
case 'failed':
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -12,16 +12,15 @@ export const FORM_TEXT = {
|
|||||||
name: { label: 'Имя', placeholder: 'Как к вам обращаться' },
|
name: { label: 'Имя', placeholder: 'Как к вам обращаться' },
|
||||||
phone: { label: 'Телефон', placeholder: '+375 29 123-45-67' },
|
phone: { label: 'Телефон', placeholder: '+375 29 123-45-67' },
|
||||||
interest: { legend: 'Что вас интересует' },
|
interest: { legend: 'Что вас интересует' },
|
||||||
comment: { label: 'Комментарий', placeholder: 'Сорт, помол, удобное время звонка — по желанию' },
|
comment: { label: 'Комментарий', placeholder: 'Сорт, количество, удобное время звонка — по желанию' },
|
||||||
honeypot: { label: 'Компания (не заполняйте)' },
|
honeypot: { label: 'Компания (не заполняйте)' },
|
||||||
submit: 'Отправить',
|
submit: 'Отправить',
|
||||||
submitting: 'Отправляем…',
|
submitting: 'Отправляем…',
|
||||||
success: 'Спасибо! Перезвоним в рабочее время',
|
success: 'Спасибо, заявка у нас. Перезвоним в рабочее время.',
|
||||||
clarified: 'Дописали к вашей заявке',
|
clarified: 'Дописали это к вашей прошлой заявке.',
|
||||||
sendAnother: 'Отправить ещё одну',
|
sendAnother: 'Отправить ещё одну',
|
||||||
rateLimited: 'Слишком много попыток. Подождите немного',
|
rateLimited: 'Слишком много попыток. Попробуйте через 10 минут или позвоните:',
|
||||||
failed: 'Не получилось отправить. Попробуйте ещё раз или позвоните:',
|
failed: 'Не получилось отправить. Попробуйте ещё раз или позвоните:',
|
||||||
callUs: 'Позвоните нам:',
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export type CtaPreset = { label: string; interest: Interest; comment?: string };
|
export type CtaPreset = { label: string; interest: Interest; comment?: string };
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
// Все тексты и факты лендинга по блокам — для вычитки. Факты только из «Фактов из ТЗ» (docs/plan.md).
|
||||||
|
// Тексты формы — в ./form.ts.
|
||||||
|
import type { Interest } from '@kvarta/shared/lead';
|
||||||
|
import { CONTACT_PHONE } from './form';
|
||||||
|
|
||||||
|
type Cta = { label: string; interest: Interest; comment?: string };
|
||||||
|
|
||||||
|
export const site = {
|
||||||
|
meta: {
|
||||||
|
title: 'Кварта: кофе свежей обжарки с доставкой по Минску',
|
||||||
|
description:
|
||||||
|
'Обжариваем кофе по четвергам, в пятницу привозим по Минску. Эфиопия, Колумбия, Бразилия, дрип-пакеты и подписка на 2 пачки в месяц.',
|
||||||
|
ogTitle: 'Кварта. Кофе, обжаренный в четверг',
|
||||||
|
ogDescription: 'Обжарка по четвергам, доставка по Минску в пятницу.',
|
||||||
|
},
|
||||||
|
|
||||||
|
hero: {
|
||||||
|
stamp: 'ЧТ · обжарка',
|
||||||
|
eyebrow: 'Обжарка кофе в Минске',
|
||||||
|
title: 'Кофе, обжаренный в четверг',
|
||||||
|
subtitle:
|
||||||
|
'В пятницу привозим по Минску, и пачка попадает к вам на 1–3 день после обжарки.',
|
||||||
|
ctaPrimary: { label: 'Оформить подписку', interest: 'subscription' } satisfies Cta,
|
||||||
|
ctaSecondary: { label: 'Заказать пачку', interest: 'one_time' } satisfies Cta,
|
||||||
|
},
|
||||||
|
|
||||||
|
freshness: {
|
||||||
|
title: 'Как устроена наша неделя',
|
||||||
|
days: [
|
||||||
|
{ day: 'ЧТ', label: 'Обжарка', caption: 'Обжариваем зерно партиями по 5 кг.' },
|
||||||
|
{ day: 'ПТ', label: 'Доставка', caption: 'Развозим заказы по Минску.' },
|
||||||
|
{ day: '1–3 день', label: 'В чашке', caption: 'Открываете пачку и варите кофе.' },
|
||||||
|
],
|
||||||
|
why: 'Кофе вкуснее, пока обжарка свежая.',
|
||||||
|
},
|
||||||
|
|
||||||
|
catalog: {
|
||||||
|
title: 'Что обжариваем',
|
||||||
|
subtitle: 'Три сорта в пачках по 250 г и дрип-пакеты.',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: 'ethiopia',
|
||||||
|
name: 'Эфиопия Иргачеффе',
|
||||||
|
notes: ['цветочный', 'бергамот'],
|
||||||
|
roast: 'светлая обжарка',
|
||||||
|
brew: null,
|
||||||
|
size: '250 г',
|
||||||
|
price: 32,
|
||||||
|
priceDisplay: '32 BYN',
|
||||||
|
cta: { label: 'Заказать', interest: 'one_time', comment: 'Эфиопия Иргачеффе, 250 г' } satisfies Cta,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'colombia',
|
||||||
|
name: 'Колумбия Уила',
|
||||||
|
notes: ['карамель', 'красное яблоко'],
|
||||||
|
roast: null,
|
||||||
|
brew: null,
|
||||||
|
size: '250 г',
|
||||||
|
price: 29,
|
||||||
|
priceDisplay: '29 BYN',
|
||||||
|
cta: { label: 'Заказать', interest: 'one_time', comment: 'Колумбия Уила, 250 г' } satisfies Cta,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'brazil',
|
||||||
|
name: 'Бразилия Серрадо',
|
||||||
|
notes: ['орех', 'шоколад'],
|
||||||
|
roast: null,
|
||||||
|
brew: 'под эспрессо',
|
||||||
|
size: '250 г',
|
||||||
|
price: 26,
|
||||||
|
priceDisplay: '26 BYN',
|
||||||
|
cta: { label: 'Заказать', interest: 'one_time', comment: 'Бразилия Серрадо, 250 г' } satisfies Cta,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'drip',
|
||||||
|
name: 'Дрип-пакеты ассорти',
|
||||||
|
notes: [],
|
||||||
|
roast: null,
|
||||||
|
brew: 'заваривается прямо в чашке',
|
||||||
|
size: '10 шт',
|
||||||
|
price: 18,
|
||||||
|
priceDisplay: '18 BYN',
|
||||||
|
cta: { label: 'Заказать', interest: 'one_time', comment: 'Дрип-пакеты ассорти, 10 шт' } satisfies Cta,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
subscription: {
|
||||||
|
title: 'Две пачки каждый месяц',
|
||||||
|
text: 'Раз в месяц привозим две пачки по 250 г. Доставка бесплатно.',
|
||||||
|
price: 54,
|
||||||
|
priceDisplay: '54 BYN в месяц',
|
||||||
|
note: 'Подробности менеджер расскажет по телефону.',
|
||||||
|
cta: { label: 'Оформить подписку', interest: 'subscription', comment: 'Подписка: 2 пачки в месяц' } satisfies Cta,
|
||||||
|
},
|
||||||
|
|
||||||
|
about: {
|
||||||
|
title: 'Кто обжаривает',
|
||||||
|
text: [
|
||||||
|
'Нас зовут Аня и Дмитрий. Раньше мы работали бариста, а в 2019 году открыли свою обжарку в Минске.',
|
||||||
|
'Обжариваем небольшими партиями по 5 кг. «Кварта» значит «четвёртая»: четверг у нас день обжарки.',
|
||||||
|
],
|
||||||
|
facts: [
|
||||||
|
{ value: '2019', label: 'открыли обжарку' },
|
||||||
|
{ value: '5 кг', label: 'одна партия' },
|
||||||
|
{ value: 'ЧТ', label: 'день обжарки' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
delivery: {
|
||||||
|
title: 'Доставка и самовывоз',
|
||||||
|
delivery: {
|
||||||
|
title: 'Доставка по Минску',
|
||||||
|
lines: [
|
||||||
|
'Привозим в пятницу.',
|
||||||
|
'От 50 BYN бесплатно.',
|
||||||
|
'Если заказ меньше, стоимость доставки уточнит менеджер.',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
pickup: {
|
||||||
|
title: 'Самовывоз',
|
||||||
|
address: 'Минск, ул. Короля, 9',
|
||||||
|
hours: [
|
||||||
|
{ days: 'Пн–пт', time: '8:00–20:00' },
|
||||||
|
{ days: 'Сб–вс', time: '10:00–18:00' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
cta: { label: 'Задать вопрос', interest: 'question' } satisfies Cta,
|
||||||
|
},
|
||||||
|
|
||||||
|
lead: {
|
||||||
|
title: 'Оставьте заявку',
|
||||||
|
subtitle: 'Менеджер перезвонит в рабочее время и всё уточнит.',
|
||||||
|
},
|
||||||
|
|
||||||
|
stickyCta: {
|
||||||
|
label: 'Заказать кофе',
|
||||||
|
note: 'Обжарка в четверг, доставка в пятницу',
|
||||||
|
interest: 'one_time' satisfies Interest,
|
||||||
|
},
|
||||||
|
|
||||||
|
footer: {
|
||||||
|
name: 'Кварта',
|
||||||
|
tagline: 'Обжарка кофе в Минске с 2019 года',
|
||||||
|
address: 'Минск, ул. Короля, 9',
|
||||||
|
hours: 'Пн–пт 8:00–20:00, сб–вс 10:00–18:00',
|
||||||
|
phone: CONTACT_PHONE,
|
||||||
|
phoneNote: 'Номер демонстрационный.',
|
||||||
|
photoCredit: 'Фото: Mona Jain, Tina Guina, Scott Soltys-Curry / Unsplash',
|
||||||
|
disclaimer: 'Учебный проект. Обжарка «Кварта» вымышленная.',
|
||||||
|
},
|
||||||
|
|
||||||
|
images: {
|
||||||
|
beans: { alt: 'Обжаренные кофейные зёрна крупным планом' },
|
||||||
|
sack: { alt: 'Открытый мешок с обжаренным кофейным зерном' },
|
||||||
|
cooler: { alt: 'Зерно остывает в охладителе ростера' },
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
Reference in New Issue
Block a user