Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Premium Weather App</title> | |
<style> | |
:root { | |
--bg-dark: #0a0e17; | |
--card-bg: #121a2a; | |
--text-primary: #e0e6f0; | |
--text-secondary: #a4b3d9; | |
--accent-sun: #ffb347; | |
--accent-rain: #4da6ff; | |
--accent-wind: #9db5ce; | |
--accent-snow: #d1e3ff; | |
--shadow-color: rgba(0, 0, 0, 0.3); | |
} | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
} | |
body { | |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; | |
background-color: var(--bg-dark); | |
color: var(--text-primary); | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
min-height: 100vh; | |
overflow-x: hidden; | |
padding: 2rem; | |
} | |
.app-header { | |
text-align: center; | |
margin-bottom: 2rem; | |
} | |
.app-title { | |
font-size: 2.5rem; | |
font-weight: 600; | |
margin-bottom: 0.5rem; | |
background: linear-gradient(90deg, #4da6ff, #ffb347, #d1e3ff); | |
-webkit-background-clip: text; | |
background-clip: text; | |
color: transparent; | |
letter-spacing: -0.5px; | |
} | |
.app-subtitle { | |
font-size: 1rem; | |
color: var(--text-secondary); | |
font-weight: 400; | |
margin-bottom: 1.5rem; | |
} | |
.premium-badge { | |
display: inline-block; | |
background: linear-gradient(135deg, #ffb347, #ff8c00); | |
color: white; | |
padding: 0.3rem 1rem; | |
border-radius: 20px; | |
font-size: 0.8rem; | |
font-weight: 600; | |
text-transform: uppercase; | |
letter-spacing: 1px; | |
box-shadow: 0 4px 15px rgba(255, 140, 0, 0.3); | |
margin-bottom: 1rem; | |
} | |
.weather-container { | |
display: flex; | |
flex-wrap: wrap; | |
justify-content: center; | |
gap: 2rem; | |
max-width: 1400px; | |
margin: 0 auto; | |
} | |
.weather-card { | |
position: relative; | |
width: 300px; | |
height: 400px; | |
background: var(--card-bg); | |
border-radius: 20px; | |
overflow: hidden; | |
box-shadow: 0 10px 30px var(--shadow-color); | |
transition: transform 0.3s ease, box-shadow 0.3s ease; | |
perspective: 1000px; | |
} | |
.weather-card:hover { | |
transform: translateY(-10px) scale(1.02); | |
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4); | |
} | |
.weather-card::before { | |
content: ''; | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
height: 5px; | |
background: linear-gradient(90deg, #4da6ff, #ffb347, #d1e3ff); | |
z-index: 10; | |
} | |
.card-content { | |
position: relative; | |
height: 100%; | |
padding: 2rem; | |
display: flex; | |
flex-direction: column; | |
z-index: 2; | |
} | |
.weather-icon { | |
font-size: 4rem; | |
margin-bottom: 1rem; | |
text-align: center; | |
} | |
.weather-title { | |
font-size: 1.8rem; | |
font-weight: 600; | |
margin-bottom: 0.5rem; | |
text-align: center; | |
} | |
.weather-desc { | |
font-size: 1rem; | |
color: var(--text-secondary); | |
margin-bottom: 2rem; | |
text-align: center; | |
} | |
.weather-temp { | |
font-size: 3rem; | |
font-weight: 300; | |
text-align: center; | |
margin: 1rem 0; | |
} | |
.weather-details { | |
margin-top: auto; | |
display: flex; | |
justify-content: space-between; | |
font-size: 0.9rem; | |
color: var(--text-secondary); | |
} | |
.detail-item { | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
} | |
.detail-value { | |
font-size: 1.2rem; | |
font-weight: 600; | |
color: var(--text-primary); | |
margin-top: 0.3rem; | |
} | |
/* Sun Animation */ | |
.sun-card { | |
position: relative; | |
} | |
.sun { | |
position: absolute; | |
width: 100px; | |
height: 100px; | |
background: radial-gradient(circle, var(--accent-sun), transparent 70%); | |
border-radius: 50%; | |
top: 50px; | |
left: 50%; | |
transform: translateX(-50%); | |
box-shadow: 0 0 50px rgba(255, 179, 71, 0.5); | |
animation: pulse 3s infinite alternate; | |
} | |
@keyframes pulse { | |
0% { | |
box-shadow: 0 0 50px rgba(255, 179, 71, 0.5); | |
} | |
100% { | |
box-shadow: 0 0 80px rgba(255, 179, 71, 0.8); | |
} | |
} | |
.sun-ray { | |
position: absolute; | |
width: 120px; | |
height: 5px; | |
background: linear-gradient(90deg, transparent, var(--accent-sun), transparent); | |
top: 50%; | |
left: 50%; | |
transform-origin: left center; | |
opacity: 0.7; | |
} | |
/* Rain Animation */ | |
.rain-card { | |
position: relative; | |
overflow: hidden; | |
} | |
.raindrop { | |
position: absolute; | |
width: 2px; | |
height: 15px; | |
background: linear-gradient(to bottom, transparent, var(--accent-rain)); | |
border-radius: 0 0 5px 5px; | |
animation: rain-fall linear infinite; | |
} | |
@keyframes rain-fall { | |
0% { | |
transform: translateY(-20px); | |
opacity: 0; | |
} | |
10% { | |
opacity: 1; | |
} | |
90% { | |
opacity: 1; | |
} | |
100% { | |
transform: translateY(400px); | |
opacity: 0; | |
} | |
} | |
.puddle { | |
position: absolute; | |
bottom: 20px; | |
width: 40px; | |
height: 10px; | |
background: rgba(77, 166, 255, 0.3); | |
border-radius: 50%; | |
animation: puddle-grow 5s infinite alternate; | |
transform-origin: center; | |
} | |
@keyframes puddle-grow { | |
0% { | |
transform: scale(0.8); | |
opacity: 0.3; | |
} | |
100% { | |
transform: scale(1.2); | |
opacity: 0.6; | |
} | |
} | |
/* Wind Animation */ | |
.wind-card { | |
position: relative; | |
} | |
.cloud { | |
position: absolute; | |
background: rgba(255, 255, 255, 0.8); | |
border-radius: 50%; | |
filter: blur(5px); | |
animation: cloud-move linear infinite; | |
} | |
@keyframes cloud-move { | |
0% { | |
transform: translateX(-50px); | |
} | |
100% { | |
transform: translateX(350px); | |
} | |
} | |
.wind-line { | |
position: absolute; | |
height: 2px; | |
background: linear-gradient(90deg, transparent, var(--accent-wind), transparent); | |
animation: wind-flow linear infinite; | |
} | |
@keyframes wind-flow { | |
0% { | |
transform: translateX(-100px); | |
opacity: 0; | |
} | |
20% { | |
opacity: 0.7; | |
} | |
80% { | |
opacity: 0.7; | |
} | |
100% { | |
transform: translateX(100px); | |
opacity: 0; | |
} | |
} | |
/* Snow Animation */ | |
.snow-card { | |
position: relative; | |
overflow: hidden; | |
} | |
.snowflake { | |
position: absolute; | |
width: 8px; | |
height: 8px; | |
background: white; | |
border-radius: 50%; | |
filter: blur(1px); | |
animation: snow-fall linear infinite; | |
} | |
@keyframes snow-fall { | |
0% { | |
transform: translateY(-20px) rotate(0deg); | |
opacity: 0; | |
} | |
10% { | |
opacity: 1; | |
} | |
90% { | |
opacity: 1; | |
} | |
100% { | |
transform: translateY(400px) rotate(360deg); | |
opacity: 0; | |
} | |
} | |
.snow-accumulation { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
height: 0; | |
background: linear-gradient(to top, rgba(209, 227, 255, 0.8), transparent); | |
border-radius: 0 0 20px 20px; | |
animation: snow-build 15s infinite alternate; | |
} | |
@keyframes snow-build { | |
0% { | |
height: 0; | |
} | |
100% { | |
height: 30px; | |
} | |
} | |
/* Controls */ | |
.controls { | |
margin-top: 3rem; | |
display: flex; | |
gap: 1rem; | |
flex-wrap: wrap; | |
justify-content: center; | |
} | |
.control-btn { | |
background: rgba(255, 255, 255, 0.1); | |
border: none; | |
color: var(--text-primary); | |
padding: 0.8rem 1.5rem; | |
border-radius: 30px; | |
font-size: 0.9rem; | |
font-weight: 500; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
backdrop-filter: blur(5px); | |
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); | |
} | |
.control-btn:hover { | |
background: rgba(255, 255, 255, 0.2); | |
transform: translateY(-2px); | |
} | |
.control-btn.active { | |
background: linear-gradient(135deg, #4da6ff, #9db5ce); | |
color: white; | |
box-shadow: 0 5px 20px rgba(77, 166, 255, 0.4); | |
} | |
/* Responsive */ | |
@media (max-width: 768px) { | |
.weather-container { | |
flex-direction: column; | |
align-items: center; | |
} | |
.weather-card { | |
width: 100%; | |
max-width: 350px; | |
} | |
} | |
/* Premium touches */ | |
.particle { | |
position: absolute; | |
border-radius: 50%; | |
background: rgba(255, 255, 255, 0.1); | |
pointer-events: none; | |
z-index: 1; | |
} | |
.glow { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
top: 0; | |
left: 0; | |
background: radial-gradient(circle at center, transparent, rgba(255, 255, 255, 0.03)); | |
z-index: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="app-header"> | |
<div class="premium-badge">Premium</div> | |
<h1 class="app-title">Atmosphere Pro</h1> | |
<p class="app-subtitle">Experience weather like never before</p> | |
</div> | |
<div class="weather-container"> | |
<!-- Sun Card --> | |
<div class="weather-card sun-card" id="sun-card"> | |
<div class="glow"></div> | |
<div class="card-content"> | |
<div class="weather-icon">☀️</div> | |
<h2 class="weather-title">Sunny</h2> | |
<p class="weather-desc">Clear skies with abundant sunshine</p> | |
<div class="weather-temp">24°</div> | |
<div class="weather-details"> | |
<div class="detail-item"> | |
<span>Humidity</span> | |
<span class="detail-value">42%</span> | |
</div> | |
<div class="detail-item"> | |
<span>UV Index</span> | |
<span class="detail-value">7</span> | |
</div> | |
<div class="detail-item"> | |
<span>Pressure</span> | |
<span class="detail-value">1012 hPa</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Rain Card --> | |
<div class="weather-card rain-card" id="rain-card"> | |
<div class="glow"></div> | |
<div class="card-content"> | |
<div class="weather-icon">🌧️</div> | |
<h2 class="weather-title">Rainy</h2> | |
<p class="weather-desc">Steady rainfall throughout the day</p> | |
<div class="weather-temp">18°</div> | |
<div class="weather-details"> | |
<div class="detail-item"> | |
<span>Humidity</span> | |
<span class="detail-value">87%</span> | |
</div> | |
<div class="detail-item"> | |
<span>Rainfall</span> | |
<span class="detail-value">12mm</span> | |
</div> | |
<div class="detail-item"> | |
<span>Pressure</span> | |
<span class="detail-value">1005 hPa</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Wind Card --> | |
<div class="weather-card wind-card" id="wind-card"> | |
<div class="glow"></div> | |
<div class="card-content"> | |
<div class="weather-icon">🌬️</div> | |
<h2 class="weather-title">Windy</h2> | |
<p class="weather-desc">Breezy with strong gusts</p> | |
<div class="weather-temp">16°</div> | |
<div class="weather-details"> | |
<div class="detail-item"> | |
<span>Wind</span> | |
<span class="detail-value">28 km/h</span> | |
</div> | |
<div class="detail-item"> | |
<span>Gusts</span> | |
<span class="detail-value">45 km/h</span> | |
</div> | |
<div class="detail-item"> | |
<span>Direction</span> | |
<span class="detail-value">NW</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Snow Card --> | |
<div class="weather-card snow-card" id="snow-card"> | |
<div class="glow"></div> | |
<div class="card-content"> | |
<div class="weather-icon">❄️</div> | |
<h2 class="weather-title">Snowy</h2> | |
<p class="weather-desc">Light snow continuing</p> | |
<div class="weather-temp">-2°</div> | |
<div class="weather-details"> | |
<div class="detail-item"> | |
<span>Humidity</span> | |
<span class="detail-value">76%</span> | |
</div> | |
<div class="detail-item"> | |
<span>Accumulation</span> | |
<span class="detail-value">5cm</span> | |
</div> | |
<div class="detail-item"> | |
<span>Pressure</span> | |
<span class="detail-value">1020 hPa</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="controls"> | |
<button class="control-btn active" data-weather="sun">Sunny</button> | |
<button class="control-btn" data-weather="rain">Rainy</button> | |
<button class="control-btn" data-weather="wind">Windy</button> | |
<button class="control-btn" data-weather="snow">Snowy</button> | |
<button class="control-btn" data-weather="all">Show All</button> | |
</div> | |
<script> | |
document.addEventListener('DOMContentLoaded', function() { | |
// Create particles for premium effect | |
createParticles(); | |
// Initialize weather animations | |
initSunAnimation(); | |
initRainAnimation(); | |
initWindAnimation(); | |
initSnowAnimation(); | |
// Set up control buttons | |
const controlBtns = document.querySelectorAll('.control-btn'); | |
const weatherCards = document.querySelectorAll('.weather-card'); | |
controlBtns.forEach(btn => { | |
btn.addEventListener('click', function() { | |
// Update active button | |
controlBtns.forEach(b => b.classList.remove('active')); | |
this.classList.add('active'); | |
const weatherType = this.dataset.weather; | |
// Show/hide cards based on selection | |
weatherCards.forEach(card => { | |
if (weatherType === 'all') { | |
card.style.display = 'block'; | |
} else { | |
card.style.display = card.id.includes(weatherType) ? 'block' : 'none'; | |
} | |
}); | |
}); | |
}); | |
// Auto-animate all cards on load | |
document.querySelector('.control-btn[data-weather="all"]').click(); | |
}); | |
function createParticles() { | |
const container = document.body; | |
const particleCount = 50; | |
for (let i = 0; i < particleCount; i++) { | |
const particle = document.createElement('div'); | |
particle.classList.add('particle'); | |
// Random properties | |
const size = Math.random() * 5 + 1; | |
const posX = Math.random() * window.innerWidth; | |
const posY = Math.random() * window.innerHeight; | |
const opacity = Math.random() * 0.3 + 0.1; | |
const animationDuration = Math.random() * 20 + 10; | |
const delay = Math.random() * 10; | |
particle.style.width = `${size}px`; | |
particle.style.height = `${size}px`; | |
particle.style.left = `${posX}px`; | |
particle.style.top = `${posY}px`; | |
particle.style.opacity = opacity; | |
particle.style.animation = `float ${animationDuration}s ease-in-out ${delay}s infinite`; | |
container.appendChild(particle); | |
} | |
// Add CSS for floating animation | |
const style = document.createElement('style'); | |
style.textContent = ` | |
@keyframes float { | |
0%, 100% { | |
transform: translate(0, 0); | |
} | |
25% { | |
transform: translate(10px, 10px); | |
} | |
50% { | |
transform: translate(-10px, 5px); | |
} | |
75% { | |
transform: translate(5px, -10px); | |
} | |
} | |
`; | |
document.head.appendChild(style); | |
} | |
function initSunAnimation() { | |
const card = document.getElementById('sun-card'); | |
// Create sun rays | |
for (let i = 0; i < 12; i++) { | |
const ray = document.createElement('div'); | |
ray.classList.add('sun-ray'); | |
ray.style.transform = `rotate(${i * 30}deg)`; | |
ray.style.animationDelay = `${i * 0.1}s`; | |
card.querySelector('.card-content').appendChild(ray); | |
} | |
// Add CSS for ray animation | |
const style = document.createElement('style'); | |
style.textContent = ` | |
.sun-ray { | |
animation: ray-pulse 2s ease-in-out infinite; | |
} | |
@keyframes ray-pulse { | |
0%, 100% { | |
opacity: 0.5; | |
width: 120px; | |
} | |
50% { | |
opacity: 0.9; | |
width: 150px; | |
} | |
} | |
`; | |
document.head.appendChild(style); | |
} | |
function initRainAnimation() { | |
const card = document.getElementById('rain-card'); | |
// Create raindrops | |
for (let i = 0; i < 60; i++) { | |
const drop = document.createElement('div'); | |
drop.classList.add('raindrop'); | |
// Random properties | |
const left = Math.random() * 100; | |
const duration = Math.random() * 0.5 + 0.5; | |
const delay = Math.random() * 2; | |
const length = Math.random() * 10 + 10; | |
drop.style.left = `${left}%`; | |
drop.style.height = `${length}px`; | |
drop.style.animationDuration = `${duration}s`; | |
drop.style.animationDelay = `${delay}s`; | |
card.appendChild(drop); | |
} | |
// Create puddles | |
for (let i = 0; i < 5; i++) { | |
const puddle = document.createElement('div'); | |
puddle.classList.add('puddle'); | |
// Random properties | |
const left = Math.random() * 80 + 10; | |
const duration = Math.random() * 3 + 2; | |
const delay = Math.random() * 3; | |
const size = Math.random() * 20 + 20; | |
puddle.style.left = `${left}%`; | |
puddle.style.width = `${size}px`; | |
puddle.style.animationDuration = `${duration}s`; | |
puddle.style.animationDelay = `${delay}s`; | |
card.appendChild(puddle); | |
} | |
} | |
function initWindAnimation() { | |
const card = document.getElementById('wind-card'); | |
// Create clouds | |
for (let i = 0; i < 4; i++) { | |
const cloud = document.createElement('div'); | |
cloud.classList.add('cloud'); | |
// Random properties | |
const size = Math.random() * 40 + 30; | |
const top = Math.random() * 100 + 20; | |
const duration = Math.random() * 30 + 20; | |
const delay = Math.random() * 10; | |
const opacity = Math.random() * 0.3 + 0.3; | |
cloud.style.width = `${size}px`; | |
cloud.style.height = `${size * 0.6}px`; | |
cloud.style.top = `${top}px`; | |
cloud.style.opacity = opacity; | |
cloud.style.animationDuration = `${duration}s`; | |
cloud.style.animationDelay = `${delay}s`; | |
card.appendChild(cloud); | |
} | |
// Create wind lines | |
for (let i = 0; i < 15; i++) { | |
const line = document.createElement('div'); | |
line.classList.add('wind-line'); | |
// Random properties | |
const width = Math.random() * 100 + 50; | |
const top = Math.random() * 300 + 50; | |
const duration = Math.random() * 3 + 1; | |
const delay = Math.random() * 5; | |
line.style.width = `${width}px`; | |
line.style.top = `${top}px`; | |
line.style.animationDuration = `${duration}s`; | |
line.style.animationDelay = `${delay}s`; | |
card.appendChild(line); | |
} | |
} | |
function initSnowAnimation() { | |
const card = document.getElementById('snow-card'); | |
// Create snow accumulation | |
const accumulation = document.createElement('div'); | |
accumulation.classList.add('snow-accumulation'); | |
card.appendChild(accumulation); | |
// Create snowflakes | |
for (let i = 0; i < 80; i++) { | |
const flake = document.createElement('div'); | |
flake.classList.add('snowflake'); | |
// Random properties | |
const left = Math.random() * 100; | |
const duration = Math.random() * 5 + 5; | |
const delay = Math.random() * 5; | |
const size = Math.random() * 3 + 2; | |
const opacity = Math.random() * 0.7 + 0.3; | |
flake.style.left = `${left}%`; | |
flake.style.width = `${size}px`; | |
flake.style.height = `${size}px`; | |
flake.style.opacity = opacity; | |
flake.style.animationDuration = `${duration}s`; | |
flake.style.animationDelay = `${delay}s`; | |
card.appendChild(flake); | |
} | |
} | |
</script> | |
</body> | |
</html> |