/* ───────────────────────────────────────────────── Home variants — V02..V08 (7 alternative Home screens) All Rose-DNA, hot pink + pastels. Vary structure, type, icons, layout, "acidness". Each variant renders its own tab bar so we can show DNA-shifts there too. ───────────────────────────────────────────────── */ /* tiny helper: simple working tab bar with custom skin per variant */ function VariantTabBar({ active, onChange, skin = {} }) { const tabs = [ { id:"home", label:"йога" }, { id:"classes", label:"занятия" }, { id:"online", label:"онлайн" }, { id:"profile", label:"профиль" }, ]; const { bg = "#fff", border = "2.5px solid #e91e8c", activeBg = "#e91e8c", activeFg = "#fff", inactiveFg = "#e91e8c", rounded = 0, fontSize = 12, fontFamily = "'Nunito',sans-serif", fontWeight = 900, iconKind = "lotus", // controls home icon } = skin; return (
{tabs.map(t=>{ const isActive = t.id===active; const ico = t.id==="home"?iconKind: t.id==="classes"?"calendar": t.id==="online"?"play":"user"; return (
onChange(t.id)} style={{ flex:1, display:"flex", flexDirection:"column", alignItems:"center", justifyContent:"center", gap:6, background: isActive? activeBg:"transparent", color: isActive? activeFg:inactiveFg, cursor:"pointer", transition:"background .2s, color .2s", }}> {t.label}
); })}
); } /* shared frame container so each variant fills the iOS canvas. If customTabBar (render fn) is provided, use it instead of the skinned VariantTabBar. This lets the configurator swap tab bars across all home variants. */ function HomeFrame({ bg, children, tabSkin, tabIdState, customTabBar }) { const [tab, setTab] = tabIdState ?? React.useState("home"); return (
{children}
}/>
); } /* Context that the configurator uses to inject a different tab bar render fn */ const TabBarContext = React.createContext(null); function TabBarSlot({ active, onChange, fallback }) { const render = React.useContext(TabBarContext); if (render) return render({ active, onChange }); return fallback; } function TabBarOverride({ render, children }) { return {children}; } /* ============ V02 — TABULAR / iOS Settings-style ============ */ function HomeV02() { return (
главная
29 APR · ANNA
{/* grouped list — iOS Settings */}
записаться
{[ { l:"Виньяса флоу", r:"08:00 · 4 места", c:"#c4b5fd" }, { l:"Инь-йога", r:"10:30 · 1 место", c:"#a7f3d0" }, { l:"Аштанга", r:"12:00 · мест нет", c:"#fde68a", muted:true }, { l:"Медитация", r:"18:00 · 9 мест", c:"#f9a8d4" }, ].map((r,i,a)=>(
{r.l.toLowerCase()}
{r.r}
))}
обучение
{COURSES.slice(0,2).map((c,i,a)=>(
{c.title}
{c.instructor.toLowerCase()} · {Math.floor(c.durationMin/60)}h
))}
новости
{NEWS.map((n,i,a)=>(
{n.category}
{n.title.toLowerCase()}
))}
); } /* ============ V03 — MAGAZINE / editorial big type ============ */ function HomeV03() { return (
vol. 04 · issue 29
apr 2026
{/* HUGE editorial title */}
практика
сегодня
{/* subhead */}
Виньяса с Аленой в 08:00, инь с Машей в 10:30. Мест ещё хватает на оба занятия.
5
{/* divider with dropcap-style hint */}
{/* feature: next class */}
следующее занятие
08:00
виньяса флоу
алена · зал 1 · 60 мин · 8 мест
{/* news as bylines */}
колонка
{NEWS.slice(0,2).map((n,i)=>(
{n.title}
{n.summary}
{n.date}
))}
); } /* ============ V04 — BRUTALIST / hot pink to the max ============ */ function HomeV04() { return (
ЙОГА.
СЕГОДНЯ.
29.04
{/* big black sticker */}
NEXT UP
VINYASA 08:00
алена · зал 1 · ещё 8 мест
записаться
{/* tile grid */}
{[ {l:"ОНЛАЙН",bg:"#fff",fg:"#000"}, {l:"СТУДИЯ",bg:"#000",fg:"#fff"}, {l:"ОДИН РАЗ",bg:"#000",fg:"#fff"}, {l:"АБОНЕМЕНТ",bg:"#fff",fg:"#000"}, ].map((t,i)=>(
{t.l}
))}
{/* news bar */}
NEWS // 03 ITEMS
{NEWS.map((n,i)=>(
{String(i+1).padStart(2,"0")}
{n.title.toUpperCase()}
))}
); } /* ============ V05 — SOFT / pillow / mega-rounded ============ */ function HomeV05() { return (
привет, анна
что выберем сегодня?
{/* big pillow CTAs */}
записаться
5 занятий сегодня
онлайн курсы
смотреть в любое время
{/* horizontal pill chips: classes */}
сегодня
{CLASSES.slice(0,4).map(c=>(
{c.time}
{c.name.toLowerCase()}
{c.teacher.toLowerCase()}
))}
{/* news pillow */}
новости студии
{NEWS.slice(0,2).map((n,i,a)=>(
{n.title.toLowerCase()}
{n.summary}
))}
); } /* ============ V06 — NEON / Y2K acid kawaii ============ */ function HomeV06() { return (
::yoga::
★ ANNA . ONLINE
29APR_06
>>> NEXT
vinyasa 08:00
// alena · room_1 · 08_seats_left
{/* neon tile grid */}
{[ {l:"online", c:"#a7f3d0", t:"#000"}, {l:"studio", c:"#fde68a", t:"#000"}, {l:"single", c:"#ff10a3", t:"#fff"}, {l:"weekly", c:"#a855f7", t:"#fff"}, ].map((t,i)=>(
{t.l}
))}
::news_log::
{NEWS.map((n,i)=>(
{String(i+1).padStart(2,"0")}.{n.category.toLowerCase()} {n.date}
{n.title.toLowerCase()}
))}
); } /* ============ V07 — STORIES / TikTok carousel ============ */ function HomeV07() { const stories = [ { c:"#c4b5fd", l:"виньяса", t:"08:00", who:"алена" }, { c:"#a7f3d0", l:"инь", t:"10:30", who:"маша" }, { c:"#fde68a", l:"аштанга", t:"12:00", who:"денис" }, { c:"#f9a8d4", l:"медитация", t:"18:00", who:"ира" }, { c:"#fed7aa", l:"растяжка", t:"19:30", who:"маша" }, ]; return ( {/* avatar row stories-style */}
сегодня 5 практик
{stories.map((s,i)=>(
{s.t}
{s.l}
))}
{/* Big TikTok card snap */}
{CLASSES.slice(0,3).map(c=>(
{c.level}
{c.duration}мин
{c.time}
{c.name.toLowerCase()}
{c.teacher.toLowerCase()} · {c.spotsTotal-c.spotsTaken} мест
записаться →
))}
{/* News strip */}
новости
{NEWS.map(n=>(
{n.category}
{n.title}
))}
); } /* ============ V08 — BENTO GRID / modular ============ */ function HomeV08() { return (
bento day
29 apr · ср
{/* bento grid */}
{/* big next class */}
NEXT · 1ч 23мин
08:00
виньяса · алена
{/* progress / streak */}
STREAK
12
дней подряд
{/* mini-tile online */}
онлайн
4 курса
{/* mini-tile abonement */}
АБОНЕМЕНТ
7
/12
{/* row of 3 small classes */} {CLASSES.slice(1,4).map(c=>(
{c.time}
{c.name.split(" ")[0].toLowerCase()}
))} {/* big news */}
NEWS · 03
{NEWS.slice(0,2).map((n,i,a)=>(
{n.title.toLowerCase()}
))}
); } Object.assign(window, { HomeV02, HomeV03, HomeV04, HomeV05, HomeV06, HomeV07, HomeV08, VariantTabBar, HomeFrame, TabBarOverride });