/* ============================================
   VISIBLEMILES — Weather Effects CSS
   Desert sandstorms and dry thunderstorms
   ============================================ */

/* ============================================
   WEATHER LAYERS (viewport-attached)
   ============================================ */

/* Base weather layer styles */
.weather-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  contain: strict;
}

/* ============================================
   VIGNETTE NOTE
   ============================================
   Vignette effects are now rendered on the lighting canvas
   (in game.js drawVignette function) for better integration
   with the day/night cycle and no CSS banding issues.
   ============================================ */

/* Sandstorm layer - contains streak particles */
/* PERF: Uses CSS custom property - JS sets value, CSS handles rendering on compositor */
/* z-index 14: UNDER night canvas (15) so particles are dimmed at night */
#sandstorm-layer {
  z-index: 14;
  --sand-opacity: 0;
  opacity: var(--sand-opacity);
  transition: opacity var(--fade-slow) ease-out;
  contain: strict;
  /* PERF: Skip rendering work when not visible (opacity: 0) */
  content-visibility: auto;
}

/* PERF: Remove entire subtree from rendering pipeline when not visible.
 * content-visibility:hidden is cheaper than animation:none on individual particles
 * because it skips style/layout/paint/composite for all children at once.
 * animation:none on paused particles would also cause a visible sync restart artifact. */
#sandstorm-layer.paused {
  content-visibility: hidden;
}

/* PERF: Same treatment for intense sub-layer when below opacity threshold */
#sandstorm-layer .sand-layer-intense.paused {
  content-visibility: hidden;
}

/* Sandstorm vignette removed - now handled by #vignette-storm */


/* Thunderstorm layer - rain drops and wind debris */
/* PERF: Uses CSS custom property - JS sets value, CSS handles rendering on compositor */
/* z-index 14: UNDER night canvas (15) so particles are dimmed at night */
#thunderstorm-layer {
  z-index: 14;
  --thunder-opacity: 0;
  opacity: var(--thunder-opacity);
  transition: opacity var(--fade-slow) ease-out;
  contain: strict;
  /* PERF: Skip rendering work when not visible (opacity: 0) */
  content-visibility: auto;
}

/* PERF: Remove entire subtree from rendering pipeline when not visible.
 * See sandstorm-layer comment above — same approach. */
#thunderstorm-layer.paused {
  content-visibility: hidden;
}

/* PERF: Same treatment for intense sub-layer when below opacity threshold */
#thunderstorm-layer .thunder-layer-intense.paused {
  content-visibility: hidden;
}

/* Weather overlay - visibility reduction tint */
/* PERF: Uses CSS custom property for background color - JS sets full value */
/* z-index 14: UNDER night canvas (15) so tint is dimmed at night */
#weather-overlay {
  z-index: 14;
  --overlay-bg: transparent;
  background: var(--overlay-bg);
  mix-blend-mode: multiply;
  contain: strict;
}

/* ============================================
   THUNDERSTORM EFFECTS — DISTANT LIGHTNING
   ============================================ */

/* 
 * Lightning as corner glow (bright corners, transparent center)
 * Creates the effect of distant lightning on the horizon
 * Light only hits the edges/corners, not the whole screen
 * 
 * z-index 24: UNDER main vignette (30) but ABOVE night canvas (15)
 */
/* 
 * Lightning - corner-only illumination
 * Four corner gradients simulate distant lightning on horizon
 */
#lightning-flash {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 24;
  transition: opacity 0.08s linear;
  contain: strict;
  opacity: 0;
  
  /* Four corner radial gradients - light ONLY in corners */
  background: 
    radial-gradient(ellipse 50% 50% at 0% 0%, oklch(from var(--weather-lightning-glow) l c h / 0.25) 0%, oklch(from var(--weather-lightning-glow) l c h / 0) 70%),
    radial-gradient(ellipse 50% 50% at 100% 0%, oklch(from var(--weather-lightning-glow) l c h / 0.25) 0%, oklch(from var(--weather-lightning-glow) l c h / 0) 70%),
    radial-gradient(ellipse 50% 50% at 0% 100%, oklch(from var(--weather-lightning-glow) l c h / 0.20) 0%, oklch(from var(--weather-lightning-glow) l c h / 0) 70%),
    radial-gradient(ellipse 50% 50% at 100% 100%, oklch(from var(--weather-lightning-glow) l c h / 0.20) 0%, oklch(from var(--weather-lightning-glow) l c h / 0) 70%);
}

