Hello Kitty • Friend Rewind
🐱🎀
🌸 "You can never have too many friends – every day is a rewind of cuteness!" 🌸
— Hello Kitty's friend rewind corner — click on any card to send a surprise virtual bow!
🎀 💖 🎀
// FRIENDS DATA with cute “rewind memory” and hello kitty aesthetics
const friendsData = [
{
id: 1,
name: "Mia ✿",
memory: "🍰 baking cookies together & laughing until midnight",
date: "july 2022 • rewind",
icon: "🐱🍰",
kittyEmoji: "🎀"
},
{
id: 2,
name: "Lily 🩷",
memory: "🌸 picnic under cherry blossoms & sharing secrets",
date: "april 2023 • rewind",
icon: "🌸🐱",
kittyEmoji: "💖"
},
{
id: 3,
name: "Chloe 🎀",
memory: "🎨 hello kitty themed art day – drawing bows everywhere",
date: "september 2023 • rewind",
icon: "🖌️🐱",
kittyEmoji: "🎀"
},
{
id: 4,
name: "Sophia 🧸",
memory: "⭐ sleepover with sanrio movies & all-night chats",
date: "december 2022 • rewind",
icon: "📺🐱",
kittyEmoji: "🌟"
},
{
id: 5,
name: "Emma 🍭",
memory: "🍬 candy store adventure + matching hello kitty charms",
date: "february 2024 • rewind",
icon: "🍭🐱",
kittyEmoji: "💕"
},
{
id: 6,
name: "Olivia 💌",
memory: "💌 handwritten letters & friendship bracelet swap",
date: "october 2023 • rewind",
icon: "💌🐱",
kittyEmoji: "🎀"
}
];
// helper: show cute toast-like alert but with modern kitty style (non-intrusive mini modal)
function showKittyMessage(message, isHeart = false) {
// create temporary floating message element
const toast = document.createElement('div');
toast.innerText = message;
toast.style.position = 'fixed';
toast.style.bottom = '30%';
toast.style.left = '50%';
toast.style.transform = 'translateX(-50%)';
toast.style.backgroundColor = '#fff0f5';
toast.style.color = '#c43b6b';
toast.style.padding = '10px 24px';
toast.style.borderRadius = '60px';
toast.style.fontWeight = 'bold';
toast.style.fontFamily = "'Quicksand', sans-serif";
toast.style.fontSize = '1rem';
toast.style.boxShadow = '0 12px 22px rgba(255,105,150,0.3)';
toast.style.border = '2px solid #ffb0c3';
toast.style.zIndex = '9999';
toast.style.backdropFilter = 'blur(6px)';
toast.style.letterSpacing = '0.5px';
if(isHeart) {
toast.innerHTML = '💖 ' + message + ' 💖';
} else {
toast.innerHTML = '🎀 ' + message + ' 🎀';
}
document.body.appendChild(toast);
setTimeout(() => {
toast.style.opacity = '0';
toast.style.transition = 'opacity 0.4s ease';
setTimeout(() => {
if(toast.parentNode) toast.remove();
}, 500);
}, 1900);
}
// function to generate random pastel color for bows? just for fun - but also handle click to "rewind surprise"
function handleRewindClick(friendName, memoryText, event) {
event.stopPropagation(); // avoid double trigger
const rewindMsg = `🎞️ Rewinding ${friendName}: ${memoryText.substring(0, 55)}... 🌸 Hello Kitty sends love!`;
showKittyMessage(rewindMsg, false);
// add little console delight (just for extra animation, but we also animate the card)
const card = event.currentTarget.closest('.friend-card');
if(card) {
card.style.transform = 'scale(0.98)';
setTimeout(() => {
card.style.transform = '';
}, 200);
}
}
function handleHeartClick(friendName, event) {
event.stopPropagation();
showKittyMessage(`💗 You sent a warm heart to ${friendName} 🩷 Besties forever!`, true);
// optional: tiny heart burst effect (just dynamic)
const btn = event.currentTarget;
btn.style.transform = 'scale(1.1)';
setTimeout(() => { btn.style.transform = ''; }, 150);
}
// main friend card click -> surprise bow animation & cute kitty message (friend rewind flashback)
function onCardClick(friend) {
showKittyMessage(`🎀 Surprise! Hello Kitty waves at ${friend.name} 🐱✨ "${friend.memory}"`, false);
// create a temporary bow animation burst on clicked card
const allCards = document.querySelectorAll('.friend-card');
// just for fun small effect
}
// render dynamic grid from data
function renderFriends() {
const gridContainer = document.getElementById('friendGrid');
if(!gridContainer) return;
gridContainer.innerHTML = '';
friendsData.forEach(friend => {
// create card element
const card = document.createElement('div');
card.className = 'friend-card';
// set data attribute for click event
card.setAttribute('data-id', friend.id);
// inner structure: media (kitty icon + bow), friend info, memory, actions
card.innerHTML = `
${friend.name}
${friend.date}
📖 ${friend.memory}
Heart
Rewind
`;
// attach card click (overall card for hello kitty surprise)
card.addEventListener('click', (e) => {
// avoid triggering if the click originated from buttons (we stopPropagation on buttons)
if(e.target.closest('.heart-btn') || e.target.closest('.rewind-btn')) {
return;
}
onCardClick(friend);
});
gridContainer.appendChild(card);
});
// attach event listeners to dynamically added buttons
attachButtonEvents();
}
function attachButtonEvents() {
// all heart buttons
const heartBtns = document.querySelectorAll('.heart-btn');
heartBtns.forEach(btn => {
btn.removeEventListener('click', heartHandler);
btn.addEventListener('click', heartHandler);
});
const rewindBtns = document.querySelectorAll('.rewind-btn');
rewindBtns.forEach(btn => {
btn.removeEventListener('click', rewindHandler);
btn.addEventListener('click', rewindHandler);
});
}
function heartHandler(event) {
event.stopPropagation();
const btn = event.currentTarget;
const friendName = btn.getAttribute('data-heart') || "friend";
handleHeartClick(friendName, event);
}
function rewindHandler(event) {
event.stopPropagation();
const btn = event.currentTarget;
const friendName = btn.getAttribute('data-rewind') || "friend";
const memory = btn.getAttribute('data-memory') || "special memory";
handleRewindClick(friendName, memory, event);
}
// add extra interactive floating bows animation on window load (cute extra)
function createFloatingBowEffect() {
const body = document.body;
setInterval(() => {
if(Math.random() > 0.85) {
const bowSpan = document.createElement('div');
bowSpan.innerHTML = '🎀';
bowSpan.style.position = 'fixed';
bowSpan.style.left = Math.random() * 90 + '%';
bowSpan.style.bottom = '-20px';
bowSpan.style.fontSize = '1.6rem';
bowSpan.style.opacity = '0.8';
bowSpan.style.pointerEvents = 'none';
bowSpan.style.zIndex = '999';
bowSpan.style.transition = 'all 3s ease-out';
body.appendChild(bowSpan);
bowSpan.animate([
{ transform: 'translateY(0px) rotate(0deg)', opacity: 0.9 },
{ transform: 'translateY(-800px) rotate(35deg)', opacity: 0 }
], {
duration: 4000,
easing: 'cubic-bezier(0.2, 0.9, 0.4, 1)'
});
setTimeout(() => {
if(bowSpan.parentNode) bowSpan.remove();
}, 4200);
}
}, 2800);
}
// friend rewind additional secret: when you double-click anywhere on main area an extra kitty says hi
function addDoubleTapKitty() {
document.body.addEventListener('dblclick', (e) => {
// avoid conflict with card double clicks, but it's fun
if(e.target.closest('.friend-card')) return;
showKittyMessage("🐱✨ Hello Kitty