Models 44

Mistral Small 4

by MistralReasoningClean
Open in new window

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

How it went

Total time
57.2 s
Cost
$0.0083
Output tokens
12,386
Spent thinking
9,690 tokens
Speed
218.8 tok/s
Console errors
0
First token after
577 ms
First visible text after
45.5 s
Prompt tokens
525
Code size
8.0 KB
Finish reason
stop
Served by
Mistral
Model id
mistralai/mistral-small-2603
Reasoning sent
{"effort":"high"}
Max output
209,715 tokens
Generated
Nov 12, 2026

What it was asked

The prompt
Create a set of four animated weather cards (sunny, rainy, snowy, stormy), made with HTML and CSS only. Requirements: - Absolutely no JavaScript: the file must not contain any <script> tag or inline event handler. - No images, no SVG, no icon fonts: every weather icon is built from HTML elements and pseudo-elements styled with CSS. - Each card shows an animated icon (rotating sun rays, falling rain drops, drifting snowflakes, flashing lightning), a city name, a temperature and a short description. - Each card has its own background gradient matching the weather. - The cards are displayed in a responsive grid (4 per row on desktop, stacked on mobile) and lift up on hover. - Smooth infinite animations using @keyframes, and respect prefers-reduced-motion.
System prompt, sent with every prompt
You are generating a self-contained web demo. It will be rendered automatically in a sandboxed iframe and compared side by side with the output of other AI models given the exact same task.

Output rules:
- Reply with exactly ONE fenced code block containing the complete file: ```html (or ```svg when the task asks for an SVG). No text before or after the code block.
- Everything must be inline: CSS in <style>, JavaScript in <script>. No external files, images, fonts or network requests, except the CDN URLs explicitly allowed by the task.
- Do not use localStorage, sessionStorage, cookies, IndexedDB, alert(), confirm(), prompt() or window.open(): they are blocked in the sandbox and will throw.
- The page must look right in a 1280×800 viewport and adapt gracefully down to 375px wide. No horizontal scrollbar.
- Something meaningful must be visible on first paint: a screenshot is taken automatically about 3 seconds after load, without any interaction.
- Everything that makes the demo interesting must be visible within the first seconds: nothing hidden behind a high score, a later level or a long play session.
- Games must start in a self-playing demo mode (a simple AI plays) behind a "Click or press a key to start" message, so the game can be judged in action without playing.
- The iframe only receives keyboard events after the user clicks it: if the demo uses the keyboard, display a clear "Click or press a key to start" message.
- The code must run with zero errors in the console of the latest Chrome.

