* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Comic Sans MS', 'Chalkboard SE', 'Arial Rounded MT Bold', cursive, sans-serif;
background: linear-gradient(135deg, #9bf6ff 0%, #a0c4ff 50%, #ffc6ff 100%);
min-height: 100vh;
padding: 40px 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
}
.header {
text-align: center;
margin-bottom: 40px;
}
.header h1 {
font-size: 48px;
font-weight: 700;
color: #370617;
margin-bottom: 10px;
text-shadow: 3px 3px 0px rgba(255, 255, 255, 0.8);
letter-spacing: 2px;
}
.header p {
font-size: 18px;
color: #6a040f;
font-weight: 600;
}
.main-card {
background: white;
border-radius: 30px;
padding: 40px;
box-shadow: 0 20px 60px rgba(55, 6, 23, 0.2);
border: 5px solid #370617;
margin-bottom: 30px;
}
.animal-display {
background: linear-gradient(135deg, #ffafcc 0%, #ffc8dd 100%);
border-radius: 20px;
padding: 40px;
text-align: center;
border: 4px solid #370617;
margin-bottom: 30px;
position: relative;
overflow: hidden;
}
.animal-display::before {
content: '🌟';
position: absolute;
top: 20px;
left: 20px;
font-size: 30px;
animation: twinkle 2s infinite;
}
.animal-display::after {
content: '✨';
position: absolute;
bottom: 20px;
right: 20px;
font-size: 30px;
animation: twinkle 2s infinite 1s;
}
@keyframes twinkle {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(1.2); }
}
.animal-icon {
font-size: 120px;
margin-bottom: 20px;
display: inline-block;
animation: bounce 2s infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
.generated-name {
font-size: 48px;
font-weight: 700;
color: #370617;
margin-bottom: 10px;
text-shadow: 2px 2px 0px rgba(255, 255, 255, 0.8);
}
.animal-species {
font-size: 24px;
color: #6a040f;
font-weight: 600;
margin-bottom: 15px;
}
.personality-trait {
display: inline-block;
background: white;
padding: 8px 20px;
border-radius: 20px;
font-size: 16px;
color: #370617;
font-weight: 600;
border: 3px solid #370617;
}
.controls {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.control-group {
background: #fff0f3;
padding: 20px;
border-radius: 15px;
border: 3px solid #370617;
}
.control-label {
display: block;
font-size: 16px;
font-weight: 700;
color: #370617;
margin-bottom: 10px;
}
.control-select {
width: 100%;
padding: 12px 16px;
border: 3px solid #370617;
border-radius: 10px;
font-size: 16px;
font-weight: 600;
color: #370617;
background: white;
cursor: pointer;
font-family: inherit;
}
.control-select:focus {
outline: none;
box-shadow: 0 0 0 4px rgba(55, 6, 23, 0.2);
}
.generate-btn {
width: 100%;
padding: 20px;
background: #370617;
color: white;
border: none;
border-radius: 15px;
font-size: 24px;
font-weight: 700;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 8px 0 #6a040f;
position: relative;
top: 0;
font-family: inherit;
text-transform: uppercase;
letter-spacing: 2px;
}
.generate-btn:hover {
background: #6a040f;
transform: translateY(-2px);
box-shadow: 0 10px 0 #370617;
}
.generate-btn:active {
transform: translateY(4px);
box-shadow: 0 4px 0 #370617;
}
.generate-btn ion-icon {
vertical-align: middle;
margin-left: 10px;
font-size: 28px;
}
.history-card {
background: white;
border-radius: 20px;
padding: 30px;
border: 4px solid #370617;
box-shadow: 0 10px 30px rgba(55, 6, 23, 0.15);
}
.history-title {
font-size: 28px;
font-weight: 700;
color: #370617;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 10px;
}
.history-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 15px;
}
.history-item {
background: linear-gradient(135deg, #cdb4db 0%, #ffc8dd 100%);
padding: 15px;
border-radius: 12px;
border: 3px solid #370617;
text-align: center;
transition: transform 0.2s;
cursor: pointer;
}
.history-item:hover {
transform: scale(1.05);
}
.history-icon {
font-size: 36px;
margin-bottom: 8px;
}
.history-name {
font-size: 18px;
font-weight: 700;
color: #370617;
margin-bottom: 5px;
}
.history-species {
font-size: 14px;
color: #6a040f;
font-weight: 600;
}
.empty-history {
text-align: center;
padding: 40px;
color: #6a040f;
font-size: 16px;
}
@media (max-width: 768px) {
.header h1 {
font-size: 36px;
}
.main-card {
padding: 25px;
}
.animal-icon {
font-size: 80px;
}
.generated-name {
font-size: 36px;
}
.animal-species {
font-size: 20px;
}
.generate-btn {
font-size: 20px;
padding: 16px;
}
.history-list {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
}
// Name components
const nameStarts = [
'Apple', 'Bella', 'Cookie', 'Dotty', 'Elvis', 'Fauna', 'Goldie', 'Hazel', 'Ivy',
'Judy', 'Kiki', 'Lily', 'Marina', 'Nibbles', 'Olive', 'Poppy', 'Quinn', 'Rosie',
'Stella', 'Tia', 'Uma', 'Violet', 'Willow', 'Zucker', 'Maple', 'Cherry', 'Daisy',
'Flora', 'Lolly', 'Molly', 'Ruby', 'Tangy', 'Beau', 'Merry', 'Peaches', 'Honey'
];
const nameEnds = [
'paw', 'tail', 'whisker', 'hop', 'leaf', 'berry', 'bloom', 'wing', 'puff',
'bell', 'star', 'moon', 'heart', 'song', 'breeze', 'glow', 'shine', 'pearl',
'blossom', 'meadow', 'brook', 'cloud', 'dream', 'joy', 'wonder'
];
// Animal data
const animals = {
cat: { icon: '🐱', species: 'Cat' },
dog: { icon: '🐶', species: 'Dog' },
rabbit: { icon: '🐰', species: 'Rabbit' },
squirrel: { icon: '🐿️', species: 'Squirrel' },
bear: { icon: '🐻', species: 'Bear' },
deer: { icon: '🦌', species: 'Deer' },
bird: { icon: '🐦', species: 'Bird' },
duck: { icon: '🦆', species: 'Duck' },
penguin: { icon: '🐧', species: 'Penguin' },
frog: { icon: '🐸', species: 'Frog' }
};
const personalities = ['Lazy', 'Jock', 'Cranky', 'Smug', 'Normal', 'Peppy', 'Snooty', 'Sisterly'];
const personalityEmojis = {
'Lazy': '😴',
'Jock': '💪',
'Cranky': '😠',
'Smug': '😎',
'Normal': '😊',
'Peppy': '⭐',
'Snooty': '💅',
'Sisterly': '💕'
};
// History storage
let villagerHistory = [];
// Elements
const animalIcon = document.getElementById('animalIcon');
const generatedName = document.getElementById('generatedName');
const animalSpecies = document.getElementById('animalSpecies');
const personalityTrait = document.getElementById('personalityTrait');
const animalTypeSelect = document.getElementById('animalType');
const personalityTypeSelect = document.getElementById('personalityType');
const generateBtn = document.getElementById('generateBtn');
const historyList = document.getElementById('historyList');
// Generate random name
function generateName() {
const start = nameStarts[Math.floor(Math.random() * nameStarts.length)];
const end = nameEnds[Math.floor(Math.random() * nameEnds.length)];
// 50% chance to use compound name, 50% chance to use just start name
if (Math.random() > 0.5) {
return start + end.charAt(0).toUpperCase() + end.slice(1);
} else {
return start;
}
}
// Get random animal type
function getRandomAnimal() {
const animalKeys = Object.keys(animals);
const randomKey = animalKeys[Math.floor(Math.random() * animalKeys.length)];
return randomKey;
}
// Get random personality
function getRandomPersonality() {
return personalities[Math.floor(Math.random() * personalities.length)];
}
// Generate villager
function generateVillager() {
let selectedAnimal = animalTypeSelect.value;
if (selectedAnimal === 'random') {
selectedAnimal = getRandomAnimal();
}
let selectedPersonality = personalityTypeSelect.value;
if (selectedPersonality === 'random') {
selectedPersonality = getRandomPersonality();
}
const name = generateName();
const animal = animals[selectedAnimal];
// Update display
animalIcon.textContent = animal.icon;
generatedName.textContent = name;
animalSpecies.textContent = animal.species;
personalityTrait.textContent = `${personalityEmojis[selectedPersonality]} ${selectedPersonality}`;
// Add to history
addToHistory({
name: name,
species: animal.species,
icon: animal.icon,
personality: selectedPersonality
});
// Animate
animalIcon.style.animation = 'none';
setTimeout(() => {
animalIcon.style.animation = 'bounce 2s infinite';
}, 10);
}
// Add to history
function addToHistory(villager) {
villagerHistory.unshift(villager);
if (villagerHistory.length > 12) {
villagerHistory.pop();
}
renderHistory();
}
// Render history
function renderHistory() {
if (villagerHistory.length === 0) {
historyList.innerHTML = '<div class="empty-history">Generate some villagers to see them here! 🌺</div>';
return;
}
historyList.innerHTML = villagerHistory.map(villager => `
<div class="history-item" onclick="showVillagerDetails('${villager.name}', '${villager.species}', '${villager.icon}', '${villager.personality}')">
<div class="history-icon">${villager.icon}</div>
<div class="history-name">${villager.name}</div>
<div class="history-species">${villager.species}</div>
</div>
`).join('');
}
// Show villager details from history
function showVillagerDetails(name, species, icon, personality) {
animalIcon.textContent = icon;
generatedName.textContent = name;
animalSpecies.textContent = species;
personalityTrait.textContent = `${personalityEmojis[personality]} ${personality}`;
// Scroll to top
window.scrollTo({ top: 0, behavior: 'smooth' });
// Animate
animalIcon.style.animation = 'none';
setTimeout(() => {
animalIcon.style.animation = 'bounce 2s infinite';
}, 10);
}
// Event listener
generateBtn.addEventListener('click', generateVillager);
// Generate initial villager
generateVillager();
No comments yet. Be the first!