LMS — Kids Learning Landing
A bright, playful marketing landing page for a make-believe kids learning platform. Features a bouncing fox mascot whose eyes follow the cursor, a sticky responsive nav with a mobile drawer, tappable subject cards, age-group paths, a parent-trust section with an animated weekly progress report, fun testimonials, and a free-trial form with email validation, a confetti burst, and toast feedback. Built with bright primary colors, chunky rounded sans type, and springy hover animations.
MCP
Code
:root {
/* Kids palette — bright primaries + white */
--yellow: #ffd23f;
--yellow-d: #f4b400;
--sky: #3aa0ff;
--sky-d: #1f7fe0;
--coral: #ff6f61;
--coral-d: #ef5340;
--grape: #7c5cff;
--mint: #1ec98b;
--ink: #2b2545;
--ink-2: #5a5475;
--muted: #8b86a3;
--bg: #fff8ec;
--bg-2: #f1f7ff;
--surface: #ffffff;
--line: rgba(43, 37, 69, 0.1);
--r-sm: 12px;
--r-md: 20px;
--r-lg: 32px;
--r-pill: 999px;
--sh-sm: 0 6px 16px rgba(43, 37, 69, 0.08);
--sh-md: 0 14px 34px rgba(43, 37, 69, 0.12);
--sh-pop: 0 18px 40px rgba(58, 160, 255, 0.28);
--font: "Nunito", system-ui, -apple-system, sans-serif;
--display: "Baloo 2", "Nunito", system-ui, sans-serif;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: var(--font);
color: var(--ink);
background: var(--bg);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
overflow-x: hidden;
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto; }
}
h1, h2, h3, h4 { font-family: var(--display); margin: 0; line-height: 1.1; color: var(--ink); }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; }
.wrap { width: min(1140px, 92vw); margin-inline: auto; }
.sr-only, .skip-link {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link:focus {
position: fixed; top: 12px; left: 12px; width: auto; height: auto;
clip: auto; z-index: 100; background: var(--ink); color: #fff;
padding: 10px 16px; border-radius: var(--r-sm);
}
/* ===== Buttons ===== */
.btn {
font-family: var(--display); font-weight: 700; font-size: 1rem;
border: none; cursor: pointer; border-radius: var(--r-pill);
padding: 13px 24px; transition: transform .18s cubic-bezier(.34,1.7,.5,1), box-shadow .2s, background .2s;
}
.btn:active { transform: scale(.94); }
.btn-big {
background: linear-gradient(180deg, var(--coral), var(--coral-d));
color: #fff; font-size: 1.1rem; padding: 15px 30px;
box-shadow: 0 10px 0 -2px var(--coral-d), var(--sh-sm);
}
.btn-big:hover { transform: translateY(-3px) scale(1.03); box-shadow: 0 14px 0 -2px var(--coral-d), var(--sh-md); }
.btn-ghost {
background: #fff; color: var(--ink); border: 2px solid var(--line);
}
.btn-ghost:hover { transform: translateY(-3px); border-color: var(--sky); color: var(--sky-d); }
.btn-soft {
background: color-mix(in srgb, var(--c) 16%, #fff);
color: var(--ink); border: 2px solid color-mix(in srgb, var(--c) 55%, #fff);
}
.btn-soft:hover { transform: translateY(-3px) rotate(-1deg); background: var(--c); color: #fff; }
/* ===== NAV ===== */
.nav {
position: sticky; top: 0; z-index: 40;
background: rgba(255, 248, 236, 0.85);
backdrop-filter: blur(10px);
border-bottom: 2px solid transparent;
transition: box-shadow .25s, border-color .25s, background .25s;
}
.nav.scrolled { box-shadow: var(--sh-sm); border-color: var(--line); background: rgba(255,255,255,.9); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 72px; }
.brand { display: flex; align-items: center; gap: 10px; font-family: var(--display); }
.brand-mark {
display: grid; place-items: center; width: 38px; height: 38px;
background: linear-gradient(135deg, var(--yellow), var(--coral));
color: #fff; border-radius: 14px; font-size: 1.3rem;
box-shadow: var(--sh-sm); animation: wobble 4s ease-in-out infinite;
}
.brand-name { font-size: 1.3rem; font-weight: 800; color: var(--ink); }
.brand-name span { color: var(--sky-d); }
.nav-links { display: flex; align-items: center; gap: 6px; }
.nav-links a { padding: 9px 14px; border-radius: var(--r-pill); font-weight: 700; color: var(--ink-2); transition: background .2s, color .2s, transform .2s; }
.nav-links a:hover { background: var(--bg-2); color: var(--sky-d); transform: translateY(-2px); }
.nav-cta { background: var(--sky); color: #fff !important; box-shadow: 0 6px 0 -1px var(--sky-d); }
.nav-cta:hover { background: var(--sky-d); transform: translateY(-2px); }
.nav-toggle { display: none; flex-direction: column; gap: 5px; background: none; border: none; cursor: pointer; padding: 8px; }
.nav-toggle span { width: 26px; height: 3px; background: var(--ink); border-radius: 3px; transition: .3s; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }
/* ===== HERO ===== */
.hero { position: relative; padding: 56px 0 80px; overflow: hidden; }
.blob { position: absolute; border-radius: 50%; filter: blur(8px); opacity: .55; z-index: 0; }
.blob-1 { width: 420px; height: 420px; background: radial-gradient(circle, #ffe79b, transparent 70%); top: -120px; right: -80px; }
.blob-2 { width: 360px; height: 360px; background: radial-gradient(circle, #bfe0ff, transparent 70%); bottom: -120px; left: -100px; }
.hero-inner { position: relative; z-index: 1; display: grid; grid-template-columns: 1.1fr .9fr; gap: 40px; align-items: center; }
.pill {
display: inline-flex; align-items: center; gap: 6px; font-weight: 800;
font-size: .85rem; padding: 7px 14px; border-radius: var(--r-pill);
font-family: var(--display);
}
.pill-amber { background: #fff2cf; color: #9a6b00; box-shadow: var(--sh-sm); }
.hero-copy h1 { font-size: clamp(2.4rem, 6vw, 3.9rem); margin: 18px 0 14px; font-weight: 800; }
.hero-copy .hl {
background: linear-gradient(120deg, var(--sky-d), var(--grape));
-webkit-background-clip: text; background-clip: text; color: transparent;
}
.lede { font-size: 1.15rem; color: var(--ink-2); max-width: 30em; font-weight: 600; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin: 26px 0 28px; }
.hero-stats { display: flex; gap: 28px; list-style: none; padding: 0; margin: 0; }
.hero-stats li { display: flex; flex-direction: column; }
.hero-stats b { font-family: var(--display); font-size: 1.6rem; color: var(--coral-d); }
.hero-stats span { font-size: .85rem; color: var(--muted); font-weight: 700; }
/* ===== Mascot ===== */
.hero-art { position: relative; display: grid; place-items: center; min-height: 360px; }
.mascot { position: relative; cursor: pointer; animation: bob 3.5s ease-in-out infinite; }
.mascot:hover { animation-play-state: paused; }
.mascot-body {
position: relative; width: 220px; height: 220px;
background: linear-gradient(160deg, #ff9776, var(--coral));
border-radius: 46% 46% 44% 44%; box-shadow: var(--sh-md);
}
.ear { position: absolute; top: -34px; width: 64px; height: 80px; background: var(--coral); border-radius: 50% 50% 50% 50%; }
.ear-l { left: 18px; transform: rotate(-18deg); }
.ear-r { right: 18px; transform: rotate(18deg); }
.ear::after { content: ""; position: absolute; inset: 14px 18px; background: #ffd9cf; border-radius: 50%; }
.face { position: absolute; inset: 0; }
.eye { position: absolute; top: 78px; width: 46px; height: 52px; background: #fff; border-radius: 50%; box-shadow: inset 0 -3px 4px rgba(0,0,0,.08); }
.eye-l { left: 42px; } .eye-r { right: 42px; }
.eye i { position: absolute; top: 16px; left: 13px; width: 20px; height: 24px; background: #2b2545; border-radius: 50%; transition: transform .12s ease-out; }
.eye i::after { content: ""; position: absolute; top: 3px; right: 3px; width: 7px; height: 7px; background: #fff; border-radius: 50%; }
.cheek { position: absolute; top: 122px; width: 30px; height: 18px; background: #ff4d7d; opacity: .45; border-radius: 50%; }
.cheek-l { left: 30px; } .cheek-r { right: 30px; }
.smile { position: absolute; top: 132px; left: 50%; transform: translateX(-50%); width: 56px; height: 28px; border: 5px solid #2b2545; border-top: none; border-radius: 0 0 60px 60px; }
.mascot-shadow { width: 150px; height: 22px; margin: 14px auto 0; background: rgba(43,37,69,.14); border-radius: 50%; filter: blur(4px); animation: shadowPulse 3.5s ease-in-out infinite; }
.float-icon { position: absolute; font-size: 2rem; filter: drop-shadow(0 6px 8px rgba(0,0,0,.12)); }
.fi-1 { top: 8%; left: 6%; animation: floaty 4s ease-in-out infinite; }
.fi-2 { top: 20%; right: 4%; animation: floaty 5s ease-in-out .4s infinite; }
.fi-3 { bottom: 14%; left: 2%; animation: floaty 4.6s ease-in-out .8s infinite; }
.fi-4 { bottom: 6%; right: 10%; animation: floaty 5.4s ease-in-out 1.2s infinite; }
/* ===== Sections ===== */
.section { padding: 72px 0; }
.band { background: linear-gradient(180deg, var(--bg-2), #fff); border-block: 2px solid var(--line); }
.head { text-align: center; max-width: 40rem; margin: 0 auto 44px; }
.kicker {
display: inline-block; font-family: var(--display); font-weight: 800;
color: var(--sky-d); background: #e2f0ff; padding: 5px 14px;
border-radius: var(--r-pill); font-size: .8rem; letter-spacing: .04em; margin-bottom: 12px;
}
.head h2 { font-size: clamp(1.9rem, 4vw, 2.7rem); }
.sub { color: var(--ink-2); font-weight: 600; margin-top: 10px; }
/* ===== Subjects ===== */
.subject-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.subject {
background: var(--surface); border: 2px solid var(--line); border-radius: var(--r-md);
padding: 24px 16px; text-align: center; cursor: pointer; font-family: var(--font);
box-shadow: var(--sh-sm); transition: transform .2s cubic-bezier(.34,1.6,.5,1), box-shadow .2s, border-color .2s;
}
.subject:hover, .subject:focus-visible {
transform: translateY(-8px) rotate(-2deg); border-color: var(--c);
box-shadow: 0 18px 30px color-mix(in srgb, var(--c) 35%, transparent); outline: none;
}
.subject.pop { animation: pop .4s cubic-bezier(.34,1.7,.5,1); }
.s-ico {
display: grid; place-items: center; width: 64px; height: 64px; margin: 0 auto 12px;
font-size: 1.9rem; border-radius: 20px;
background: color-mix(in srgb, var(--c) 22%, #fff);
}
.subject h3 { font-size: 1.15rem; }
.subject small { color: var(--muted); font-weight: 700; }
/* ===== Ages ===== */
.age-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: start; }
.age {
position: relative; background: var(--surface); border: 3px solid color-mix(in srgb, var(--c) 35%, #fff);
border-radius: var(--r-lg); padding: 30px 26px; text-align: center;
box-shadow: var(--sh-sm); transition: transform .25s, box-shadow .25s;
}
.age:hover { transform: translateY(-8px); box-shadow: 0 22px 40px color-mix(in srgb, var(--c) 28%, transparent); }
.age.featured { transform: scale(1.04); border-color: var(--c); box-shadow: var(--sh-pop); }
.age.featured:hover { transform: scale(1.04) translateY(-8px); }
.age-flag {
position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
background: var(--c); color: #fff; font-family: var(--display); font-weight: 800;
font-size: .8rem; padding: 6px 16px; border-radius: var(--r-pill); box-shadow: var(--sh-sm); white-space: nowrap;
}
.age-emoji {
font-size: 3rem; width: 92px; height: 92px; margin: 8px auto 14px;
display: grid; place-items: center; border-radius: 50%;
background: color-mix(in srgb, var(--c) 18%, #fff); transition: transform .3s;
}
.age:hover .age-emoji { transform: scale(1.1) rotate(8deg); }
.age h3 { font-size: 1.4rem; }
.age-range { color: var(--c); font-family: var(--display); font-weight: 800; margin: 4px 0 14px; }
.age ul { list-style: none; padding: 0; margin: 0 0 22px; text-align: left; display: grid; gap: 9px; }
.age li { position: relative; padding-left: 28px; color: var(--ink-2); font-weight: 600; }
.age li::before { content: "⭐"; position: absolute; left: 0; }
.pick-age { width: 100%; }
/* ===== Parents ===== */
.parents-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.trust-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 26px; }
.trust { display: flex; gap: 12px; background: var(--surface); border: 2px solid var(--line); border-radius: var(--r-md); padding: 16px; box-shadow: var(--sh-sm); transition: transform .2s; }
.trust:hover { transform: translateY(-4px); }
.t-ico { font-size: 1.6rem; }
.trust b { display: block; font-family: var(--display); font-size: 1.02rem; }
.trust p { font-size: .88rem; color: var(--muted); font-weight: 600; margin-top: 2px; }
.report-card { background: var(--surface); border: 2px solid var(--line); border-radius: var(--r-lg); padding: 24px; box-shadow: var(--sh-md); }
.rc-head { display: flex; align-items: center; gap: 12px; padding-bottom: 16px; border-bottom: 2px dashed var(--line); margin-bottom: 18px; }
.rc-avatar { width: 48px; height: 48px; display: grid; place-items: center; font-size: 1.6rem; background: var(--bg-2); border-radius: 50%; }
.rc-head b { font-family: var(--display); font-size: 1.1rem; }
.rc-head small { display: block; color: var(--muted); font-weight: 700; }
.rc-badge { margin-left: auto; background: #e2fbef; color: #0c8a5c; font-family: var(--display); font-weight: 800; font-size: .8rem; padding: 6px 12px; border-radius: var(--r-pill); }
.rc-row { display: grid; grid-template-columns: 70px 1fr 44px; align-items: center; gap: 12px; margin-bottom: 14px; font-weight: 700; }
.rc-row > span { color: var(--ink-2); }
.rc-row > b { text-align: right; font-family: var(--display); color: var(--sky-d); }
.bar { height: 14px; background: var(--bg-2); border-radius: var(--r-pill); overflow: hidden; }
.bar i { display: block; height: 100%; width: var(--p); border-radius: var(--r-pill); background: linear-gradient(90deg, var(--mint), var(--sky)); transform-origin: left; animation: grow 1s cubic-bezier(.34,1.3,.5,1) both; }
.rc-foot { display: flex; justify-content: space-between; padding-top: 16px; border-top: 2px dashed var(--line); }
.rc-stat { text-align: center; }
.rc-stat b { display: block; font-family: var(--display); font-size: 1.3rem; color: var(--coral-d); }
.rc-stat span { font-size: .76rem; color: var(--muted); font-weight: 700; }
/* ===== Testimonials ===== */
.quotes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.quote { background: var(--surface); border: 2px solid var(--line); border-radius: var(--r-md); padding: 24px; box-shadow: var(--sh-sm); transition: transform .2s, box-shadow .2s; }
.quote:hover { transform: translateY(-6px) rotate(1deg); box-shadow: var(--sh-md); }
.stars { color: var(--yellow-d); letter-spacing: 2px; font-size: 1.1rem; margin-bottom: 8px; }
.quote blockquote { margin: 0 0 16px; font-size: 1.05rem; font-weight: 700; color: var(--ink); }
.quote figcaption { display: flex; align-items: center; gap: 10px; color: var(--ink-2); font-weight: 700; font-size: .9rem; }
.av { width: 34px; height: 34px; display: grid; place-items: center; border-radius: 50%; background: var(--c); color: #fff; font-family: var(--display); font-weight: 800; }
/* ===== Trial ===== */
.trial { padding: 80px 0; }
.trial-card {
background: linear-gradient(135deg, var(--sky), var(--grape));
color: #fff; text-align: center; border-radius: var(--r-lg);
padding: 52px 32px; box-shadow: var(--sh-pop); position: relative; overflow: hidden;
}
.trial-card::before { content: "🎈🎨🚀⭐🔢🎵"; position: absolute; inset: 0; font-size: 2rem; opacity: .12; letter-spacing: 40px; line-height: 70px; pointer-events: none; }
.trial-card h2 { color: #fff; font-size: clamp(1.8rem, 4vw, 2.6rem); position: relative; }
.trial-card p { position: relative; margin-top: 10px; font-weight: 600; opacity: .95; }
.trial-form { position: relative; display: flex; gap: 10px; max-width: 480px; margin: 26px auto 12px; flex-wrap: wrap; justify-content: center; }
.trial-form input {
flex: 1 1 240px; min-width: 0; border: none; border-radius: var(--r-pill);
padding: 14px 20px; font-family: var(--font); font-size: 1rem; font-weight: 600;
box-shadow: var(--sh-sm);
}
.trial-form input.err { outline: 3px solid var(--yellow); }
.trial-form .btn-big { background: linear-gradient(180deg, var(--yellow), var(--yellow-d)); color: var(--ink); box-shadow: 0 8px 0 -2px var(--yellow-d); }
.trial-note { position: relative; display: block; font-weight: 700; opacity: .9; font-size: .85rem; }
/* ===== Footer ===== */
.footer { background: var(--ink); color: #cfc9e6; padding: 56px 0 28px; }
.foot-inner { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 32px; padding-bottom: 32px; border-bottom: 1px solid rgba(255,255,255,.12); }
.foot-brand { display: flex; flex-direction: column; gap: 12px; max-width: 24em; }
.foot-brand p { color: #a39ec2; font-weight: 600; font-size: .95rem; }
.footer h4 { color: #fff; font-size: 1rem; margin-bottom: 14px; }
.footer nav a { display: block; padding: 5px 0; color: #b3aed0; font-weight: 600; transition: color .2s, transform .2s; }
.footer nav a:hover { color: var(--yellow); transform: translateX(4px); }
.foot-bottom { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; padding-top: 22px; color: #8e89ab; font-weight: 600; font-size: .88rem; }
/* ===== Toast ===== */
.toast {
position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 140%);
background: var(--ink); color: #fff; font-weight: 700; font-family: var(--display);
padding: 14px 22px; border-radius: var(--r-pill); box-shadow: var(--sh-md);
z-index: 90; transition: transform .4s cubic-bezier(.34,1.6,.5,1); max-width: 90vw;
}
.toast.show { transform: translate(-50%, 0); }
/* ===== Reveal ===== */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s cubic-bezier(.2,.8,.2,1); }
.reveal.in { opacity: 1; transform: none; }
/* ===== Keyframes ===== */
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-14px); } }
@keyframes shadowPulse { 0%,100% { transform: scale(1); opacity: .5; } 50% { transform: scale(.82); opacity: .32; } }
@keyframes floaty { 0%,100% { transform: translateY(0) rotate(-4deg); } 50% { transform: translateY(-16px) rotate(4deg); } }
@keyframes wobble { 0%,100% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } }
@keyframes grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes pop { 0% { transform: scale(1); } 40% { transform: scale(1.12) rotate(-3deg); } 100% { transform: scale(1); } }
/* ===== Responsive ===== */
@media (max-width: 920px) {
.subject-grid { grid-template-columns: repeat(3, 1fr); }
.parents-inner { grid-template-columns: 1fr; }
.foot-inner { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
.nav-toggle { display: flex; }
.nav-links {
position: absolute; top: 72px; left: 0; right: 0; flex-direction: column;
align-items: stretch; gap: 4px; background: #fff; padding: 14px;
border-bottom: 2px solid var(--line); box-shadow: var(--sh-md);
clip-path: inset(0 0 100% 0); transition: clip-path .3s ease;
}
.nav-links.open { clip-path: inset(0 0 0 0); }
.nav-links a { padding: 12px 16px; text-align: center; }
.hero-inner { grid-template-columns: 1fr; text-align: center; }
.hero-copy .lede { margin-inline: auto; }
.hero-actions, .hero-stats { justify-content: center; }
.hero-art { order: -1; min-height: 300px; }
.age-grid { grid-template-columns: 1fr; }
.age.featured { transform: none; }
.quotes { grid-template-columns: 1fr; }
}
@media (max-width: 520px) {
.subject-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
.trust-grid { grid-template-columns: 1fr; }
.foot-inner { grid-template-columns: 1fr; }
.hero-stats { gap: 18px; }
.section { padding: 54px 0; }
}(function () {
"use strict";
/* ---------- Toast helper ---------- */
const toastEl = document.getElementById("toast");
let toastTimer;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(() => toastEl.classList.remove("show"), 2600);
}
/* ---------- Mobile nav ---------- */
const toggle = document.getElementById("navToggle");
const links = document.getElementById("navlinks");
if (toggle && links) {
toggle.addEventListener("click", () => {
const open = links.classList.toggle("open");
toggle.setAttribute("aria-expanded", String(open));
});
links.querySelectorAll("a").forEach((a) =>
a.addEventListener("click", () => {
links.classList.remove("open");
toggle.setAttribute("aria-expanded", "false");
})
);
}
/* ---------- Sticky nav shadow ---------- */
const nav = document.querySelector(".nav");
const onScroll = () => nav && nav.classList.toggle("scrolled", window.scrollY > 12);
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();
/* ---------- Scroll reveal ---------- */
const revealEls = document.querySelectorAll(".reveal");
if ("IntersectionObserver" in window) {
const io = new IntersectionObserver(
(entries) => {
entries.forEach((e) => {
if (e.isIntersecting) {
e.target.classList.add("in");
io.unobserve(e.target);
}
});
},
{ threshold: 0.14 }
);
revealEls.forEach((el) => io.observe(el));
} else {
revealEls.forEach((el) => el.classList.add("in"));
}
/* ---------- Mascot eyes follow cursor ---------- */
const mascot = document.getElementById("mascot");
const pupils = document.querySelectorAll(".eye i");
if (mascot && pupils.length) {
window.addEventListener(
"mousemove",
(e) => {
const r = mascot.getBoundingClientRect();
const cx = r.left + r.width / 2;
const cy = r.top + r.height / 2;
const dx = Math.max(-5, Math.min(5, (e.clientX - cx) / 40));
const dy = Math.max(-4, Math.min(4, (e.clientY - cy) / 40));
pupils.forEach((p) => (p.style.transform = `translate(${dx}px, ${dy}px)`));
},
{ passive: true }
);
const greetings = ["Hi friend! 👋", "Let's learn! 🦊", "You're awesome! ⭐", "Ready to play? 🎈"];
let gi = 0;
mascot.addEventListener("click", () => {
toast(greetings[gi++ % greetings.length]);
mascot.animate(
[{ transform: "scale(1)" }, { transform: "scale(1.12) rotate(-6deg)" }, { transform: "scale(1)" }],
{ duration: 450, easing: "cubic-bezier(.34,1.7,.5,1)" }
);
});
}
/* ---------- Subject cards ---------- */
document.querySelectorAll(".subject").forEach((card) => {
card.addEventListener("click", () => {
const name = card.dataset.name;
const lessons = card.dataset.lessons;
const fact = card.dataset.fact;
card.classList.remove("pop");
void card.offsetWidth; // restart animation
card.classList.add("pop");
toast(`${name} — ${lessons} lessons. ${fact}`);
});
});
/* ---------- Age picker ---------- */
document.querySelectorAll(".pick-age").forEach((btn) => {
btn.addEventListener("click", () => {
const card = btn.closest(".age");
const group = card ? card.querySelector("h3").textContent.trim() : "this path";
toast(`Yay! ${group} path picked — scroll down to start free 🎉`);
const trial = document.getElementById("trial");
if (trial) trial.scrollIntoView({ behavior: "smooth", block: "center" });
});
});
/* ---------- "Watch the fun" ---------- */
const playBtn = document.getElementById("playBtn");
if (playBtn) playBtn.addEventListener("click", () => toast("🎬 Demo video is just for show in this fictional UI!"));
/* ---------- Trial form ---------- */
const form = document.getElementById("trialForm");
const email = document.getElementById("email");
if (form && email) {
const valid = (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
form.addEventListener("submit", (e) => {
e.preventDefault();
const v = email.value.trim();
if (!valid(v)) {
email.classList.add("err");
email.focus();
toast("Oops! Please enter a valid email 📧");
return;
}
email.classList.remove("err");
toast(`🎉 Welcome aboard! Your 7-day free trial is ready, ${v.split("@")[0]}!`);
form.reset();
celebrate();
});
email.addEventListener("input", () => email.classList.remove("err"));
}
/* ---------- Confetti burst ---------- */
function celebrate() {
const emojis = ["⭐", "🎈", "🎉", "🦊", "💛", "🚀", "🎨"];
for (let i = 0; i < 26; i++) {
const s = document.createElement("span");
s.textContent = emojis[(Math.random() * emojis.length) | 0];
s.style.cssText =
"position:fixed;left:" +
(40 + Math.random() * 20) +
"%;top:55%;font-size:" +
(16 + Math.random() * 18) +
"px;pointer-events:none;z-index:120;will-change:transform,opacity;";
document.body.appendChild(s);
const dx = (Math.random() - 0.5) * 520;
const dy = -160 - Math.random() * 320;
s.animate(
[
{ transform: "translate(0,0) rotate(0)", opacity: 1 },
{ transform: `translate(${dx}px, ${dy}px) rotate(${(Math.random() - 0.5) * 720}deg)`, opacity: 0 },
],
{ duration: 1100 + Math.random() * 700, easing: "cubic-bezier(.2,.6,.3,1)" }
).onfinish = () => s.remove();
}
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Sparkly Learners — Fun Learning for Kids</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;600;700;800&family=Nunito:wght@400;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<!-- ===== NAV ===== -->
<header class="nav" id="top">
<div class="wrap nav-inner">
<a class="brand" href="#top" aria-label="Sparkly Learners home">
<span class="brand-mark" aria-hidden="true">★</span>
<span class="brand-name">Sparkly<span>Learners</span></span>
</a>
<nav class="nav-links" id="navlinks" aria-label="Primary">
<a href="#subjects">Subjects</a>
<a href="#ages">Ages</a>
<a href="#parents">For Parents</a>
<a href="#love">Kids Love It</a>
<a class="nav-cta" href="#trial">Start Free</a>
</nav>
<button class="nav-toggle" id="navToggle" aria-expanded="false" aria-controls="navlinks" aria-label="Toggle menu">
<span></span><span></span><span></span>
</button>
</div>
</header>
<main id="main">
<!-- ===== HERO ===== -->
<section class="hero">
<div class="blob blob-1" aria-hidden="true"></div>
<div class="blob blob-2" aria-hidden="true"></div>
<div class="wrap hero-inner">
<div class="hero-copy reveal">
<span class="pill pill-amber">🎉 Over 200 fun lessons</span>
<h1>Where learning feels<br><span class="hl">like playtime!</span></h1>
<p class="lede">Games, songs and stories that teach reading, math and science — built for curious kids ages 4 to 11. Safe, ad-free, and packed with stickers to collect.</p>
<div class="hero-actions">
<a class="btn btn-big" href="#trial">Start free trial 🚀</a>
<button class="btn btn-ghost" id="playBtn" type="button">▶ Watch the fun</button>
</div>
<ul class="hero-stats">
<li><b>1.2M</b><span>happy kids</span></li>
<li><b>4.9★</b><span>parent rating</span></li>
<li><b>100%</b><span>ad-free</span></li>
</ul>
</div>
<div class="hero-art reveal" aria-hidden="true">
<div class="mascot" id="mascot" title="Hi, I'm Ziggy!">
<div class="mascot-body">
<div class="ear ear-l"></div>
<div class="ear ear-r"></div>
<div class="face">
<div class="eye eye-l"><i></i></div>
<div class="eye eye-r"><i></i></div>
<div class="cheek cheek-l"></div>
<div class="cheek cheek-r"></div>
<div class="smile"></div>
</div>
</div>
<div class="mascot-shadow"></div>
</div>
<span class="float-icon fi-1">🔢</span>
<span class="float-icon fi-2">🎨</span>
<span class="float-icon fi-3">📚</span>
<span class="float-icon fi-4">🔬</span>
</div>
</div>
</section>
<!-- ===== SUBJECTS ===== -->
<section class="section" id="subjects">
<div class="wrap">
<div class="head reveal">
<span class="kicker">Pick & play</span>
<h2>Subjects kids adore</h2>
<p class="sub">Every subject is a playground. Tap a card to peek inside!</p>
</div>
<div class="subject-grid" id="subjectGrid">
<button class="subject" style="--c:#ffd23f" data-name="Reading & Phonics" data-lessons="48" data-fact="Build words, sound out letters and meet friendly story characters."><span class="s-ico">📖</span><h3>Reading</h3><small>48 lessons</small></button>
<button class="subject" style="--c:#3aa0ff" data-name="Math & Numbers" data-lessons="52" data-fact="Counting, shapes and number games that feel like puzzles."><span class="s-ico">🔢</span><h3>Math</h3><small>52 lessons</small></button>
<button class="subject" style="--c:#ff6f61" data-name="Science Lab" data-lessons="36" data-fact="Bubbling experiments, animals and the wonders of space."><span class="s-ico">🔬</span><h3>Science</h3><small>36 lessons</small></button>
<button class="subject" style="--c:#7c5cff" data-name="Art Studio" data-lessons="29" data-fact="Color, draw and craft your own masterpieces step by step."><span class="s-ico">🎨</span><h3>Art</h3><small>29 lessons</small></button>
<button class="subject" style="--c:#1ec98b" data-name="World Explorer" data-lessons="24" data-fact="Travel the globe, learn flags, animals and cool places."><span class="s-ico">🌍</span><h3>World</h3><small>24 lessons</small></button>
<button class="subject" style="--c:#ff9f1c" data-name="Music Maker" data-lessons="18" data-fact="Sing along, tap the beat and discover musical instruments."><span class="s-ico">🎵</span><h3>Music</h3><small>18 lessons</small></button>
<button class="subject" style="--c:#ef5da8" data-name="Coding Kids" data-lessons="21" data-fact="Drag-and-drop blocks to make characters move and dance."><span class="s-ico">🤖</span><h3>Coding</h3><small>21 lessons</small></button>
<button class="subject" style="--c:#36c5f0" data-name="Big Feelings" data-lessons="16" data-fact="Stories about kindness, sharing and naming our emotions."><span class="s-ico">💛</span><h3>Feelings</h3><small>16 lessons</small></button>
</div>
</div>
</section>
<!-- ===== AGE GROUPS ===== -->
<section class="section band" id="ages">
<div class="wrap">
<div class="head reveal">
<span class="kicker">Just right for them</span>
<h2>Choose your child's age</h2>
<p class="sub">Lessons grow with your child — pick a path to get started.</p>
</div>
<div class="age-grid">
<article class="age reveal" style="--c:#ffd23f">
<div class="age-emoji">🐣</div>
<h3>Little Sprouts</h3>
<p class="age-range">Ages 4–5</p>
<ul>
<li>Letters & first sounds</li>
<li>Counting to 20</li>
<li>Colors & shapes</li>
</ul>
<button class="btn btn-soft pick-age" type="button">Start here</button>
</article>
<article class="age reveal featured" style="--c:#3aa0ff">
<span class="age-flag">Most popular</span>
<div class="age-emoji">🦊</div>
<h3>Bright Explorers</h3>
<p class="age-range">Ages 6–8</p>
<ul>
<li>Reading full stories</li>
<li>Add, subtract & tell time</li>
<li>Science experiments</li>
</ul>
<button class="btn btn-soft pick-age" type="button">Start here</button>
</article>
<article class="age reveal" style="--c:#ff6f61">
<div class="age-emoji">🚀</div>
<h3>Super Learners</h3>
<p class="age-range">Ages 9–11</p>
<ul>
<li>Chapter reading & writing</li>
<li>Multiplication & fractions</li>
<li>Coding & logic puzzles</li>
</ul>
<button class="btn btn-soft pick-age" type="button">Start here</button>
</article>
</div>
</div>
</section>
<!-- ===== PARENT TRUST ===== -->
<section class="section" id="parents">
<div class="wrap parents-inner">
<div class="parents-copy reveal">
<span class="kicker">For grown-ups</span>
<h2>Built for kids, trusted by parents</h2>
<p class="sub">No ads. No surprise links. Just safe, screen-time you can feel good about — with weekly progress reports delivered to your inbox.</p>
<div class="trust-grid">
<div class="trust"><span class="t-ico">🛡️</span><div><b>Safe & ad-free</b><p>Zero ads, no external links, kid-walled navigation.</p></div></div>
<div class="trust"><span class="t-ico">📊</span><div><b>Progress reports</b><p>See what they're learning every Sunday by email.</p></div></div>
<div class="trust"><span class="t-ico">⏰</span><div><b>Screen-time limits</b><p>Set daily caps and gentle stop reminders.</p></div></div>
<div class="trust"><span class="t-ico">🔒</span><div><b>Private by design</b><p>COPPA-aligned. We never sell kids' data.</p></div></div>
</div>
</div>
<aside class="report-card reveal" aria-label="Sample weekly progress report">
<header class="rc-head">
<span class="rc-avatar">🦊</span>
<div>
<b>Mia's week</b>
<small>Bright Explorer · Age 7</small>
</div>
<span class="rc-badge">+3 stars</span>
</header>
<div class="rc-row">
<span>Reading</span>
<div class="bar"><i style="--p:82%"></i></div>
<b>82%</b>
</div>
<div class="rc-row">
<span>Math</span>
<div class="bar"><i style="--p:64%"></i></div>
<b>64%</b>
</div>
<div class="rc-row">
<span>Science</span>
<div class="bar"><i style="--p:91%"></i></div>
<b>91%</b>
</div>
<footer class="rc-foot">
<div class="rc-stat"><b>14</b><span>lessons done</span></div>
<div class="rc-stat"><b>48m</b><span>this week</span></div>
<div class="rc-stat"><b>🏅 9</b><span>badges</span></div>
</footer>
</aside>
</div>
</section>
<!-- ===== TESTIMONIALS ===== -->
<section class="section band" id="love">
<div class="wrap">
<div class="head reveal">
<span class="kicker">Two thumbs up</span>
<h2>Kids & parents love it</h2>
</div>
<div class="quotes">
<figure class="quote reveal">
<div class="stars">★★★★★</div>
<blockquote>"My daughter asks to do her math lessons. I never thought I'd hear that!"</blockquote>
<figcaption><span class="av" style="--c:#ffd23f">P</span> Priya R. · parent of Mia, 7</figcaption>
</figure>
<figure class="quote reveal">
<div class="stars">★★★★★</div>
<blockquote>"The fox mascot is my best friend and I got 12 stickers!!! 🦊⭐"</blockquote>
<figcaption><span class="av" style="--c:#3aa0ff">L</span> Leo, age 6</figcaption>
</figure>
<figure class="quote reveal">
<div class="stars">★★★★★</div>
<blockquote>"Finally a kids app with no ads. The weekly report keeps me in the loop."</blockquote>
<figcaption><span class="av" style="--c:#ff6f61">D</span> Daniel O. · dad of two</figcaption>
</figure>
</div>
</div>
</section>
<!-- ===== TRIAL CTA ===== -->
<section class="trial" id="trial">
<div class="wrap trial-card reveal">
<h2>Try 7 days free 🎈</h2>
<p>Unlock every subject and badge. No card needed to start — cancel anytime.</p>
<form class="trial-form" id="trialForm" novalidate>
<label class="sr-only" for="email">Parent email</label>
<input type="email" id="email" name="email" placeholder="Parent's email address" autocomplete="email" required />
<button class="btn btn-big" type="submit">Get started</button>
</form>
<small class="trial-note">Free for 7 days, then $7.99/mo. Parent approval required.</small>
</div>
</section>
</main>
<!-- ===== FOOTER ===== -->
<footer class="footer">
<div class="wrap foot-inner">
<div class="foot-brand">
<span class="brand-mark" aria-hidden="true">★</span>
<p>Sparkly Learners makes everyday learning joyful, safe and free of distractions.</p>
</div>
<nav aria-label="Footer">
<h4>Learn</h4>
<a href="#subjects">Subjects</a>
<a href="#ages">Age groups</a>
<a href="#love">Reviews</a>
</nav>
<nav aria-label="Company">
<h4>Family</h4>
<a href="#parents">For parents</a>
<a href="#parents">Safety</a>
<a href="#trial">Pricing</a>
</nav>
<nav aria-label="Help">
<h4>Help</h4>
<a href="#top">Support</a>
<a href="#top">Privacy</a>
<a href="#top">Contact</a>
</nav>
</div>
<div class="wrap foot-bottom">
<span>© 2026 Sparkly Learners (a fictional demo).</span>
<span class="foot-emoji">Made with 💛 for curious kids</span>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Kids Learning Landing
A full marketing landing page for “Sparkly Learners”, a fictional kids’ learning app. The design leans into a bright primary palette — sunny yellow, sky blue and coral on white — with chunky rounded type (Baloo 2 for headings, Nunito for body) and springy, bouncy hover animations throughout. The hero stars Ziggy the fox mascot, who bobs gently, follows your cursor with his eyes, and waves a friendly greeting when tapped.
Below the hero, a grid of tappable subject cards reveals lesson counts and fun facts via a toast, age-group paths (Little Sprouts, Bright Explorers, Super Learners) let kids pick where to start, and a parent-trust section pairs safety promises with an animated sample weekly progress report. Friendly testimonials and a free-trial CTA round it out — the email form validates input, fires a celebratory emoji confetti burst on success, and confirms with a toast.
Everything is responsive from wide desktop down to ~360px, including a collapsing mobile nav
drawer, sticky-header shadow on scroll, scroll-reveal animations, and a prefers-reduced-motion
fallback. Vanilla JS only, no frameworks or build step.
Illustrative UI only — fictional courses, not a real learning platform.