/* Regular flash - distant rumble */
#lightning-flash.flash {
  opacity: 0.4;
}

/* Strong flash - closer strike */
#lightning-flash.flash-strong {
  opacity: 0.6;
}

/* Horizon flash - top corners only */
#lightning-flash.flash-horizon {
  opacity: 0.35;
  background: 
    radial-gradient(ellipse 60% 40% at 0% 0%, oklch(from var(--weather-lightning-glow) l c h / 0.30) 0%, oklch(from var(--weather-lightning-glow) l c h / 0) 70%),
    radial-gradient(ellipse 60% 40% at 100% 0%, oklch(from var(--weather-lightning-glow) l c h / 0.30) 0%, oklch(from var(--weather-lightning-glow) l c h / 0) 70%);
}

/* ============================================
   SPIT RAIN (cosmetic, very rare)
   ============================================ */

/* Rain container (spit rain during thunder) */
/* Rain opacity can use transition (rare event, not per-frame) */
/* z-index 14: UNDER night canvas (15) so rain is dimmed at night */
#rain-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 14;
  opacity: 0;
  transition: opacity var(--fade-slow) ease;
  overflow: hidden;
  contain: strict;
  /* PERF: Skip rendering when inactive (opacity: 0) */
  content-visibility: auto;
}

#rain-layer.active {
  opacity: 1;
}

/* Sand gust layer (sandstorm equivalent to rain) */
#sand-gust-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 14;
  opacity: 0;
  transition: opacity var(--fade-standard) ease;
  overflow: hidden;
  contain: strict;
  /* PERF: Skip rendering when inactive (opacity: 0) */
  content-visibility: auto;
}

#sand-gust-layer.active {
  opacity: 1;
}

.sand-gust-particle {
  /* PERF: No will-change - container handles compositing */
  contain: layout style;
}

/* Individual rain drops - simple vertical lines */
/* PERF: No will-change on individual particles - container handles compositing */
.rain-drop {
  position: absolute;
  width: 1px;
  height: 12px;
  background: linear-gradient(
    to bottom,
    oklch(from var(--weather-rain-drop) l c h / 0) 0%,
    oklch(from var(--weather-rain-drop) l c h / 0.6) 30%,
    oklch(from var(--weather-rain-drop) l c h / 0.8) 70%,
    oklch(from var(--weather-rain-drop) l c h / 0) 100%
  );
  pointer-events: none;
  /* Hidden by default - animation reveals */
  opacity: 0;
  contain: layout style;
}

/* Rain keyframes generated at runtime: rain-fall-${variant} in weather.js */

/* ============================================
   HEAT HAZE
   ============================================
   Now rendered on lighting canvas (game.js drawHeatHaze)
   for better integration and no CSS banding issues.
   ============================================ */

/* Reduce motion: static */
@media (prefers-reduced-motion: reduce) {
  #heat-haze::before,
  #heat-haze::after {
    animation: none;
  }
}

/* ============================================
   DUST DEVILS (ambient clear weather effect)
   Independent pixels orbiting in a vortex pattern.
   All animation handled by JS (WAAPI) for independent motion.
   ============================================ */

/* Container for dust devil pixels */
#dust-devil-container {
  contain: strict;
}

/* Individual dust pixels - CSS animation, world-anchored */
/* PERF: No will-change on individual particles - reduces GPU layer count */
.dust-devil-pixel {
  position: absolute;
  z-index: 12;  /* Above trains (11), below ships (13), UNDER night canvas (15) */
  pointer-events: none;
  contain: layout style;
  transition: opacity var(--fade-slow) ease-out;
}

