Files
naomi e2d2f02d60
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 53s
feat: hairy button
2026-05-07 13:32:36 -07:00

469 lines
15 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🎪 Naomi's Silly Sites Carnival 🎪</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Bungee+Shade&family=Fredoka:wght@400;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Fredoka', cursive;
background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4, #feca57, #ff9ff3);
background-size: 300% 300%;
animation: gradientShift 10s ease infinite;
min-height: 100vh;
overflow-x: hidden;
position: relative;
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* Floating background elements */
.floating-emoji {
position: absolute;
font-size: 2rem;
animation: float 15s infinite ease-in-out;
opacity: 0.7;
user-select: none;
cursor: pointer;
transition: transform 0.3s;
}
.floating-emoji:hover {
transform: scale(1.5) rotate(360deg);
}
@keyframes float {
0%, 100% {
transform: translateY(0) translateX(0) rotate(0deg);
}
25% {
transform: translateY(-100px) translateX(50px) rotate(90deg);
}
50% {
transform: translateY(-50px) translateX(-50px) rotate(180deg);
}
75% {
transform: translateY(-150px) translateX(100px) rotate(270deg);
}
}
/* Main container */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
position: relative;
z-index: 10;
}
/* Header */
.header {
text-align: center;
margin-bottom: 3rem;
animation: bounceIn 1s ease-out;
}
@keyframes bounceIn {
0% {
transform: scale(0);
opacity: 0;
}
60% {
transform: scale(1.2);
}
100% {
transform: scale(1);
opacity: 1;
}
}
h1 {
font-family: 'Bungee Shade', cursive;
font-size: clamp(2.5rem, 8vw, 5rem);
color: #fff;
text-shadow: 3px 3px 0 #ff6b6b, 6px 6px 0 #4ecdc4, 9px 9px 0 #45b7d1;
margin-bottom: 1rem;
animation: wiggle 2s ease-in-out infinite;
}
@keyframes wiggle {
0%, 100% { transform: rotate(-3deg); }
50% { transform: rotate(3deg); }
}
.subtitle {
font-size: 1.5rem;
color: #fff;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
margin-bottom: 0.5rem;
}
.tagline {
font-size: 1.2rem;
color: #fff;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
font-style: italic;
}
/* Site cards */
.sites-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 2rem;
margin-top: 3rem;
}
.site-card {
background: rgba(255, 255, 255, 0.9);
border-radius: 20px;
padding: 2rem;
text-align: center;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
cursor: pointer;
animation: slideUp 0.6s ease-out;
animation-fill-mode: backwards;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
.site-card::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(45deg, transparent, rgba(255,255,255,0.3), transparent);
transform: rotate(45deg);
transition: all 0.6s;
opacity: 0;
}
.site-card:hover::before {
animation: shine 0.6s ease-out;
}
@keyframes shine {
0% {
top: -50%;
left: -50%;
opacity: 0;
}
50% {
opacity: 1;
}
100% {
top: 150%;
left: 150%;
opacity: 0;
}
}
.site-card:hover {
transform: translateY(-10px) scale(1.05);
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.site-card:hover .site-icon,
.site-card:hover .site-title,
.site-card:hover .site-description {
color: #fff;
}
@keyframes slideUp {
from {
transform: translateY(30px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.site-card:nth-child(1) { animation-delay: 0.1s; }
.site-card:nth-child(2) { animation-delay: 0.2s; }
.site-card:nth-child(3) { animation-delay: 0.3s; }
.site-card:nth-child(4) { animation-delay: 0.4s; }
.site-icon {
font-size: 3rem;
margin-bottom: 1rem;
animation: bounce 2s infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.site-title {
font-size: 1.5rem;
font-weight: 700;
margin-bottom: 0.5rem;
color: #333;
}
.site-description {
color: #666;
line-height: 1.6;
}
/* Coming soon card */
.coming-soon {
background: repeating-linear-gradient(
45deg,
#f0f0f0,
#f0f0f0 10px,
#e0e0e0 10px,
#e0e0e0 20px
);
border: 3px dashed #999;
cursor: not-allowed;
opacity: 0.7;
}
.coming-soon:hover {
transform: none;
background: repeating-linear-gradient(
45deg,
#f0f0f0,
#f0f0f0 10px,
#e0e0e0 10px,
#e0e0e0 20px
);
}
/* Fun cursor trail effect */
.cursor-trail {
position: fixed;
width: 20px;
height: 20px;
background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, transparent 70%);
border-radius: 50%;
pointer-events: none;
z-index: 9999;
transition: transform 0.1s ease;
}
/* Footer */
.footer {
text-align: center;
margin-top: 4rem;
padding: 2rem;
color: #fff;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
.footer a {
color: #fff;
text-decoration: none;
font-weight: 700;
border-bottom: 2px solid transparent;
transition: border-color 0.3s;
}
.footer a:hover {
border-color: #fff;
}
/* Responsive */
@media (max-width: 768px) {
.sites-grid {
grid-template-columns: 1fr;
}
h1 {
font-size: 2.5rem;
}
}
/* Accessibility */
.site-card:focus-visible {
outline: 3px solid #4ecdc4;
outline-offset: 3px;
}
/* Fun loading animation */
.loading-dots {
display: inline-block;
}
.loading-dots span {
display: inline-block;
animation: loadingDot 1.4s infinite;
}
.loading-dots span:nth-child(1) { animation-delay: 0s; }
.loading-dots span:nth-child(2) { animation-delay: 0.2s; }
.loading-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes loadingDot {
0%, 80%, 100% {
transform: scale(1);
opacity: 1;
}
40% {
transform: scale(1.3);
opacity: 0.5;
}
}
</style>
</head>
<body>
<!-- Floating background elements -->
<div class="floating-emoji" style="top: 10%; left: 10%; animation-delay: 0s;">🎈</div>
<div class="floating-emoji" style="top: 20%; left: 80%; animation-delay: 2s;">🎪</div>
<div class="floating-emoji" style="top: 60%; left: 5%; animation-delay: 4s;">🎨</div>
<div class="floating-emoji" style="top: 70%; left: 90%; animation-delay: 6s;">🌈</div>
<div class="floating-emoji" style="top: 30%; left: 50%; animation-delay: 8s;"></div>
<div class="floating-emoji" style="top: 80%; left: 40%; animation-delay: 10s;">🎭</div>
<div class="floating-emoji" style="top: 50%; left: 70%; animation-delay: 12s;">🎯</div>
<div class="floating-emoji" style="top: 15%; left: 30%; animation-delay: 14s;">🎡</div>
<div class="container">
<header class="header">
<h1>Silly Sites Carnival</h1>
<p class="subtitle">Welcome to Naomi's Collection of Delightfully Ridiculous Web Pages!</p>
<p class="tagline">Where serious coding meets silly ideas 🎉</p>
</header>
<main class="sites-grid">
<a href="/travel-agency/" class="site-card" tabindex="0">
<div class="site-icon">✈️</div>
<h2 class="site-title">Dubious Travel Agency</h2>
<p class="site-description">Book your next adventure to places that definitely exist! We promise!</p>
</a>
<a href="/hairy-button/" class="site-card" tabindex="0">
<div class="site-icon">🦱</div>
<h2 class="site-title">The Hairy Button</h2>
<p class="site-description">A button. With hair. Click it and watch it grow. Don't ask questions.</p>
</a>
<div class="site-card coming-soon" tabindex="0">
<div class="site-icon">🎲</div>
<h2 class="site-title">Random Nonsense Generator</h2>
<p class="site-description">Future home of absolutely meaningless content!</p>
</div>
<div class="site-card coming-soon" tabindex="0">
<div class="site-icon">🦄</div>
<h2 class="site-title">Unicorn University</h2>
<p class="site-description">Learn skills that don't exist yet!</p>
</div>
</main>
<footer class="footer">
<p>Made with 💜 and a healthy dose of silliness by <a href="https://www.nhcarrigan.com">Naomi</a></p>
<p>Found a bug? It's probably a feature! But you can <a href="https://support.nhcarrigan.com">report it anyway</a>.</p>
</footer>
</div>
<script>
// Add some interactive silliness!
const emojis = ['🎈', '🎪', '🎨', '🌈', '✨', '🎭', '🎯', '🎡', '🎉', '🎊', '🎠', '🎢'];
// Click floating emojis to change them
document.querySelectorAll('.floating-emoji').forEach(emoji => {
emoji.addEventListener('click', function() {
const randomEmoji = emojis[Math.floor(Math.random() * emojis.length)];
this.textContent = randomEmoji;
// Burst effect
const burst = document.createElement('div');
burst.style.position = 'absolute';
burst.style.left = '50%';
burst.style.top = '50%';
burst.style.transform = 'translate(-50%, -50%)';
burst.style.fontSize = '3rem';
burst.textContent = randomEmoji;
burst.style.animation = 'burst 0.6s ease-out forwards';
this.appendChild(burst);
setTimeout(() => burst.remove(), 600);
});
});
// Create cursor trail on mouse move
let mouseX = 0, mouseY = 0;
const trails = [];
const maxTrails = 10;
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
if (trails.length >= maxTrails) {
const oldTrail = trails.shift();
oldTrail.remove();
}
const trail = document.createElement('div');
trail.className = 'cursor-trail';
trail.style.left = mouseX + 'px';
trail.style.top = mouseY + 'px';
trail.style.background = `hsl(${Math.random() * 360}, 100%, 70%)`;
document.body.appendChild(trail);
trails.push(trail);
setTimeout(() => {
trail.style.transform = 'scale(0)';
setTimeout(() => {
const index = trails.indexOf(trail);
if (index > -1) trails.splice(index, 1);
trail.remove();
}, 300);
}, 100);
});
// Add burst animation
const style = document.createElement('style');
style.textContent = `
@keyframes burst {
0% {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
100% {
transform: translate(-50%, -50%) scale(3);
opacity: 0;
}
}
`;
document.head.appendChild(style);
// Console easter egg
console.log('%c🎪 Welcome to the Silly Sites Carnival! 🎪', 'font-size: 24px; color: #ff6b6b; font-weight: bold; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);');
console.log('%cYou found the secret console message! Here\'s a joke:', 'font-size: 16px; color: #4ecdc4;');
console.log('%cWhy do programmers prefer dark mode?\n\nBecause light attracts bugs! 🐛', 'font-size: 14px; color: #45b7d1;');
</script>
</body>
<script defer="" src="https://analytics.nhcarrigan.com/js/pa-YUXAn1vhhRttySUAw_LMN.js"></script>
<script>
window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
plausible.init({
customProperties: {
domain: "silly.nhcarrigan.com",
page: "NHCarrigan - Software Engineering & Community Management",
path: "/",
},
})
</script>
<script async="" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3569924701890974" crossorigin="anonymous"></script>
</html>