Models 44

MiMo-V2.6-Flash

by Xiaomireasoning defaultClean
Open in new window

Running live in a sandboxed frame. Click inside it before using the keyboard.

How it went

Total time
3 min 9 s
Cost
$0.0046
Output tokens
16,289
Spent thinking
10,408 tokens
Speed
86.6 tok/s
Console errors
0
First token after
468 ms
First visible text after
2 min 36 s
Prompt tokens
502
Code size
15.2 KB
Finish reason
stop
Served by
Cohere
Model id
xiaomi/mimo-v2.6-flash
Reasoning sent
model default
Max output
131,072 tokens
Generated
Nov 13, 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 · 401 lines

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Weather Cards — HTML &amp; CSS Only</title>
<style>
/* ============ BASE ============ */
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  min-height:100vh;
  font-family:"Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;
  color:#e9eefb;
  background:
    radial-gradient(1100px 620px at 12% -12%, #1e2c56 0%, rgba(30,44,86,0) 62%),
    radial-gradient(900px 560px at 92% 112%, #2a3358 0%, rgba(42,51,88,0) 60%),
    linear-gradient(180deg,#090d1a 0%,#101730 55%,#090d18 100%);
  -webkit-font-smoothing:antialiased;
}
.page{max-width:1220px;margin:0 auto;padding:46px 22px 54px}

/* ============ HEADER ============ */
.head{text-align:center;margin-bottom:34px}
.eyebrow{
  display:inline-flex;align-items:center;gap:9px;margin:0 0 12px;
  font-size:11px;letter-spacing:.26em;text-transform:uppercase;font-weight:700;
  color:#8fb2ff;
}
.eyebrow::before{
  content:"";width:8px;height:8px;border-radius:50%;
  background:linear-gradient(180deg,#ffe27a,#ff9d2e);
  box-shadow:0 0 12px rgba(255,180,60,.9);
}
.head h1{
  margin:0;font-size:clamp(30px,5.4vw,46px);font-weight:800;
  letter-spacing:-.03em;
  background:linear-gradient(180deg,#ffffff 20%,#a9bbf0 110%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.sub{margin:12px auto 0;max-width:560px;font-size:14.5px;line-height:1.6;color:#9aa8cc}

/* ============ GRID ============ */
.grid{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:20px;
}
@media (max-width:1080px){.grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){.grid{grid-template-columns:1fr;gap:18px}}

/* ============ CARD SHELL ============ */
.card{
  position:relative;min-width:0;overflow:hidden;
  display:flex;flex-direction:column;
  border-radius:26px;
  box-shadow:0 22px 44px -24px rgba(0,0,0,.95), inset 0 1px 0 rgba(255,255,255,.35);
  transition:transform .45s cubic-bezier(.2,.8,.2,1), box-shadow .45s cubic-bezier(.2,.8,.2,1);
  outline:none;
}
.card::after{
  content:"";position:absolute;inset:0;z-index:5;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.20),rgba(255,255,255,0) 34%);
}
.card:hover,.card:focus-visible{
  transform:translateY(-14px);
  box-shadow:0 40px 66px -28px rgba(0,0,0,1), inset 0 1px 0 rgba(255,255,255,.5);
}

/* per-card gradients */
.sunny {background:linear-gradient(155deg,#ffeeb0 0%,#ffcf57 46%,#ff9a3b 100%);color:#5d2c00}
.rainy {background:linear-gradient(155deg,#c3daf7 0%,#5f92d8 48%,#31548e 100%);color:#ffffff}
.snowy {background:linear-gradient(155deg,#ffffff 0%,#ddefff 48%,#9ac4ee 100%);color:#0f3863}
.storm {background:linear-gradient(155deg,#4d5779 0%,#2b3352 52%,#12172c 100%);color:#eaeeff}

/* ============ SCENE ============ */
.scene{position:relative;height:178px;overflow:hidden}
.scene::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 92% at 50% 0%,rgba(255,255,255,.30),rgba(255,255,255,0) 72%);
}

/* ---------- SUNNY ---------- */
.glow{
  position:absolute;left:50%;top:50%;width:230px;height:230px;
  transform:translate(-50%,-50%);
  background:radial-gradient(circle,rgba(255,255,255,.75) 0%,rgba(255,241,170,.35) 40%,rgba(255,255,255,0) 68%);
  animation:pulse 4.2s ease-in-out infinite;
}
.sun{position:absolute;left:50%;top:50%;width:150px;height:150px;transform:translate(-50%,-50%)}
.core{
  position:absolute;left:50%;top:50%;width:76px;height:76px;margin:-38px 0 0 -38px;
  border-radius:50%;
  background:radial-gradient(circle at 32% 26%,#fff9cf 0%,#ffd64a 46%,#ff9c19 100%);
  box-shadow:0 0 0 9px rgba(255,214,70,.30),0 0 44px rgba(255,168,40,.85);
  animation:breathe 3.8s ease-in-out infinite;
}
.rays{position:absolute;inset:0;animation:spin 17s linear infinite}
.rays i{
  position:absolute;left:50%;top:50%;display:block;
  width:6px;height:32px;margin-left:-3px;margin-top:-68px;
  transform-origin:3px 68px;border-radius:4px;
  background:linear-gradient(180deg,#fff3b0,#ffab16);
  animation:twinkle 2.6s ease-in-out infinite;
}
.rays i:nth-child(1){transform:rotate(0deg)}
.rays i:nth-child(2){transform:rotate(45deg) scale(.72);animation-delay:.3s}
.rays i:nth-child(3){transform:rotate(90deg);animation-delay:.6s}
.rays i:nth-child(4){transform:rotate(135deg) scale(.72);animation-delay:.9s}
.rays i:nth-child(5){transform:rotate(180deg);animation-delay:1.2s}
.rays i:nth-child(6){transform:rotate(225deg) scale(.72);animation-delay:1.5s}
.rays i:nth-child(7){transform:rotate(270deg);animation-delay:1.8s}
.rays i:nth-child(8){transform:rotate(315deg) scale(.72);animation-delay:2.1s}

/* ---------- CLOUD (rain / snow / storm) ---------- */
.cloud{
  position:absolute;left:50%;top:44px;width:132px;height:46px;margin-left:-66px;
  border-radius:26px;
  background:linear-gradient(180deg,#f4f9ff 0%,#c6d6ee 100%);
  box-shadow:0 16px 26px -14px rgba(8,22,48,.6);
}
.cloud .puff{position:absolute;display:block;border-radius:50%;
  background:radial-gradient(circle at 34% 28%,#ffffff 0%,#e6eefb 55%,#cfddf2 100%)}
.cloud .p1{width:70px;height:70px;left:8px;top:-34px}
.cloud .p2{width:50px;height:50px;right:14px;top:-24px}
.snowy .cloud{background:linear-gradient(180deg,#ffffff 0%,#e2edfa 100%)}
.snowy .cloud .puff{background:radial-gradient(circle at 34% 28%,#ffffff 0%,#f1f8ff 58%,#dceaf9 100%)}
.storm .cloud{
  background:linear-gradient(180deg,#5b668c 0%,#2f3858 100%);
  box-shadow:0 18px 30px -14px rgba(0,0,0,.75);
}
.storm .cloud .puff{background:radial-gradient(circle at 34% 28%,#7e8ab1 0%,#4b5679 60%,#333d5e 100%)}

/* ---------- RAIN ---------- */
.rain{position:absolute;left:0;right:0;top:100px;height:78px}
.rain i{
  position:absolute;display:block;width:4px;height:20px;border-radius:4px;
  background:linear-gradient(180deg,rgba(255,255,255,0) 0%,#dcefff 34%,#6fb2ff 100%);
  box-shadow:0 0 6px rgba(120,185,255,.55);
  transform:rotate(10deg);opacity:1;
  animation:fall 1.1s linear infinite;
}
.rain i:nth-child(1){left:14%;top:0;animation-duration:1.05s;animation-delay:0s}
.rain i:nth-child(2){left:27%;top:24px;animation-duration:1.25s;animation-delay:-.4s}
.rain i:nth-child(3){left:39%;top:8px;animation-duration:.95s;animation-delay:-.7s}
.rain i:nth-child(4){left:51%;top:34px;animation-duration:1.15s;animation-delay:-.2s}
.rain i:nth-child(5){left:63%;top:4px;animation-duration:1.3s;animation-delay:-.9s}
.rain i:nth-child(6){left:75%;top:28px;animation-duration:1s;animation-delay:-.55s}
.rain i:nth-child(7){left:87%;top:12px;animation-duration:1.2s;animation-delay:-.3s}
.rain i:nth-child(8){left:33%;top:52px;animation-duration:1.1s;animation-delay:-.85s}
.storm .rain i{animation-name:fallFast}

/* ---------- SNOW ---------- */
.snow{position:absolute;left:0;right:0;top:0;bottom:0}
.snow > i{position:absolute;display:block;top:0;animation:flakeFall 9s linear infinite}
.snow > i:nth-child(1){left:11%;top:2px;animation-duration:9s;animation-delay:0s}
.snow > i:nth-child(2){left:25%;top:30px;animation-duration:11s;animation-delay:-3.4s}
.snow > i:nth-child(3){left:39%;top:62px;animation-duration:9.6s;animation-delay:-6.1s}
.snow > i:nth-child(4){left:53%;top:96px;animation-duration:12s;animation-delay:-1.8s}
.snow > i:nth-child(5){left:66%;top:128px;animation-duration:10.2s;animation-delay:-7.6s}
.snow > i:nth-child(6){left:80%;top:156px;animation-duration:11.4s;animation-delay:-4.7s}
.snow > i:nth-child(7){left:47%;top:172px;animation-duration:10.6s;animation-delay:-9s}
.snow i > span{
  position:relative;display:block;width:15px;height:3.5px;border-radius:3px;
  background:#ffffff;box-shadow:0 0 7px rgba(255,255,255,.9);
  animation:sway 3.6s ease-in-out infinite;
}
.snow i > span::before,.snow i > span::after{
  content:"";position:absolute;inset:0;border-radius:3px;background:#ffffff;
}
.snow i > span::before{transform:rotate(60deg)}
.snow i > span::after{transform:rotate(-60deg)}
.snow > i:nth-child(2) > span{width:11px;animation-delay:-.6s}
.snow > i:nth-child(3) > span{width:18px;animation-delay:-1.2s}
.snow > i:nth-child(4) > span{width:9px;animation-delay:-1.8s}
.snow > i:nth-child(5) > span{width:14px;animation-delay:-2.4s}
.snow > i:nth-child(6) > span{width:12px;animation-delay:-3s}
.snow > i:nth-child(7) > span{width:16px;animation-delay:-.9s}

/* ---------- STORM: lightning + sky flash ---------- */
.bolt{
  position:absolute;left:50%;top:92px;width:34px;height:64px;margin-left:-18px;
  background:linear-gradient(180deg,#fffbe0 0%,#ffe066 55%,#ffab12 100%);
  clip-path:polygon(60% 0,12% 58%,46% 58%,26% 100%,92% 40%,55% 40%);
  filter:drop-shadow(0 0 14px rgba(255,222,110,.95));
  opacity:1;animation:boltFlash 3.2s ease-in-out infinite;
}
.storm .scene::before{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(198,214,255,.05),rgba(150,175,255,.35));
  opacity:0;animation:skyFlash 3.2s ease-in-out infinite;
}

/* ============ INFO ============ */
.info{position:relative;padding:2px 22px 24px;z-index:3}
.row{display:flex;align-items:center;justify-content:space-between;gap:10px}
.city{
  margin:0;font-size:13px;font-weight:800;letter-spacing:.2em;
  text-transform:uppercase;opacity:.9;
}
.tag{
  flex:none;font-size:10px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  padding:5px 10px;border-radius:999px;
  background:rgba(255,255,255,.24);border:1px solid rgba(255,255,255,.38);
  backdrop-filter:blur(2px);
}
.sunny .tag{background:rgba(255,255,255,.45);border-color:rgba(255,255,255,.6);color:#7a3c00}
.snowy .tag{background:rgba(255,255,255,.6);border-color:rgba(255,255,255,.8);color:#123a63}
.temp{
  margin:12px 0 6px;font-size:62px;line-height:.95;font-weight:800;letter-spacing:-.045em;
}
.temp sup{font-size:.4em;vertical-align:top;position:relative;top:.16em;font-weight:700;letter-spacing:0}
.desc{margin:0;font-size:13.5px;line-height:1.5;opacity:.85}
.hilo{
  display:flex;gap:16px;margin-top:14px;padding-top:13px;
  border-top:1px solid currentColor;
  font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;opacity:.62;
}

/* ============ FOOTER ============ */
.foot{
  margin-top:38px;text-align:center;font-size:12.5px;letter-spacing:.06em;color:#7d8cb2;
}

/* ============ KEYFRAMES ============ */
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes twinkle{0%,100%{opacity:.55}50%{opacity:1}}
@keyframes pulse{
  0%,100%{transform:translate(-50%,-50%) scale(1);opacity:.8}
  50%{transform:translate(-50%,-50%) scale(1.15);opacity:1}
}
@keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
@keyframes fall{
  0%{transform:translateY(-46px) rotate(10deg);opacity:0}
  14%{opacity:1}
  88%{opacity:.9}
  100%{transform:translateY(74px) rotate(10deg);opacity:0}
}
@keyframes fallFast{
  0%{transform:translateY(-58px) rotate(14deg);opacity:0}
  12%{opacity:1}
  90%{opacity:.95}
  100%{transform:translateY(92px) rotate(14deg);opacity:0}
}
@keyframes flakeFall{
  0%{transform:translateY(-185px);opacity:0}
  8%{opacity:1}
  88%{opacity:.95}
  100%{transform:translateY(185px);opacity:0}
}
@keyframes sway{
  0%,100%{transform:translateX(-8px) rotate(0deg)}
  50%{transform:translateX(8px) rotate(180deg)}
}
@keyframes boltFlash{
  0%{opacity:0}
  4%{opacity:1}
  8%{opacity:.3}
  11%{opacity:1}
  17%{opacity:0}
  100%{opacity:0}
}
@keyframes skyFlash{
  0%{opacity:0}
  4%{opacity:.6}
  8%{opacity:.14}
  11%{opacity:.55}
  17%{opacity:0}
  100%{opacity:0}
}

/* ============ REDUCED MOTION ============ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation:none !important;
    transition:none !important;
  }
}

/* ============ SMALL SCREENS ============ */
@media (max-width:420px){
  .page{padding:34px 16px 44px}
  .info{padding:2px 20px 22px}
  .temp{font-size:56px}
  .scene{height:168px}
}
</style>
</head>
<body>
<div class="page">

  <header class="head">
    <p class="eyebrow">Animated · CSS only</p>
    <h1>Weather Cards</h1>
    <p class="sub">Four hand-built scenes — rotating rays, falling rain, drifting snow and flashing lightning, drawn with nothing but HTML elements and pseudo-elements.</p>
  </header>

  <section class="grid">

    <!-- ================= SUNNY ================= -->
    <article class="card sunny" tabindex="0">
      <div class="scene">
        <div class="glow"></div>
        <div class="sun">
          <div class="rays">
            <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
          </div>
          <div class="core"></div>
        </div>
      </div>
      <div class="info">
        <div class="row">
          <h2 class="city">Cairo</h2>
          <span class="tag">Clear</span>
        </div>
        <div class="temp">34<sup>°</sup></div>
        <p class="desc">Bright sunshine with a light desert breeze.</p>
        <div class="hilo"><span>Feels 37°</span><span>Humidity 18%</span></div>
      </div>
    </article>

    <!-- ================= RAINY ================= -->
    <article class="card rainy" tabindex="0">
      <div class="scene">
        <div class="cloud">
          <b class="puff p1"></b>
          <b class="puff p2"></b>
        </div>
        <div class="rain">
          <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
      </div>
      <div class="info">
        <div class="row">
          <h2 class="city">London</h2>
          <span class="tag">Rain</span>
        </div>
        <div class="temp">12<sup>°</sup></div>
        <p class="desc">Steady rainfall continuing into the evening.</p>
        <div class="hilo"><span>Feels 9°</span><span>Rain 8 mm</span></div>
      </div>
    </article>

    <!-- ================= SNOWY ================= -->
    <article class="card snowy" tabindex="0">
      <div class="scene">
        <div class="cloud">
          <b class="puff p1"></b>
          <b class="puff p2"></b>
        </div>
        <div class="snow">
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
        </div>
      </div>
      <div class="info">
        <div class="row">
          <h2 class="city">Reykjavík</h2>
          <span class="tag">Snow</span>
        </div>
        <div class="temp">-4<sup>°</sup></div>
        <p class="desc">Light snowflakes drifting over quiet streets.</p>
        <div class="hilo"><span>Feels -9°</span><span>Wind 14 km/h</span></div>
      </div>
    </article>

    <!-- ================= STORMY ================= -->
    <article class="card storm" tabindex="0">
      <div class="scene">
        <div class="cloud">
          <b class="puff p1"></b>
          <b class="puff p2"></b>
        </div>
        <div class="bolt"></div>
        <div class="rain">
          <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
      </div>
      <div class="info">
        <div class="row">
          <h2 class="city">Mumbai</h2>
          <span class="tag">Storm</span>
        </div>
        <div class="temp">27<sup>°</sup></div>
        <p class="desc">Thunderstorms with heavy showers nearby.</p>
        <div class="hilo"><span>Feels 31°</span><span>Gusts 62 km/h</span></div>
      </div>
    </article>

  </section>

  <footer class="foot">HTML &amp; CSS only — no JavaScript, no images, no SVG, no icon fonts.</footer>

</div>
</body>
</html>
Reasoning trace (10,408 tokens)
Let me create a complete HTML file with four animated weather cards, CSS-only, no JS, no SVG, no images.

Design: header, grid of 4 cards. Each card has an icon area built from divs/pseudo-elements.

Sunny: sun disc with rotating rays (use a container with rays as child divs, or pseudo-elements — I can use multiple divs for rays). Let's build rays with 8 divs each rotated, animated rotation of the whole ray container.

Rainy: cloud made of divs + drops falling.

Snowy: cloud + snowflakes drifting (6 flakes, each with staggered delays).

Stormy: dark cloud + flashing lightning (clip-path polygon bolt) + rain.

Backgrounds gradients per card.

Responsive grid: grid-template-columns repeat(4,1fr), media query below 900 → 2, below 560 → 1. Requirement says 4 per row desktop, stacked on mobile.

Hover: translateY(-10px).

prefers-reduced-motion: animation none.

Let me write carefully.

Structure:

```html
<body>
 <header class="page-head">...</header>
 <main class="grid">
  <article class="card sunny">
    <div class="scene">
      <div class="sun"><div class="rays">...8 spans</div><div class="core"></div></div>
    </div>
    <div class="meta">
      <div class="city">Cairo</div>
      <div class="temp">34<span>°</span></div>
      <div class="desc">Clear & Sunny</div>
    </div>
    <div class="badge">...</div>
  </article>
  ...
```

Let's design each card visually rich: top scene area ~160px, then info.

Sunny scene: radial glow, sun with rays rotating.

Sun: position absolute center, .core is 70px circle with radial-gradient yellow-orange, box-shadow glow. .rays has 8 rays as spans, each absolutely positioned, width 4px, height 26px, background gradient, positioned above core: top:-40px; left:50%; transform-origin: center 58px... Let's do: .rays { position:absolute; inset:0; animation: spin 14s linear infinite; } each span { position:absolute; left:50%; top:50%; width:6px; height:30px; margin-left:-3px; margin-top:-58px; transform-origin: 3px 58px; border-radius:3px; background:linear-gradient(#ffd54a,#ff9a1f); transform: rotate(Ndeg);}

Actually with margin-top:-58px the element spans from y=50%-58 to y=50%-28, i.e. top of ray at -58 relative center, bottom at -28. transform-origin at (3px, 58px) relative to element = center of element's ... wait element top at -58, origin y=58 means 58px below element top = 0 relative center = center point. Good: origin = sun center. So rotate(Ndeg) works.

Rays lengths alternate maybe. Fine.

Also add a slow pulsing glow.

Rain scene: cloud composed of three circles + a base rectangle. Use a .cloud div with ::before (big circle) and ::after (small circle) plus a base? Let's use structure:

.cloud { position:absolute; width:96px; height:36px; border-radius:20px; background:linear-gradient(#e8eef7,#b9c6da); }
.cloud::before { content:''; position:absolute; width:52px;height:52px; border-radius:50%; background:same; left:8px; top:-28px;}
.cloud::after { width:34px;height:34px; right:10px; top:-18px; }

But background gradient continuity — using same gradient on each part creates seams. Use solid color-ish gradient with slight gradient per part; acceptable. Better: give cloud parts a shared look by using flat-ish color with subtle gradient; seams minimal.

Alternatively use a mask-free approach: cloud as one element with box-shadow circles... Simpler: use solid color #dfe7f3 for cloud body and add highlight overlay via ::before on wrapper. Let's just do flat-ish gradient per part — visually fine.

Actually a neat trick: cloud element has the circles as children with same background color and a parent gradient overlay using overflow hidden? Let's do: .cloud wrapper overflow:visible; parts solid color; then a pseudo overlay on wrapper shaped same as cloud? Too complex. Flat color with drop-shadow is fine, plus a bottom shading via linear-gradient on the main body only... I'll use solid colors with a subtle inner highlight on the main body.

Hmm, but different weather: rainy cloud lighter (day rain), stormy darker cloud.

Drops: use spans in a .drops container, each animated translateY with delays, skewed line shape (width 3px height 18px, border-radius, background linear-gradient transparent → blue, rotate 12deg).

Snowflakes: small circles/diamonds? Requirement: snowflakes built from HTML+CSS. Make each flake a div with 6 pseudo?? Pseudo limited to 2. Use a div with ::before and ::after as crossing bars plus the div itself as third bar → 6-point star. That's doable: .flake has background bar horizontal; ::before rotated 60deg, ::after rotated -60deg. All same color. Nice.

Let's do: .flake { width:14px;height:3px;border-radius:2px;background:#fff; position:absolute; } ::before/::after same but absolutely positioned inset:0 with transform rotate(60deg)/(120deg)... Actually rotate(60deg) and rotate(-60deg) gives 6 points. Use transform-origin center.

Snow drift animation: translateY from -20 to 140 with horizontal sway using two nested elements: outer .flake-wrap animates fall, inner .flake animates sway. Let's make wrapper divs .snowfall > span.snow (fall animation) each containing i.flake (sway animation).

Lightning: div .bolt with clip-path polygon, animated flash (opacity/filter). Plus rain in stormy.

Also scene backgrounds differ per card.

Card content: city name, temperature, description. Also maybe a small footer with hi/lo — not required, keep minimal but polished.

Let's also add a top-right small badge like "Now" ? Keep simple.

Card layout: 
.card { border-radius: 24px; padding: 0; overflow:hidden; position:relative; display:flex; flex-direction:column; }
.scene { height:170px; position:relative; overflow:hidden; }
.info { padding: 22px 24px 26px; }

Card background gradient: the card itself gets the gradient; scene maybe transparent so gradient shows through, with a slight overlay. Simpler: card background = weather gradient, scene has a radial highlight overlay.

Text colors: sunny card dark text on warm gradient; rainy on blue; snow on pale blue-white; storm on dark navy with light text.

Hover: transform translateY(-12px); box-shadow deepen.

Grid: display:grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap:22px; max-width:1180px; margin auto.

At <=1000px: 2 cols; <=560px: 1 col.

Header: title "Weather Deck", subtitle.

Also add a decorative "sun ray" background? Keep clean: body background dark-ish gradient? Let's use a light neutral: body background: linear-gradient(160deg,#0e1526, #1b2438)? Cards pop nicely on dark. But stormy card dark text... let's do dark page with light cards.

Page bg: linear-gradient(180deg, #0b1020, #131a2e 60%, #0d1222). Add subtle radial glows.

Card gradients:
- sunny: linear-gradient(160deg,#fff3c4,#ffd166 55%,#ff9f43) — dark text #4a2c00.
- rainy: linear-gradient(160deg,#a8c8ee,#5b8fd6 60%,#3a5f9e) — white text.
- snowy: linear-gradient(160deg,#ffffff,#d9ecff 50%,#a9cdf0) — dark blue text.
- stormy: linear-gradient(160deg,#3b4463,#232a44 55%,#12172b) — light text.

Icons sit on scene area with translucent panel? Add .scene::after subtle vignette.

Let's write drop positions with inline style? Inline styles are allowed (only inline event handlers banned). But better to use CSS classes .d1..d6.

Let me write CSS carefully.

Rain drops animation: 
@keyframes fall { 0%{transform:translateY(-30px) rotate(14deg); opacity:0} 10%{opacity:1} 90%{opacity:1} 100%{transform:translateY(130px) rotate(14deg); opacity:0} }

Since drops are positioned at top of scene under cloud, container .rain { position:absolute; left:0; right:0; top:96px; height:80px; } drops absolute with left percentages, animation fall 1.1s linear infinite with delays.

Hmm transform translateY within container of fixed height; overflow hidden by scene.

Snow similar: @keyframes snowfall { from{transform:translateY(-10px)} to{transform:translateY(150px)} } with opacity fade at ends.

Let's set scene height 180px.

Cloud position: centered, top ~55px.

For rainy: cloud top 46px; rain from top 100px.

For stormy: cloud darker, lightning bolt below cloud slightly left, rain too.

Bolt: 
.bolt { position:absolute; left:50%; margin-left:-14px; top:104px; width:34px; height:56px; background:linear-gradient(180deg,#fff6c0,#ffd54a); clip-path: polygon(58% 0, 10% 56%, 44% 56%, 26% 100%, 92% 38%, 55% 38%); animation: flash 2.4s infinite; }
@keyframes flash {0%,100%{opacity:0} 4%{opacity:1} 10%{opacity:.9} 14%{opacity:0} 18%{opacity:1} 30%{opacity:0} }

Hmm flashes should be brief. Also add a glow behind: .scene-storm::before white flash overlay animation.

Also stormy rain drops animate faster.

Snow cloud white.

Sunny scene: also maybe small clouds drifting? Keep sun with glow rings.

Let's also add animated shimmer on the temperature? Not needed.

prefers-reduced-motion: * { animation: none !important; transition: none !important; } but keep final states sensible: rays visible, drops visible at some position? If animation none, drops stay at their initial transform (none → position as set). Let's set base positions so static looks fine: drops positioned in scene without transform (translateY(0)), opacity 1 default. So define .drop { opacity:1; animation: fall ...} and keyframes handle. Without animation they'd be at their static top position, all visible — fine.

Bolt: default opacity should be 0 for static? If reduced motion, no flash → bolt hidden. Better set base opacity:1 so static shows lightning bolt visible. But then normal animation keyframes start at 0 anyway. Set .bolt {opacity:1; animation:flash 2.6s infinite steps?}. Keyframes control. With animation none, opacity 1 → visible bolt. Good.

Snowflakes static: positioned across scene, visible. Good.

Now, header + footer note.

Also add "cards lifted on hover" and focus-visible maybe.

Let me write the HTML.

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Weather Cards — CSS Only</title>
<style> ... </style>
</head>
<body>
<div class="page">
  <header class="head">
    <p class="eyebrow">Animated · CSS only</p>
    <h1>Weather Cards</h1>
    <p class="sub">Four hand-built scenes — no images, no SVG, no JavaScript.</p>
  </header>
  <section class="grid">
   ... cards
  </section>
  <footer class="foot">Built with HTML &amp; CSS only.</footer>
</div>
</body>
```

Each card:

```html
<article class="card sunny" tabindex="0">
  <div class="scene">
    <div class="glow"></div>
    <div class="sun">
      <div class="rays"><i></i>×8</div>
      <div class="core"></div>
    </div>
  </div>
  <div class="info">
    <div class="row"><h2 class="city">Cairo</h2><span class="tag">Clear</span></div>
    <div class="temp">34<sup>°</sup></div>
    <p class="desc">Sunny and warm all afternoon</p>
  </div>
</article>
```

Temperature big: font-size 56px.

Tag badge: small pill.

Rainy card scene: cloud + rain.
```html
<div class="scene">
  <div class="cloud"><b></b><b></b></div>  <!-- circles -->
  <div class="rain"><i></i>×6</div>
</div>
```
Cloud main element is the bar; b elements are circles (use <b> tags styled as circles - but <b> is inline; set display:block/absolute). Fine.

Snowy: cloud white + snowfall spans.

Stormy: cloud dark, bolt, rain.

Also maybe a temperature drop visual. Enough.

Mobile: scene height same; grid 1 col at <=640. At 375 width, card padding fine.

Also add min-width:0 to grid items to avoid overflow.

Let's write the code fully.

CSS details:

```css
*{box-sizing:border-box}
html,body{margin:0}
body{
  min-height:100vh;
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
  background: radial-gradient(1200px 600px at 15% -10%, #1d2a4d 0%, transparent 60%),
              radial-gradient(900px 500px at 90% 110%, #26314f 0%, transparent 60%),
              linear-gradient(180deg,#0a0e1c,#0f1426 50%,#0a0e1a);
  color:#e8edf9;
  -webkit-font-smoothing:antialiased;
}
```

page { max-width:1200px; margin:0 auto; padding:48px 24px 64px; }

head text-align:center; margin-bottom:36px.

h1 font-size clamp(30px,5vw,46px), letter-spacing -0.02em.

grid.

.card {
 position:relative; min-width:0; border-radius:26px; overflow:hidden;
 box-shadow: 0 18px 40px -20px rgba(0,0,0,.8), 0 0 0 1px rgba(255,255,255,.06) inset;
 transition: transform .45s cubic-bezier(.2,.8,.2,1), box-shadow .45s;
 display:flex; flex-direction:column;
}
.card:hover,.card:focus-visible{transform:translateY(-14px); box-shadow:0 34px 60px -24px rgba(0,0,0,.9), 0 0 0 1px rgba(255,255,255,.14) inset;}

Focus visible for keyboard, no handlers needed (tabindex ok).

.card::after — top gloss: position absolute inset 0, background linear-gradient(180deg, rgba(255,255,255,.18), transparent 40%); pointer-events none; but might cover scene; fine, it's a subtle gloss. Ensure it doesn't block nothing (no interactivity anyway).

Scene: height 176px; position relative; overflow:hidden.

Sunny scene:
.glow { position:absolute; left:50%; top:52%; width:220px;height:220px; transform:translate(-50%,-50%); background:radial-gradient(circle, rgba(255,255,255,.55), rgba(255,255,255,0) 65%); animation: pulse 4s ease-in-out infinite; }

.sun { position:absolute; left:50%; top:50%; width:140px;height:140px; transform:translate(-50%,-50%); }
.core{position:absolute; left:50%; top:50%; width:74px;height:74px;margin:-37px 0 0 -37px;border-radius:50%; background:radial-gradient(circle at 32% 28%, #fff6c2, #ffd43b 45%, #ff9d1c); box-shadow:0 0 0 8px rgba(255,214,64,.28), 0 0 40px rgba(255,180,40,.75); animation: breathe 3.6s ease-in-out infinite;}
.rays{position:absolute; inset:0; animation:spin 16s linear infinite;}
.rays i{position:absolute; left:50%; top:50%; width:6px; height:30px; margin-left:-3px; margin-top:-66px; transform-origin:3px 66px; border-radius:4px; background:linear-gradient(180deg,#fff0a8,#ffab16); }

Wait: ray center should be at sun center; margin-top:-66px puts element top at center-66, height 30 → bottom at center-36. origin (3, 66) = center-66+66 = center. Good. Ray inner end at center-36 = radius 36 (core radius 37) — slightly overlapping. Good.

Rotate positions: nth-child(1) rotate(0) ... 8 children every 45deg. Alternate lengths: even ones shorter? give nth-child(even){height:22px;margin-top:-64px} → then origin must adjust: origin 3px 64px. Simpler: keep uniform but set two sizes with matching origins. Let's just do uniform to avoid bugs, or vary by using transform: rotate() scale(0.7) — scaling along Y from origin scales distance too (origin at center) → shorter and moved closer. transform: rotate(45deg) scale(.72) — that works: ray shrinks toward center. 

So: .rays i:nth-child(odd){transform:rotate(calc(...))}. Can't compute easily; write 8 rules manually with nth-child.

1: rotate(0deg)
2: rotate(45deg) scale(.7)
3: rotate(90deg)
4: rotate(135deg) scale(.7)
5: rotate(180deg)
6: rotate(225deg) scale(.7)
7: rotate(270deg)
8: rotate(315deg) scale(.7)

Also each ray could have its own pulse: animation: rayPulse 2s ease-in-out infinite alternate with delays — but transform conflict: animation on child overrides transform from CSS? The .rays i transform is set in CSS rule; animation on same element with keyframes containing transform would override. Use separate keyframes per ray? Too much. Instead put scale pulse via a wrapper? Skip; the rotating container plus glow pulse is enough. Actually could animate opacity of rays: .rays i{animation: twinkle 2.6s ease-in-out infinite;} with nth-child delays — opacity animation doesn't conflict with transform. Do that.

Cloud:
.cloud{position:absolute; left:50%; top:52px; width:112px; height:40px; margin-left:-56px; border-radius:22px; background:linear-gradient(180deg,#f4f8ff,#c9d6ea); box-shadow:0 12px 24px -12px rgba(15,30,60,.6);}
.cloud b{position:absolute; display:block; border-radius:50%; background:inherit?} — background:inherit would inherit the gradient box of parent? `background:inherit` inherits parent's background (gradient sized to that element's box) — actually inherit takes computed value of parent's background shorthand which includes background-image with size auto relative to element → each part gets gradient sized to its own box. Visually it's a vertical gradient so vertical alignment matters (offset). Simpler: give b a solid color matching mid gradient: #dbe5f4? Let's define cloud background as solid-ish: background:linear-gradient(180deg,#fbfdff 0%, #dbe6f6 100%) on main, and b elements background:#e9f0fa with slight variation. Seam acceptable.

Better approach: main bar as bottom part darker, circles lighter top — actually that looks like proper cloud shading (top lighter, bottom darker). Cloud main bar: linear-gradient(180deg,#e4ecf8,#c2d0e6). Circles: radial-gradient(circle at 35% 30%, #ffffff, #dbe5f5 70%, #cbd8ec). Looks fine.

Circle 1: width 60px;height:60px; left:10px; top:-32px. Circle 2: width:44px;height:44px; right:12px; top:-22px. Add a third? max children: main + 2 = fine (I can add more <b>s, no limit). Add third small: left:44px? Let's keep 2 for clean shape; maybe 3 for fluffy: b:nth-child(1) big left, b(2) medium right, b(3)? Let's use 2 plus main.

Cloud width 112 might be small relative to scene 176. Scale up: width 130, height 46, radius 24; circles 68 and 50.

Rain container: position absolute; left:0; right:0; top:104px; bottom:0;
drop i: position:absolute; width:4px; height:20px; border-radius:4px; background:linear-gradient(180deg, rgba(255,255,255,0), #cfe6ff 30%, #6fb4ff); transform: rotate(12deg); opacity:.95; animation: fall var(--d) linear infinite;

Use per-drop: .rain i:nth-child(1){left:18%; animation-duration:1.05s; animation-delay:0s} etc. Simpler: set left & delays & durations individually in 8 rules.

@keyframes fall{
 0%{transform:translateY(-40px) rotate(12deg); opacity:0}
 12%{opacity:1}
 85%{opacity:.9}
 100%{transform:translateY(90px) rotate(12deg); opacity:0}
}
Container height 72 (104→176). translateY from -40 to 90 covers.

Snow:
.snow i (wrapper): position:absolute; top:-16px; animation: flakeFall var(--t) linear infinite;
.flake inner: the star span. Structure: <i><b></b></i>? Let's use <i> wrapper with class-less inner <b> star. But <b> used for cloud circles — different card so fine.

Star: .snow i > span { display:block; width:14px; height:3px; border-radius:2px; background:#fff; box-shadow:0 0 6px rgba(255,255,255,.8); animation: sway 3s ease-in-out infinite; position:relative;}
 ::before/::after {content:''; position:absolute; inset:0; border-radius:2px; background:inherit? } background: #fff.

Wait `background:inherit` on pseudo inherits parent's background-image which is white → fine. Use explicit #fff.

transform rotate(60deg) / rotate(-60deg) with transform-origin center.

Hmm a 14x3 bar rotated 60 and -60 plus horizontal = 6-point star. Good.

@keyframes flakeFall{ from{transform:translateY(-20px)} to{transform:translateY(180px)} } plus opacity fade at end. Combine translate only; wrapper handles fall, inner handles sway rotate/scale.

But wrapper opacity fade: include in fall keyframes.

Sway: @keyframes sway{0%,100%{transform:rotate(0deg) translateX(-6px)}50%{transform:rotate(180deg) translateX(6px)}} — rotating a star 180 looks fine (symmetric-ish). Actually rotating gives spin, nice.

Note: inner span needs its own transform (not conflicting with wrapper). Good.

Stormy: cloud darker: main gradient #4a5474 → #2a3352; circles radial #6b7699 → #3a4568.
.bolt with flash animation and a white overlay flash.

Also add darker scene background overlay for storm: .storm .scene::before { content:''; position:absolute; inset:0; background:linear-gradient(180deg, rgba(255,255,255,.0), rgba(120,140,220,.15)); animation: skyFlash 5s infinite; }

@keyframes skyFlash{0%,7%,9%,100%{opacity:0} 8%{opacity:1} 8.5%{opacity:.2}}

Hmm timing with bolt. Let's do both with same duration 3.2s: bolt flashes at 0-14%, sky at 6-10%.

@keyframes boltFlash{
0%{opacity:0} 4%{opacity:1} 8%{opacity:.35} 11%{opacity:1} 16%{opacity:0} 100%{opacity:0}
}
@keyframes skyFlash{0%{opacity:0} 4%{opacity:.55} 8%{opacity:.15} 11%{opacity:.5} 16%{opacity:0} 100%{opacity:0}}

Also a glow around bolt: box-shadow.

Also stormy rain faster & more drops.

Info block:
.info{padding:6px 24px 26px; position:relative;}
.row{display:flex; align-items:center; justify-content:space-between; gap:10px;}
.city{margin:0; font-size:15px; letter-spacing:.16em; text-transform:uppercase; font-weight:700; opacity:.85}
.tag{font-size:11px; letter-spacing:.1em; text-transform:uppercase; padding:5px 10px; border-radius:999px; background:rgba(255,255,255,.18); border:1px solid rgba(255,255,255,.25)} — for sunny card white pill on yellow might be low contrast; use per-card colors.

.temp{font-size:64px; line-height:1; font-weight:800; letter-spacing:-.04em; margin:10px 0 6px;}
.temp sup{font-size:.42em; vertical-align:top; position:relative; top:.14em; font-weight:600}

.desc{margin:0; font-size:14px; opacity:.8}

Colors per card: 
.sunny{background:linear-gradient(155deg,#ffe9a8 0%,#ffc94d 45%,#ff9a3c 100%); color:#5a2f00}
.sunny .tag{background:rgba(255,255,255,.42); border-color:rgba(255,255,255,.55); color:#7a3d00}
.rainy{background:linear-gradient(155deg,#bcd6f6 0%,#5f92d8 45%,#33558f 100%); color:#fff}
.snowy{background:linear-gradient(155deg,#ffffff 0%,#dcefff 45%,#9cc6ee 100%); color:#123a63}
.stormy{background:linear-gradient(155deg,#4b5578 0%,#2b3352 50%,#141a30 100%); color:#e9edff}

Scene backgrounds: add per card a subtle radial highlight:
.scene::after{content:''; position:absolute; inset:0; background:radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,.28), transparent 70%); pointer-events:none}

For sunny card maybe the scene sits on same gradient — fine.

Also the card::after gloss — may double. Keep card::after as a top highlight line only: background:linear-gradient(180deg,rgba(255,255,255,.22),rgba(255,255,255,0) 30%). Fine.

Careful: .card::after with inset:0 and z-index maybe above content. Set z-index:3; pointer-events:none. Content should be below but visible since gradient transparent mostly. OK.

Order: .scene has overflow hidden so animations don't spill.

Grid responsive:
.grid{display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:20px;}
@media (max-width:1080px){grid-template-columns:repeat(2,minmax(0,1fr))}
@media (max-width:640px){grid-template-columns:1fr; gap:18px}

Requirement: 4 per row on desktop, stacked on mobile — intermediate 2 is fine. But at 1280 viewport with max-width 1200 and padding 24 → available 1152, 4 cards ~273px each. Good.

At exactly 1280 screenshot: fine.

Reduce motion:
@media (prefers-reduced-motion: reduce){
 *,*::before,*::after{animation:none !important; transition:none !important;}
}

Static states: drops at top of container with translateY(0) → they'd be at container top (104px) clustered. Positions have left offsets and various tops? I set only left; so all at y=104 (top of container). With animation none they'd overlap horizontally? They have different left %, so they'd appear as a row of drops at same height — a bit odd. Add individual `top` offsets: .rain i:nth-child(n){top: Xpx} varying 0..60. Then fall animation transform from -40 to 90 → passes through. With static, drops scattered at different heights. Good, set top values.

Similarly snow wrappers: give varying top: -20, 10, 40, 70, 100 etc. and animation translateY from 0 to 180? Let's define: wrapper top set individually (e.g., -30, 5, 40, 75, 110, 140) and animation translates from -60 to 60? Simpler: fall keyframes translateY(-40px) → translateY(60px) with base tops spread; loop seams. Hmm.

Let's do: wrapper top: -20px fixed for all, animation translateY(0) → translateY(200px), delays staggered negative? With negative delays all appear mid-fall at load — nice for screenshot! Actually first paint at 3s screenshot: animations running, all fine regardless.

For static/reduced-motion: wrappers all at top -20 (above scene, clipped) → invisible. Bad. So vary static tops and use keyframes from translateY(0) to translateY(180px) with wrapper tops spread from -20 to 100 (some hidden above). Hmm.

Alternative: give each wrapper a distinct `top` in [0..150] and animate translateY(-160px)→translateY(0) with delays so that they enter from top. Static state: spread across scene → visible. During animation they move downward from their position -160 to their position... they'd end at their base top then jump back to -160 (wrap). At the wrap moment flake disappears from bottom and reappears at top: that's a normal loop but base positions differ meaning each flake travels same distance; fine, they just loop at different absolute positions. Actually if base top=100, translateY goes -160→0, meaning flake travels from y=-60 to y=100 — but never goes below 100. So flakes with base top 100 only fall in upper area. Not great.

Better: two-layer approach: wrapper has static `top` (spread) and animation `fall` translating from -170px to +... hmm.

Let's do: wrapper tops spread in [0, 150]. Animation: translateY(-170px) → translateY(170px) (total travel 340). Each flake travels across whole scene repeatedly, entering from above regardless of base. With base top=100 and translateY(-170) → y=-70 (above scene, clipped) and at +170 → y=270 (below). Good. Static (no animation) → y = base top, spread visible. 

Same for rain: wrapper? drops static top spread [0,50] within container (container height 72 + overflow into scene bottom). Animation translateY(-40px)→translateY(60px): with base 0 → -40..60; base 50 → 10..110 (clipped at scene bottom 176 = container top 104 + 72 → base 50+60=110 > 72, clipped, fine). Static shows spread. Good enough.

Set rain container top:100px; height:76px; overflow visible but scene clips.

Let's assign rain drops (8): left:14%,26%,38%,50%,62%,74%,86%,32%? Use varied.

Durations: .95s–1.35s; delays 0, .15, .3, .45, .6, .75, .25, .5.

Snow 7 flakes with lefts 12,26,40,55,68,82,50 %; tops 0,20,45,70,95,120,145? Wait static top must be within scene (0..170). tops: 4, 28, 52, 76, 100, 124, 148. And animation from translateY(-180) to translateY(180).

Sizes vary: scale on inner star (.8, 1, 1.2) — but inner star has sway animation with transform. Conflict. Instead vary width/height per nth-child for the star's bar: nth-child rules target .snow i span. Fine: .snow i:nth-child(2) > span{width:10px} etc.

Delays: stagger so they don't sync: delays 0,-.4,-.9,-1.3,-1.8,-2.2,-2.6 s (negative = start mid-flight, good for screenshot immediately). Actually positive delays also fine after 3s. Use negative for instant liveliness.

Hmm careful: negative delay with animation means starts partway — fine.

Also sway delays staggered.

Storm rain: reuse .rain styles but inside .storm scene; add class .rain--fast? Just use `.storm .rain i{animation-duration:...}` — but durations set per nth-child. Instead give storm its own rules: `.storm .rain i:nth-child(n){animation-duration:.7s}` placed after individual rules with higher specificity (.storm .rain i:nth-child(1) = 0,2,2? ). Specificity: .storm .rain i:nth-child(1) → classes:2, pseudo-class:1, element:1 → (0,3,1)? vs .rain i:nth-child(1) → (0,2,1). So .storm rule wins. Simpler: give storm its own drop markup/class names: use class `drop2`. I'll just write `.storm .rain i{animation-duration:.72s !important}`? avoid !important... it's fine honestly but let's just define storm rain nth rules separately.

Actually simplest: define durations via nth-child in a generic way and for storm, override with `.storm .rain i:nth-child(1){animation-duration:.7s}` etc. — that's 8 extra rules. Or: set animation duration on the .rain container? Not inherited.

Alternative: put the per-drop timing using `animation-duration` from nth-child, and for storm just accept same duration but different keyframes (rainFall2 faster-looking). Use different keyframe distance: storm drops travel farther in same time → faster. `.storm .rain i{animation-name:fallFast}` — specificity (0,2,1) vs `.rain i:nth-child(1)` (0,2,1) equal → later rule wins. Place .storm rules after the nth rules. But nth rules set animation shorthand including name; .storm sets animation-name only → later in source with equal specificity wins for name. Good.

Wait: `.rain i:nth-child(1)` specificity: .rain class (1) + :nth-child (1) = 0,2,1? classes/pseudo-classes count = 2, elements = 1. `.storm .rain i` = 0,2,1. Equal. Later wins. 

Let's finalize keyframes:

@keyframes fall{
0%{transform:translateY(-46px) rotate(10deg);opacity:0}
14%{opacity:1}
88%{opacity:.85}
100%{transform:translateY(70px) rotate(10deg);opacity:0}
}
@keyframes fallFast{
0%{transform:translateY(-60px) rotate(14deg);opacity:0}
12%{opacity:1}
90%{opacity:.9}
100%{transform:translateY(90px) rotate(14deg);opacity:0}
}

Also drops should be tilted; include rotate in both.

Sun spin: @keyframes spin{to{transform:rotate(360deg)}}
pulse: @keyframes pulse{0%,100%{transform:translate(-50%,-50%) scale(1);opacity:.85}50%{transform:translate(-50%,-50%) scale(1.14);opacity:1}}
breathe: core scale small: careful core uses margin centering; animate transform scale only: @keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
twinkle: opacity .55→1.

Scene for sunny: maybe add slight horizon? Not needed.

Footer/notes.

Also maybe add a small "degrees" row like "H 36° L 24°" for polish. Add under desc: .hilo with two spans? Requirement only city, temp, desc. Add small hilo as extra detail — nice. Let's include `<div class="hilo"><span>Feels 37°</span><span>Humidity 18%</span></div>` maybe too much. I'll add a subtle hilo line for realism.

Keep text short.

Cities: Cairo, London, Reykjavík, São Paulo? Stormy → Mumbai. Sunny → Cairo; Rainy → London; Snowy → Reykjavík; Stormy → Mumbai (monsoon). Temps: 34°, 12°, -4°, 27°.

Descriptions: "Clear skies, light breeze", "Steady rain through evening", "Light snow, roads slippery", "Thunderstorms with heavy showers".

Layout height: card ~176 + info ~ 200 → ~376px. Two rows? No, one row of 4 on desktop. Page height fine for 800 viewport: header ~140 + cards 380 + footer → ~600. Good.

Let's write everything.

Info padding: 4px 22px 24px; temp 60px.

Let me write final HTML.

Also note: no `<script>`, no inline event handlers (no `on*` attributes, no `style` attr — I'll avoid inline style entirely).

Edge: `<i>` and `<b>` used — style them display:block.

Writing rays: 8 `<i></i>`.

Cloud markup:
```html
<div class="cloud">
  <b class="puff p1"></b>
  <b class="puff p2"></b>
</div>
```

Cloud styles shared via .cloud class; color variants via card class: `.rainy .cloud{...}` etc. I'll define base cloud with light color, and `.storm .cloud` overrides.

Let me write CSS for cloud:

.cloud{position:absolute; left:50%; top:44px; width:132px; height:46px; margin-left:-66px; border-radius:26px;
 background:linear-gradient(180deg,#f2f7ff 0%,#c8d7ee 100%);
 box-shadow:0 16px 26px -14px rgba(8,20,45,.55);}
.cloud .puff{position:absolute; display:block; border-radius:50%;
 background:radial-gradient(circle at 34% 28%, #ffffff 0%, #e6eefb 55%, #cfdcf1 100%);}
.p1{width:70px;height:70px;left:8px;top:-34px;}
.p2{width:50px;height:50px;right:14px;top:-24px;}

Cloud top 44 → circle top = 44-34 = 10 in scene. Bottom of bar = 90. Rain container top 100. Scene height 176 → rain area 76px. Good.

Snowy cloud: whiter: `.snowy .cloud{background:linear-gradient(180deg,#ffffff,#dfeaf8)} .snowy .puff{background:radial-gradient(circle at 34% 28%,#fff,#eef6ff 60%,#dceaf9)}`

Storm cloud: `.storm .cloud{background:linear-gradient(180deg,#59648a,#2e3757); box-shadow:0 18px 30px -14px rgba(0,0,0,.7)} .storm .puff{background:radial-gradient(circle at 34% 28%,#7b87ad,#4a5578 60%,#333d5e)}`

Snow scene: also add subtle snowy ground? Not needed.

Bolt position: left:50%, margin-left:-16px, top:96px, width:32px, height:62px.

Bolt clip-path polygon: points: (60% 0) (12% 58%) (46% 58%) (28% 100%) (92% 40%) (56% 40%). Let's sanity check: that's a classic bolt. Fine.

Add glow: filter: drop-shadow(0 0 12px rgba(255,224,110,.9)).

Storm also has rain in container top 100 but bolt occupies center-left. Put rain drops with left offsets avoiding overlap — doesn't matter much.

Also add a "flash" overlay covering whole scene: .storm .scene::before? But .scene::after is used for vignette; use ::before for flash.

Let's ensure .scene::after vignette for all cards defined, .storm .scene::before for flash.

Sky flash keyframes with opacity 0 base (reduced motion → none → opacity 0 → fine, invisible, good).

Bolt base opacity: set 1 (so reduced motion shows bolt). animation flash handles.

Now header eyebrow with a small CSS dot maybe.

Write footer: "HTML & CSS only — no JavaScript, no images, no SVG."

Let's produce final code.

Reduced motion: also ensure rays container doesn't rotate → static rays fine.

One more: hover lift on cards; also `@media (hover:none)` maybe keep. Fine.

Now check the transition on transform while animations exist — card has no transform animation so fine.

Write it.

Potential issue: `.card::after` gloss with z-index may cover; set .card{isolation:isolate} not needed.

Final code:

I'll write carefully with comments.

Text contrast: sunny card color #5a2b00 on orange bottom gradient — bottom of card is #ff9a3c, dark brown text ok.

.desc opacity .85.

.temp on sunny: dark brown, big. Good.

Let me write.
Raw response
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Weather Cards — HTML &amp; CSS Only</title>
<style>
/* ============ BASE ============ */
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  min-height:100vh;
  font-family:"Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;
  color:#e9eefb;
  background:
    radial-gradient(1100px 620px at 12% -12%, #1e2c56 0%, rgba(30,44,86,0) 62%),
    radial-gradient(900px 560px at 92% 112%, #2a3358 0%, rgba(42,51,88,0) 60%),
    linear-gradient(180deg,#090d1a 0%,#101730 55%,#090d18 100%);
  -webkit-font-smoothing:antialiased;
}
.page{max-width:1220px;margin:0 auto;padding:46px 22px 54px}

/* ============ HEADER ============ */
.head{text-align:center;margin-bottom:34px}
.eyebrow{
  display:inline-flex;align-items:center;gap:9px;margin:0 0 12px;
  font-size:11px;letter-spacing:.26em;text-transform:uppercase;font-weight:700;
  color:#8fb2ff;
}
.eyebrow::before{
  content:"";width:8px;height:8px;border-radius:50%;
  background:linear-gradient(180deg,#ffe27a,#ff9d2e);
  box-shadow:0 0 12px rgba(255,180,60,.9);
}
.head h1{
  margin:0;font-size:clamp(30px,5.4vw,46px);font-weight:800;
  letter-spacing:-.03em;
  background:linear-gradient(180deg,#ffffff 20%,#a9bbf0 110%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.sub{margin:12px auto 0;max-width:560px;font-size:14.5px;line-height:1.6;color:#9aa8cc}

/* ============ GRID ============ */
.grid{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:20px;
}
@media (max-width:1080px){.grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){.grid{grid-template-columns:1fr;gap:18px}}

/* ============ CARD SHELL ============ */
.card{
  position:relative;min-width:0;overflow:hidden;
  display:flex;flex-direction:column;
  border-radius:26px;
  box-shadow:0 22px 44px -24px rgba(0,0,0,.95), inset 0 1px 0 rgba(255,255,255,.35);
  transition:transform .45s cubic-bezier(.2,.8,.2,1), box-shadow .45s cubic-bezier(.2,.8,.2,1);
  outline:none;
}
.card::after{
  content:"";position:absolute;inset:0;z-index:5;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.20),rgba(255,255,255,0) 34%);
}
.card:hover,.card:focus-visible{
  transform:translateY(-14px);
  box-shadow:0 40px 66px -28px rgba(0,0,0,1), inset 0 1px 0 rgba(255,255,255,.5);
}

/* per-card gradients */
.sunny {background:linear-gradient(155deg,#ffeeb0 0%,#ffcf57 46%,#ff9a3b 100%);color:#5d2c00}
.rainy {background:linear-gradient(155deg,#c3daf7 0%,#5f92d8 48%,#31548e 100%);color:#ffffff}
.snowy {background:linear-gradient(155deg,#ffffff 0%,#ddefff 48%,#9ac4ee 100%);color:#0f3863}
.storm {background:linear-gradient(155deg,#4d5779 0%,#2b3352 52%,#12172c 100%);color:#eaeeff}

/* ============ SCENE ============ */
.scene{position:relative;height:178px;overflow:hidden}
.scene::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 92% at 50% 0%,rgba(255,255,255,.30),rgba(255,255,255,0) 72%);
}

/* ---------- SUNNY ---------- */
.glow{
  position:absolute;left:50%;top:50%;width:230px;height:230px;
  transform:translate(-50%,-50%);
  background:radial-gradient(circle,rgba(255,255,255,.75) 0%,rgba(255,241,170,.35) 40%,rgba(255,255,255,0) 68%);
  animation:pulse 4.2s ease-in-out infinite;
}
.sun{position:absolute;left:50%;top:50%;width:150px;height:150px;transform:translate(-50%,-50%)}
.core{
  position:absolute;left:50%;top:50%;width:76px;height:76px;margin:-38px 0 0 -38px;
  border-radius:50%;
  background:radial-gradient(circle at 32% 26%,#fff9cf 0%,#ffd64a 46%,#ff9c19 100%);
  box-shadow:0 0 0 9px rgba(255,214,70,.30),0 0 44px rgba(255,168,40,.85);
  animation:breathe 3.8s ease-in-out infinite;
}
.rays{position:absolute;inset:0;animation:spin 17s linear infinite}
.rays i{
  position:absolute;left:50%;top:50%;display:block;
  width:6px;height:32px;margin-left:-3px;margin-top:-68px;
  transform-origin:3px 68px;border-radius:4px;
  background:linear-gradient(180deg,#fff3b0,#ffab16);
  animation:twinkle 2.6s ease-in-out infinite;
}
.rays i:nth-child(1){transform:rotate(0deg)}
.rays i:nth-child(2){transform:rotate(45deg) scale(.72);animation-delay:.3s}
.rays i:nth-child(3){transform:rotate(90deg);animation-delay:.6s}
.rays i:nth-child(4){transform:rotate(135deg) scale(.72);animation-delay:.9s}
.rays i:nth-child(5){transform:rotate(180deg);animation-delay:1.2s}
.rays i:nth-child(6){transform:rotate(225deg) scale(.72);animation-delay:1.5s}
.rays i:nth-child(7){transform:rotate(270deg);animation-delay:1.8s}
.rays i:nth-child(8){transform:rotate(315deg) scale(.72);animation-delay:2.1s}

/* ---------- CLOUD (rain / snow / storm) ---------- */
.cloud{
  position:absolute;left:50%;top:44px;width:132px;height:46px;margin-left:-66px;
  border-radius:26px;
  background:linear-gradient(180deg,#f4f9ff 0%,#c6d6ee 100%);
  box-shadow:0 16px 26px -14px rgba(8,22,48,.6);
}
.cloud .puff{position:absolute;display:block;border-radius:50%;
  background:radial-gradient(circle at 34% 28%,#ffffff 0%,#e6eefb 55%,#cfddf2 100%)}
.cloud .p1{width:70px;height:70px;left:8px;top:-34px}
.cloud .p2{width:50px;height:50px;right:14px;top:-24px}
.snowy .cloud{background:linear-gradient(180deg,#ffffff 0%,#e2edfa 100%)}
.snowy .cloud .puff{background:radial-gradient(circle at 34% 28%,#ffffff 0%,#f1f8ff 58%,#dceaf9 100%)}
.storm .cloud{
  background:linear-gradient(180deg,#5b668c 0%,#2f3858 100%);
  box-shadow:0 18px 30px -14px rgba(0,0,0,.75);
}
.storm .cloud .puff{background:radial-gradient(circle at 34% 28%,#7e8ab1 0%,#4b5679 60%,#333d5e 100%)}

/* ---------- RAIN ---------- */
.rain{position:absolute;left:0;right:0;top:100px;height:78px}
.rain i{
  position:absolute;display:block;width:4px;height:20px;border-radius:4px;
  background:linear-gradient(180deg,rgba(255,255,255,0) 0%,#dcefff 34%,#6fb2ff 100%);
  box-shadow:0 0 6px rgba(120,185,255,.55);
  transform:rotate(10deg);opacity:1;
  animation:fall 1.1s linear infinite;
}
.rain i:nth-child(1){left:14%;top:0;animation-duration:1.05s;animation-delay:0s}
.rain i:nth-child(2){left:27%;top:24px;animation-duration:1.25s;animation-delay:-.4s}
.rain i:nth-child(3){left:39%;top:8px;animation-duration:.95s;animation-delay:-.7s}
.rain i:nth-child(4){left:51%;top:34px;animation-duration:1.15s;animation-delay:-.2s}
.rain i:nth-child(5){left:63%;top:4px;animation-duration:1.3s;animation-delay:-.9s}
.rain i:nth-child(6){left:75%;top:28px;animation-duration:1s;animation-delay:-.55s}
.rain i:nth-child(7){left:87%;top:12px;animation-duration:1.2s;animation-delay:-.3s}
.rain i:nth-child(8){left:33%;top:52px;animation-duration:1.1s;animation-delay:-.85s}
.storm .rain i{animation-name:fallFast}

/* ---------- SNOW ---------- */
.snow{position:absolute;left:0;right:0;top:0;bottom:0}
.snow > i{position:absolute;display:block;top:0;animation:flakeFall 9s linear infinite}
.snow > i:nth-child(1){left:11%;top:2px;animation-duration:9s;animation-delay:0s}
.snow > i:nth-child(2){left:25%;top:30px;animation-duration:11s;animation-delay:-3.4s}
.snow > i:nth-child(3){left:39%;top:62px;animation-duration:9.6s;animation-delay:-6.1s}
.snow > i:nth-child(4){left:53%;top:96px;animation-duration:12s;animation-delay:-1.8s}
.snow > i:nth-child(5){left:66%;top:128px;animation-duration:10.2s;animation-delay:-7.6s}
.snow > i:nth-child(6){left:80%;top:156px;animation-duration:11.4s;animation-delay:-4.7s}
.snow > i:nth-child(7){left:47%;top:172px;animation-duration:10.6s;animation-delay:-9s}
.snow i > span{
  position:relative;display:block;width:15px;height:3.5px;border-radius:3px;
  background:#ffffff;box-shadow:0 0 7px rgba(255,255,255,.9);
  animation:sway 3.6s ease-in-out infinite;
}
.snow i > span::before,.snow i > span::after{
  content:"";position:absolute;inset:0;border-radius:3px;background:#ffffff;
}
.snow i > span::before{transform:rotate(60deg)}
.snow i > span::after{transform:rotate(-60deg)}
.snow > i:nth-child(2) > span{width:11px;animation-delay:-.6s}
.snow > i:nth-child(3) > span{width:18px;animation-delay:-1.2s}
.snow > i:nth-child(4) > span{width:9px;animation-delay:-1.8s}
.snow > i:nth-child(5) > span{width:14px;animation-delay:-2.4s}
.snow > i:nth-child(6) > span{width:12px;animation-delay:-3s}
.snow > i:nth-child(7) > span{width:16px;animation-delay:-.9s}

/* ---------- STORM: lightning + sky flash ---------- */
.bolt{
  position:absolute;left:50%;top:92px;width:34px;height:64px;margin-left:-18px;
  background:linear-gradient(180deg,#fffbe0 0%,#ffe066 55%,#ffab12 100%);
  clip-path:polygon(60% 0,12% 58%,46% 58%,26% 100%,92% 40%,55% 40%);
  filter:drop-shadow(0 0 14px rgba(255,222,110,.95));
  opacity:1;animation:boltFlash 3.2s ease-in-out infinite;
}
.storm .scene::before{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(180deg,rgba(198,214,255,.05),rgba(150,175,255,.35));
  opacity:0;animation:skyFlash 3.2s ease-in-out infinite;
}

/* ============ INFO ============ */
.info{position:relative;padding:2px 22px 24px;z-index:3}
.row{display:flex;align-items:center;justify-content:space-between;gap:10px}
.city{
  margin:0;font-size:13px;font-weight:800;letter-spacing:.2em;
  text-transform:uppercase;opacity:.9;
}
.tag{
  flex:none;font-size:10px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  padding:5px 10px;border-radius:999px;
  background:rgba(255,255,255,.24);border:1px solid rgba(255,255,255,.38);
  backdrop-filter:blur(2px);
}
.sunny .tag{background:rgba(255,255,255,.45);border-color:rgba(255,255,255,.6);color:#7a3c00}
.snowy .tag{background:rgba(255,255,255,.6);border-color:rgba(255,255,255,.8);color:#123a63}
.temp{
  margin:12px 0 6px;font-size:62px;line-height:.95;font-weight:800;letter-spacing:-.045em;
}
.temp sup{font-size:.4em;vertical-align:top;position:relative;top:.16em;font-weight:700;letter-spacing:0}
.desc{margin:0;font-size:13.5px;line-height:1.5;opacity:.85}
.hilo{
  display:flex;gap:16px;margin-top:14px;padding-top:13px;
  border-top:1px solid currentColor;
  font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;font-weight:700;opacity:.62;
}

/* ============ FOOTER ============ */
.foot{
  margin-top:38px;text-align:center;font-size:12.5px;letter-spacing:.06em;color:#7d8cb2;
}

/* ============ KEYFRAMES ============ */
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes twinkle{0%,100%{opacity:.55}50%{opacity:1}}
@keyframes pulse{
  0%,100%{transform:translate(-50%,-50%) scale(1);opacity:.8}
  50%{transform:translate(-50%,-50%) scale(1.15);opacity:1}
}
@keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
@keyframes fall{
  0%{transform:translateY(-46px) rotate(10deg);opacity:0}
  14%{opacity:1}
  88%{opacity:.9}
  100%{transform:translateY(74px) rotate(10deg);opacity:0}
}
@keyframes fallFast{
  0%{transform:translateY(-58px) rotate(14deg);opacity:0}
  12%{opacity:1}
  90%{opacity:.95}
  100%{transform:translateY(92px) rotate(14deg);opacity:0}
}
@keyframes flakeFall{
  0%{transform:translateY(-185px);opacity:0}
  8%{opacity:1}
  88%{opacity:.95}
  100%{transform:translateY(185px);opacity:0}
}
@keyframes sway{
  0%,100%{transform:translateX(-8px) rotate(0deg)}
  50%{transform:translateX(8px) rotate(180deg)}
}
@keyframes boltFlash{
  0%{opacity:0}
  4%{opacity:1}
  8%{opacity:.3}
  11%{opacity:1}
  17%{opacity:0}
  100%{opacity:0}
}
@keyframes skyFlash{
  0%{opacity:0}
  4%{opacity:.6}
  8%{opacity:.14}
  11%{opacity:.55}
  17%{opacity:0}
  100%{opacity:0}
}

/* ============ REDUCED MOTION ============ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation:none !important;
    transition:none !important;
  }
}

/* ============ SMALL SCREENS ============ */
@media (max-width:420px){
  .page{padding:34px 16px 44px}
  .info{padding:2px 20px 22px}
  .temp{font-size:56px}
  .scene{height:168px}
}
</style>
</head>
<body>
<div class="page">

  <header class="head">
    <p class="eyebrow">Animated · CSS only</p>
    <h1>Weather Cards</h1>
    <p class="sub">Four hand-built scenes — rotating rays, falling rain, drifting snow and flashing lightning, drawn with nothing but HTML elements and pseudo-elements.</p>
  </header>

  <section class="grid">

    <!-- ================= SUNNY ================= -->
    <article class="card sunny" tabindex="0">
      <div class="scene">
        <div class="glow"></div>
        <div class="sun">
          <div class="rays">
            <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
          </div>
          <div class="core"></div>
        </div>
      </div>
      <div class="info">
        <div class="row">
          <h2 class="city">Cairo</h2>
          <span class="tag">Clear</span>
        </div>
        <div class="temp">34<sup>°</sup></div>
        <p class="desc">Bright sunshine with a light desert breeze.</p>
        <div class="hilo"><span>Feels 37°</span><span>Humidity 18%</span></div>
      </div>
    </article>

    <!-- ================= RAINY ================= -->
    <article class="card rainy" tabindex="0">
      <div class="scene">
        <div class="cloud">
          <b class="puff p1"></b>
          <b class="puff p2"></b>
        </div>
        <div class="rain">
          <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
      </div>
      <div class="info">
        <div class="row">
          <h2 class="city">London</h2>
          <span class="tag">Rain</span>
        </div>
        <div class="temp">12<sup>°</sup></div>
        <p class="desc">Steady rainfall continuing into the evening.</p>
        <div class="hilo"><span>Feels 9°</span><span>Rain 8 mm</span></div>
      </div>
    </article>

    <!-- ================= SNOWY ================= -->
    <article class="card snowy" tabindex="0">
      <div class="scene">
        <div class="cloud">
          <b class="puff p1"></b>
          <b class="puff p2"></b>
        </div>
        <div class="snow">
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
          <i><span></span></i>
        </div>
      </div>
      <div class="info">
        <div class="row">
          <h2 class="city">Reykjavík</h2>
          <span class="tag">Snow</span>
        </div>
        <div class="temp">-4<sup>°</sup></div>
        <p class="desc">Light snowflakes drifting over quiet streets.</p>
        <div class="hilo"><span>Feels -9°</span><span>Wind 14 km/h</span></div>
      </div>
    </article>

    <!-- ================= STORMY ================= -->
    <article class="card storm" tabindex="0">
      <div class="scene">
        <div class="cloud">
          <b class="puff p1"></b>
          <b class="puff p2"></b>
        </div>
        <div class="bolt"></div>
        <div class="rain">
          <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
      </div>
      <div class="info">
        <div class="row">
          <h2 class="city">Mumbai</h2>
          <span class="tag">Storm</span>
        </div>
        <div class="temp">27<sup>°</sup></div>
        <p class="desc">Thunderstorms with heavy showers nearby.</p>
        <div class="hilo"><span>Feels 31°</span><span>Gusts 62 km/h</span></div>
      </div>
    </article>

  </section>

  <footer class="foot">HTML &amp; CSS only — no JavaScript, no images, no SVG, no icon fonts.</footer>

</div>
</body>
</html>