/* Storm fade-out: gracefully hide dust devils when storms start.
 * Uses animation:none to fully detach the keyframes. (A paused animation is also
 * dormant per session 511's measurement; the old "paused still costs per-frame
 * compositor bookkeeping, Chromium bug 40728212" claim was disproven.) */
.dust-devil-pixel.storm-fade {
  opacity: 0 !important;
  animation: none !important;
}

/* ============================================
   AMBIENT DUST (permanent background effect)
   ============================================ */

/* Container - layout isolation for perf */
/* ============================================
   AMBIENT DUST - World-anchored particles
   Position set via left/top (world coords)
   Animation uses RELATIVE transforms so they stay anchored
   ============================================ */

.ambient-dust-pixel {
  position: absolute;
  pointer-events: none;
  z-index: 14;  /* UNDER night canvas (15) so dust is dimmed at night */
  opacity: 0;
  /* PERF: No will-change on individual particles - container handles compositing */
  contain: layout style;
  transition: opacity var(--fade-slow) ease-out;
}

/* Storm fade-out: gracefully hide ambient dust when storms start.
 * Uses animation:none to fully detach the keyframes. (A paused animation is also
 * dormant per session 511's measurement; the old "paused still costs per-frame
 * compositor bookkeeping, Chromium bug 40728212" claim was disproven.) */
.ambient-dust-pixel.storm-fade {
  opacity: 0 !important;
  animation: none !important;
}

/* Active state triggers animation */
.ambient-dust-pixel.active {
  animation-duration: 5s;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}

/* Four swirl variants for variety */
.ambient-dust-pixel.dust-anim-1 { animation-name: dust-swirl-1; }
.ambient-dust-pixel.dust-anim-2 { animation-name: dust-swirl-2; }
.ambient-dust-pixel.dust-anim-3 { animation-name: dust-swirl-3; }
.ambient-dust-pixel.dust-anim-4 { animation-name: dust-swirl-4; }

/* Swirl variant 1: clockwise spiral up-right */
/* PERF: Uses 3D transforms for GPU acceleration */
@keyframes dust-swirl-1 {
  0% { transform: translate3d(0, 0, 0) rotate3d(0, 0, 1, 0deg) scale3d(0.5, 0.5, 1); opacity: 0; }
  10% { transform: translate3d(4px, -3px, 0) rotate3d(0, 0, 1, 36deg) scale3d(0.7, 0.7, 1); opacity: 0.72; }
  25% { transform: translate3d(12px, -8px, 0) rotate3d(0, 0, 1, 90deg) scale3d(0.9, 0.9, 1); opacity: 0.72; }
  50% { transform: translate3d(18px, -18px, 0) rotate3d(0, 0, 1, 180deg) scale3d(1, 1, 1); opacity: 0.65; }
  75% { transform: translate3d(22px, -28px, 0) rotate3d(0, 0, 1, 270deg) scale3d(0.85, 0.85, 1); opacity: 0.4; }
  100% { transform: translate3d(25px, -38px, 0) rotate3d(0, 0, 1, 360deg) scale3d(0.6, 0.6, 1); opacity: 0; }
}

/* Swirl variant 2: counter-clockwise spiral up-left */
@keyframes dust-swirl-2 {
  0% { transform: translate3d(0, 0, 0) rotate3d(0, 0, 1, 0deg) scale3d(0.6, 0.6, 1); opacity: 0; }
  10% { transform: translate3d(-3px, -4px, 0) rotate3d(0, 0, 1, -36deg) scale3d(0.75, 0.75, 1); opacity: 0.68; }
  25% { transform: translate3d(-10px, -10px, 0) rotate3d(0, 0, 1, -90deg) scale3d(0.9, 0.9, 1); opacity: 0.68; }
  50% { transform: translate3d(-16px, -20px, 0) rotate3d(0, 0, 1, -180deg) scale3d(1, 1, 1); opacity: 0.6; }
  75% { transform: translate3d(-20px, -28px, 0) rotate3d(0, 0, 1, -270deg) scale3d(0.8, 0.8, 1); opacity: 0.35; }
  100% { transform: translate3d(-22px, -36px, 0) rotate3d(0, 0, 1, -360deg) scale3d(0.55, 0.55, 1); opacity: 0; }
}

