/* ---------- Base reset ---------- */
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}



body {

  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ---------- Visual effect layer ----------
        This wrapper <div> holds the iframe that runs raindrops.js.
        Visual properties (blend mode, opacity) live here so they
        stay stable even while the iframe inside is being swapped during a resize.
        We keep blend/opacity here (stable), and only swap the internal iframe when needed. */
#rain-layer {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  /* fallback */
  height: 100dvh;
  /* modern browsers */
  pointer-events: none;
  z-index: 1;
  mix-blend-mode: screen;
  opacity: 0.9;
  background: transparent;
}

/* The iframe is just the renderer container.
            The iframe itself has no visual role — it simply fills
            its parent wrapper 100%. All blending is handled by the
            wrapper above. */
#rain-layer > iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  background: transparent;
}

/* Accessibility: respect user preference.
            If the user's OS is set to "reduce motion", hide the
            effect layer entirely via CSS. The JS side also checks
            this and skips mounting. */
@media (prefers-reduced-motion: reduce) {
  #rain-layer {
    display: none;
  }
}