Mistral Large 4
by MistralReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 2 min 55 s
- Cost
- $0.032
- Output tokens
- 13,594
- Spent thinking
- 9,852 tokens
- Speed
- 78.4 tok/s
- Console errors
- 0
- First token after
- 1.2 s
- First visible text after
- 1 min 60 s
- Prompt tokens
- 519
- Code size
- 10.2 KB
- Finish reason
- stop
- Served by
- Mistral
- Model id
mistralai/mistral-large-4-0- Reasoning sent
model default- Max output
- 262,144 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 · 273 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Weather Cards</title>
<style>
* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; overflow-x: hidden; }
body {
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
color: #fff;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: clamp(18px, 3vh, 34px);
padding: clamp(20px, 4vw, 44px) clamp(16px, 4vw, 40px);
background:
radial-gradient(1100px 650px at 50% -12%, #2a416d 0%, rgba(42,65,109,0) 60%),
linear-gradient(180deg, #111c31 0%, #070b15 100%);
}
.page-head { text-align: center; }
h1 { margin: 0; font-size: clamp(1.65rem, 3.4vw, 2.6rem); letter-spacing: .02em; }
.subtitle { margin: .45rem 0 0; color: #b9c7e8; font-size: clamp(.9rem, 1.6vw, 1rem); }
.grid {
width: min(1160px, 100%);
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: clamp(14px, 1.8vw, 24px);
}
.card {
--ink: #fff;
position: relative;
min-width: 0;
min-height: 318px;
padding: 26px 22px 24px;
border-radius: 26px;
overflow: hidden;
color: var(--ink);
box-shadow: 0 18px 40px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.35);
transform: translateY(0);
transition: transform .38s cubic-bezier(.2,.8,.2,1), box-shadow .38s ease;
}
.card::after {
content: "";
position: absolute;
inset: 0;
pointer-events: none;
background: linear-gradient(115deg, rgba(255,255,255,.28), rgba(255,255,255,0) 42%);
}
.card:hover {
transform: translateY(-14px) scale(1.025);
box-shadow: 0 32px 62px rgba(0,0,0,.46), inset 0 1px 0 rgba(255,255,255,.42);
}
.card--sunny { background: linear-gradient(160deg, #ffe082 0%, #ffb300 48%, #ff8f00 100%); --ink: #5b3a00; }
.card--rainy { background: linear-gradient(160deg, #90caf9 0%, #4f7cac 52%, #28435f 100%); --ink: #f2f8ff; }
.card--snowy { background: linear-gradient(160deg, #ffffff 0%, #d9ecff 48%, #a9cbe8 100%); --ink: #24435f; }
.card--stormy { background: linear-gradient(160deg, #7c6bb8 0%, #473a78 48%, #1d1738 100%); --ink: #f5f1ff; }
.scene { position: relative; height: 132px; display: grid; place-items: center; margin: 2px 0 16px; }
.icon { position: relative; width: 132px; height: 122px; }
.icon--sunny .rays {
position: absolute;
inset: 2px;
border-radius: 50%;
background: repeating-conic-gradient(from 0deg, #ffd54f 0 9deg, rgba(255,213,79,0) 9deg 30deg);
-webkit-mask: radial-gradient(circle at center, transparent 0 35px, #000 36px 54px, transparent 55px);
mask: radial-gradient(circle at center, transparent 0 35px, #000 36px 54px, transparent 55px);
animation: spin 16s linear infinite;
}
.icon--sunny .core {
position: absolute;
inset: 34px;
border-radius: 50%;
background: radial-gradient(circle at 34% 30%, #fffde7 0 16%, #ffee58 42%, #ffc400 72%, #ff9100 100%);
box-shadow: 0 0 22px rgba(255,202,40,.9), 0 0 58px rgba(255,145,0,.45);
animation: pulse 4.5s ease-in-out infinite;
}
.cloud {
position: absolute;
left: 50%;
top: 6px;
width: 88px;
height: 32px;
margin-left: -44px;
border-radius: 999px;
background: linear-gradient(#ffffff, #d7e3f2);
box-shadow: inset 0 -7px 0 rgba(70,95,130,.16), 0 10px 18px rgba(20,40,70,.18);
animation: bob 5s ease-in-out infinite;
}
.cloud::before,
.cloud::after {
content: "";
position: absolute;
border-radius: 50%;
background: linear-gradient(#ffffff, #e6eef7);
}
.cloud::before { width: 40px; height: 40px; left: 16px; top: -24px; }
.cloud::after { width: 32px; height: 32px; right: 16px; top: -18px; }
.icon--rainy .drop {
position: absolute;
top: 56px;
width: 7px;
height: 17px;
border-radius: 50% 50% 65% 65% / 35% 35% 65% 65%;
background: linear-gradient(#e1f5fe, #29b6f6);
opacity: .9;
animation: rain-fall 1.35s linear infinite;
}
.d1 { left: 34px; animation-duration: 1.15s; animation-delay: 0s; }
.d2 { left: 52px; animation-duration: 1.35s; animation-delay: .25s; }
.d3 { left: 70px; animation-duration: 1.5s; animation-delay: .5s; }
.d4 { left: 88px; animation-duration: 1.25s; animation-delay: .1s; }
.d5 { left: 106px; animation-duration: 1.45s; animation-delay: .65s; }
.icon--snowy .cloud { background: linear-gradient(#ffffff, #eef6ff); box-shadow: inset 0 -7px 0 rgba(80,115,150,.12), 0 10px 18px rgba(60,90,125,.16); }
.icon--snowy .cloud::before,
.icon--snowy .cloud::after { background: linear-gradient(#ffffff, #f2f8ff); }
.icon--snowy .flake {
position: absolute;
width: 16px;
height: 16px;
background:
linear-gradient(#fff,#fff) center/100% 2px no-repeat,
linear-gradient(#fff,#fff) center/2px 100% no-repeat;
filter: drop-shadow(0 1px 1px rgba(36,67,95,.35));
opacity: .95;
animation: snow-drift 3.4s ease-in-out infinite;
}
.flake::before,
.flake::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(#fff,#fff) center/100% 2px no-repeat;
}
.flake::before { transform: rotate(60deg); }
.flake::after { transform: rotate(120deg); }
.f1 { left: 34px; top: 56px; animation-duration: 3.1s; animation-delay: 0s; }
.f2 { left: 56px; top: 66px; animation-duration: 3.6s; animation-delay: .45s; }
.f3 { left: 78px; top: 52px; animation-duration: 3.3s; animation-delay: .9s; }
.f4 { left: 100px; top: 62px; animation-duration: 3.8s; animation-delay: .2s; }
.f5 { left: 62px; top: 48px; animation-duration: 3.0s; animation-delay: 1.15s; }
.icon--stormy .cloud {
background: linear-gradient(#7b84ad, #4a4f78);
box-shadow: inset 0 -7px 0 rgba(10,10,35,.35), 0 10px 18px rgba(0,0,0,.35);
}
.icon--stormy .cloud::before,
.icon--stormy .cloud::after { background: linear-gradient(#868fb4, #565b86); }
.icon--stormy .bolt {
position: absolute;
left: 50%;
top: 48px;
width: 30px;
height: 58px;
margin-left: -15px;
background: linear-gradient(#fffde7 0%, #ffee58 45%, #ffb300 100%);
clip-path: polygon(64% 0, 16% 52%, 42% 52%, 28% 100%, 90% 36%, 58% 36%);
filter: drop-shadow(0 0 10px rgba(255,235,59,.95));
opacity: .95;
animation: lightning 2.4s ease-in-out infinite;
}
.city { margin: 0; font-size: clamp(1.25rem, 2vw, 1.55rem); font-weight: 800; letter-spacing: .01em; }
.temp { margin: .25rem 0 .55rem; font-size: clamp(2.2rem, 3.4vw, 3rem); line-height: 1; font-weight: 850; }
.desc { margin: 0; font-size: .95rem; line-height: 1.45; opacity: .88; max-width: 24ch; }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse {
0%, 100% { transform: scale(1); filter: brightness(1); }
50% { transform: scale(1.055); filter: brightness(1.08); }
}
@keyframes bob {
0%, 100% { transform: translateX(-50%) translateY(0); }
50% { transform: translateX(-50%) translateY(5px); }
}
@keyframes rain-fall {
0% { transform: translate3d(0,-14px,0) rotate(12deg); opacity: 0; }
12% { opacity: .95; }
100% { transform: translate3d(8px,62px,0) rotate(12deg); opacity: 0; }
}
@keyframes snow-drift {
0% { transform: translate3d(0,-12px,0) rotate(0deg); opacity: 0; }
18% { opacity: 1; }
50% { transform: translate3d(10px,22px,0) rotate(180deg); }
100% { transform: translate3d(-8px,44px,0) rotate(360deg); opacity: 0; }
}
@keyframes lightning {
0%, 100% { opacity: .14; transform: scale(.94); }
6%, 14% { opacity: 1; transform: scale(1.08); }
22% { opacity: .2; transform: scale(.96); }
34%, 42% { opacity: 1; transform: scale(1.05); }
55% { opacity: .18; }
}
@media (max-width: 1040px) {
.grid { grid-template-columns: repeat(2, minmax(0, 1fr)); width: min(720px, 100%); }
.card { min-height: 300px; }
}
@media (max-width: 600px) {
body { justify-content: flex-start; }
.grid { grid-template-columns: 1fr; width: min(420px, 100%); }
.card { min-height: 280px; padding: 24px 20px 22px; }
.scene { height: 122px; }
.icon { transform: scale(.94); }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
.card:hover { transform: none !important; }
}
</style>
</head>
<body>
<header class="page-head">
<h1>Four animated skies</h1>
<p class="subtitle">Pure HTML & CSS weather cards</p>
</header>
<main class="grid" aria-label="Weather cards">
<article class="card card--sunny">
<div class="scene" aria-hidden="true">
<div class="icon icon--sunny"><span class="rays"></span><span class="core"></span></div>
</div>
<h2 class="city">Cairo</h2>
<div class="temp">38°</div>
<p class="desc">Bright sunshine and hot desert air all day.</p>
</article>
<article class="card card--rainy">
<div class="scene" aria-hidden="true">
<div class="icon icon--rainy">
<span class="cloud"></span>
<span class="drop d1"></span><span class="drop d2"></span><span class="drop d3"></span><span class="drop d4"></span><span class="drop d5"></span>
</div>
</div>
<h2 class="city">London</h2>
<div class="temp">12°</div>
<p class="desc">Steady showers under cool grey skies.</p>
</article>
<article class="card card--snowy">
<div class="scene" aria-hidden="true">
<div class="icon icon--snowy">
<span class="cloud"></span>
<span class="flake f1"></span><span class="flake f2"></span><span class="flake f3"></span><span class="flake f4"></span><span class="flake f5"></span>
</div>
</div>
<h2 class="city">Tromsø</h2>
<div class="temp">-6°</div>
<p class="desc">Soft snow drifting over a quiet fjord town.</p>
</article>
<article class="card card--stormy">
<div class="scene" aria-hidden="true">
<div class="icon icon--stormy">
<span class="cloud"></span>
<span class="bolt"></span>
</div>
</div>
<h2 class="city">Bangkok</h2>
<div class="temp">29°</div>
<p class="desc">Heavy clouds, bright flashes and warm rain.</p>
</article>
</main>
</body>
</html>Reasoning trace (9,852 tokens)
We need output exactly one fenced code block with complete HTML file, no JS, no SVG, no images, no icon fonts. Need CSS-only animated weather cards. Need visible first paint, responsive 1280x800 and 375 wide, no horizontal scrollbar. Need prefers-reduced-motion. Need no script tags or inline event handlers. We can use HTML/CSS only. Need four cards sunny, rainy, snowy, stormy. Each icon built from HTML elements and pseudo-elements styled CSS. Need rotating sun rays, falling rain drops, drifting snowflakes, flashing lightning. Each card city name temp description, background gradient matching weather. Responsive grid 4 per row desktop stacked mobile, lift on hover. Smooth infinite @keyframes and respect reduced motion.
Need produce final only code block. Need craft robust CSS. Need ensure no <script>. No external resources. Need maybe use CSS variables. Need icons: sunny: div.sun with rays using pseudo? Rotating rays: .icon.sun .core (circle) and .rays element with pseudo? Could make sun icon as <span class="icon sunny"><span class="core"></span><span class="rays"></span></span>. rays as a square with multiple box-shadows? But no images; box-shadow okay CSS. Rotating rays can be a pseudo-element with conic-gradient? Hmm weather icon built from HTML elements and pseudo-elements styled with CSS. We can use divs. For sun rays, use .rays with ::before/::after? Simpler: .sun { position relative } .sun .disc { width/height border-radius background radial-gradient } .sun .rays { position absolute inset:-18px; animation spin; background: repeating-conic-gradient(from 0deg, #ffd54d 0 8deg, transparent 8deg 30deg); border-radius:50%; mask: radial-gradient(circle, transparent 34px, #000 35px 44px, transparent 45px); } But mask with radial-gradient is CSS, okay. Or use box-shadow rays: .rays { width:8px;height:8px;border-radius:50%; box-shadow: 0 -46px 0 0 #ffd54d, ... } and animate rotate. Simpler: .rays is small dot at center with box-shadows creating 8 rays around, transform rotate. Since .rays rotates around center, box-shadow offsets rotate too. Need place at center. Good.
Rain: icon with cloud (HTML element) + drops. Cloud built with pseudo-elements: .cloud { width 70 height 26 border-radius background } .cloud::before/::after circles. Rain drops as multiple <i> elements? Requirement every weather icon built from HTML elements and pseudo-elements; using <i> elements okay? Better use spans with classes drop d1 etc. Each drop is a span styled as teardrop via border-radius and rotate? CSS raindrop: width 6 height 14 border-radius 50% 50% 50% 50% / 60% 60% 40% 40%; background linear-gradient; transform: rotate(18deg)? Falling animation translateY. Use 5 drops with delays. Cloud maybe also drifts? Requirement falling rain drops. Good.
Snow: cloud + snowflakes drifting. Snowflakes as spans with ::before/::after? A simple asterisk snowflake from a span with background? Could use .flake { width:10px;height:10px; border-radius:50%; background:#fff; box-shadow: 0 0 6px #fff; animation drift } plus maybe pseudo cross? To look like snowflake, use .flake::before and ::after as lines (width 12 height 2 background white) rotated 0/60/120 via three? A span has only two pseudo elements, but can use box-shadow? Could make .flake with background radial and use ::before/::after as bars; enough. Or use character? No icon fonts, but text snowflake ❄ is emoji not icon font? Avoid. Build flake: span.flake with width 14 height 14; ::before content:"" position absolute left:0 top:6px width:14 height:2 background white border-radius; box-shadow: 0 0 0? Need 3 axes: ::before horizontal, ::after vertical? Then box-shadow on ::before maybe create rotated copies? box-shadow can't rotate. Could use ::before with background: linear-gradient? Simpler: flake as white circle with blur; drifting snowflakes can be dots, acceptable? Requirement drifting snowflakes; dots with slight sway okay, but flakes better. We can make each flake a <span class="flake"><i></i></span>? More HTML elements. Simpler use .flake { position:absolute; width:12px;height:12px; } .flake::before { content:""; position:absolute; inset:5px 0; height:2px; background:#fff; border-radius:2px; box-shadow: 0 -? } Not rotated. Could use multiple box-shadows with transforms? Not.
Alternative snowflake using CSS: .flake { width:14px; height:14px; background: radial-gradient(circle, #fff 0 3px, transparent 4px); } .flake::before, .flake::after { content:""; position:absolute; left:50%; top:50%; width:14px; height:2px; background:#fff; border-radius:2px; transform:translate(-50%,-50%) rotate(60deg); } .flake::after rotate(120deg); and .flake itself has a horizontal bar via box-shadow? We can set .flake::before rotate(0) and ::after rotate(60), and .flake has background? Need third line at 120 can be box-shadow? Could add child <b> for third line, but no need. Use .flake::before (0deg), .flake::after (60deg), and .flake { box-shadow? } maybe .flake has a pseudo only two. Could set .flake background: linear-gradient(#fff,#fff) center/14px 2px no-repeat, linear-gradient(#fff,#fff) center/2px 14px no-repeat; but that's two axes plus ::before/::after rotated 60/120 gives 4 axes. Good: .flake { background: linear-gradient(#fff,#fff) center/100% 2px no-repeat, linear-gradient(#fff,#fff) center/2px 100% no-repeat; } .flake::before { content:""; position:absolute; inset:0; background: linear-gradient(#fff,#fff) center/100% 2px no-repeat; transform: rotate(60deg);} .flake::after same rotate(120deg). Nice. Need position relative.
Storm: cloud + lightning bolt flashing. Lightning built from HTML element/pseudo: .bolt { width:18px; height:34px; background: linear-gradient(#fff59d,#ffd54d); clip-path: polygon(60% 0, 20% 55%, 45% 55%, 35% 100%, 85% 40%, 55% 40%); animation flash } clip-path CSS okay (not SVG/image). Flashing lightning via opacity/scale keyframes. Maybe also rain drops for storm? Requirement stormy flashing lightning; can include cloud and bolt, maybe rain too. Keep.
Cards: .cards grid: grid-template-columns: repeat(4, minmax(0,1fr)); gap 22px; @media max-width 900px repeat(2,...); max-width 560px 1fr (stacked mobile). They say stacked on mobile; at 375 one column. Could do 2 columns at <=980 and 1 at <=620. "4 per row on desktop, stacked on mobile" okay. Desktop 1280: 4 per row. Need fit height 800; cards maybe 300px tall. Use body min-height 100vh, padding, display grid place-items center. Title maybe. Need first paint visible. Add header with title. No JS.
Lift on hover: .card { transition transform .35s, box-shadow; } .card:hover { transform: translateY(-12px) scale(1.02); box-shadow bigger }. Respect reduced motion: @media (prefers-reduced-motion: reduce) { *,*::before,*::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior:auto } } But if animation iteration count 1 with duration .001ms, infinite animations stop; icons static. Good. Maybe better set animation: none !important for infinite; but then some elements with animation fill? Simpler: .icon * { animation: none !important; } and transitions none. Need ensure visible static: rain drops positioned at top? If animation none, drops all at initial positions maybe overlapping? Set initial positions distributed via top values? If animation none, they remain at their keyframe from? Actually if animation removed, element uses its base styles. We should set base positions for drops/flakes to visible locations (e.g., top: 70px; opacity etc) and keyframes from translateY(-10px) to translateY(90px). If animation none, they sit at base top maybe mid card; acceptable. For sun rays animation none static rays okay. Lightning static visible. Good.
Need no horizontal scrollbar: body margin 0; overflow-x hidden maybe. Use box-sizing border-box. Cards width 100%.
Need maybe use semantic HTML. No event handlers. No <script>. Ensure no inline event handler. Fine.
Need produce exactly one fenced code block. Use ```html. No text before/after. Need complete file. Let's design carefully.
Potential issue: "No images, no SVG, no icon fonts" - CSS gradients are fine. clip-path fine. Avoid url(). No external fonts; use system font stack.
Need each card has own background gradient matching weather. Card backgrounds: sunny warm yellow-orange; rainy blue-gray; snowy pale icy; stormy dark purple. Text color appropriate. Maybe card has gradient and inner icon panel? Requirement card background gradient; we can make whole card gradient. Text readability: sunny card dark text? Use white text with text-shadow maybe on all, but sunny bright needs dark text. Could set per-card --ink. Use color: var(--ink). Sunny --ink:#5b4300; rainy --ink:#eaf4ff; snowy --ink:#27435f; stormy --ink:#f4f0ff.
Layout: header at top, grid below. In 800 height, header ~90, grid cards ~360, fits. Use body min-height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:28px; padding:32px 24px. But for 375x? height maybe; fine. To fit 1280x800, cards maybe height 330. Use .card { min-height: 320px; }. Header small. Total 32+? okay.
Weather icon area: .scene { height: 130px; position:relative; display:grid; place-items:center; margin-bottom:18px; } Each icon inside. For rain/snow/storm, cloud at top and precip below. Need consistent.
Sunny icon: .icon--sun { position:relative; width:120px; height:120px; } .sun-core { position:absolute; inset:28px; border-radius:50%; background: radial-gradient(circle at 35% 30%, #fff9c4 0 18%, #ffe082 38%, #ffb300 72%, #ff8f00 100%); box-shadow: 0 0 24px rgba(255,193,7,.75), 0 0 60px rgba(255,152,0,.35); animation: sunGlow 4s ease-in-out infinite; } .sun-rays { position:absolute; left:50%; top:50%; width:10px; height:10px; margin:-5px; border-radius:50%; background:transparent; box-shadow: 0 -58px 0 0 #ffca28, 41px -41px 0 0 #ffca28, 58px 0 0 0 #ffca28, 41px 41px 0 0 #ffca28, 0 58px 0 0 #ffca28, -41px 41px 0 0 #ffca28, -58px 0 0 0 #ffca28, -41px -41px 0 0 #ffca28; animation: spin 14s linear infinite; } But box-shadow rays are circles (dots) not rays. Could make rays elongated by using a .sun-rays element with width:10px;height:26px; background: linear-gradient(#ffca28, rgba(255,202,40,0)); border-radius: 10px; box-shadow: 0 -70px 0 0? box-shadow copies same shape; if element is vertical ray at top, shadows around create 8 rays. Set .sun-rays { width:12px; height:28px; left:50%; top:50%; margin:-14px 0 0 -6px; transform-origin: 50% 60px? Hmm if rotate around center of icon, the ray element must be positioned at center and transform rotate; box-shadow offsets are relative to element, so they rotate with element if transform on element? Box-shadow is painted relative to element's border box before transform? Actually transforms apply to the element including its box-shadow? The box-shadow is part of element rendering and transforms with it. If we set element at center with box-shadow rays around, then rotate element, all rays rotate around element center. Good. Use .sun-rays { position:absolute; left:50%; top:50%; width:12px; height:26px; margin:-13px 0 0 -6px; border-radius:8px; background:linear-gradient(#ffe082, #ffb300); box-shadow: 0 -64px 0 0 #ffca28, 45px -45px 0 0 #ffca28, 64px 0 0 0 #ffca28, 45px 45px 0 0 #ffca28, 0 64px 0 0 #ffca28, -45px 45px 0 0 #ffca28, -64px 0 0 0 #ffca28, -45px -45px 0 0 #ffca28; animation: spin 16s linear infinite; } This yields one vertical ray plus 7 shadow rays (all same orientation vertical, but when rotated around center, vertical orientation remains vertical relative to element? Wait box-shadow offsets are in element's local coordinate; each shadow has same shape (vertical bar) at different offset. Rotating the element rotates the entire cluster, so bars remain radial? Let's visualize: one bar above center (offset 0,-64), its long axis vertical (along radius), good. Shadow at (45,-45) also vertical bar, but for a ray at 45°, its long axis should be along the radius (NE-SW), not vertical. Since all shadow copies are translated not rotated, their long axis stays vertical, so at diagonal positions they won't be radial; they'd look like parallel vertical bars arranged in circle, not sun rays. To make rays radial, each would need rotation, impossible with box-shadow. Alternative use conic-gradient ring with mask; it creates radial rays correctly. Use .sun-rays { position:absolute; inset:-6px; border-radius:50%; background: repeating-conic-gradient(from 0deg, #ffd54f 0deg 10deg, rgba(255,213,79,0) 10deg 30deg); -webkit-mask: radial-gradient(circle, transparent 0 34px, #000 35px 52px, transparent 53px); mask: radial-gradient(circle, transparent 0 34px, #000 35px 52px, transparent 53px); animation: spin 16s linear infinite; } This is CSS gradient/mask, no images. It will show rays as arc segments radial? Repeating-conic creates wedges; masked to annulus; rotating gives sun rays. Good. Need mask support in Chrome yes. Fallback: if mask unsupported, would be full circle of wedges maybe okay; but Chrome supports. Could also use radial mask. Fine.
But requirement "rotating sun rays" yes.
Rain icon: .icon--rain { position:relative; width:130px; height:120px; } .cloud { position:absolute; top:8px; left:50%; transform:translateX(-50%); width:86px; height:30px; background: linear-gradient(#f8fbff,#cfd8e3); border-radius: 999px; box-shadow: inset 0 -6px 0 rgba(90,110,140,.18); animation: cloudBob 5s ease-in-out infinite; } .cloud::before { content:""; position:absolute; left:14px; top:-22px; width:38px; height:38px; background:inherit; border-radius:50%; box-shadow: inset -5px -6px 0 rgba(90,110,140,.12);} .cloud::after { right:14px; top:-16px; width:30px;height:30px; ...} Need background inherit may not inherit gradient? background: inherit on pseudo inherits from cloud? yes but maybe use same gradient. Simpler set background same. Drops: .drop { position:absolute; top:58px; width:7px; height:16px; border-radius: 50% 50% 60% 60% / 40% 40% 60% 60%; background: linear-gradient(#b3e5fc, #29b6f6); transform: rotate(14deg); opacity:.9; animation: fall 1.4s linear infinite; } positions left: 38px, 56px, 74px, 92px with delays. But if base top 58 and animation from translateY(-8px) to translateY(58px), at animation running drops cycle. With reduced motion animation none, all drops at top 58 left positions, visible under cloud maybe a row; okay. Could set base opacity .85. Keyframes fall { from { transform: translate3d(0,-12px,0) rotate(14deg); opacity:0 } 15% {opacity:.95} to { transform: translate3d(6px,64px,0) rotate(14deg); opacity:0 } } Need each drop maybe different animation-duration. Good.
Snow: similar cloud but lighter; flakes .flake position absolute top:56px; width:16px;height:16px; background gradients as above; animation: drift 3.2s ease-in-out infinite; positions left 34/58/82/102? Keyframes drift { 0% { transform: translate3d(0,-10px,0) rotate(0deg); opacity:0 } 20% {opacity:1} 50% { transform: translate3d(8px,24px,0) rotate(160deg)} 100% { transform: translate3d(-6px,62px,0) rotate(320deg); opacity:0 } } But rotate on flake with background lines and pseudo rotates whole flake, good. Different delays/durations. Base top maybe 58. If reduced motion, visible row of flakes under cloud. Fine.
Storm: cloud dark + bolt. .icon--storm width 130 height 120. .cloud.storm { background: linear-gradient(#616a8c,#343a5e); } cloud pseudo same. Bolt: position absolute left:50%; top:52px; width:26px; height:52px; margin-left:-13px; background: linear-gradient(#fffde7, #ffd600); clip-path: polygon(62% 0, 18% 54%, 44% 54%, 30% 100%, 88% 38%, 56% 38%); filter: drop-shadow(0 0 8px rgba(255,235,59,.9)); animation: flash 2.2s ease-in-out infinite; } Keyframes flash { 0%, 55%, 100% {opacity:.12; transform: scale(.92)} 8%, 18%, 38% {opacity:1; transform: scale(1.06)} 25% {opacity:.25} } Need maybe lightning flashing: mostly off with flashes. Base opacity .12 so reduced motion shows faint bolt. Maybe better base opacity .9? Requirement flashing lightning; reduced motion should probably show static visible. If animation none, bolt at base opacity. Set base opacity:.95 so visible static. Keyframes can animate opacity. Good. Also maybe rain drops in storm? not necessary. Could add two drops? Not required. Keep storm with cloud + bolt. Maybe add dark rain? no.
Card content: city name (h2), temp (div.temp), description (p). Use °C. Cities: Cairo 38°, Reykjavík? Snowy maybe "Tromsø" -8°, Rainy "London" 12°, Stormy "Bangkok" 29°? Sunny "Cairo". Descriptions short. Need maybe weather label? fine.
Hover lift: transform translateY(-14px). But card children animations unaffected. Add cursor default. Use will-change maybe.
Need responsive: .grid { width:min(1180px, 100%); display:grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: clamp(14px, 2vw, 24px); } @media (max-width: 1020px) { grid-template-columns: repeat(2, minmax(0,1fr)); } @media (max-width: 600px) { grid-template-columns: 1fr; } At 375 one column. No horizontal scrollbar: body overflow-x:hidden; .card min-width:0.
Potential issue with card height in 800: header + 4 cards in one row. Card min-height maybe 300. Let's compute: body padding 28 top/bottom, header margin. If body display flex column justify center, total content height header 80 + gap 24 + card 320 = 424, fits. Good. At mobile, stacked 4 cards height ~4*300+header=1300, page scroll vertical okay; no horizontal. Screenshot at 1280x800 shows all four. Good.
Need maybe page background. Use body background: radial/linear gradient dark. But cards have own gradients. Body background can be neutral. Ensure contrast.
Need no JavaScript: ensure no word script? It's okay if CSS has no script. Avoid comments mentioning script? Comments okay but no <script>. We can include meta viewport. No inline handlers.
Need "HTML and CSS only" - file can have <style> only. Good.
Need maybe include <noscript>? Not needed.
Let's craft final code. Need exact one fenced code block. Ensure code block language html. No text before/after. Fine.
Double-check CSS pseudo-elements count and syntax.
Detailed CSS plan:
:root { --radius: 26px; }
* { box-sizing: border-box; }
html, body { margin:0; min-height:100%; }
body { font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif; background: radial-gradient(1200px 700px at 50% -10%, #263b63 0%, #101a2e 55%, #070b14 100%); color:#fff; min-height:100vh; overflow-x:hidden; display:flex; flex-direction:column; align-items:center; justify-content:center; gap: clamp(18px, 3vh, 34px); padding: clamp(20px, 4vw, 44px) clamp(16px, 4vw, 40px); }
.page-title { text-align:center; margin:0; } h1 { margin:0; font-size: clamp(1.6rem, 3.4vw, 2.6rem); letter-spacing:.02em; } .subtitle { margin:.45rem 0 0; color:#b9c7e8; font-size: clamp(.9rem, 1.6vw, 1rem); }
.grid { width: min(1160px, 100%); display:grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: clamp(14px, 1.8vw, 24px); }
.card { --ink:#fff; position:relative; min-height: 318px; padding: 26px 22px 24px; border-radius: var(--radius); overflow:hidden; color:var(--ink); box-shadow: 0 18px 40px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.35); transition: transform .38s cubic-bezier(.2,.8,.2,1), box-shadow .38s ease; transform: translateY(0); }
.card::after { content:""; position:absolute; inset:0; background: linear-gradient(115deg, rgba(255,255,255,.28), rgba(255,255,255,0) 38%); pointer-events:none; } maybe sheen.
.card:hover, .card:focus-visible { transform: translateY(-14px) scale(1.025); box-shadow: 0 32px 60px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.4); }
.card:focus-visible { outline: 3px solid rgba(255,255,255,.75); outline-offset:4px; } Cards not focusable (no tabindex) so focus not needed. Hover only.
.card--sunny { background: linear-gradient(160deg, #ffe082 0%, #ffb300 48%, #ff8f00 100%); --ink:#5b3a00; }
.card--rainy { background: linear-gradient(160deg, #90caf9 0%, #4f7cac 52%, #28435f 100%); --ink:#f2f8ff; }
.card--snowy { background: linear-gradient(160deg, #ffffff 0%, #d9ecff 48%, #a9cbe8 100%); --ink:#24435f; }
.card--stormy { background: linear-gradient(160deg, #7c6bb8 0%, #473a78 48%, #1d1738 100%); --ink:#f5f1ff; }
.scene { height: 132px; display:grid; place-items:center; margin: 2px 0 16px; position:relative; }
.icon { position:relative; width:132px; height:122px; }
Sun: .icon--sunny .rays { position:absolute; inset:2px; border-radius:50%; background: repeating-conic-gradient(from 0deg, #ffd54f 0 9deg, rgba(255,213,79,0) 9deg 30deg); -webkit-mask: radial-gradient(circle at center, transparent 0 35px, #000 36px 54px, transparent 55px); mask: radial-gradient(circle at center, transparent 0 35px, #000 36px 54px, transparent 55px); animation: spin 16s linear infinite; }
.icon--sunny .core { position:absolute; inset:34px; border-radius:50%; background: radial-gradient(circle at 34% 30%, #fffde7 0 16%, #ffee58 42%, #ffc400 72%, #ff9100 100%); box-shadow: 0 0 22px rgba(255,202,40,.9), 0 0 58px rgba(255,145,0,.45); animation: pulse 4.5s ease-in-out infinite; }
Need mask radial with px in 132 icon: center, transparent to 35, black 36-54, transparent 55. Since inset 2, radius ~63, annulus 35-54 leaves core inset 34 radius 32, good gap. Rays rotate.
@keyframes spin { to { transform: rotate(360deg); } } from default 0.
Clouds: .cloud { position:absolute; left:50%; top:6px; width:88px; height:32px; margin-left:-44px; border-radius:999px; background: linear-gradient(#ffffff, #d7e3f2); box-shadow: inset 0 -7px 0 rgba(70,95,130,.16), 0 10px 18px rgba(20,40,70,.18); animation: bob 5s ease-in-out infinite; }
.cloud::before, .cloud::after { content:""; position:absolute; border-radius:50%; background: inherit; box-shadow: inherit? } Can't inherit box-shadow maybe; set explicitly. .cloud::before { width:40px;height:40px; left:16px; top:-24px; background: linear-gradient(#fff,#e6eef7); } .cloud::after { width:32px;height:32px; right:16px; top:-18px; background: linear-gradient(#fff,#e6eef7); }
For storm cloud: .icon--stormy .cloud { background: linear-gradient(#7b84ad,#4a4f78); box-shadow: inset 0 -7px 0 rgba(10,10,35,.35), 0 10px 18px rgba(0,0,0,.35); } .icon--stormy .cloud::before, ... background: linear-gradient(#868fb4,#565b86); }
Precip container? Use drops directly in icon.
.rain .drop { position:absolute; top:56px; width:7px; height:17px; border-radius: 50% 50% 65% 65% / 35% 35% 65% 65%; background: linear-gradient(#e1f5fe, #29b6f6); opacity:.9; animation: rain-fall 1.35s linear infinite; }
.drop:nth-child? We'll place drops after cloud inside icon: <span class="cloud"></span><span class="drop" style? no inline style? Inline style is CSS? Requirement HTML and CSS only; inline style attributes are CSS but maybe allowed? They said CSS in <style>, everything inline; avoid style attributes. Use classes d1 d2 d3 d4. .d1 { left:42px; animation-delay:0s; animation-duration:1.25s; } etc. Since no inline style. Good.
@keyframes rain-fall { 0% { transform: translate3d(0,-14px,0) rotate(12deg); opacity:0; } 12% { opacity:.95; } 100% { transform: translate3d(8px,62px,0) rotate(12deg); opacity:0; } }
If base top 56, translate 62 -> 118 within icon height 122, okay. Some drop at left 96 maybe. Use 5 drops: left 36,54,72,90,108; durations 1.15,1.35,1.5,1.25,1.45; delays 0,.25,.5,.1,.65.
Snow flakes: .snow .flake { position:absolute; top:54px; width:16px; height:16px; background: linear-gradient(#fff,#fff) center/100% 2px no-repeat, linear-gradient(#fff,#fff) center/2px 100% no-repeat; opacity:.95; animation: snow-drift 3.4s ease-in-out infinite; }
.flake::before, .flake::after { content:""; position:absolute; inset:0; background: linear-gradient(#fff,#fff) center/100% 2px no-repeat; }
.flake::before { transform: rotate(60deg); } .flake::after { transform: rotate(120deg); }
Positions f1 left:36 top:58; f2 left:58 top:70; f3 left:80 top:52; f4 left:102 top:66; f5 left:48? maybe 5 flakes. Use classes. Keyframes snow-drift { 0% { transform: translate3d(0,-12px,0) rotate(0deg); opacity:0;} 18%{opacity:1;} 50% { transform: translate3d(10px,26px,0) rotate(180deg);} 100% { transform: translate3d(-8px,58px,0) rotate(360deg); opacity:0; } } Base transform none; reduced motion shows cross flakes at top positions. Good. Maybe background with #fff on snowy card (white card) invisible; but snow card background is light blue, flakes white with drop-shadow. Add filter: drop-shadow(0 1px 1px rgba(36,67,95,.35)). Good.
Storm bolt: .icon--stormy .bolt { position:absolute; left:50%; top:48px; width:30px; height:58px; margin-left:-15px; background: linear-gradient(#fffde7 0%, #ffee58 45%, #ffb300 100%); clip-path: polygon(64% 0, 16% 52%, 42% 52%, 28% 100%, 90% 36%, 58% 36%); filter: drop-shadow(0 0 10px rgba(255,235,59,.95)); opacity:.95; animation: lightning 2.4s ease-in-out infinite; }
@keyframes lightning { 0%, 100% { opacity:.14; transform: scale(.94); } 6%, 14% { opacity:1; transform: scale(1.08); } 22% { opacity:.2; transform: scale(.96); } 34%, 42% { opacity:1; transform: scale(1.05); } 55% { opacity:.18; } }
Base opacity .95 but animation overrides when running; reduced motion animation none -> opacity .95 visible. Good.
Maybe storm cloud should be above bolt; bolt top 48 under cloud. Fine.
Text: .city { margin:0; font-size: clamp(1.25rem, 2vw, 1.55rem); font-weight:800; letter-spacing:.01em; } .temp { margin:.25rem 0 .55rem; font-size: clamp(2.2rem, 3.4vw, 3rem); line-height:1; font-weight:850; } .desc { margin:0; font-size:.95rem; line-height:1.45; opacity:.88; max-width: 24ch; } For sunny dark ink, opacity .75 maybe. Fine.
Maybe add small badge? Not needed.
Media queries: @media (max-width: 1040px) { .grid { grid-template-columns: repeat(2, minmax(0,1fr)); width:min(720px,100%);} .card{min-height:300px;} } @media (max-width: 600px) { .grid { grid-template-columns: 1fr; width:min(420px,100%);} body { justify-content:flex-start; } .card { min-height: 280px; } .scene { height:120px; } } At 375, stacked. But requirement 4 per row desktop; at 1280 yes. At 1040 two columns, at 600 one. Good. Maybe at <=480 card padding smaller.
Reduced motion: @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; } .card:hover { transform:none; } } This will make animations run once quickly to final keyframe? With animation-fill-mode default none, after finishing, element returns to base styles. For drops, base opacity .9 top 56 visible row; fine. For rays, base transform none, rays annulus static; fine. For bolt, base opacity .95; fine. For core pulse base. Good. But animation-iteration-count 1 with infinite animations means they run once; okay. Some prefer animation: none !important. If animation:none, same base. Use animation: none !important for all? Then hover transition none. Simpler: @media (prefers-reduced-motion: reduce) { .rays,.core,.cloud,.drop,.flake,.bolt { animation: none !important; } .card { transition:none; } .card:hover { transform:none; } } This clearly stops. But requirement respect prefers-reduced-motion; this does. However if animation none on .drop, base top positions show a row of drops under cloud (since left classes and top 56). Good. For .flake base top varied, visible. Fine. Use universal to be safe: *,*::before,*::after { animation: none !important; transition: none !important; } .card:hover { transform: translateY(0); } But setting animation none on pseudo okay. This might hide? no. Use this.
Need no horizontal scrollbar: overflow-x hidden on body and html maybe. Set html { overflow-x:hidden; } body too. Grid width min. Good.
Need first paint: animations running immediately; CSS animations start at load. Good.
Potential issue: mask property with radial-gradient using px in mask; if `mask` shorthand with radial-gradient maybe okay. In Chrome, `mask: radial-gradient(...)` works? CSS mask shorthand accepts mask-image etc; radial-gradient is image, yes. Include -webkit-mask for safety. If both -webkit-mask and mask set, okay. Need mask-mode? default match-source for image? For radial-gradient (alpha), mask-mode default match-source? For <mask-source> maybe alpha? It should use alpha. Good.
Potential issue: repeating-conic-gradient support in Chrome yes.
Need ensure no SVG in code. We don't use. No images. No url. No icon fonts. Good.
Need maybe temperature degree symbol okay. City names with non-ASCII (Tromsø) fine.
Let's compose final. Keep code not too huge but complete. Need exactly one code block. Ensure no markdown text outside. Final channel only code block.
Let's write HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS Weather Cards</title>
<style>
...
</style>
</head>
<body>
<header class="page-head">
<h1>Four animated skies</h1>
<p class="subtitle">Pure HTML & CSS weather cards</p>
</header>
<main class="grid" aria-label="Weather cards">
<article class="card card--sunny">
<div class="scene" aria-hidden="true">
<div class="icon icon--sunny"><span class="rays"></span><span class="core"></span></div>
</div>
<h2 class="city">Cairo</h2>
<div class="temp">38°</div>
<p class="desc">Bright sunshine and hot desert air all day.</p>
</article>
... rainy: icon icon--rainy: <span class="cloud"></span><span class="drop d1"></span>... city London temp 12° desc "Steady showers with cool grey skies."
snowy: icon--snowy with cloud and flakes; city Tromsø temp -6° desc "Soft snow drifting over a quiet fjord town."
stormy: icon--stormy cloud + bolt; city Bangkok 29° desc "Heavy clouds, bright flashes and warm rain."
</main>
</body>
</html>
Need aria-hidden on scene okay (no event). Fine.
CSS details with classes. Need .icon--rainy .cloud etc. Since card classes card--rainy but icon icon--rainy. Use both.
Let's ensure .cloud::before background inherit? If .cloud has background gradient, pseudo background: inherit might inherit computed background-image? For pseudo, inherit takes from originating element? It should inherit background properties, but background is not inherited by default; `background: inherit` explicitly inherits, yes. But box-shadow inset maybe not. Simpler explicit.
Need cloud pseudo z-index? .cloud::before top -24 might extend above icon; scene height 132, icon height 122, cloud top 6, pseudo top -24 => y=-18 relative icon, within scene? Icon centered in scene height 132; icon top = (132-122)/2=5, pseudo absolute top -24 -> scene y = 5+6-24 = -13, overflows scene but card overflow hidden; could clip top of cloud. Hmm scene height 132, icon height 122 placed by grid center; cloud pseudo extends above icon by 24, so may be clipped by card? Card overflow hidden, but scene not overflow hidden; card padding 26, scene margin; icon top within card = padding 26 + scene top? scene y=26, icon y=31, cloud pseudo y=31+6-24=13, within card padding (top 13) okay not clipped. Good. Card overflow hidden only at border. Fine.
But .scene display grid place-items center; .icon height 122; scene height 132. Good.
For sun, rays inset 2 within icon height 122, annulus radius up to 55; icon half=61, fits. core inset 34 -> diameter 54, radius 27; mask inner transparent 35, gap 8. Good.
Rain drops left positions within icon width 132: d1 left 34, d2 52, d3 70, d4 88, d5 106. Drop width 7. Good. top base 58. Keyframe to translate y 62 -> 120, within icon height 122, opacity 0 at end. Good.
Snow flakes positions f1 left 34 top 56, f2 56 top 68, f3 78 top 50, f4 100 top 62, f5 62 top 82? Maybe too many; 5 okay. Keyframe to y 58 from base top up to 82 -> 140 > icon height, but opacity 0 at end; during may go beyond icon bottom but scene/card overflow? card overflow hidden, scene not overflow hidden, but icon not overflow hidden; drops can visually go into text area if animation translates beyond icon; card overflow hidden only at card border, so rain can fall into text area if too far. Keep translate end within icon: top base max 82 + 58 = 140 > icon bottom 122, would overlap city text maybe. Better set flake base tops around 52-66 and translate end 46 so max 112. Keyframes snow-drift to translate3d(-8px,46px) not 58. For rain base top 56 + 62 =118 okay. For snow, use top base 54-66 and keyframe to +44 => max 110. Good. Set snow-drift 100% translate3d(-8px,44px,0). 50% translate(10px,22px). Fine.
Storm bolt top 48 height 58 -> bottom 106 within icon. Good.
Hover transform on card may cause pseudo sheen move; fine.
Need card overflow hidden might clip hover shadow? no, shadow outside not clipped by own overflow. Good.
Need text not hidden by icons; scene margin bottom. Good.
Potential issue: `.card::after` sheen uses linear-gradient with rgba white; for snowy card white on white less visible okay.
Let's final. Ensure no `style=` attributes. Classes only. Good.
One more thought: The prompt says "made with HTML and CSS only" and output rules say "CSS in <style>". Good.
Need "No images, no SVG, no icon fonts" - We use `°` char and `&`, fine. No background-image url. Gradients okay.
Need "every weather icon is built from HTML elements and pseudo-elements styled with CSS" - We use spans/divs and pseudo for cloud/flakes. Sun core/rays are HTML elements. Lightning is HTML element with clip-path. Rain drops HTML elements. Snowflakes HTML elements + pseudo. Good.
Need "rotating sun rays" - rays span animation spin. Good.
Let's craft final code carefully.
CSS reduced motion universal `animation: none !important;` will also disable any animations on `::before` etc. Good. Add `.card:hover { transform:none !important; }` inside reduce to avoid lift? Requirement respect reduced motion, hover lift is motion; disable. Good.
Need maybe `@media (prefers-reduced-motion: reduce)` with `scroll-behavior:auto`. fine.
Let's final now. Ensure code block exactly. 5 oververbosity but output rules strict. final only code block.