/* Swirl variant 3: wide lazy spiral right */
@keyframes dust-swirl-3 {
  0% { transform: translate3d(0, 0, 0) rotate3d(0, 0, 1, 0deg) scale3d(0.5, 0.5, 1); opacity: 0; }
  12% { transform: translate3d(8px, -2px, 0) rotate3d(0, 0, 1, 45deg) scale3d(0.75, 0.75, 1); opacity: 0.68; }
  33% { transform: translate3d(18px, -8px, 0) rotate3d(0, 0, 1, 120deg) scale3d(0.95, 0.95, 1); opacity: 0.72; }
  55% { transform: translate3d(25px, -18px, 0) rotate3d(0, 0, 1, 200deg) scale3d(1, 1, 1); opacity: 0.6; }
  78% { transform: translate3d(28px, -30px, 0) rotate3d(0, 0, 1, 280deg) scale3d(0.8, 0.8, 1); opacity: 0.35; }
  100% { transform: translate3d(30px, -42px, 0) rotate3d(0, 0, 1, 360deg) scale3d(0.55, 0.55, 1); opacity: 0; }
}

/* Swirl variant 4: gentle float with half rotation */
@keyframes dust-swirl-4 {
  0% { transform: translate3d(0, 0, 0) rotate3d(0, 0, 1, 0deg) scale3d(0.55, 0.55, 1); opacity: 0; }
  15% { transform: translate3d(-2px, -6px, 0) rotate3d(0, 0, 1, 30deg) scale3d(0.75, 0.75, 1); opacity: 0.68; }
  35% { transform: translate3d(2px, -14px, 0) rotate3d(0, 0, 1, 70deg) scale3d(0.9, 0.9, 1); opacity: 0.68; }
  55% { transform: translate3d(5px, -22px, 0) rotate3d(0, 0, 1, 110deg) scale3d(0.95, 0.95, 1); opacity: 0.55; }
  78% { transform: translate3d(3px, -32px, 0) rotate3d(0, 0, 1, 150deg) scale3d(0.8, 0.8, 1); opacity: 0.3; }
  100% { transform: translate3d(0px, -40px, 0) rotate3d(0, 0, 1, 180deg) scale3d(0.6, 0.6, 1); opacity: 0; }
}

/* ============================================
   SANDSTORM DRIFT KEYFRAMES
   4 base variants + 4 intense variants
   Short opacity fades at start/end mask loop reset
   ============================================ */

@keyframes sand-drift-v0 {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  5% { opacity: 0.6; }
  95% { opacity: 0.6; }
  100% { transform: translate3d(700px, 250px, 0); opacity: 0; }
}
@keyframes sand-drift-v1 {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  6% { opacity: 0.55; }
  94% { opacity: 0.55; }
  100% { transform: translate3d(750px, 180px, 0); opacity: 0; }
}
@keyframes sand-drift-v2 {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  4% { opacity: 0.65; }
  96% { opacity: 0.65; }
  100% { transform: translate3d(680px, 320px, 0); opacity: 0; }
}
@keyframes sand-drift-v3 {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  7% { opacity: 0.5; }
  93% { opacity: 0.5; }
  100% { transform: translate3d(720px, 200px, 0); opacity: 0; }
}

@keyframes sand-drift-intense-v0 {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  4% { opacity: 0.7; }
  96% { opacity: 0.7; }
  100% { transform: translate3d(900px, 140px, 0); opacity: 0; }
}
@keyframes sand-drift-intense-v1 {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  5% { opacity: 0.65; }
  95% { opacity: 0.65; }
  100% { transform: translate3d(950px, 100px, 0); opacity: 0; }
}
@keyframes sand-drift-intense-v2 {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  3% { opacity: 0.75; }
  97% { opacity: 0.75; }
  100% { transform: translate3d(880px, 160px, 0); opacity: 0; }
}
@keyframes sand-drift-intense-v3 {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  6% { opacity: 0.6; }
  94% { opacity: 0.6; }
  100% { transform: translate3d(920px, 80px, 0); opacity: 0; }
}

