FUTURE MINDS — futureminds.uz
---
1. THE ONE-LINE BRIEF
Build a trilingual (UZ/RU/EN), animation-rich marketing site + trial-day booking engine for a Tashkent kindergarten. The design goal is explicit: parents should fall a little bit in love before they ever visit. The site's single conversion job: **book a free trial day.**
Stack: Next.js 14+ (App Router) · Vercel · Supabase (Postgres, Auth, Storage) · GitHub · Tailwind + Framer Motion + Lottie.
---
2. DESIGN DIRECTION — "A Day That Unfolds"
Concept
This is the single memorable element. Everything else stays disciplined around it.
Palette — derived from their actual logo (pink child, blue child, orange book, gold stars)
Typography
Motion system (this is where "too much animation" becomes "finest," not "noisy")
1. **Page-load overture (once, ~1.2s):** the two logo children "jump" into the header, stars pop in with spring physics, headline letters rise word-by-word (staggerChildren: 0.06). Skip entirely on repeat visits (sessionStorage flag).
2. **Scroll-driven day cycle (the signature):** `useScroll` + `useTransform` mapping scrollYProgress → background gradient stops, sun/moon position along an SVG arc, and parallax cloud layers (3 depths, translateY at 0.2x / 0.5x / 0.8x).
3. **Scroll reveals:** every section's content enters with `whileInView` spring (y: 24 → 0, once: true). Cards get a playful 1.5° rotation settle.
4. **Micro-interactions:** buttons squash-and-stretch on tap (scale 0.94 with spring bounce — the classic animation-principle squash kids' brands use); nav stars twinkle on hover; the WhatsApp/Telegram FAB gently breathes.
5. **Ambient life (subtle, GPU-cheap):** floating alphabet letters and shapes drift in the hero at very low opacity; a paper-airplane Lottie flies across on section transitions.
6. **Interactive delight:** hero elements are touchable — tap a balloon, it bobs; tap a star, it spins and chimes (muted by default, sound toggle). On desktop, elements shy away slightly from the cursor (magnetic-repel, spring stiffness 120).
**Hard rules:**
- `prefers-reduced-motion`: all of the above collapses to simple fades. Non-negotiable.
- Only animate `transform` and `opacity`. No layout-property animation. 60fps on a mid-range Android — Uzbekistan is a mobile-first, Android-heavy market and this site will mostly be seen on phones via Instagram/Telegram links.
- Lottie files < 100KB each, lazy-loaded below the fold.
- Lighthouse performance ≥ 85 mobile is a release gate. If an animation costs more than it delights, cut it.
Illustration language
---
3. PAGE ARCHITECTURE
```
/ Home — the "day that unfolds" scroll journey
/programs Age-based program picker (1.5–3, 3–5, 5–7 + summer camp 3–12)
/day A Day at Future Minds (schedule timeline, meals — 4x daily)
/teachers Teacher profiles ("Наши профессиональные воспитатели")
/gallery Photo/video gallery (Supabase Storage, masonry, lightbox)
/fees Transparent pricing — 3,600,000 so'm/mo, what's included
/visit ★ TRIAL DAY BOOKING — the conversion page
/contact Yandex Maps embed, landmarks (near Indian embassy),
phone +998 94 7296050, Telegram/WhatsApp deep links
/news Announcements & seasonal posts (feeds marketing engine later)
```
Home page section flow (scroll = day)
i18n
Uzbekistan-specific decisions
---
4. SUPABASE SCHEMA
```sql
-- ENUMS
create type locale as enum ('uz','ru','en');
create type booking_status as enum ('new','confirmed','visited','enrolled','cancelled','no_show');
create type media_kind as enum ('photo','video');
-- PROGRAMS (age groups + summer camp)
create table programs (
id uuid primary key default gen_random_uuid(),
slug text unique not null, -- 'toddlers','juniors','pre-school','summer-camp'
age_min numeric(3,1) not null, -- 1.5
age_max numeric(3,1) not null, -- 7 (camp: 12)
monthly_fee_uzs bigint, -- 3600000; null for camp (one-off pricing)
sort_order int default 0,
is_active boolean default true,
created_at timestamptz default now()
);
create table program_translations (
program_id uuid references programs(id) on delete cascade,
locale locale not null,
name text not null,
tagline text,
description text,
highlights jsonb, -- ["English daily","Swimming", ...]
primary key (program_id, locale)
);
-- TEACHERS
create table teachers (
id uuid primary key default gen_random_uuid(),
photo_path text, -- supabase storage
years_experience int,
sort_order int default 0,
is_active boolean default true
);
create table teacher_translations (
teacher_id uuid references teachers(id) on delete cascade,
locale locale not null,
full_name text not null,
role text, -- 'Senior educator'
bio text,
primary key (teacher_id, locale)
);
-- DAILY SCHEDULE (drives the /day page AND the home scroll narrative)
create table schedule_items (
id uuid primary key default gen_random_uuid(),
program_id uuid references programs(id),
starts_at time not null,
ends_at time,
icon text, -- lucide icon name
sort_order int default 0
);
create table schedule_translations (
schedule_item_id uuid references schedule_items(id) on delete cascade,
locale locale not null,
title text not null, -- 'Morning circle'
primary key (schedule_item_id, locale)
);
-- GALLERY
create table media_items (
id uuid primary key default gen_random_uuid(),
kind media_kind not null default 'photo',
storage_path text not null,
alt_text jsonb, -- {"uz":"...","ru":"...","en":"..."}
tags text[], -- ['navruz','swimming','classroom']
is_featured boolean default false, -- appears on home strip
taken_on date,
created_at timestamptz default now()
);
-- NEWS / ANNOUNCEMENTS (later: source for the Canva marketing engine)
create table posts (
id uuid primary key default gen_random_uuid(),
slug text unique not null,
cover_path text,
published_at timestamptz,
is_published boolean default false
);
create table post_translations (
post_id uuid references posts(id) on delete cascade,
locale locale not null,
title text not null,
body text, -- markdown
primary key (post_id, locale)
);
-- ★ TRIAL DAY BOOKINGS (the conversion engine)
create table trial_bookings (
id uuid primary key default gen_random_uuid(),
parent_name text not null,
phone text not null, -- +998...
telegram_username text,
child_name text,
child_age numeric(3,1) not null,
preferred_date date not null,
program_id uuid references programs(id),
locale locale not null default 'ru', -- language they booked in → reply in it
message text,
status booking_status default 'new',
source text default 'website', -- 'website','instagram','telegram'
created_at timestamptz default now(),
updated_at timestamptz default now()
);
-- TESTIMONIALS
create table testimonials (
id uuid primary key default gen_random_uuid(),
parent_name text not null,
locale locale not null,
quote text not null,
is_featured boolean default false,
sort_order int default 0
);
-- CONTACT/LEAD messages (non-booking inquiries)
create table inquiries (
id uuid primary key default gen_random_uuid(),
name text not null,
phone text not null,
message text,
locale locale default 'ru',
handled boolean default false,
created_at timestamptz default now()
);
```
RLS policy summary
Anti-spam on public inserts
---
5. TELEGRAM BOT INTEGRATION (lead alerts)
Supabase Database Webhook on `trial_bookings` insert → Edge Function → Telegram Bot API `sendMessage` to a private admin group:
```
🎈 New trial day booking!
Parent: {parent_name} · {phone}
Child: {child_name}, {child_age} yrs
Date: {preferred_date} · Program: {program}
Language: {locale} · Source: {source}
```
Buttons in the bot message (callback): ✅ Confirm / 📞 Called / ❌ Cancel → updates `status`. Director manages leads without ever opening the admin panel. Same pattern for `inquiries`.
Env: `TELEGRAM_BOT_TOKEN`, `TELEGRAM_ADMIN_CHAT_ID`.
---
6. ADMIN PANEL (/admin — keep it boring and fast)
Protected by Supabase Auth. Plain, functional UI (the playfulness is for parents, not for the back office):
- Bookings kanban: New → Confirmed → Visited → Enrolled (this pipeline is also your enrollment-funnel report to the client)
- Gallery upload (drag-drop → Supabase Storage, auto-resize via next/image)
- Posts editor (markdown), teachers, testimonials, schedule CRUD
- All content editable in 3 locales with tabbed inputs
---
7. SEO & PERFORMANCE
- SSG/ISR for all public pages; revalidate on admin publish.
- Metadata + OpenGraph per locale; JSON-LD `Preschool` schema with address, geo, phone, priceRange, openingHours.
- Target queries: "частный детский сад Ташкент Мирзо Улугбек", "xususiy bog'cha Toshkent", "kindergarten Tashkent english".
- next/image everywhere, AVIF/WebP, hero illustrations as optimized SVG.
- Fonts: next/font with Cyrillic + Latin subsets only.
- Budget: LCP < 2.5s on 4G Android, CLS < 0.05, Lighthouse mobile ≥ 85.
---
8. BUILD ORDER (suggested Claude Code session plan)
1. Scaffold: Next.js + Tailwind + next-intl + Supabase client, deploy skeleton to Vercel immediately.
2. Run schema migration + seed with real data from their Instagram (programs, fees, schedule, contacts).
3. Design system: tokens, fonts, mascot SVG components, motion primitives (SquashButton, RevealSection, DayCycleBackground).
4. Home page with full day-cycle scroll signature.
5. /visit booking flow + server action + Turnstile + Telegram webhook.
6. Remaining pages + gallery.
7. /admin.
8. Motion/perf polish pass: test on a real mid-range Android, reduced-motion audit, Lighthouse gate.
---
9. WHAT NOT TO DO
- No pure-white background, no generic SaaS look, no stock photo heroes.
- No AI-photoreal children imagery in the brand system.
- No autoplaying sound. Sound only behind an explicit toggle.
- No animation of layout properties; no scroll-jacking (native scroll speed always).
- Don't hide the price. Their transparency is a differentiator — design it proudly.
- Don't build email flows. This market runs on Telegram and phone calls.