:root {
  --bg-start: #081218;
  --bg-mid: #14272e;
  --bg-end: #1c3742;
  --card: rgba(255, 255, 255, 0.08);
  --card-border: rgba(255, 255, 255, 0.15);
  --text: #f5f7fa;
  --muted: #b8c2cc;
  --accent: #ffd166;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: linear-gradient(135deg, var(--bg-start), var(--bg-mid), var(--bg-end));
  background-attachment: fixed;
  transition: background 1s ease;
}

body.theme-sunny    { --bg-start: #b9942f; --bg-mid: #b85f48; --bg-end: #b04f44; }
body.theme-cloudy   { --bg-start: #474e62; --bg-mid: #525c6e; --bg-end: #6b7585; }
body.theme-rainy    { --bg-start: #1a2530; --bg-mid: #243c47; --bg-end: #2e6470; }
body.theme-snowy    { --bg-start: #4f6489; --bg-mid: #65778e; --bg-end: #8b93a4; }
body.theme-stormy   { --bg-start: #141516; --bg-mid: #28292a; --bg-end: #38424c; }
body.theme-foggy    { --bg-start: #3a4254; --bg-mid: #5e6573; --bg-end: #7a828e; }
body.theme-night    { --bg-start: #060d22; --bg-mid: #101a38; --bg-end: #1a2650; }

/* Dappled light bloom — a soft luminous wash, like sun through haze. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(60% 45% at 30% 22%, rgba(255, 248, 224, 0.28), transparent 70%),
    radial-gradient(50% 40% at 78% 70%, rgba(255, 235, 245, 0.18), transparent 70%);
  mix-blend-mode: soft-light;
}

/* Canvas tooth — fine grain overlaid across the whole page. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  opacity: 0.10;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 220px 220px;
}

.dashboard { position: relative; z-index: 2; }

.dashboard {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 20px 60px;
}

.header { text-align: center; margin-bottom: 24px; }
.header h1 { margin: 0 0 6px; font-weight: 600; letter-spacing: 0.5px; }
.location { margin: 0; color: var(--muted); }

.unit-toggle {
  display: inline-flex;
  margin-top: 12px;
  border: 1px solid var(--card-border);
  border-radius: 999px;
  overflow: hidden;
  background: var(--card);
}
.unit-btn {
  background: transparent;
  color: var(--text);
  border: 0;
  padding: 6px 16px;
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.2s ease;
}
.unit-btn:hover { background: rgba(255, 255, 255, 0.08); }
.unit-btn.active {
  background: rgba(255, 255, 255, 0.2);
  font-weight: 600;
}

.actions { margin-top: 12px; }
.action-btn {
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--card-border);
  border-radius: 999px;
  padding: 6px 18px;
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.1s ease;
}
.action-btn:hover { background: rgba(255, 255, 255, 0.15); }
.action-btn:active { transform: scale(0.96); }
.action-btn.spinning { opacity: 0.6; pointer-events: none; }

.card {
  background: var(--card);
  border: 1px solid var(--card-border);
  border-radius: 18px;
  padding: 24px;
  margin-bottom: 20px;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.animation-card { display: flex; align-items: center; gap: 24px; }
.animation-stage {
  position: relative;
  width: 160px;
  height: 160px;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: 16px;
  background: rgba(0, 0, 0, 0.15);
}

.conditions { flex: 1; }
.temp { font-size: 56px; font-weight: 300; line-height: 1; }
.description { font-size: 20px; margin-top: 6px; }
.details { margin-top: 10px; color: var(--muted); font-size: 14px; line-height: 1.6; }

.map-card h2 { margin: 0 0 12px; font-weight: 500; }
.map {
  width: 100%;
  height: 340px;
  border-radius: 12px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.15);
}
/* Leaflet draws its own stacking context; keep its controls/text readable. */
.map .leaflet-control-attribution {
  background: rgba(255, 255, 255, 0.8);
  color: #333;
}
.map .leaflet-control-attribution a { color: #2c5364; }
.radar-time {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--muted);
  min-height: 1em;
}

.clothing-card h2 { margin: 0 0 12px; font-weight: 500; }
.clothing-list { margin: 0; padding-left: 20px; line-height: 1.8; }

.driving-card h2 { margin: 0 0 12px; font-weight: 500; }
.driving-rating {
  display: inline-block;
  padding: 6px 14px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 12px;
  background: rgba(255, 255, 255, 0.15);
}
.driving-rating.good      { background: rgba(46, 204, 113, 0.25); color: #d4f5dd; }
.driving-rating.fair      { background: rgba(241, 196, 15, 0.25); color: #fff4c2; }
.driving-rating.poor      { background: rgba(230, 126, 34, 0.3);  color: #ffd9b3; }
.driving-rating.hazardous { background: rgba(231, 76, 60, 0.35);  color: #ffd0c9; }
.driving-reasons { margin: 0; padding-left: 20px; line-height: 1.8; }
.driving-reasons:empty { display: none; }

.forecast-card h2 { margin: 0 0 12px; font-weight: 500; }
.forecast-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}
.forecast-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px 6px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.06);
}
.forecast-name { font-size: 13px; color: var(--muted); }
.forecast-icon { line-height: 1; display: flex; }
.wc-icon {
  width: 40px;
  height: 40px;
  overflow: visible;
  filter: url(#monet-soft);
}
.wc-icon * {
  stroke-linecap: round;
  stroke-linejoin: round;
}
.forecast-temps { display: flex; gap: 6px; font-size: 14px; }
.forecast-hi { font-weight: 600; }
.forecast-lo { color: var(--muted); }

/* ===== Animated forecast icons ===== */
/* Sub-parts of the impressionist SVG icons get gentle, always-on motion.
   transform-box: fill-box makes transform-origin resolve within each
   element's own bounding box rather than the SVG viewport. */
.wc-icon g, .wc-icon path, .wc-icon line, .wc-icon circle { transform-box: fill-box; }

.fc-rays {
  transform-origin: center;
  animation: fc-spin 14s linear infinite;
}
.fc-sun-core {
  transform-origin: center;
  animation: fc-pulse 3s ease-in-out infinite;
}
@keyframes fc-spin { to { transform: rotate(360deg); } }
@keyframes fc-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }

.fc-cloud {
  transform-origin: center;
  animation: fc-bob 5s ease-in-out infinite;
}
@keyframes fc-bob {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(1.6px); }
}

.fc-drop {
  transform-origin: center;
  animation: fc-fall 1.1s linear infinite;
}
.fc-drop:nth-child(2) { animation-delay: 0.37s; }
.fc-drop:nth-child(3) { animation-delay: 0.73s; }
@keyframes fc-fall {
  0%   { transform: translateY(-3px); opacity: 0; }
  25%  { opacity: 1; }
  100% { transform: translateY(4px); opacity: 0; }
}

.fc-flake {
  transform-origin: center;
  animation: fc-drift 2.4s linear infinite;
}
.fc-flake:nth-child(2) { animation-delay: 0.8s; }
.fc-flake:nth-child(3) { animation-delay: 1.6s; }
@keyframes fc-drift {
  0%   { transform: translate(0, -3px); opacity: 0; }
  25%  { opacity: 1; }
  100% { transform: translate(1px, 4px); opacity: 0; }
}

.fc-bolt {
  transform-origin: center;
  animation: fc-flicker 3.5s ease-in-out infinite;
}
@keyframes fc-flicker {
  0%, 55%, 62%, 100% { opacity: 0.35; }
  58%, 66%           { opacity: 1; }
}

.fc-fog {
  transform-origin: center;
  animation: fc-sway 6s ease-in-out infinite;
}
@keyframes fc-sway {
  0%, 100% { transform: translateX(-1.4px); }
  50%      { transform: translateX(1.4px); }
}

@media (max-width: 420px) {
  .forecast-grid { gap: 6px; }
  .forecast-day { padding: 10px 2px; }
  .forecast-name { font-size: 12px; }
  .wc-icon { width: 30px; height: 30px; }
  .forecast-temps { font-size: 13px; }
}

.error {
  background: rgba(255, 80, 80, 0.18);
  border: 1px solid rgba(255, 120, 120, 0.4);
  padding: 14px 18px;
  border-radius: 12px;
  text-align: center;
}

@media (max-width: 520px) {
  .animation-card { flex-direction: column; text-align: center; }
}

/* ===== Weather animations ===== */
/* Shapes get inked outlines plus a watercolor displacement filter so they
   look hand-painted rather than geometric. Ink outlines on multi-part
   shapes (clouds) are faked with four offset drop-shadows on the silhouette. */

/* Sun */
.sun {
  position: absolute;
  top: 50%; left: 50%;
  width: 72px; height: 72px;
  margin: -36px 0 0 -36px;
  background:
    radial-gradient(circle at 40% 38%, rgba(255, 252, 230, 0.95), transparent 55%),
    radial-gradient(circle at 60% 65%, rgba(255, 170, 120, 0.6), transparent 60%),
    radial-gradient(circle at 50% 50%, #fff0b0, #ffce7a 55%, #ff9e5e);
  border-radius: 50%;
  box-shadow: 0 0 34px rgba(255, 221, 150, 0.55);
  filter: url(#monet);
  animation: pulse 3s ease-in-out infinite;
}
.sun-rays {
  position: absolute;
  top: 50%; left: 50%;
  width: 140px; height: 140px;
  margin: -70px 0 0 -70px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 10deg, rgba(255,221,150,0.30) 10deg 16deg, transparent 16deg 45deg, rgba(255,221,150,0.30) 45deg 51deg, transparent 51deg 90deg, rgba(255,221,150,0.30) 90deg 96deg, transparent 96deg 135deg, rgba(255,221,150,0.30) 135deg 141deg, transparent 141deg 180deg, rgba(255,221,150,0.30) 180deg 186deg, transparent 186deg 225deg, rgba(255,221,150,0.30) 225deg 231deg, transparent 231deg 270deg, rgba(255,221,150,0.30) 270deg 276deg, transparent 276deg 315deg, rgba(255,221,150,0.30) 315deg 321deg, transparent 321deg 360deg);
  filter: url(#monet) blur(1px);
  opacity: 0.85;
  animation: spin 18s linear infinite;
}
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@keyframes spin { to { transform: rotate(360deg); } }

/* Cloud */
.cloud {
  position: absolute;
  width: 126px; height: 40px;
  background:
    radial-gradient(circle at 30% 30%, rgba(255, 250, 245, 0.95), transparent 70%),
    radial-gradient(circle at 75% 60%, rgba(214, 222, 240, 0.85), transparent 75%),
    #eef0f6;
  border-radius: 42px;
  opacity: 0.9;
  filter: url(#monet) blur(0.6px);
  animation: drift1 9s ease-in-out infinite;
}
.cloud::before, .cloud::after {
  content: "";
  position: absolute;
  background:
    radial-gradient(circle at 40% 35%, rgba(255, 246, 238, 0.95), transparent 75%),
    #e6eaf3;
  border-radius: 50%;
}
.cloud::before { width: 50px; height: 50px; top: -22px; left: 20px; }
.cloud::after  { width: 40px; height: 40px; top: -17px; left: 64px; }
.cloud.c1 { top: 34px; left: 14px; }
.cloud.c2 { top: 92px; left: 40px; opacity: 0.8; animation: drift2 12s ease-in-out infinite; animation-delay: -3s; }
.cloud.c3 { top: 62px; left: 78px; opacity: 0.55; animation: drift3 16s ease-in-out infinite; animation-delay: -7s; }
/* Per-depth drift bakes scale into the keyframe — a plain scale on the element
   would be clobbered by the transform the animation sets each frame. */
@keyframes drift1 { 0%, 100% { transform: translateX(0); }            50% { transform: translateX(15px); } }
@keyframes drift2 { 0%, 100% { transform: translateX(0) scale(0.8); } 50% { transform: translateX(12px) scale(0.8); } }
@keyframes drift3 { 0%, 100% { transform: translateX(0) scale(0.55);} 50% { transform: translateX(22px) scale(0.55); } }

/* Storm clouds — darker, churning. */
.cloud.storm {
  background:
    radial-gradient(circle at 30% 30%, rgba(132, 140, 162, 0.95), transparent 70%),
    radial-gradient(circle at 75% 60%, rgba(86, 94, 116, 0.9), transparent 75%),
    #717a8e;
}
.cloud.storm::before, .cloud.storm::after {
  background:
    radial-gradient(circle at 40% 35%, rgba(150, 158, 178, 0.9), transparent 75%),
    #5e6679;
}

/* Rain */
@property --drift-x {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}
@property --drop-tilt {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}
.animation-stage {
  --drift-x: 0px;
  --drop-tilt: 0deg;
  transition: --drift-x 1.2s ease, --drop-tilt 1.2s ease;
}
.rain-drop {
  position: absolute;
  width: 3px; height: 14px;
  background: linear-gradient(transparent, rgba(120, 162, 196, 0.85));
  border-radius: 60% 60% 50% 50% / 80% 80% 40% 40%;
  transform-origin: top center;
  filter: blur(0.8px);
  animation: fall 0.9s linear infinite;
}
/* Depth: near drops are larger, faster, sharper; far drops smaller, slower, hazier. */
.rain-drop.near { width: 3.5px; height: 16px; filter: blur(0.6px); animation-duration: 0.75s; }
.rain-drop.far  { width: 2px;   height: 10px; filter: blur(1.3px) opacity(0.65); animation-duration: 1.15s; }
@keyframes fall {
  0%   { transform: translate(0, -20px) rotate(var(--drop-tilt)); opacity: 0; }
  20%  { opacity: 1; }
  100% { transform: translate(var(--drift-x), 180px) rotate(var(--drop-tilt)); opacity: 0; }
}

/* Splash ripples at the base of the stage. */
.splash {
  position: absolute;
  bottom: 6px;
  width: 8px; height: 3px;
  border: 1px solid rgba(150, 188, 218, 0.7);
  border-radius: 50%;
  opacity: 0;
  filter: blur(0.5px);
  animation: splash 1.1s linear infinite;
}
@keyframes splash {
  0%, 100% { transform: scale(0.3); opacity: 0; }
  10%      { opacity: 0.8; }
  60%      { transform: scale(1.4); opacity: 0; }
}

/* Snow — outer element falls (and follows wind via --drift-x); inner glyph
   sways side to side, so the two motions compose without clobbering each other. */
.snowflake {
  position: absolute;
  animation: snowfall 4s linear infinite;
}
.snowflake.far  { animation-duration: 5.5s; }
.snowflake.near { animation-duration: 3.2s; }
.flake-glyph {
  display: block;
  color: #f3f7fc;
  font-size: 14px;
  text-shadow: 0 0 3px rgba(220, 230, 245, 0.9);
  filter: url(#monet-soft) blur(0.4px);
  animation: flake-sway 2.6s ease-in-out infinite;
}
.snowflake.far .flake-glyph  { font-size: 10px; opacity: 0.6; }
.snowflake.near .flake-glyph { font-size: 16px; }
@keyframes snowfall {
  0%   { transform: translate(0, -20px); opacity: 0; }
  20%  { opacity: 1; }
  100% { transform: translate(var(--drift-x), 180px); opacity: 0; }
}
@keyframes flake-sway {
  0%, 100% { transform: translateX(-5px); }
  50%      { transform: translateX(5px); }
}

/* Lightning — a forked bolt struck over a full-stage flash, double-flicker. */
.lightning {
  position: absolute;
  inset: 0;
  background: #fff;
  opacity: 0;
  animation: flash 4s infinite;
}
@keyframes flash {
  0%, 91%, 100% { opacity: 0; }
  92%, 95%      { opacity: 0.85; }
  93.5%         { opacity: 0.2; }
}
.bolt {
  position: absolute;
  top: 36px; left: 64px;
  width: 30px; height: 84px;
  background: rgba(255, 244, 190, 0.98);
  clip-path: polygon(58% 0, 24% 46%, 50% 46%, 18% 100%, 72% 40%, 44% 40%, 70% 0);
  filter: drop-shadow(0 0 6px rgba(255, 232, 150, 0.9));
  opacity: 0;
  animation: bolt-strike 4s infinite;
}
@keyframes bolt-strike {
  0%, 91%, 97%, 100% { opacity: 0; }
  92%, 95%           { opacity: 1; }
  93.5%              { opacity: 0.15; }
}

/* Fog */
.fog-layer {
  position: absolute;
  left: -50%;
  width: 200%;
  height: 30px;
  background: linear-gradient(90deg, transparent, rgba(247,245,237,0.55), transparent);
  border-radius: 50%;
  filter: url(#monet) blur(1.5px);
  animation: fogmove 7s linear infinite;
}
.fog-layer.f1 { top: 40px;  animation-duration: 7s; }
.fog-layer.f2 { top: 80px;  animation-delay: -3s; opacity: 0.7; animation-duration: 9s; }
.fog-layer.f3 { top: 120px; animation-delay: -5s; opacity: 0.5; animation-duration: 11s; }
.fog-layer.f4 { top: 14px;  animation-delay: -2s; opacity: 0.4; animation-duration: 13s; }
@keyframes fogmove {
  0%   { transform: translate(-25%, 0); }
  50%  { transform: translate(0, 3px); }
  100% { transform: translate(25%, 0); }
}

/* Moon */
.moon {
  position: absolute;
  top: 50%; left: 50%;
  width: 70px; height: 70px;
  margin: -35px 0 0 -35px;
  background:
    radial-gradient(circle at 38% 36%, rgba(255, 253, 240, 0.95), transparent 60%),
    radial-gradient(circle at 50% 50%, #fbf7e6, #c4c6ec 72%);
  border-radius: 50%;
  box-shadow: 0 0 28px rgba(225, 225, 255, 0.4);
  filter: url(#monet);
}
.star {
  position: absolute;
  width: 2px; height: 2px;
  background: #fff;
  border-radius: 50%;
  animation: twinkle 2s ease-in-out infinite;
}
@keyframes twinkle { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }

/* Faint wisp clouds drifting across the stage (day sun + night). */
.wisp {
  position: absolute;
  width: 96px; height: 22px;
  background: radial-gradient(circle at 40% 50%, rgba(255, 252, 246, 0.5), transparent 72%);
  border-radius: 50%;
  filter: url(#monet) blur(2px);
  opacity: 0.28;
  animation: wisp-cross 22s linear infinite;
}
.wisp.w1 { top: 28px; }
.wisp.w2 { top: 100px; opacity: 0.18; animation-duration: 30s; animation-delay: -12s; }
@keyframes wisp-cross {
  0%   { transform: translateX(-120px); }
  100% { transform: translateX(180px); }
}

/* Floating light motes around the sun. */
.mote {
  position: absolute;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 246, 214, 0.95), transparent 70%);
  filter: blur(1px);
  opacity: 0;
  animation: mote-float 7s ease-in-out infinite;
}
@keyframes mote-float {
  0%, 100% { opacity: 0; transform: translateY(0); }
  50%      { opacity: 0.8; transform: translateY(-14px); }
}

/* Occasional shooting star at night. */
.shooting-star {
  position: absolute;
  width: 60px; height: 2px;
  background: linear-gradient(90deg, transparent, #ffffff);
  border-radius: 2px;
  opacity: 0;
  animation: shoot 8s ease-in infinite;
}
@keyframes shoot {
  0%, 85%  { opacity: 0; transform: translate(40px, -20px) rotate(20deg); }
  88%      { opacity: 0.9; }
  100%     { opacity: 0; transform: translate(-80px, 36px) rotate(20deg); }
}