/* ============================================
   WEATHER INDICATOR (minimap/worldmap)
   ============================================ */

.weather-indicator {
  position: absolute;
  top: var(--gui-padding);
  right: var(--gui-padding);
  padding: var(--gui-padding-sm);
  font-size: var(--font-size-xs);
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--fade-slow) ease;
  z-index: 10;
}

.weather-indicator.active {
  opacity: 1;
}

/* Full storms - bold styling */
.weather-indicator.sandstorm {
  background: var(--weather-badge-sandstorm-bg);
  color: var(--weather-badge-sandstorm-text);
  box-shadow: 0 0 8px var(--weather-badge-sandstorm-glow);
}

.weather-indicator.thunder {
  background: var(--weather-badge-thunder-bg);
  color: var(--weather-badge-thunder-text);
  box-shadow: 0 0 8px var(--weather-badge-thunder-glow);
  animation: thunder-pulse 2s ease-in-out infinite;
}

@keyframes thunder-pulse {
  0%, 100% {
    box-shadow: 0 0 8px var(--weather-badge-thunder-glow);
  }
  50% {
    box-shadow: 0 0 16px var(--weather-badge-thunder-pulse);
  }
}

/* Light weather - subtler styling, no animation */
.weather-indicator.light_dust {
  background: var(--weather-badge-dust-bg);
  color: var(--weather-badge-dust-text);
  box-shadow: 0 0 4px var(--weather-badge-dust-glow);
}

.weather-indicator.light_rain {
  background: var(--weather-badge-rain-bg);
  color: var(--weather-badge-rain-text);
  box-shadow: 0 0 4px var(--weather-badge-rain-glow);
}

/* ============================================
   STORM INTENSITY EFFECTS
   ============================================ */

/* Screen shake on #viewport (NOT #world)
   #viewport has no JS transforms - camera only controls #world inside it.
   This makes it safe to animate #viewport's transform independently.
   Uses 3D transforms for GPU acceleration. */

/* Continuous subtle shake during peak storms */
@keyframes storm-shake {
  0%, 100% { transform: translate3d(0, 0, 0); }
  10% { transform: translate3d(1.5px, -0.5px, 0); }
  30% { transform: translate3d(-1px, 1px, 0); }
  50% { transform: translate3d(0.5px, 0.5px, 0); }
  70% { transform: translate3d(-1.5px, -1px, 0); }
  90% { transform: translate3d(1px, 0.5px, 0); }
}

/* Intense gust shake - brief burst */
@keyframes gust-shake {
  0%, 100% { transform: translate3d(0, 0, 0); }
  15% { transform: translate3d(3px, -1px, 0); }
  35% { transform: translate3d(-2px, 2px, 0); }
  55% { transform: translate3d(2px, -1px, 0); }
  75% { transform: translate3d(-3px, 1px, 0); }
}

#viewport.storm-shake {
  animation: storm-shake 0.4s ease-in-out infinite;
}

#viewport.gust-shake {
  animation: gust-shake 0.25s ease-in-out;
}


/* ============================================
   PERFORMANCE OPTIMIZATIONS
   ============================================ */

/* Create isolated stacking contexts for particle systems
   This reduces compositor complexity by preventing layer blending with unrelated elements */
#sandstorm-layer,
#thunderstorm-layer,
#rain-layer,
#sand-gust-layer {
  isolation: isolate;
}

/* Particle containment for GPU layering */
#sandstorm-layer > div,
#thunderstorm-layer > div,
#rain-layer > div,
#sand-gust-layer > div {
  contain: layout style paint;
}

/* Reduce motion for accessibility */
@media (prefers-reduced-motion: reduce) {
  #sandstorm-layer,
  #rain-layer,
  #heat-haze,
  .dust-devil {
    display: none;
  }
  
  /* Keep overlay tints but disable transitions */
  #weather-overlay,
  #lightning-flash {
    transition: none;
  }
}
