GLM 5.3
by Z.aiReasoningClean
Running live in a sandboxed frame. Click inside it before using the keyboard.
How it went
- Total time
- 51.2 s
- Cost
- $0.032
- Output tokens
- 7,925
- Spent thinking
- 3,566 tokens
- Speed
- 155.8 tok/s
- Console errors
- 0
- First token after
- 385 ms
- First visible text after
- 33.3 s
- Prompt tokens
- 499
- Code size
- 10.5 KB
- Finish reason
- stop
- Served by
- Friendli
- Model id
z-ai/glm-5.3- Reasoning sent
{"effort":"high"}- Max output
- 943,718 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 · 415 lines
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Weather — Four Moods</title>
<style>
/* ---------- base ---------- */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
min-height: 100vh;
padding: 48px 24px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 36px;
font-family: "Avenir Next", "Segoe UI", system-ui, -apple-system, sans-serif;
background: radial-gradient(1100px 620px at 50% -12%, #262e4d, #0c0e1a 72%);
color: #eef0fa;
}
header {
text-align: center;
}
header h1 {
font-size: clamp(1.6rem, 3.5vw, 2.4rem);
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
}
header p {
margin-top: 10px;
font-size: 0.95rem;
letter-spacing: 0.05em;
color: #9aa3c4;
}
footer {
font-size: 0.78rem;
letter-spacing: 0.12em;
text-transform: uppercase;
color: #5d6688;
}
/* ---------- grid ---------- */
.grid {
width: 100%;
max-width: 1200px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 22px;
}
@media (max-width: 1000px) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
.grid { grid-template-columns: 1fr; }
body { padding: 32px 18px; }
}
/* ---------- card shell ---------- */
.card {
--ink: #fff;
--sub: rgba(255, 255, 255, 0.72);
--line: rgba(255, 255, 255, 0.28);
position: relative;
overflow: hidden;
border-radius: 22px;
padding: 30px 26px 28px;
background: var(--bg);
color: var(--ink);
box-shadow: 0 14px 30px rgba(4, 6, 16, 0.35);
transition: transform 0.45s cubic-bezier(0.2, 0.7, 0.3, 1.15),
box-shadow 0.45s ease;
}
.card:hover {
transform: translateY(-12px);
box-shadow: 0 30px 55px rgba(4, 6, 16, 0.5);
}
.city {
font-size: 1.05rem;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.temp {
margin-top: 14px;
font-size: 3.3rem;
font-weight: 700;
line-height: 1;
letter-spacing: -0.02em;
}
.temp sup {
font-size: 0.45em;
vertical-align: 0.9em;
font-weight: 500;
}
.desc {
margin-top: 10px;
font-size: 0.92rem;
line-height: 1.5;
color: var(--sub);
}
.hilo {
margin-top: 18px;
padding-top: 14px;
border-top: 1px solid var(--line);
font-size: 0.74rem;
font-weight: 600;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--sub);
display: flex;
justify-content: space-between;
}
/* ---------- shared icon stage ---------- */
.icon {
position: relative;
height: 104px;
margin-bottom: 24px;
}
/* ---------- cloud (built from div + pseudo-elements) ---------- */
.cloud {
position: absolute;
top: 16px;
left: 12px;
width: 86px;
height: 28px;
border-radius: 16px;
background: var(--cloud);
}
.cloud::before,
.cloud::after {
content: "";
position: absolute;
border-radius: 50%;
background: inherit;
}
.cloud::before {
width: 38px;
height: 38px;
left: 13px;
top: -19px;
}
.cloud::after {
width: 28px;
height: 28px;
left: 48px;
top: -13px;
}
/* ---------- SUN ---------- */
.sun {
position: absolute;
left: 6px;
top: 6px;
width: 90px;
height: 90px;
animation: spin 20s linear infinite;
}
.sun::before {
content: "";
position: absolute;
inset: 23px;
border-radius: 50%;
background: radial-gradient(circle at 35% 32%, #fff3b8, #ffd34e 52%, #ffb100);
box-shadow: 0 0 26px rgba(255, 196, 70, 0.8);
animation: pulse 3.2s ease-in-out infinite;
}
.ray {
position: absolute;
top: 0;
left: calc(50% - 3px);
width: 6px;
height: 15px;
border-radius: 3px;
background: linear-gradient(#ffe28a, #ffb63d);
transform-origin: 3px 45px;
}
.ray:nth-child(1) { transform: rotate(0deg); }
.ray:nth-child(2) { transform: rotate(45deg); }
.ray:nth-child(3) { transform: rotate(90deg); }
.ray:nth-child(4) { transform: rotate(135deg); }
.ray:nth-child(5) { transform: rotate(180deg); }
.ray:nth-child(6) { transform: rotate(225deg); }
.ray:nth-child(7) { transform: rotate(270deg); }
.ray:nth-child(8) { transform: rotate(315deg); }
/* ---------- RAIN DROPS ---------- */
.drop {
position: absolute;
top: 54px;
width: 4px;
height: 16px;
border-radius: 4px;
background: linear-gradient(180deg, rgba(215,235,255,0), #d7ebff 55%, #9cc7f2);
animation: fall 1.15s linear infinite;
}
.drop:nth-child(1) { left: 18px; }
.drop:nth-child(2) { left: 38px; animation-delay: 0.24s; }
.drop:nth-child(3) { left: 58px; animation-delay: 0.48s; }
.drop:nth-child(4) { left: 78px; animation-delay: 0.1s; }
.drop:nth-child(5) { left: 98px; animation-delay: 0.36s; }
/* ---------- SNOWFLAKES ---------- */
.flake {
position: absolute;
top: 50px;
width: 8px;
height: 8px;
border-radius: 50%;
background: #ffffff;
box-shadow: 0 0 7px rgba(255, 255, 255, 0.95);
animation: drift 3.4s ease-in-out infinite;
}
.flake:nth-child(1) { left: 16px; animation-delay: 0s; }
.flake:nth-child(2) { left: 40px; animation-delay: 0.9s; }
.flake:nth-child(3) { left: 64px; animation-delay: 1.8s; }
.flake:nth-child(4) { left: 88px; animation-delay: 0.5s; }
.flake:nth-child(5) { left: 108px; animation-delay: 2.4s; }
.flake:nth-child(6) { left: 30px; animation-delay: 2.9s; width: 6px; height: 6px; }
/* ---------- LIGHTNING ---------- */
.bolt {
position: absolute;
left: 46px;
top: 44px;
width: 36px;
height: 54px;
background: linear-gradient(180deg, #fff8b5, #ffd23c 45%, #ff9c2c);
clip-path: polygon(38% 0%, 95% 0%, 48% 46%, 92% 46%, 8% 100%, 40% 54%, 5% 54%);
filter: drop-shadow(0 0 10px rgba(255, 214, 92, 0.85));
animation: flash 2.8s infinite;
}
.storm-drops .drop:nth-child(1) { left: 20px; animation-duration: 0.9s; }
.storm-drops .drop:nth-child(2) { left: 96px; animation-duration: 1.05s; animation-delay: 0.4s; }
/* ---------- card themes ---------- */
.card--sunny {
--bg: linear-gradient(168deg, #ffe49a 0%, #ffbe63 52%, #ff9752 100%);
--ink: #50260a;
--sub: rgba(80, 38, 10, 0.68);
--line: rgba(80, 38, 10, 0.25);
}
.card--rainy {
--bg: linear-gradient(168deg, #5d7fa6 0%, #3c5a7d 55%, #27405c 100%);
--cloud: #e8f0f8;
}
.card--snowy {
--bg: linear-gradient(168deg, #c9e6ff 0%, #93bfe8 55%, #6f9fd4 100%);
--ink: #123a63;
--sub: rgba(18, 58, 99, 0.68);
--line: rgba(18, 58, 99, 0.25);
--cloud: #f4faff;
}
.card--stormy {
--bg: linear-gradient(168deg, #43466b 0%, #2b2c4c 55%, #17182e 100%);
--cloud: #4b4f78;
}
.card--stormy .cloud::before,
.card--stormy .cloud::after {
filter: brightness(1.18);
}
/* ---------- keyframes ---------- */
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.07); }
}
@keyframes fall {
0% { transform: translateY(0); opacity: 0; }
14% { opacity: 1; }
82% { opacity: 1; }
100% { transform: translateY(40px); opacity: 0; }
}
@keyframes drift {
0% { transform: translate(0, 0); opacity: 0; }
12% { opacity: 1; }
50% { transform: translate(5px, 18px); }
86% { opacity: 1; }
100% { transform: translate(-4px, 38px); opacity: 0; }
}
@keyframes flash {
0%, 40%, 47%, 60%, 100% { opacity: 0.12; }
42%, 44% { opacity: 1; }
57% { opacity: 0.85; }
}
/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation: none !important;
transition: none !important;
}
.card:hover {
transform: none;
}
.bolt { opacity: 1; }
.drop { top: 78px; opacity: 1; }
.flake { top: 84px; opacity: 1; }
}
</style>
</head>
<body>
<header>
<h1>Weather · Four Moods</h1>
<p>Animated forecasts built from pure HTML elements and CSS — no images, no SVG, no JavaScript.</p>
</header>
<main class="grid">
<!-- SUNNY -->
<article class="card card--sunny">
<div class="icon" aria-hidden="true">
<div class="sun">
<span class="ray"></span><span class="ray"></span><span class="ray"></span><span class="ray"></span>
<span class="ray"></span><span class="ray"></span><span class="ray"></span><span class="ray"></span>
</div>
</div>
<h2 class="city">Valencia</h2>
<p class="temp">29<sup>°C</sup></p>
<p class="desc">Bright and cloudless with a warm breeze drifting in from the sea.</p>
<div class="hilo"><span>H 31°</span><span>L 21°</span></div>
</article>
<!-- RAINY -->
<article class="card card--rainy">
<div class="icon" aria-hidden="true">
<div class="cloud"></div>
<span class="drop"></span><span class="drop"></span><span class="drop"></span>
<span class="drop"></span><span class="drop"></span>
</div>
<h2 class="city">Portland</h2>
<p class="temp">14<sup>°C</sup></p>
<p class="desc">Steady showers all afternoon — keep the umbrella close at hand.</p>
<div class="hilo"><span>H 16°</span><span>L 9°</span></div>
</article>
<!-- SNOWY -->
<article class="card card--snowy">
<div class="icon" aria-hidden="true">
<div class="cloud"></div>
<span class="flake"></span><span class="flake"></span><span class="flake"></span>
<span class="flake"></span><span class="flake"></span><span class="flake"></span>
</div>
<h2 class="city">Reykjavík</h2>
<p class="temp">-3<sup>°C</sup></p>
<p class="desc">Gentle snow drifting down over quiet, frost-covered streets.</p>
<div class="hilo"><span>H 0°</span><span>L -8°</span></div>
</article>
<!-- STORMY -->
<article class="card card--stormy">
<div class="icon" aria-hidden="true">
<div class="cloud"></div>
<span class="bolt"></span>
<span class="drop"></span><span class="drop"></span>
</div>
<h2 class="city">New Orleans</h2>
<p class="temp">22<sup>°C</sup></p>
<p class="desc">Thunder rolling overhead with frequent lightning strikes nearby.</p>
<div class="hilo"><span>H 26°</span><span>L 19°</span></div>
</article>
</main>
<footer>Hover a card to lift it · 100% HTML + CSS</footer>
</body>
</html>Reasoning trace (3,566 tokens)
Create HTML/CSS-only weather cards. Icons built from divs and pseudo-elements. Four cards: sunny, rainy, snowy, stormy. Animations: rotating sun rays, falling rain drops, drifting snowflakes, flashing lightning. Responsive grid, hover lift, prefers-reduced-motion.
Need rain drops and snowflakes from HTML elements — can add a few divs for drops/flakes inside the icon. No SVG, no images.
Let me design:
Sun: circle core with ::before/::after? Rays: a container div with 8 rays via pseudo-elements... Better: core circle (div.sun-core) plus ray container rotating, rays made from repeating child divs. I can use child divs for rays — 8 spans, each rotated. That's fine HTML.
Rain: cloud (div with ::before/::after bumps) plus drop spans animating translateY with staggered animation-delay.
Snow: cloud + snowflake dots drifting down with sway.
Storm: dark cloud + lightning bolt built from... a bolt shape via clip-path on a div, flashing with opacity keyframes.
Background gradients per card. Grid: repeat(auto-fit, minmax(240px,1fr)) — 4 per row desktop at 1280 (4 cards fit). Actually with fixed 4 cards, use grid-template-columns: repeat(4, 1fr) with media query to 1 column on mobile (or 2 at mid). Hover translateY lift.
Reduced motion: disable animations.
Keep it polished: nice typography, subtle details. Let me write the code.
Bolt via clip-path polygon: polygon(40% 0, 100% 0, 55% 45%, 85% 45%, 20% 100%, 45% 55%, 10% 55%) roughly. Let me craft: classic bolt: polygon(45% 0%, 100% 0%, 50% 50%, 90% 50%, 15% 100%, 40% 60%, 5% 60%). Good enough.
Sun rays: 8 spans each 6px tall bars positioned top center, transform rotate(i*45deg) translateY. Use nth-child to rotate. Also add pulse scale on core.
Rain drops: teardrop via border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%? Simpler: small rounded bar with border-radius 0 0 50% 50% — elongated drop. Animate translateY from cloud bottom down, fade.
Snowflakes: small white circles, translate down with horizontal sway (use two animations or single keyframe with translate both).
Card design: rounded cards, temperature big, city name, description. Maybe a "feels like" or hi/lo small detail. Add subtle animated background layers? Keep icons in an icon stage area.
Let me write.
CSS variables per card for accent colors.
Structure:
<section class="weather-grid">
<article class="card card--sunny">
<div class="icon icon--sun"> ... </div>
<h2 class="city">...</h2>
<p class="temp">...</p>
<p class="desc">...</p>
<div class="meta">...</div>
</article>
...
</section>
Header with title.
Sun icon:
<div class="icon icon-sun">
<div class="sun">
<span class="ray"></span> ×8
</div>
</div>
.sun { position relative, width/height 90px, core via ::before circle; rays positioned absolute at center, transform-origin bottom... } Each ray: position absolute, left 50%, top 0, width 6px, height 100%?? Simpler: ray is a child span: absolute, left calc(50% - 3px), top: 0, width 6, height 18, background, border-radius, transform-origin: center calc offset. Better: rays as full-height spans with a bar rendered via ::before at top? Hmm, each ray span: absolute inset 0? Alternative: ray span width 6px height 50% of container, top 0, left 50% - 3px, transform-origin: 3px 45px (center). Then rotate nth-child.
Container .sun: 90×90. Core: ::before circle 40px centered. Rays container: wrap all rays in .rays div that rotates slowly (spin). Each ray height 90px? Ray: position absolute; top:0; left:calc(50% - 3px); width:6px; height:90px; background transparent; ::before at top: bar 6×16 at top. Actually simpler: ray itself is 6px wide, 16px tall, positioned top:0 left calc(50% - 3px), transform-origin: 3px 45px. Then nth-child rotations 0,45,...315. The .rays wrapper spins 20s linear infinite. Rays could also pulse. Good.
Cloud shape: .cloud div width 80 height 26, border-radius 13px, background; ::before circle 34px at left top overlapping; ::after circle 26px right. Standard CSS cloud.
Cloud with ::before/::after needs background matching. Position: cloud base at bottom.
Rain drops: spans inside .icon-rain below cloud. .drop { width:5px; height:14px; border-radius: 0 0 6px 6px... } Actually classic: border-radius: 50% 50% 50% 50% / 30% 30% 70% 70% gives teardrop? Let me just use border-radius: 0 0 5px 5px with rounded top too: border-radius: 3px; simple bars look fine as rain streaks. Or teardrop: border-radius: 50% 50% 50% 50% / 25% 25% 75% 75%? A common CSS raindrop: border-radius: 0 50% 50% 50%; transform rotate(45deg) — that's a drop pointing up. Simplest attractive: rounded-bottom streaks. I'll use teardrops: width 8 height 8 background, border-radius 50% 50% 50% 50% / 60% 60% 40% 40%... Let me just do streak: width 4, height 16, border-radius 4px, with gradient fade. Fine.
Stagger delays via nth-child.
Snow: .flake spans, circles 8px, animate fall with sway using keyframes translate(0,0)→(4px,15px)→(-4px,30px)→... ends at translateY(40px), opacity fade.
Storm: dark cloud + bolt div with clip-path, flash animation opacity steps + maybe a flash overlay on card? Keep bolt flashing: keyframes flicker.
Backgrounds:
- sunny: linear-gradient warm amber/sky
- rainy: slate blue-gray
- snowy: pale ice blue
- stormy: dark indigo
Hover: translateY(-10px) + shadow, transition. Also maybe icon scales.
Reduced motion: @media (prefers-reduced-motion: reduce) { *,*::before,*::after { animation: none !important; transition: none !important } }
Responsive: grid-template-columns: repeat(4, 1fr); @media max-width 1024: 2 cols; max-width 560: 1 col. At 1280 wide four cards of ~280px each — fine.
Also demo note? No JS required, it's static animation — always visible. Fine.
Add fonts: system stack. Add a small footer hint? Keep header: "Weather — Four Moods" etc.
Let me write full code.
Extra details: temperature with degree symbol, hi/lo. Small tag like "H:24° L:16°".
Card text colors: white-ish on darker cards; for snowy light card maybe dark text? Snowy gradient light icy — use dark navy text? Keep snowy background as medium blue-to-pale with white text with shadow. Let's do:
- sunny: #FFB25E → #FF8A5C? Actually gradient top to bottom: linear-gradient(160deg, #ffd194, #ff8a59)? Text dark? White text with dark shadow works on orange. Use #2b1a3a? Let's make text white on all but add slight shadow; snowy: gradient #a8c8f0 → #e8f4ff too light for white. Use gradient #7fa8d9 → #b8d8f0 white text okay-ish. Or give snowy darker text: #16324f. I'll give each card a --text and --sub variable.
Sunny text: #5b2a12? On warm amber, dark brown text reads nice. Hmm mixed text colors fine since each card defines vars.
Sunny: bg linear-gradient(165deg, #FFE29A 0%, #FFA85C 100%)? text #6b2d0e... Let's pick: text #4a2508, sub rgba(74,37,8,.65). Nice.
Rainy: bg linear-gradient(165deg, #4b6cb7, #2b3a67)? Actually rain mood: #5C7C9E → #2F4858. text white.
Snowy: bg linear-gradient(165deg, #BFE3FF, #7FB3E8)? text #14406b.
Stormy: bg linear-gradient(165deg, #3a3a5c, #17172b)? Dark indigo. text #e8e8f5.
Alright, write it.
Bolt clip-path: polygon(32% 0%, 78% 0%, 52% 38%, 82% 38%, 22% 100%, 42% 52%, 12% 52%) — check: starts top-left-ish, top-right, mid-right going down... Common bolt: polygon(40% 0, 100% 0, 45% 50%, 90% 50%, 10% 100%, 35% 55%, 5% 55%). I'll use that. Yellow gradient background on bolt.
Flash animation:
@keyframes flash { 0%,55%,60%,100% {opacity:.25} 56%,58% {opacity:1} 70%{opacity:.9} 72%{opacity:.3} } — something irregular.
Also add a subtle glow behind bolt via filter drop-shadow.
Also maybe rain card cloud drips... fine.
Icon stage: height 110px, display flex center, margin-bottom.
Rain drops positioning: absolute inside icon relative to stage. Place drops at left offsets 25%,45%,65% etc, top ~ cloud bottom. Use absolute positioning with left: calc(...). I'll position via nth-child left values.
Icon container: position relative; width 140px; height 110px; margin auto.
Rain icon: cloud centered top. Drops: 5 drops.
Let me code.
.card:hover .icon maybe slight scale? Add.
Also add small "wind lines" on sunny? Skip.
Write final HTML.
Ensure no <script>. Include header with page title and subtitle.
Reduced motion also pauses spin etc.
Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Four Moods of Weather</title>
<style>
:root{--radius:22px}
*{box-sizing:border-box;margin:0;padding:0}
body{
font-family:'Avenir Next','Segoe UI',system-ui,sans-serif;
min-height:100vh;
background:#0e1220 radial-gradient? Actually background: #12141f with subtle gradient;
display:flex;flex-direction:column;align-items:center;justify-content:center;
padding:40px 24px;
background: radial-gradient(1200px 600px at 50% -10%, #232a44, #0d0f1a 70%);
}
header text-align center margin-bottom.
h1 letter-spacing etc color #f0ecf7.
.grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;width:100%;max-width:1200px}
media queries.
.card{border-radius; padding:34px 26px 30px; position:relative; overflow:hidden; box-shadow:0 12px 28px rgba(0,0,0,.28); transition: transform .45s cubic-bezier(.2,.7,.3,1.2), box-shadow .45s; text-align:center? or left. Left-aligned with icon centered maybe. I'll center everything for cleanliness. Actually left-aligned looks designed. Let's do left: icon stage left-aligned too. Hmm centered icons simpler with absolute positioning? No, absolute positioning works regardless. I'll left-align content.
Hover: transform translateY(-12px); box-shadow bigger. Also a ::after highlight sheen? optional.
Text colors via vars:
.card{color:var(--ink)}
.city{font-size:1.15rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase}
.temp{font-size:3.4rem;font-weight:700;line-height:1}
sup ° smaller.
.desc{font-size:.95rem;color:var(--sub);line-height:1.45}
.hilo{font-size:.8rem;letter-spacing:.08em;text-transform:uppercase;color:var(--sub);margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
Icons.
.icon{position:relative;height:96px;margin-bottom:26px}
Sun:
.sun{position:absolute;left:8px;top:4px;width:88px;height:88px;animation:spin 18s linear infinite}
.sun::before core circle.
Actually core: .sun-core as ::before: content:'';position:absolute;inset:22px;background:radial-gradient(circle at 35% 35%, #fff2b0, #ffcf3f 55%, #ffb300);border-radius:50%;box-shadow:0 0 24px rgba(255,190,60,.75); animation: pulse 3.2s ease-in-out infinite.
.ray{position:absolute;top:0;left:calc(50% - 3px);width:6px;height:88px;transform-origin:50% 44px} — with rotate around center: origin should be center of 88 box: 44px. ray element height 88 but visible part only top bar via... hmm if height 88 and background full it'd be a line across. Instead: ray height 16px, top 0, transform-origin: 3px 44px (center). width 6, background gradient, border-radius 3px.
.ray:nth-child(1){transform:rotate(0deg)} ... 8 at 45deg steps. Also animation delay stagger? The whole .sun spins so no need.
Pulse core also scale slightly.
@keyframes spin{to{transform:rotate(360deg)}}
Cloud base class:
.cloud{position:absolute;width:84px;height:28px;border-radius:16px;top:14px;left:10px}
.cloud::before{content:'';position:absolute;width:36px;height:36px;border-radius:50%;left:12px;top:-18px}
.cloud::after{... width:28px;height:28px;left:46px;top:-12px}
Background set per card via variable --cloud.
Rain drops:
.drop{position:absolute;top:52px;width:4px;height:15px;border-radius:4px;background:linear-gradient(#cfe8ff,#7fb8e8);animation:fall 1.1s linear infinite}
nth-child left/delay: 5 drops at left 16,36,56,76,96 px? Icon width ~140. cloud spans left 10 to 94. drops left: 18,38,58,78,98? width 140 okay. delays: 0,.22,.44,.1,.33.
@keyframes fall{0%{transform:translateY(0);opacity:0}15%{opacity:1}80%{opacity:1}100%{transform:translateY(38px);opacity:0}}
Snowflakes: .flake{position:absolute;top:50px;width:8px;height:8px;border-radius:50%;background:#fff;box-shadow:0 0 6px rgba(255,255,255,.9);animation:drift 3.2s ease-in-out infinite}
@keyframes drift{0%{transform:translate(0,0);opacity:0}12%{opacity:1}50%{transform:translate(5px,18px)}88%{opacity:1}100%{transform:translate(-4px,36px);opacity:0}}
nth-child lefts and delays.
Storm bolt:
.bolt{position:absolute;left:44px;top:46px;width:34px;height:52px;background:linear-gradient(#fff7ae,#ffd23c 45%,#ff9d2e);clip-path:polygon(38% 0,95% 0,48% 46%,92% 46%,8% 100%,40% 54%,5% 54%);animation:flash 2.6s infinite;filter:drop-shadow(0 0 10px rgba(255,214,92,.8))}
@keyframes flash{0%,42%,48%,56%,100%{opacity:.15}44%,46%{opacity:1}54%{opacity:.85}}
Check clip-path: polygon points (38%,0),(95%,0),(48%,46%),(92%,46%),(8%,100%),(40%,54%),(5%,54%). Sequence: top edge from 38 to 95; down-left to 48,46; right to 92,46; diagonal down-left to 8,100; up to 40,54; left to 5,54; back to 38,0? Closing back to first point (38,0) — the segment from (5,54) to (38,0) is the left slanted edge. Looks like a bolt. Good.
Also stormy rain? Add two drops maybe on storm too — yes add drops to storm card as well for interest. Sure, add 3 drops.
Cloud colors: rainy cloud #e6eef7 whiteish; storm cloud #3a3f5c darker with slightly lighter top? just #454b6e.
Icon container heights: storm bolt extends to ~98, height 100px fine. Set .icon height 108 maybe. Bolt top:46 +52=98. Fine.
Hi/Lo lines: --line rgba colors.
Also give cards decorative ::before radial glow? e.g., sunny card sun glow. Keep simple.
Media queries:
@media (max-width:1000px){.grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.grid{grid-template-columns:1fr}}
Reduced motion:
@media (prefers-reduced-motion:reduce){
*,*::before,*::after{animation:none!important;transition:none!important}
.card:hover{transform:none}
}
Header: h1 "Weather, in Four Moods" + p subtitle.
Also maybe footer small note "Pure HTML + CSS — no JavaScript". Nice touch.
Write it all out.