// SWAPP main page — based on Figma layout, refined.
// Structure: Hero → Cases (tabs) → 3 advantages (3D) → How it works (4 cards w/ 3D) →
// Campaign creation flow → Influencer ratings → Light section "1000 bloggers waiting" →
// Calculator (tiered) → Blog → FAQ → Contact CTA → Footer.
const D = {
bg: '#000000',
bg2: '#0a0a0a',
card: '#141414',
cardHi: '#1a1a1a',
line: '#262626',
lineHi: '#333333',
ink: '#ffffff',
ink2: '#e5e5e5',
mute: '#a3a3a3',
mute2: '#737373',
green: '#22ee5e',
greenSolid: '#1bcc4f',
greenDim: '#0fa53d',
greenInk: '#001a08',
greenGlow: 'rgba(34,238,94,0.18)',
greenGlowStrong: 'rgba(34,238,94,0.4)',
light: '#d9d9d9',
lightWarm: '#e6e6e3',
bronze: '#cd7f32',
silver: '#c0c0c0',
gold: '#f5c842'
};
// Expose tokens for sibling files
if (typeof window !== 'undefined') window.__SwappTokens = D;
// App Store URL — wired to every «Скачать приложение» CTA.
const SWAPP_APP_STORE = 'https://apps.apple.com/kz/app/swapp-%D1%80%D0%B5%D0%BA%D0%BB%D0%B0%D0%BC%D0%B0-c-%D0%B1%D0%BB%D0%BE%D0%B3%D0%B5%D1%80%D0%B0%D0%BC%D0%B8/id6739431825';
if (typeof window !== 'undefined') window.__SwappAppStore = SWAPP_APP_STORE;
function ConservativeVariant() {
// Final desktop layout — locked variants:
// Hero → TrustLogos → Cases (Manifesto) → Calculator → How (Timeline) →
// Advantages (Split) → Bloggers waiting → Ratings (Profile) → FAQ →
// Blog (Cards) → Contact CTA → Footer
return (
);
}
function Logo({ size = 'md' }) {
const heights = { sm: 22, md: 30, lg: 44 };
const h = heights[size];
const w = h * (226 / 50);
return (
);
}
function DarkNav() {
return (
{['Кейсы', 'Преимущества', 'Как это работает?', 'Тариф', 'Блог', 'Блогерам', 'Контакты'].map((n, i) =>
{n}
)}
);
}
function DownloadAppButton() {
return (
Скачать приложение
);
}
// ─── HERO ────────────────────────────────────────────────────
function Hero() {
return (
Реклама с инфлюенсерами
по бартеру.
Создайте оффер — и получайте отклики от проверенных инфлюенсеров уже сегодня.
{/* Mini stats strip */}
{[
{ v: '80+', l: 'брендов' },
{ v: '5 000+', l: 'инфлюенсеров' },
{ v: '10 мин', l: 'до запуска' }].
map((s, i) =>
)}
{/* Hero creative — composite collage (woman + bag + barter card + brunch card + cosmetics) */}
);
}
function RatingsSection() {
const tiers = [
{
title: 'Бронза',
sub: 'Маленькая аудитория — глубокое доверие',
handle: '@alma_food', niche: 'Еда · Алматы',
followers: '8.2K', er: '8.4%', score: 28,
photo: 'assets/rating-bronze.jpg',
avatar: 'assets/rating-bronze-avatar.jpg'
},
{
title: 'Серебро',
sub: 'Своя ниша, свой голос, стабильный отклик',
handle: '@arman.runs', niche: 'Мода · Алматы',
followers: '34.6K', er: '5.1%', score: 37,
photo: 'assets/rating-silver.jpg',
avatar: 'assets/rating-silver-avatar.jpg'
},
{
title: 'Золото',
sub: 'Масштаб без потери настоящей вовлечённости',
handle: '@aizere.kz', niche: 'Спорт · Астана',
followers: '128K', er: '3.6%', score: 84,
photo: 'assets/rating-gold.jpg',
avatar: 'assets/rating-gold-avatar.jpg'
}];
return (
Рейтинг инфлюенсера
Считаем по 40+ параметрам — не по подписчикам. Пост у блогера с 5 тыс. живых подписчиков часто работает сильнее, чем у звезды с миллионом.
{tiers.map((t) =>
{/* Top glass pill — avatar + handle + score */}
{t.handle}
{t.followers} подписчиков
{t.score} /100
{/* Bottom: title + UGC sub + ER hero stat */}
{t.title}
{t.sub}
{t.er}
вовлечённость
)}
Чем выше рейтинг — тем ценнее бартер, который ожидает инфлюенсер. Вы сами решаете, что предложить.
);
}
function BloggersWaiting() {
const niches = ['Спорт', 'Еда', 'Концерты', 'Красота', 'Образование', 'Туризм', 'Услуги', 'и ещё'];
const activeSet = new Set(['Спорт', 'Красота', 'Услуги']);
return (
{/* Decorative dotted texture, subtle on the left edge */}
{/* TEXT column */}
Сделайте предложение — его ждут
{niches.map((n, i) => {
const isLast = i === niches.length - 1;
const isActive = activeSet.has(n);
return (
{isLast ? '+ ещё 12' : n}
);
})}
Подберите тех, кто говорит с вашей аудиторией. Без переплат агентствам.
{/* IMAGE column — bleeds left into text column for compositional unity */}
{/* Soft glow halo to anchor the products visually */}
);
}
function AppStoreBadge() {
return (
Download on the
App Store
);
}
function CalculatorSection() {
const [bronze, setBronze] = React.useState({ cost: 5000, count: 5 });
const [silver, setSilver] = React.useState({ cost: 12000, count: 3 });
const [gold, setGold] = React.useState({ cost: 30000, count: 1 });
const total = bronze.count + silver.count + gold.count;
const barterCost = bronze.cost * bronze.count + silver.cost * silver.count + gold.cost * gold.count;
const commission = total * 5000;
const totalCost = barterCost + commission;
const reach = bronze.count * 1500 + silver.count * 4500 + gold.count * 12000;
const cpm = reach > 0 ? Math.round(totalCost / (reach / 1000)) : 0;
return (
Калькулятор охвата
Сравните с таргетом и агентствами.
{setBronze({ cost: 0, count: 0 });setSilver({ cost: 0, count: 0 });setGold({ cost: 0, count: 0 });}}
style={{ flex: 1, background: D.card, color: D.ink, border: `1px solid ${D.line}`, padding: 18, borderRadius: 14, fontSize: 15, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit' }}>Сбросить
Рассчитать
{/* Result */}
Расчёт кампании
Примерный охват
{reach.toLocaleString('ru-RU')}
просмотров
Тот же охват иначе
0 ? `${Math.round(reach * 1.5 / 1000)} — ${Math.round(reach * 2.2 / 1000)} тыс. ₸` : '—'} />
0 ? `${Math.round(reach * 1.1 / 1000)} — ${Math.round(reach * 1.4 / 1000)} тыс. ₸` : '—'} />
);
}
function TierRow({ name, color, value, onChange }) {
return (
onChange({ ...value, cost: v })} suffix="₸" />
onChange({ ...value, count: v })} max={50} />
);
}
function NumField({ label, value, onChange, suffix, max = 1000000 }) {
return (
{label}
onChange(Math.min(max, +e.target.value || 0))}
style={{ background: 'transparent', border: 'none', color: D.ink, fontSize: 15, fontWeight: 600, fontFamily: 'inherit', width: '100%', outline: 'none', padding: 0, fontVariantNumeric: 'tabular-nums' }} />
{suffix && {suffix} }
);
}
function ResultLine({ label, value, bold, compact }) {
return (
);
}
// ─── BLOG ──────────────────────────────────────────────
function BlogSection() {
const posts = [
{ tag: 'Кейс', category: 'Клиентский кейс', title: 'Как «КАМИН» собрал 138 000 просмотров за неделю', date: '10.11.2024', read: '4 мин', hue: 145, image: 'assets/kamin-blog.jpg' },
{ tag: 'Гайд', category: 'Бриф и ТЗ', title: 'Что писать в ТЗ блогеру, чтобы получить нужный контент', date: '02.11.2024', read: '7 мин', hue: 25 },
{ tag: 'Аналитика', category: 'CPM и экономика', title: 'Сравнили SWAPP и Instagram-таргет: где CPM ниже', date: '18.10.2024', read: '5 мин', hue: 220 }];
return (
);
}
function BlogCard({ post }) {
return (
{post.image ?
:
}
{post.tag}
{post.category}
{post.title}
{post.date} · {post.read}
);
}
// ─── FAQ ──────────────────────────────────────────────
function FaqSection() {
const items = [
{ q: 'Чем SWAPP отличается от рассылки в Direct?', a: 'Три вещи: мы сами проверяем блогеров — данные приходят напрямую от Instagram в реальном времени. Весь процесс автоматизирован в приложении (без переписок). И комиссия возвращается, если ТЗ не выполнено.' },
{ q: 'Что такое Бронза/Серебро/Золото?', a: 'Это рейтинг по реальному влиянию: ER, качество аудитории, география, соответствие нише. Подсчитан по 40 параметрам, не по подписчикам.' },
{ q: 'Можно ли выбрать конкретного блогера?', a: 'Да. Перед подтверждением визита вы видите рейтинг, охват, ER и примеры контента каждого кандидата.' },
{ q: 'Как работает возврат 100%?', a: 'Комиссия 5 000 ₸ списывается только после модерации. Если ТЗ не выполнено или блогер не пришёл — деньги возвращаются на баланс автоматически.' },
{ q: 'Кто платит за бартер?', a: 'Бартер — это ваши услуги или товары. Вы определяете его сами. Платформа берёт фиксированные 5 000 ₸ за блогера.' },
{ q: 'Сколько стоит запуск?', a: 'Минимальное пополнение — 20 000 ₸ (4 блогера). Кампанию можно запустить за 10 минут.' }];
const [open, setOpen] = React.useState(0);
return (
FAQ
Не нашли ответа? Пишите на hi@swapp.kz — отвечаем в течение часа.
{items.map((f, i) => {
const isOpen = open === i;
return (
setOpen(isOpen ? -1 : i)}
style={{ width: '100%', background: 'transparent', border: 'none', padding: '24px 28px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left', color: D.ink, gap: 16 }}>
{f.q}
+
{isOpen &&
{f.a}
}
);
})}
);
}
// ─── CONTACT CTA / FINAL CTA ─────────────────────────
// Final CTA mirroring mobile MFinalCta, scaled up for desktop.
function ContactCta() {
return (
{/* Atmospheric halo at bottom */}
{/* Grid pattern, masked to bottom */}
Запустите первую кампанию за 10 минут.
Создайте оффер — и уже сегодня первые верифицированные блогеры откликнутся на ваш бартер.
);
}
// ─── FOOTER ──────────────────────────────────────
// Структура: ЛОГО · Навигация · Контакты · О компании
function Footer() {
return (
{/* Лого */}
B2B-платформа для бартерной рекламы с верифицированными инфлюенсерами Казахстана.
Все системы работают
{/* Навигация */}
{/* Контакты */}
{/* О компании */}
О компании
ТОО «SWAPP»
БИН 240240012345
Алматы, ул. Достык 200
офис 1407
{/* Bottom strip */}
© 2026 SWAPP. Все права защищены.
);
}
function FooterCol({ title, items }) {
return (
{title}
{items.map((it, i) => {
const obj = typeof it === 'string' ? { l: it } : it;
return (
);
})}
);
}
Object.assign(window, { ConservativeVariant, D_THEME: D, Logo });