Code run-1.html · 340 lines

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Weather Cards</title>
  <style>
    :root {
      --sun-yellow: #FFD700;
      --sun-ray-yellow: #FFC107;
      --rain-blue: #1E88E5;
      --snow-blue: #B3E5FC;
      --storm-purple: #7B1FA2;
      --storm-lightning: #FFD600;
      --text-light: #FFFFFF;
      --text-dark: #212121;
    }

    @media (prefers-reduced-motion: reduce) {
      * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
      }
    }

    body {
      margin: 0;
      padding: 20px;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
      background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
      min-height: 100vh;
    }

    .container {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 20px;
      max-width: 1280px;
      margin: 0 auto;
    }

    .card {
      position: relative;
      padding: 20px;
      border-radius: 16px;
      color: var(--text-light);
      text-align: center;
      box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
      transition: transform 0.3s ease;
      overflow: hidden;
      min-height: 300px;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }

    .card:hover {
      transform: translateY(-10px);
    }

    .card-icon {
      margin-bottom: 15px;
      height: 100px;
      position: relative;
    }

    .card-city {
      font-size: 1.5rem;
      font-weight: bold;
      margin-bottom: 10px;
      text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
    }

    .card-temp {
      font-size: 2.5rem;
      font-weight: bold;
      margin-bottom: 10px;
      text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
    }

    .card-desc {
      font-size: 1rem;
      opacity: 0.9;
      text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
    }

    /* Sunny card */
    .card-sunny {
      background: linear-gradient(135deg, #FFD700 0%, #FFA726 100%);
    }

    .card-sunny .sun {
      position: relative;
      width: 60px;
      height: 60px;
      background: var(--sun-yellow);
      border-radius: 50%;
      margin: 0 auto 10px;
      z-index: 2;
    }

    .card-sunny .rays {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 100px;
      height: 100px;
      transform: translate(-50%, -50%);
      z-index: 1;
    }

    .card-sunny .rays::before,
    .card-sunny .rays::after {
      content: '';
      position: absolute;
      background: var(--sun-ray-yellow);
      border-radius: 5px;
    }

    .card-sunny .rays::before {
      width: 4px;
      height: 20px;
      top: 0;
      left: 50%;
      transform-origin: center;
      animation: rotate 8s linear infinite;
    }

    .card-sunny .rays::after {
      width: 20px;
      height: 4px;
      top: 50%;
      left: 0;
      transform-origin: center;
      animation: rotate 10s linear infinite reverse;
    }

    @keyframes rotate {
      from { transform: translate(-50%, -50%) rotate(0deg); }
      to { transform: translate(-50%, -50%) rotate(360deg); }
    }

    /* Rainy card */
    .card-rainy {
      background: linear-gradient(135deg, #1E88E5 0%, #0D47A1 100%);
    }

    .card-rainy .rain {
      position: relative;
      width: 4px;
      height: 60px;
      background: var(--text-light);
      margin: 0 auto;
      border-radius: 2px;
      animation: fall 1s ease-in-out infinite;
    }

    .card-rainy .rain::before {
      content: '';
      position: absolute;
      width: 12px;
      height: 4px;
      background: var(--text-light);
      border-radius: 2px;
      top: 100%;
      left: -4px;
      animation: fall 1.2s ease-in-out infinite;
    }

    .card-rainy .rain::after {
      content: '';
      position: absolute;
      width: 8px;
      height: 4px;
      background: var(--text-light);
      border-radius: 2px;
      top: 100%;
      right: -2px;
      animation: fall 1.4s ease-in-out infinite;
    }

    @keyframes fall {
      0% {
        transform: translateY(0);
        opacity: 0;
      }
      10% {
        opacity: 1;
      }
      90% {
        opacity: 1;
      }
      100% {
        transform: translateY(100px);
        opacity: 0;
      }
    }

    /* Snowy card */
    .card-snowy {
      background: linear-gradient(135deg, #B3E5FC 0%, #0D47A1 100%);
    }

    .card-snowy .snowflake {
      position: absolute;
      width: 6px;
      height: 6px;
      background: var(--text-light);
      border-radius: 50%;
      margin: 0 auto;
      box-shadow: 0 0 0 2px var(--text-light);
    }

    .card-snowy .snowflake:nth-child(1) { top: 20%; left: 20%; animation: drift 4s linear infinite; }
    .card-snowy .snowflake:nth-child(2) { top: 20%; right: 20%; animation: drift 5s linear infinite reverse; }
    .card-snowy .snowflake:nth-child(3) { top: 60%; left: 30%; animation: drift 6s linear infinite; }
    .card-snowy .snowflake:nth-child(4) { top: 60%; right: 30%; animation: drift 4.5s linear infinite reverse; }
    .card-snowy .snowflake:nth-child(5) { top: 40%; left: 50%; transform: translateX(-50%); animation: drift 5.5s linear infinite; }

    @keyframes drift {
      0% {
        transform: translateY(0) rotate(0deg);
        opacity: 0;
      }
      20% {
        opacity: 1;
      }
      80% {
        opacity: 1;
      }
      100% {
        transform: translateY(100px) rotate(360deg);
        opacity: 0;
      }
    }

    /* Stormy card */
    .card-stormy {
      background: linear-gradient(135deg, #7B1FA2 0%, #4A148C 100%);
    }

    .card-stormy .lightning {
      position: relative;
      width: 0;
      height: 0;
      border-left: 15px solid transparent;
      border-right: 15px solid transparent;
      border-top: 40px solid var(--storm-lightning);
      margin: 0 auto 10px;
      animation: flash 1.5s ease-in-out infinite;
    }

    .card-stormy .rain-streak {
      position: absolute;
      width: 4px;
      height: 60px;
      background: var(--text-light);
      border-radius: 2px;
      top: 100%;
      left: 50%;
      transform: translateX(-50%);
      animation: fall 1.5s ease-in-out infinite;
    }

    @keyframes flash {
      0%, 50%, 100% { opacity: 1; }
      25%, 75% { opacity: 0.3; }
    }

    /* Responsive layout */
    @media (max-width: 1024px) {
      .container {
        grid-template-columns: repeat(3, 1fr);
      }
    }

    @media (max-width: 768px) {
      .container {
        grid-template-columns: repeat(2, 1fr);
      }
    }

    @media (max-width: 480px) {
      .container {
        grid-template-columns: 1fr;
      }

      .card {
        min-height: 250px;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="card card-sunny">
      <div class="card-icon">
        <div class="sun"></div>
        <div class="rays"></div>
      </div>
      <div class="card-city">Los Angeles</div>
      <div class="card-temp">28°C</div>
      <div class="card-desc">Clear skies all day</div>
    </div>

    <div class="card card-rainy">
      <div class="card-icon">
        <div class="rain"></div>
      </div>
      <div class="card-city">London</div>
      <div class="card-temp">15°C</div>
      <div class="card-desc">Light rain expected</div>
    </div>

    <div class="card card-snowy">
      <div class="card-icon">
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
      </div>
      <div class="card-city">Moscow</div>
      <div class="card-temp">-2°C</div>
      <div class="card-desc">Snowfall throughout</div>
    </div>

    <div class="card card-stormy">
      <div class="card-icon">
        <div class="lightning"></div>
        <div class="rain-streak"></div>
      </div>
      <div class="card-city">New York</div>
      <div class="card-temp">12°C</div>
      <div class="card-desc">Thunderstorms likely</div>
    </div>
  </div>
</body>
</html>
Reasoning trace (9,690 tokens)
I need to create four animated weather cards with HTML and CSS only, no JavaScript. Let me break down the requirements:

1. Four cards: sunny, rainy, snowy, stormy
2. Each card has:
   - Animated icon (sun rays rotating, rain drops falling, snowflakes drifting, lightning flashing)
   - City name
   - Temperature
   - Short description
   - Background gradient matching the weather
3. Responsive grid: 4 per row on desktop, stacked on mobile
4. Cards lift up on hover
5. Smooth infinite animations using @keyframes
6. Respect prefers-reduced-motion
7. No images, no SVG, no icon fonts - use HTML elements and pseudo-elements
8. No JavaScript at all

Let me plan the structure:
- Each card will be a div with class "card" and a modifier like "card-sunny", "card-rainy", etc.
- The icon will be created using HTML elements (spans, divs) styled with CSS
- For sunny: multiple rays around a sun circle
- For rainy: multiple rain drop elements
- For snowy: multiple snowflake elements
- For stormy: lightning bolt and maybe some rain
- Each card will have a gradient background specific to the weather
- Use CSS variables for colors to make it easier
- Use @media queries for responsive layout
- Use prefers-reduced-motion to respect user preferences

Let me think about the animations:
- Sunny: sun rays rotating (infinite rotation)
- Rainy: rain drops falling (translateY animation)
- Snowy: snowflakes drifting (translateX/Y with slight rotation)
- Stormy: lightning flashing (opacity/visibility animation)

For the icons, I'll use HTML elements:
- Sunny: a central circle with multiple ray elements around it
- Rainy: multiple vertical lines for rain drops
- Snowy: multiple snowflake elements (maybe using spans with borders)
- Stormy: a zigzag line for lightning

Let me structure the HTML:
- A container div with class "container"
- Four card divs with appropriate classes

CSS structure:
- Define CSS variables for colors
- Define keyframes for each animation
- Style the container as a grid
- Style each card type with its background gradient
- Style the icon for each weather type
- Add hover effect (transform: translateY)
- Use prefers-reduced-motion to reduce or disable animations

Let me start coding:

First, the HTML structure:

```html
<div class="container">
  <div class="card card-sunny">
    <div class="card-icon">
      <div class="sun"></div>
      <div class="rays"></div>
    </div>
    <div class="card-city">Los Angeles</div>
    <div class="card-temp">28°C</div>
    <div class="card-desc">Clear skies all day</div>
  </div>

  <div class="card card-rainy">
    <div class="card-icon">
      <div class="rain"></div>
    </div>
    <div class="card-city">London</div>
    <div class="card-temp">15°C</div>
    <div class="card-desc">Light rain expected</div>
  </div>

  <div class="card card-snowy">
    <div class="card-icon">
      <div class="snow"></div>
    </div>
    <div class="card-city">Moscow</div>
    <div class="card-temp">-2°C</div>
    <div class="card-desc">Snowfall throughout</div>
  </div>

  <div class="card card-stormy">
    <div class="card-icon">
      <div class="storm"></div>
    </div>
    <div class="card-city">New York</div>
    <div class="card-temp">12°C</div>
    <div class="card-desc">Thunderstorms likely</div>
  </div>
</div>
```

Now for the CSS:

I'll define:
- CSS variables for colors
- Keyframes for each animation
- Grid layout for the container
- Card styling including gradients
- Icon styling
- Hover effects
- Reduced motion handling

Let me write the complete CSS:

```css
:root {
  --sun-yellow: #FFD700;
  --sun-ray-yellow: #FFC107;
  --rain-blue: #1E88E5;
  --snow-blue: #B3E5FC;
  --storm-purple: #7B1FA2;
  --storm-lightning: #FFD600;
  --text-light: #FFFFFF;
  --text-dark: #212121;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Base styles */
body {
  margin: 0;
  padding: 20px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  min-height: 100vh;
}

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  max-width: 1280px;
  margin: 0 auto;
}

.card {
  position: relative;
  padding: 20px;
  border-radius: 16px;
  color: var(--text-light);
  text-align: center;
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
  transition: transform 0.3s ease;
  overflow: hidden;
  min-height: 300px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.card:hover {
  transform: translateY(-10px);
}

.card-icon {
  margin-bottom: 15px;
  height: 100px;
  position: relative;
}

/* Sunny card */
.card-sunny {
  background: linear-gradient(135deg, #FFD700 0%, #FFA726 100%);
}

.sun {
  position: relative;
  width: 60px;
  height: 60px;
  background: var(--sun-yellow);
  border-radius: 50%;
  margin: 0 auto;
  z-index: 2;
}

.rays {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100px;
  height: 100px;
  z-index: 1;
}

.rays::before,
.rays::after {
  content: '';
  position: absolute;
  background: var(--sun-ray-yellow);
  border-radius: 5px;
}

.rays::before {
  width: 4px;
  height: 20px;
  top: 0;
  left: 50%;
  transform-origin: center;
}

.rays::after {
  width: 20px;
  height: 4px;
  top: 50%;
  left: 0;
  transform-origin: center;
}

@keyframes rotate {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

@keyframes ray-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

.sunny .rays::before {
  animation: rotate 8s linear infinite;
}

.sunny .rays::after {
  animation: rotate 10s linear infinite reverse;
}

/* Rainy card */
.card-rainy {
  background: linear-gradient(135deg, #1E88E5 0%, #0D47A1 100%);
}

.rain {
  position: relative;
  width: 4px;
  height: 60px;
  background: var(--text-light);
  margin: 0 auto;
  border-radius: 2px;
}

.rain::before {
  content: '';
  position: absolute;
  width: 12px;
  height: 4px;
  background: var(--text-light);
  border-radius: 2px;
  top: 100%;
  left: -4px;
}

.rain::after {
  content: '';
  position: absolute;
  width: 8px;
  height: 4px;
  background: var(--text-light);
  border-radius: 2px;
  top: 100%;
  right: -2px;
}

@keyframes fall {
  0% {
    transform: translateY(0);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    transform: translateY(100px);
    opacity: 0;
  }
}

.rainy .rain {
  animation: fall 1s ease-in-out infinite;
}

.rainy .rain::before,
.rainy .rain::after {
  animation: fall 1.2s ease-in-out infinite;
}

/* Snowy card */
.card-snowy {
  background: linear-gradient(135deg, #B3E5FC 0%, #0D47A1 100%);
}

.snow {
  position: relative;
  width: 60px;
  height: 60px;
  margin: 0 auto;
}

.snowflake {
  position: absolute;
  color: var(--text-light);
  font-size: 20px;
  animation: drift 4s linear infinite;
}

.snowflake:nth-child(1) { top: 0; left: 0; animation-delay: 0s; }
.snowflake:nth-child(2) { top: 0; right: 0; animation-delay: 0.5s; }
.snowflake:nth-child(3) { bottom: 0; left: 0; animation-delay: 1s; }
.snowflake:nth-child(4) { bottom: 0; right: 0; animation-delay: 1.5s; }
.snowflake:nth-child(5) { top: 50%; left: 50%; animation-delay: 2s; transform: translate(-50%, -50%); }

@keyframes drift {
  0% {
    transform: translateY(0) rotate(0deg);
    opacity: 0;
  }
  20% {
    opacity: 1;
  }
  80% {
    opacity: 1;
  }
  100% {
    transform: translateY(100px) rotate(360deg);
    opacity: 0;
  }
}

/* Stormy card */
.card-stormy {
  background: linear-gradient(135deg, #7B1FA2 0%, #4A148C 100%);
}

.storm {
  position: relative;
  width: 60px;
  height: 80px;
  margin: 0 auto;
}

.lightning {
  position: absolute;
  width: 0;
  height: 0;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
  border-top: 40px solid var(--storm-lightning);
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  animation: flash 1.5s ease-in-out infinite;
}

.storm::before {
  content: '';
  position: absolute;
  width: 4px;
  height: 60px;
  background: var(--text-light);
  border-radius: 2px;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  animation: fall 1.5s ease-in-out infinite;
}

@keyframes flash {
  0%, 50%, 100% { opacity: 1; }
  25%, 75% { opacity: 0.3; }
}

/* Card content */
.card-city {
  font-size: 1.5rem;
  font-weight: bold;
  margin-bottom: 10px;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

.card-temp {
  font-size: 2.5rem;
  font-weight: bold;
  margin-bottom: 10px;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

.card-desc {
  font-size: 1rem;
  opacity: 0.9;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

/* Responsive layout */
@media (max-width: 1024px) {
  .container {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 768px) {
  .container {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .container {
    grid-template-columns: 1fr;
  }

  .card {
    min-height: 250px;
  }
}
```

Wait, I need to fix the HTML structure. The classes for the icons need to be specific to each card. Let me revise:

Actually, looking at my CSS, I'm using classes like `.sunny .rays` which means the rays element needs to be inside an element with class "sunny". But in my HTML structure, the card has class `card-sunny`, not `sunny`.

Let me adjust the CSS to use `.card-sunny .rays` instead, or better yet, use the card class directly.

Actually, let me restructure the HTML to have the weather type as a class on the card, and then style based on that:

```html
<div class="container">
  <div class="card card-sunny">
    <div class="card-icon">
      <div class="sun-icon">
        <div class="sun"></div>
        <div class="rays"></div>
      </div>
    </div>
    <div class="card-city">Los Angeles</div>
    <div class="card-temp">28°C</div>
    <div class="card-desc">Clear skies all day</div>
  </div>

  <div class="card card-rainy">
    <div class="card-icon">
      <div class="rain-icon">
        <div class="rain"></div>
      </div>
    </div>
    <div class="card-city">London</div>
    <div class="card-temp">15°C</div>
    <div class="card-desc">Light rain expected</div>
  </div>

  <div class="card card-snowy">
    <div class="card-icon">
      <div class="snow-icon">
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
      </div>
    </div>
    <div class="card-city">Moscow</div>
    <div class="card-temp">-2°C</div>
    <div class="card-desc">Snowfall throughout</div>
  </div>

  <div class="card card-stormy">
    <div class="card-icon">
      <div class="storm-icon">
        <div class="lightning"></div>
        <div class="rain-streak"></div>
      </div>
    </div>
    <div class="card-city">New York</div>
    <div class="card-temp">12°C</div>
    <div class="card-desc">Thunderstorms likely</div>
  </div>
</div>
```

And then update the CSS accordingly. Let me rewrite the entire thing more carefully:

Actually, to make it cleaner, I'll use the card class directly for styling. Let me simplify:

```html
<div class="container">
  <div class="card card-sunny">
    <div class="card-icon">
      <div class="sun"></div>
      <div class="rays"></div>
    </div>
    <div class="card-city">Los Angeles</div>
    <div class="card-temp">28°C</div>
    <div class="card-desc">Clear skies all day</div>
  </div>

  <div class="card card-rainy">
    <div class="card-icon">
      <div class="rain"></div>
    </div>
    <div class="card-city">London</div>
    <div class="card-temp">15°C</div>
    <div class="card-desc">Light rain expected</div>
  </div>

  <div class="card card-snowy">
    <div class="card-icon">
      <div class="snowflake"></div>
      <div class="snowflake"></div>
      <div class="snowflake"></div>
      <div class="snowflake"></div>
      <div class="snowflake"></div>
    </div>
    <div class="card-city">Moscow</div>
    <div class="card-temp">-2°C</div>
    <div class="card-desc">Snowfall throughout</div>
  </div>

  <div class="card card-stormy">
    <div class="card-icon">
      <div class="lightning"></div>
    </div>
    <div class="card-city">New York</div>
    <div class="card-temp">12°C</div>
    <div class="card-desc">Thunderstorms likely</div>
  </div>
</div>
```

Now for the CSS, I'll use the card class to scope the styles:

```css
:root {
  --sun-yellow: #FFD700;
  --sun-ray-yellow: #FFC107;
  --rain-blue: #1E88E5;
  --snow-blue: #B3E5FC;
  --storm-purple: #7B1FA2;
  --storm-lightning: #FFD600;
  --text-light: #FFFFFF;
  --text-dark: #212121;
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Base styles */
body {
  margin: 0;
  padding: 20px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  min-height: 100vh;
}

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
  max-width: 1280px;
  margin: 0 auto;
}

.card {
  position: relative;
  padding: 20px;
  border-radius: 16px;
  color: var(--text-light);
  text-align: center;
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
  transition: transform 0.3s ease;
  overflow: hidden;
  min-height: 300px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.card:hover {
  transform: translateY(-10px);
}

.card-icon {
  margin-bottom: 15px;
  height: 100px;
  position: relative;
}

/* Sunny card */
.card-sunny {
  background: linear-gradient(135deg, #FFD700 0%, #FFA726 100%);
}

.card-sunny .sun {
  position: relative;
  width: 60px;
  height: 60px;
  background: var(--sun-yellow);
  border-radius: 50%;
  margin: 0 auto 10px;
  z-index: 2;
}

.card-sunny .rays {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100px;
  height: 100px;
  transform: translate(-50%, -50%);
  z-index: 1;
}

.card-sunny .rays::before,
.card-sunny .rays::after {
  content: '';
  position: absolute;
  background: var(--sun-ray-yellow);
  border-radius: 5px;
}

.card-sunny .rays::before {
  width: 4px;
  height: 20px;
  top: 0;
  left: 50%;
  transform-origin: center;
  animation: rotate 8s linear infinite;
}

.card-sunny .rays::after {
  width: 20px;
  height: 4px;
  top: 50%;
  left: 0;
  transform-origin: center;
  animation: rotate 10s linear infinite reverse;
}

@keyframes rotate {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

/* Rainy card */
.card-rainy {
  background: linear-gradient(135deg, #1E88E5 0%, #0D47A1 100%);
}

.card-rainy .rain {
  position: relative;
  width: 4px;
  height: 60px;
  background: var(--text-light);
  margin: 0 auto;
  border-radius: 2px;
  animation: fall 1s ease-in-out infinite;
}

.card-rainy .rain::before {
  content: '';
  position: absolute;
  width: 12px;
  height: 4px;
  background: var(--text-light);
  border-radius: 2px;
  top: 100%;
  left: -4px;
  animation: fall 1.2s ease-in-out infinite;
}

.card-rainy .rain::after {
  content: '';
  position: absolute;
  width: 8px;
  height: 4px;
  background: var(--text-light);
  border-radius: 2px;
  top: 100%;
  right: -2px;
  animation: fall 1.4s ease-in-out infinite;
}

@keyframes fall {
  0% {
    transform: translateY(0);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  90% {
    opacity: 1;
  }
  100% {
    transform: translateY(100px);
    opacity: 0;
  }
}

/* Snowy card */
.card-snowy {
  background: linear-gradient(135deg, #B3E5FC 0%, #0D47A1 100%);
}

.card-snowy .snowflake {
  position: absolute;
  width: 6px;
  height: 6px;
  background: var(--text-light);
  border-radius: 50%;
  margin: 0 auto;
  box-shadow: 0 0 0 2px var(--text-light);
}

.card-snowy .snowflake:nth-child(1) { top: 20%; left: 20%; animation: drift 4s linear infinite; }
.card-snowy .snowflake:nth-child(2) { top: 20%; right: 20%; animation: drift 5s linear infinite reverse; }
.card-snowy .snowflake:nth-child(3) { top: 60%; left: 30%; animation: drift 6s linear infinite; }
.card-snowy .snowflake:nth-child(4) { top: 60%; right: 30%; animation: drift 4.5s linear infinite reverse; }
.card-snowy .snowflake:nth-child(5) { top: 40%; left: 50%; transform: translateX(-50%); animation: drift 5.5s linear infinite; }

@keyframes drift {
  0% {
    transform: translateY(0) rotate(0deg);
    opacity: 0;
  }
  20% {
    opacity: 1;
  }
  80% {
    opacity: 1;
  }
  100% {
    transform: translateY(100px) rotate(360deg);
    opacity: 0;
  }
}

/* Stormy card */
.card-stormy {
  background: linear-gradient(135deg, #7B1FA2 0%, #4A148C 100%);
}

.card-stormy .lightning {
  position: relative;
  width: 0;
  height: 0;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
  border-top: 40px solid var(--storm-lightning);
  margin: 0 auto 10px;
  animation: flash 1.5s ease-in-out infinite;
}

.card-stormy .lightning::before {
  content: '';
  position: absolute;
  width: 4px;
  height: 60px;
  background: var(--text-light);
  border-radius: 2px;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  animation: fall 1.5s ease-in-out infinite;
}

@keyframes flash {
  0%, 50%, 100% { opacity: 1; }
  25%, 75% { opacity: 0.3; }
}

/* Card content */
.card-city {
  font-size: 1.5rem;
  font-weight: bold;
  margin-bottom: 10px;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

.card-temp {
  font-size: 2.5rem;
  font-weight: bold;
  margin-bottom: 10px;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

.card-desc {
  font-size: 1rem;
  opacity: 0.9;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

/* Responsive layout */
@media (max-width: 1024px) {
  .container {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 768px) {
  .container {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .container {
    grid-template-columns: 1fr;
  }

  .card {
    min-height: 250px;
  }
}
```

Wait, I need to make sure the snowflakes are positioned correctly. Let me adjust the snowflake positioning. The card-icon has height 100px and is positioned relatively. The snowflakes should be positioned within that container.

Also, I need to make sure the card-icon container is properly sized. Let me adjust:

Actually, looking at the code, the card-icon has height: 100px and position: relative, which is good. The snowflakes are absolutely positioned within it.

Let me also check the stormy card - it needs both lightning and rain. Let me update that:

```css
.card-stormy .lightning {
  position: relative;
  width: 0;
  height: 0;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
  border-top: 40px solid var(--storm-lightning);
  margin: 0 auto 10px;
  animation: flash 1.5s ease-in-out infinite;
}

.card-stormy .rain-streak {
  position: absolute;
  width: 4px;
  height: 60px;
  background: var(--text-light);
  border-radius: 2px;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  animation: fall 1.5s ease-in-out infinite;
}
```

And update the HTML for stormy:

```html
<div class="card card-stormy">
  <div class="card-icon">
    <div class="lightning"></div>
    <div class="rain-streak"></div>
  </div>
  <div class="card-city">New York</div>
  <div class="card-temp">12°C</div>
  <div class="card-desc">Thunderstorms likely</div>
</div>
```

Now let me put it all together in a single HTML file with inline CSS:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Weather Cards</title>
  <style>
    :root {
      --sun-yellow: #FFD700;
      --sun-ray-yellow: #FFC107;
      --rain-blue: #1E88E5;
      --snow-blue: #B3E5FC;
      --storm-purple: #7B1FA2;
      --storm-lightning: #FFD600;
      --text-light: #FFFFFF;
      --text-dark: #212121;
    }

    @media (prefers-reduced-motion: reduce) {
      * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
      }
    }

    /* Base styles */
    body {
      margin: 0;
      padding: 20px;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
      background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
      min-height: 100vh;
    }

    .container {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 20px;
      max-width: 1280px;
      margin: 0 auto;
    }

    .card {
      position: relative;
      padding: 20px;
      border-radius: 16px;
      color: var(--text-light);
      text-align: center;
      box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
      transition: transform 0.3s ease;
      overflow: hidden;
      min-height: 300px;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }

    .card:hover {
      transform: translateY(-10px);
    }

    .card-icon {
      margin-bottom: 15px;
      height: 100px;
      position: relative;
    }

    /* Sunny card */
    .card-sunny {
      background: linear-gradient(135deg, #FFD700 0%, #FFA726 100%);
    }

    .card-sunny .sun {
      position: relative;
      width: 60px;
      height: 60px;
      background: var(--sun-yellow);
      border-radius: 50%;
      margin: 0 auto 10px;
      z-index: 2;
    }

    .card-sunny .rays {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 100px;
      height: 100px;
      transform: translate(-50%, -50%);
      z-index: 1;
    }

    .card-sunny .rays::before,
    .card-sunny .rays::after {
      content: '';
      position: absolute;
      background: var(--sun-ray-yellow);
      border-radius: 5px;
    }

    .card-sunny .rays::before {
      width: 4px;
      height: 20px;
      top: 0;
      left: 50%;
      transform-origin: center;
      animation: rotate 8s linear infinite;
    }

    .card-sunny .rays::after {
      width: 20px;
      height: 4px;
      top: 50%;
      left: 0;
      transform-origin: center;
      animation: rotate 10s linear infinite reverse;
    }

    @keyframes rotate {
      from { transform: translate(-50%, -50%) rotate(0deg); }
      to { transform: translate(-50%, -50%) rotate(360deg); }
    }

    /* Rainy card */
    .card-rainy {
      background: linear-gradient(135deg, #1E88E5 0%, #0D47A1 100%);
    }

    .card-rainy .rain {
      position: relative;
      width: 4px;
      height: 60px;
      background: var(--text-light);
      margin: 0 auto;
      border-radius: 2px;
      animation: fall 1s ease-in-out infinite;
    }

    .card-rainy .rain::before {
      content: '';
      position: absolute;
      width: 12px;
      height: 4px;
      background: var(--text-light);
      border-radius: 2px;
      top: 100%;
      left: -4px;
      animation: fall 1.2s ease-in-out infinite;
    }

    .card-rainy .rain::after {
      content: '';
      position: absolute;
      width: 8px;
      height: 4px;
      background: var(--text-light);
      border-radius: 2px;
      top: 100%;
      right: -2px;
      animation: fall 1.4s ease-in-out infinite;
    }

    @keyframes fall {
      0% {
        transform: translateY(0);
        opacity: 0;
      }
      10% {
        opacity: 1;
      }
      90% {
        opacity: 1;
      }
      100% {
        transform: translateY(100px);
        opacity: 0;
      }
    }

    /* Snowy card */
    .card-snowy {
      background: linear-gradient(135deg, #B3E5FC 0%, #0D47A1 100%);
    }

    .card-snowy .snowflake {
      position: absolute;
      width: 6px;
      height: 6px;
      background: var(--text-light);
      border-radius: 50%;
      margin: 0 auto;
      box-shadow: 0 0 0 2px var(--text-light);
    }

    .card-snowy .snowflake:nth-child(1) { top: 20%; left: 20%; animation: drift 4s linear infinite; }
    .card-snowy .snowflake:nth-child(2) { top: 20%; right: 20%; animation: drift 5s linear infinite reverse; }
    .card-snowy .snowflake:nth-child(3) { top: 60%; left: 30%; animation: drift 6s linear infinite; }
    .card-snowy .snowflake:nth-child(4) { top: 60%; right: 30%; animation: drift 4.5s linear infinite reverse; }
    .card-snowy .snowflake:nth-child(5) { top: 40%; left: 50%; transform: translateX(-50%); animation: drift 5.5s linear infinite; }

    @keyframes drift {
      0% {
        transform: translateY(0) rotate(0deg);
        opacity: 0;
      }
      20% {
        opacity: 1;
      }
      80% {
        opacity: 1;
      }
      100% {
        transform: translateY(100px) rotate(360deg);
        opacity: 0;
      }
    }

    /* Stormy card */
    .card-stormy {
      background: linear-gradient(135deg, #7B1FA2 0%, #4A148C 100%);
    }

    .card-stormy .lightning {
      position: relative;
      width: 0;
      height: 0;
      border-left: 15px solid transparent;
      border-right: 15px solid transparent;
      border-top: 40px solid var(--storm-lightning);
      margin: 0 auto 10px;
      animation: flash 1.5s ease-in-out infinite;
    }

    .card-stormy .rain-streak {
      position: absolute;
      width: 4px;
      height: 60px;
      background: var(--text-light);
      border-radius: 2px;
      top: 100%;
      left: 50%;
      transform: translateX(-50%);
      animation: fall 1.5s ease-in-out infinite;
    }

    @keyframes flash {
      0%, 50%, 100% { opacity: 1; }
      25%, 75% { opacity: 0.3; }
    }

    /* Card content */
    .card-city {
      font-size: 1.5rem;
      font-weight: bold;
      margin-bottom: 10px;
      text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
    }

    .card-temp {
      font-size: 2.5rem;
      font-weight: bold;
      margin-bottom: 10px;
      text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
    }

    .card-desc {
      font-size: 1rem;
      opacity: 0.9;
      text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
    }

    /* Responsive layout */
    @media (max-width: 1024px) {
      .container {
        grid-template-columns: repeat(3, 1fr);
      }
    }

    @media (max-width: 768px) {
      .container {
        grid-template-columns: repeat(2, 1fr);
      }
    }

    @media (max-width: 480px) {
      .container {
        grid-template-columns: 1fr;
      }

      .card {
        min-height: 250px;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="card card-sunny">
      <div class="card-icon">
        <div class="sun"></div>
        <div class="rays"></div>
      </div>
      <div class="card-city">Los Angeles</div>
      <div class="card-temp">28°C</div>
      <div class="card-desc">Clear skies all day</div>
    </div>

    <div class="card card-rainy">
      <div class="card-icon">
        <div class="rain"></div>
      </div>
      <div class="card-city">London</div>
      <div class="card-temp">15°C</div>
      <div class="card-desc">Light rain expected</div>
    </div>

    <div class="card card-snowy">
      <div class="card-icon">
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
        <div class="snowflake"></div>
      </div>
      <div class="card-city">Moscow</div>
      <div class="card-temp">-2°C</div>
      <div class="card-desc">Snowfall throughout</div>
    </div>

    <div class="card card-stormy">
      <div class="card-icon">
        <div class="lightning"></div>
        <div class="rain-streak"></div>
      </div>
      <div class="card-city">New York</div>
      <div class="card-temp">12°C</div>
      <div class="card-desc">Thunderstorms likely</div>
    </div>
  </div>
</body>
</html>
```

Let me verify this meets all requirements:
1. ✓ No JavaScript - no script tags
2. ✓ No images, no SVG, no icon fonts - using HTML elements and CSS
3. ✓ Four cards with different weather conditions
4. ✓ Each card has animated icon:
   - Sunny: rotating sun rays
   - Rainy: falling rain drops
   - Snowy: drifting snowflakes
   - Stormy: flashing lightning with rain streak
5. ✓ Each card has city name, temperature, description
6. ✓ Each card has background gradient matching weather
7. ✓ Responsive grid: 4 per row on desktop, stacked on mobile
8. ✓ Cards lift up on hover
9. ✓ Smooth infinite animations using @keyframes
10. ✓ Respects prefers-reduced-motion

Let me check the animations more carefully:
- Sunny: rays rotate in opposite directions at different speeds - looks good
- Rainy: multiple rain drops with different sizes and animation delays - looks good
- Snowy: multiple snowflakes with different positions and animation delays - looks good
- Stormy: lightning flashes and rain falls - looks good

The responsive layout uses media queries to adjust from 4 columns down to 1 column.

The hover effect uses transform: translateY(-10px) which creates a nice lift effect.

The prefers-reduced-motion media query will disable or reduce animations when the user has that preference set.

Everything is inline in a single HTML file with no external resources.

This should work!