Mistral Small 4
by MistralReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 57.2 s
- Cost
- $0.0083
- Output tokens
- 12,386
- Spent thinking
- 9,690 tokens
- Speed
- 218.8 tok/s
- Console errors
- 0
- First token after
- 577 ms
- First visible text after
- 45.5 s
- Prompt tokens
- 525
- Code size
- 8.0 KB
- Finish reason
- stop
- Served by
- Mistral
- Model id
mistralai/mistral-small-2603- Reasoning sent
{"effort":"high"}- Max output
- 209,715 tokens
- Generated
- Nov 12, 2026
What it was asked
The prompt
Create a set of four animated weather cards (sunny, rainy, snowy, stormy), made with HTML and CSS only. Requirements: - Absolutely no JavaScript: the file must not contain any <script> tag or inline event handler. - No images, no SVG, no icon fonts: every weather icon is built from HTML elements and pseudo-elements styled with CSS. - Each card shows an animated icon (rotating sun rays, falling rain drops, drifting snowflakes, flashing lightning), a city name, a temperature and a short description. - Each card has its own background gradient matching the weather. - The cards are displayed in a responsive grid (4 per row on desktop, stacked on mobile) and lift up on hover. - Smooth infinite animations using @keyframes, and respect prefers-reduced-motion.
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task. Output rules: - Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block. - Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task. - Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw. - The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar. - Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction. - Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session. - Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing. - The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message. - The code must run with zero errors in the console of the latest Chrome.
Code run-1.html · 340 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather Cards</title>
<style>
:root {
--sun-yellow: #FFD700;
--sun-ray-yellow: #FFC107;
--rain-blue: #1E88E5;
--snow-blue: #B3E5FC;
--storm-purple: #7B1FA2;
--storm-lightning: #FFD600;
--text-light: #FFFFFF;
--text-dark: #212121;
}
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
body {
margin: 0;
padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
}
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
max-width: 1280px;
margin: 0 auto;
}
.card {
position: relative;
padding: 20px;
border-radius: 16px;
color: var(--text-light);
text-align: center;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
transition: transform 0.3s ease;
overflow: hidden;
min-height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
}
.card:hover {
transform: translateY(-10px);
}
.card-icon {
margin-bottom: 15px;
height: 100px;
position: relative;
}
.card-city {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 10px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.card-temp {
font-size: 2.5rem;
font-weight: bold;
margin-bottom: 10px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.card-desc {
font-size: 1rem;
opacity: 0.9;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
/* Sunny card */
.card-sunny {
background: linear-gradient(135deg, #FFD700 0%, #FFA726 100%);
}
.card-sunny .sun {
position: relative;
width: 60px;
height: 60px;
background: var(--sun-yellow);
border-radius: 50%;
margin: 0 auto 10px;
z-index: 2;
}
.card-sunny .rays {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
z-index: 1;
}
.card-sunny .rays::before,
.card-sunny .rays::after {
content: '';
position: absolute;
background: var(--sun-ray-yellow);
border-radius: 5px;
}
.card-sunny .rays::before {
width: 4px;
height: 20px;
top: 0;
left: 50%;
transform-origin: center;
animation: rotate 8s linear infinite;
}
.card-sunny .rays::after {
width: 20px;
height: 4px;
top: 50%;
left: 0;
transform-origin: center;
animation: rotate 10s linear infinite reverse;
}
@keyframes rotate {
from { transform: translate(-50%, -50%) rotate(0deg); }
to { transform: translate(-50%, -50%) rotate(360deg); }
}
/* Rainy card */
.card-rainy {
background: linear-gradient(135deg, #1E88E5 0%, #0D47A1 100%);
}
.card-rainy .rain {
position: relative;
width: 4px;
height: 60px;
background: var(--text-light);
margin: 0 auto;
border-radius: 2px;
animation: fall 1s ease-in-out infinite;
}
.card-rainy .rain::before {
content: '';
position: absolute;
width: 12px;
height: 4px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: -4px;
animation: fall 1.2s ease-in-out infinite;
}
.card-rainy .rain::after {
content: '';
position: absolute;
width: 8px;
height: 4px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
right: -2px;
animation: fall 1.4s ease-in-out infinite;
}
@keyframes fall {
0% {
transform: translateY(0);
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
transform: translateY(100px);
opacity: 0;
}
}
/* Snowy card */
.card-snowy {
background: linear-gradient(135deg, #B3E5FC 0%, #0D47A1 100%);
}
.card-snowy .snowflake {
position: absolute;
width: 6px;
height: 6px;
background: var(--text-light);
border-radius: 50%;
margin: 0 auto;
box-shadow: 0 0 0 2px var(--text-light);
}
.card-snowy .snowflake:nth-child(1) { top: 20%; left: 20%; animation: drift 4s linear infinite; }
.card-snowy .snowflake:nth-child(2) { top: 20%; right: 20%; animation: drift 5s linear infinite reverse; }
.card-snowy .snowflake:nth-child(3) { top: 60%; left: 30%; animation: drift 6s linear infinite; }
.card-snowy .snowflake:nth-child(4) { top: 60%; right: 30%; animation: drift 4.5s linear infinite reverse; }
.card-snowy .snowflake:nth-child(5) { top: 40%; left: 50%; transform: translateX(-50%); animation: drift 5.5s linear infinite; }
@keyframes drift {
0% {
transform: translateY(0) rotate(0deg);
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
transform: translateY(100px) rotate(360deg);
opacity: 0;
}
}
/* Stormy card */
.card-stormy {
background: linear-gradient(135deg, #7B1FA2 0%, #4A148C 100%);
}
.card-stormy .lightning {
position: relative;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 40px solid var(--storm-lightning);
margin: 0 auto 10px;
animation: flash 1.5s ease-in-out infinite;
}
.card-stormy .rain-streak {
position: absolute;
width: 4px;
height: 60px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: 50%;
transform: translateX(-50%);
animation: fall 1.5s ease-in-out infinite;
}
@keyframes flash {
0%, 50%, 100% { opacity: 1; }
25%, 75% { opacity: 0.3; }
}
/* Responsive layout */
@media (max-width: 1024px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.container {
grid-template-columns: 1fr;
}
.card {
min-height: 250px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="card card-sunny">
<div class="card-icon">
<div class="sun"></div>
<div class="rays"></div>
</div>
<div class="card-city">Los Angeles</div>
<div class="card-temp">28°C</div>
<div class="card-desc">Clear skies all day</div>
</div>
<div class="card card-rainy">
<div class="card-icon">
<div class="rain"></div>
</div>
<div class="card-city">London</div>
<div class="card-temp">15°C</div>
<div class="card-desc">Light rain expected</div>
</div>
<div class="card card-snowy">
<div class="card-icon">
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
</div>
<div class="card-city">Moscow</div>
<div class="card-temp">-2°C</div>
<div class="card-desc">Snowfall throughout</div>
</div>
<div class="card card-stormy">
<div class="card-icon">
<div class="lightning"></div>
<div class="rain-streak"></div>
</div>
<div class="card-city">New York</div>
<div class="card-temp">12°C</div>
<div class="card-desc">Thunderstorms likely</div>
</div>
</div>
</body>
</html>Reasoning trace (9,690 tokens)
I need to create four animated weather cards with HTML and CSS only, no JavaScript. Let me break down the requirements:
1. Four cards: sunny, rainy, snowy, stormy
2. Each card has:
- Animated icon (sun rays rotating, rain drops falling, snowflakes drifting, lightning flashing)
- City name
- Temperature
- Short description
- Background gradient matching the weather
3. Responsive grid: 4 per row on desktop, stacked on mobile
4. Cards lift up on hover
5. Smooth infinite animations using @keyframes
6. Respect prefers-reduced-motion
7. No images, no SVG, no icon fonts - use HTML elements and pseudo-elements
8. No JavaScript at all
Let me plan the structure:
- Each card will be a div with class "card" and a modifier like "card-sunny", "card-rainy", etc.
- The icon will be created using HTML elements (spans, divs) styled with CSS
- For sunny: multiple rays around a sun circle
- For rainy: multiple rain drop elements
- For snowy: multiple snowflake elements
- For stormy: lightning bolt and maybe some rain
- Each card will have a gradient background specific to the weather
- Use CSS variables for colors to make it easier
- Use @media queries for responsive layout
- Use prefers-reduced-motion to respect user preferences
Let me think about the animations:
- Sunny: sun rays rotating (infinite rotation)
- Rainy: rain drops falling (translateY animation)
- Snowy: snowflakes drifting (translateX/Y with slight rotation)
- Stormy: lightning flashing (opacity/visibility animation)
For the icons, I'll use HTML elements:
- Sunny: a central circle with multiple ray elements around it
- Rainy: multiple vertical lines for rain drops
- Snowy: multiple snowflake elements (maybe using spans with borders)
- Stormy: a zigzag line for lightning
Let me structure the HTML:
- A container div with class "container"
- Four card divs with appropriate classes
CSS structure:
- Define CSS variables for colors
- Define keyframes for each animation
- Style the container as a grid
- Style each card type with its background gradient
- Style the icon for each weather type
- Add hover effect (transform: translateY)
- Use prefers-reduced-motion to reduce or disable animations
Let me start coding:
First, the HTML structure:
```html
<div class="container">
<div class="card card-sunny">
<div class="card-icon">
<div class="sun"></div>
<div class="rays"></div>
</div>
<div class="card-city">Los Angeles</div>
<div class="card-temp">28°C</div>
<div class="card-desc">Clear skies all day</div>
</div>
<div class="card card-rainy">
<div class="card-icon">
<div class="rain"></div>
</div>
<div class="card-city">London</div>
<div class="card-temp">15°C</div>
<div class="card-desc">Light rain expected</div>
</div>
<div class="card card-snowy">
<div class="card-icon">
<div class="snow"></div>
</div>
<div class="card-city">Moscow</div>
<div class="card-temp">-2°C</div>
<div class="card-desc">Snowfall throughout</div>
</div>
<div class="card card-stormy">
<div class="card-icon">
<div class="storm"></div>
</div>
<div class="card-city">New York</div>
<div class="card-temp">12°C</div>
<div class="card-desc">Thunderstorms likely</div>
</div>
</div>
```
Now for the CSS:
I'll define:
- CSS variables for colors
- Keyframes for each animation
- Grid layout for the container
- Card styling including gradients
- Icon styling
- Hover effects
- Reduced motion handling
Let me write the complete CSS:
```css
:root {
--sun-yellow: #FFD700;
--sun-ray-yellow: #FFC107;
--rain-blue: #1E88E5;
--snow-blue: #B3E5FC;
--storm-purple: #7B1FA2;
--storm-lightning: #FFD600;
--text-light: #FFFFFF;
--text-dark: #212121;
}
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* Base styles */
body {
margin: 0;
padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
}
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
max-width: 1280px;
margin: 0 auto;
}
.card {
position: relative;
padding: 20px;
border-radius: 16px;
color: var(--text-light);
text-align: center;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
transition: transform 0.3s ease;
overflow: hidden;
min-height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
}
.card:hover {
transform: translateY(-10px);
}
.card-icon {
margin-bottom: 15px;
height: 100px;
position: relative;
}
/* Sunny card */
.card-sunny {
background: linear-gradient(135deg, #FFD700 0%, #FFA726 100%);
}
.sun {
position: relative;
width: 60px;
height: 60px;
background: var(--sun-yellow);
border-radius: 50%;
margin: 0 auto;
z-index: 2;
}
.rays {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
z-index: 1;
}
.rays::before,
.rays::after {
content: '';
position: absolute;
background: var(--sun-ray-yellow);
border-radius: 5px;
}
.rays::before {
width: 4px;
height: 20px;
top: 0;
left: 50%;
transform-origin: center;
}
.rays::after {
width: 20px;
height: 4px;
top: 50%;
left: 0;
transform-origin: center;
}
@keyframes rotate {
from { transform: translate(-50%, -50%) rotate(0deg); }
to { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes ray-pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
.sunny .rays::before {
animation: rotate 8s linear infinite;
}
.sunny .rays::after {
animation: rotate 10s linear infinite reverse;
}
/* Rainy card */
.card-rainy {
background: linear-gradient(135deg, #1E88E5 0%, #0D47A1 100%);
}
.rain {
position: relative;
width: 4px;
height: 60px;
background: var(--text-light);
margin: 0 auto;
border-radius: 2px;
}
.rain::before {
content: '';
position: absolute;
width: 12px;
height: 4px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: -4px;
}
.rain::after {
content: '';
position: absolute;
width: 8px;
height: 4px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
right: -2px;
}
@keyframes fall {
0% {
transform: translateY(0);
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
transform: translateY(100px);
opacity: 0;
}
}
.rainy .rain {
animation: fall 1s ease-in-out infinite;
}
.rainy .rain::before,
.rainy .rain::after {
animation: fall 1.2s ease-in-out infinite;
}
/* Snowy card */
.card-snowy {
background: linear-gradient(135deg, #B3E5FC 0%, #0D47A1 100%);
}
.snow {
position: relative;
width: 60px;
height: 60px;
margin: 0 auto;
}
.snowflake {
position: absolute;
color: var(--text-light);
font-size: 20px;
animation: drift 4s linear infinite;
}
.snowflake:nth-child(1) { top: 0; left: 0; animation-delay: 0s; }
.snowflake:nth-child(2) { top: 0; right: 0; animation-delay: 0.5s; }
.snowflake:nth-child(3) { bottom: 0; left: 0; animation-delay: 1s; }
.snowflake:nth-child(4) { bottom: 0; right: 0; animation-delay: 1.5s; }
.snowflake:nth-child(5) { top: 50%; left: 50%; animation-delay: 2s; transform: translate(-50%, -50%); }
@keyframes drift {
0% {
transform: translateY(0) rotate(0deg);
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
transform: translateY(100px) rotate(360deg);
opacity: 0;
}
}
/* Stormy card */
.card-stormy {
background: linear-gradient(135deg, #7B1FA2 0%, #4A148C 100%);
}
.storm {
position: relative;
width: 60px;
height: 80px;
margin: 0 auto;
}
.lightning {
position: absolute;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 40px solid var(--storm-lightning);
top: 0;
left: 50%;
transform: translateX(-50%);
animation: flash 1.5s ease-in-out infinite;
}
.storm::before {
content: '';
position: absolute;
width: 4px;
height: 60px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: 50%;
transform: translateX(-50%);
animation: fall 1.5s ease-in-out infinite;
}
@keyframes flash {
0%, 50%, 100% { opacity: 1; }
25%, 75% { opacity: 0.3; }
}
/* Card content */
.card-city {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 10px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.card-temp {
font-size: 2.5rem;
font-weight: bold;
margin-bottom: 10px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.card-desc {
font-size: 1rem;
opacity: 0.9;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
/* Responsive layout */
@media (max-width: 1024px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.container {
grid-template-columns: 1fr;
}
.card {
min-height: 250px;
}
}
```
Wait, I need to fix the HTML structure. The classes for the icons need to be specific to each card. Let me revise:
Actually, looking at my CSS, I'm using classes like `.sunny .rays` which means the rays element needs to be inside an element with class "sunny". But in my HTML structure, the card has class `card-sunny`, not `sunny`.
Let me adjust the CSS to use `.card-sunny .rays` instead, or better yet, use the card class directly.
Actually, let me restructure the HTML to have the weather type as a class on the card, and then style based on that:
```html
<div class="container">
<div class="card card-sunny">
<div class="card-icon">
<div class="sun-icon">
<div class="sun"></div>
<div class="rays"></div>
</div>
</div>
<div class="card-city">Los Angeles</div>
<div class="card-temp">28°C</div>
<div class="card-desc">Clear skies all day</div>
</div>
<div class="card card-rainy">
<div class="card-icon">
<div class="rain-icon">
<div class="rain"></div>
</div>
</div>
<div class="card-city">London</div>
<div class="card-temp">15°C</div>
<div class="card-desc">Light rain expected</div>
</div>
<div class="card card-snowy">
<div class="card-icon">
<div class="snow-icon">
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
</div>
</div>
<div class="card-city">Moscow</div>
<div class="card-temp">-2°C</div>
<div class="card-desc">Snowfall throughout</div>
</div>
<div class="card card-stormy">
<div class="card-icon">
<div class="storm-icon">
<div class="lightning"></div>
<div class="rain-streak"></div>
</div>
</div>
<div class="card-city">New York</div>
<div class="card-temp">12°C</div>
<div class="card-desc">Thunderstorms likely</div>
</div>
</div>
```
And then update the CSS accordingly. Let me rewrite the entire thing more carefully:
Actually, to make it cleaner, I'll use the card class directly for styling. Let me simplify:
```html
<div class="container">
<div class="card card-sunny">
<div class="card-icon">
<div class="sun"></div>
<div class="rays"></div>
</div>
<div class="card-city">Los Angeles</div>
<div class="card-temp">28°C</div>
<div class="card-desc">Clear skies all day</div>
</div>
<div class="card card-rainy">
<div class="card-icon">
<div class="rain"></div>
</div>
<div class="card-city">London</div>
<div class="card-temp">15°C</div>
<div class="card-desc">Light rain expected</div>
</div>
<div class="card card-snowy">
<div class="card-icon">
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
</div>
<div class="card-city">Moscow</div>
<div class="card-temp">-2°C</div>
<div class="card-desc">Snowfall throughout</div>
</div>
<div class="card card-stormy">
<div class="card-icon">
<div class="lightning"></div>
</div>
<div class="card-city">New York</div>
<div class="card-temp">12°C</div>
<div class="card-desc">Thunderstorms likely</div>
</div>
</div>
```
Now for the CSS, I'll use the card class to scope the styles:
```css
:root {
--sun-yellow: #FFD700;
--sun-ray-yellow: #FFC107;
--rain-blue: #1E88E5;
--snow-blue: #B3E5FC;
--storm-purple: #7B1FA2;
--storm-lightning: #FFD600;
--text-light: #FFFFFF;
--text-dark: #212121;
}
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* Base styles */
body {
margin: 0;
padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
}
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
max-width: 1280px;
margin: 0 auto;
}
.card {
position: relative;
padding: 20px;
border-radius: 16px;
color: var(--text-light);
text-align: center;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
transition: transform 0.3s ease;
overflow: hidden;
min-height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
}
.card:hover {
transform: translateY(-10px);
}
.card-icon {
margin-bottom: 15px;
height: 100px;
position: relative;
}
/* Sunny card */
.card-sunny {
background: linear-gradient(135deg, #FFD700 0%, #FFA726 100%);
}
.card-sunny .sun {
position: relative;
width: 60px;
height: 60px;
background: var(--sun-yellow);
border-radius: 50%;
margin: 0 auto 10px;
z-index: 2;
}
.card-sunny .rays {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
z-index: 1;
}
.card-sunny .rays::before,
.card-sunny .rays::after {
content: '';
position: absolute;
background: var(--sun-ray-yellow);
border-radius: 5px;
}
.card-sunny .rays::before {
width: 4px;
height: 20px;
top: 0;
left: 50%;
transform-origin: center;
animation: rotate 8s linear infinite;
}
.card-sunny .rays::after {
width: 20px;
height: 4px;
top: 50%;
left: 0;
transform-origin: center;
animation: rotate 10s linear infinite reverse;
}
@keyframes rotate {
from { transform: translate(-50%, -50%) rotate(0deg); }
to { transform: translate(-50%, -50%) rotate(360deg); }
}
/* Rainy card */
.card-rainy {
background: linear-gradient(135deg, #1E88E5 0%, #0D47A1 100%);
}
.card-rainy .rain {
position: relative;
width: 4px;
height: 60px;
background: var(--text-light);
margin: 0 auto;
border-radius: 2px;
animation: fall 1s ease-in-out infinite;
}
.card-rainy .rain::before {
content: '';
position: absolute;
width: 12px;
height: 4px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: -4px;
animation: fall 1.2s ease-in-out infinite;
}
.card-rainy .rain::after {
content: '';
position: absolute;
width: 8px;
height: 4px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
right: -2px;
animation: fall 1.4s ease-in-out infinite;
}
@keyframes fall {
0% {
transform: translateY(0);
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
transform: translateY(100px);
opacity: 0;
}
}
/* Snowy card */
.card-snowy {
background: linear-gradient(135deg, #B3E5FC 0%, #0D47A1 100%);
}
.card-snowy .snowflake {
position: absolute;
width: 6px;
height: 6px;
background: var(--text-light);
border-radius: 50%;
margin: 0 auto;
box-shadow: 0 0 0 2px var(--text-light);
}
.card-snowy .snowflake:nth-child(1) { top: 20%; left: 20%; animation: drift 4s linear infinite; }
.card-snowy .snowflake:nth-child(2) { top: 20%; right: 20%; animation: drift 5s linear infinite reverse; }
.card-snowy .snowflake:nth-child(3) { top: 60%; left: 30%; animation: drift 6s linear infinite; }
.card-snowy .snowflake:nth-child(4) { top: 60%; right: 30%; animation: drift 4.5s linear infinite reverse; }
.card-snowy .snowflake:nth-child(5) { top: 40%; left: 50%; transform: translateX(-50%); animation: drift 5.5s linear infinite; }
@keyframes drift {
0% {
transform: translateY(0) rotate(0deg);
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
transform: translateY(100px) rotate(360deg);
opacity: 0;
}
}
/* Stormy card */
.card-stormy {
background: linear-gradient(135deg, #7B1FA2 0%, #4A148C 100%);
}
.card-stormy .lightning {
position: relative;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 40px solid var(--storm-lightning);
margin: 0 auto 10px;
animation: flash 1.5s ease-in-out infinite;
}
.card-stormy .lightning::before {
content: '';
position: absolute;
width: 4px;
height: 60px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: 50%;
transform: translateX(-50%);
animation: fall 1.5s ease-in-out infinite;
}
@keyframes flash {
0%, 50%, 100% { opacity: 1; }
25%, 75% { opacity: 0.3; }
}
/* Card content */
.card-city {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 10px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.card-temp {
font-size: 2.5rem;
font-weight: bold;
margin-bottom: 10px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.card-desc {
font-size: 1rem;
opacity: 0.9;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
/* Responsive layout */
@media (max-width: 1024px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.container {
grid-template-columns: 1fr;
}
.card {
min-height: 250px;
}
}
```
Wait, I need to make sure the snowflakes are positioned correctly. Let me adjust the snowflake positioning. The card-icon has height 100px and is positioned relatively. The snowflakes should be positioned within that container.
Also, I need to make sure the card-icon container is properly sized. Let me adjust:
Actually, looking at the code, the card-icon has height: 100px and position: relative, which is good. The snowflakes are absolutely positioned within it.
Let me also check the stormy card - it needs both lightning and rain. Let me update that:
```css
.card-stormy .lightning {
position: relative;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 40px solid var(--storm-lightning);
margin: 0 auto 10px;
animation: flash 1.5s ease-in-out infinite;
}
.card-stormy .rain-streak {
position: absolute;
width: 4px;
height: 60px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: 50%;
transform: translateX(-50%);
animation: fall 1.5s ease-in-out infinite;
}
```
And update the HTML for stormy:
```html
<div class="card card-stormy">
<div class="card-icon">
<div class="lightning"></div>
<div class="rain-streak"></div>
</div>
<div class="card-city">New York</div>
<div class="card-temp">12°C</div>
<div class="card-desc">Thunderstorms likely</div>
</div>
```
Now let me put it all together in a single HTML file with inline CSS:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather Cards</title>
<style>
:root {
--sun-yellow: #FFD700;
--sun-ray-yellow: #FFC107;
--rain-blue: #1E88E5;
--snow-blue: #B3E5FC;
--storm-purple: #7B1FA2;
--storm-lightning: #FFD600;
--text-light: #FFFFFF;
--text-dark: #212121;
}
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* Base styles */
body {
margin: 0;
padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
}
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
max-width: 1280px;
margin: 0 auto;
}
.card {
position: relative;
padding: 20px;
border-radius: 16px;
color: var(--text-light);
text-align: center;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
transition: transform 0.3s ease;
overflow: hidden;
min-height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
}
.card:hover {
transform: translateY(-10px);
}
.card-icon {
margin-bottom: 15px;
height: 100px;
position: relative;
}
/* Sunny card */
.card-sunny {
background: linear-gradient(135deg, #FFD700 0%, #FFA726 100%);
}
.card-sunny .sun {
position: relative;
width: 60px;
height: 60px;
background: var(--sun-yellow);
border-radius: 50%;
margin: 0 auto 10px;
z-index: 2;
}
.card-sunny .rays {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
transform: translate(-50%, -50%);
z-index: 1;
}
.card-sunny .rays::before,
.card-sunny .rays::after {
content: '';
position: absolute;
background: var(--sun-ray-yellow);
border-radius: 5px;
}
.card-sunny .rays::before {
width: 4px;
height: 20px;
top: 0;
left: 50%;
transform-origin: center;
animation: rotate 8s linear infinite;
}
.card-sunny .rays::after {
width: 20px;
height: 4px;
top: 50%;
left: 0;
transform-origin: center;
animation: rotate 10s linear infinite reverse;
}
@keyframes rotate {
from { transform: translate(-50%, -50%) rotate(0deg); }
to { transform: translate(-50%, -50%) rotate(360deg); }
}
/* Rainy card */
.card-rainy {
background: linear-gradient(135deg, #1E88E5 0%, #0D47A1 100%);
}
.card-rainy .rain {
position: relative;
width: 4px;
height: 60px;
background: var(--text-light);
margin: 0 auto;
border-radius: 2px;
animation: fall 1s ease-in-out infinite;
}
.card-rainy .rain::before {
content: '';
position: absolute;
width: 12px;
height: 4px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: -4px;
animation: fall 1.2s ease-in-out infinite;
}
.card-rainy .rain::after {
content: '';
position: absolute;
width: 8px;
height: 4px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
right: -2px;
animation: fall 1.4s ease-in-out infinite;
}
@keyframes fall {
0% {
transform: translateY(0);
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
transform: translateY(100px);
opacity: 0;
}
}
/* Snowy card */
.card-snowy {
background: linear-gradient(135deg, #B3E5FC 0%, #0D47A1 100%);
}
.card-snowy .snowflake {
position: absolute;
width: 6px;
height: 6px;
background: var(--text-light);
border-radius: 50%;
margin: 0 auto;
box-shadow: 0 0 0 2px var(--text-light);
}
.card-snowy .snowflake:nth-child(1) { top: 20%; left: 20%; animation: drift 4s linear infinite; }
.card-snowy .snowflake:nth-child(2) { top: 20%; right: 20%; animation: drift 5s linear infinite reverse; }
.card-snowy .snowflake:nth-child(3) { top: 60%; left: 30%; animation: drift 6s linear infinite; }
.card-snowy .snowflake:nth-child(4) { top: 60%; right: 30%; animation: drift 4.5s linear infinite reverse; }
.card-snowy .snowflake:nth-child(5) { top: 40%; left: 50%; transform: translateX(-50%); animation: drift 5.5s linear infinite; }
@keyframes drift {
0% {
transform: translateY(0) rotate(0deg);
opacity: 0;
}
20% {
opacity: 1;
}
80% {
opacity: 1;
}
100% {
transform: translateY(100px) rotate(360deg);
opacity: 0;
}
}
/* Stormy card */
.card-stormy {
background: linear-gradient(135deg, #7B1FA2 0%, #4A148C 100%);
}
.card-stormy .lightning {
position: relative;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 40px solid var(--storm-lightning);
margin: 0 auto 10px;
animation: flash 1.5s ease-in-out infinite;
}
.card-stormy .rain-streak {
position: absolute;
width: 4px;
height: 60px;
background: var(--text-light);
border-radius: 2px;
top: 100%;
left: 50%;
transform: translateX(-50%);
animation: fall 1.5s ease-in-out infinite;
}
@keyframes flash {
0%, 50%, 100% { opacity: 1; }
25%, 75% { opacity: 0.3; }
}
/* Card content */
.card-city {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 10px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.card-temp {
font-size: 2.5rem;
font-weight: bold;
margin-bottom: 10px;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
.card-desc {
font-size: 1rem;
opacity: 0.9;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}
/* Responsive layout */
@media (max-width: 1024px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 480px) {
.container {
grid-template-columns: 1fr;
}
.card {
min-height: 250px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="card card-sunny">
<div class="card-icon">
<div class="sun"></div>
<div class="rays"></div>
</div>
<div class="card-city">Los Angeles</div>
<div class="card-temp">28°C</div>
<div class="card-desc">Clear skies all day</div>
</div>
<div class="card card-rainy">
<div class="card-icon">
<div class="rain"></div>
</div>
<div class="card-city">London</div>
<div class="card-temp">15°C</div>
<div class="card-desc">Light rain expected</div>
</div>
<div class="card card-snowy">
<div class="card-icon">
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
<div class="snowflake"></div>
</div>
<div class="card-city">Moscow</div>
<div class="card-temp">-2°C</div>
<div class="card-desc">Snowfall throughout</div>
</div>
<div class="card card-stormy">
<div class="card-icon">
<div class="lightning"></div>
<div class="rain-streak"></div>
</div>
<div class="card-city">New York</div>
<div class="card-temp">12°C</div>
<div class="card-desc">Thunderstorms likely</div>
</div>
</div>
</body>
</html>
```
Let me verify this meets all requirements:
1. ✓ No JavaScript - no script tags
2. ✓ No images, no SVG, no icon fonts - using HTML elements and CSS
3. ✓ Four cards with different weather conditions
4. ✓ Each card has animated icon:
- Sunny: rotating sun rays
- Rainy: falling rain drops
- Snowy: drifting snowflakes
- Stormy: flashing lightning with rain streak
5. ✓ Each card has city name, temperature, description
6. ✓ Each card has background gradient matching weather
7. ✓ Responsive grid: 4 per row on desktop, stacked on mobile
8. ✓ Cards lift up on hover
9. ✓ Smooth infinite animations using @keyframes
10. ✓ Respects prefers-reduced-motion
Let me check the animations more carefully:
- Sunny: rays rotate in opposite directions at different speeds - looks good
- Rainy: multiple rain drops with different sizes and animation delays - looks good
- Snowy: multiple snowflakes with different positions and animation delays - looks good
- Stormy: lightning flashes and rain falls - looks good
The responsive layout uses media queries to adjust from 4 columns down to 1 column.
The hover effect uses transform: translateY(-10px) which creates a nice lift effect.
The prefers-reduced-motion media query will disable or reduce animations when the user has that preference set.
Everything is inline in a single HTML file with no external resources.
This should work!