/* ============================================
   CSS CUSTOM PROPERTIES
   ============================================ */

/* Animation phases for organic motion */
@property --s1 {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
@property --s2 {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
@property --s3 {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
@property --rotation {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

/* Mesh gradient positions and colors */
@property --mesh-x-0 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 85%;
}
@property --mesh-y-0 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 80%;
}
@property --mesh-c-0 {
  syntax: "<color>";
  inherits: false;
  initial-value: hsla(150.88, 62%, 73%, 1);
}
@property --mesh-s-start-0 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 9%;
}
@property --mesh-s-end-0 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 55%;
}

@property --mesh-x-1 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 60%;
}
@property --mesh-y-1 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 24%;
}
@property --mesh-c-1 {
  syntax: "<color>";
  inherits: false;
  initial-value: hsla(220, 100%, 72%, 1);
}
@property --mesh-s-start-1 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 5%;
}
@property --mesh-s-end-1 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 72%;
}

@property --mesh-x-2 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 13%;
}
@property --mesh-y-2 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 82%;
}
@property --mesh-c-2 {
  syntax: "<color>";
  inherits: false;
  initial-value: hsla(297.79, 100%, 55%, 0.49);
}
@property --mesh-s-start-2 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 5%;
}
@property --mesh-s-end-2 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 52%;
}

@property --mesh-x-3 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 24%;
}
@property --mesh-y-3 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 7%;
}
@property --mesh-c-3 {
  syntax: "<color>";
  inherits: false;
  initial-value: hsla(182, 72%, 68%, 1);
}
@property --mesh-s-start-3 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 13%;
}
@property --mesh-s-end-3 {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 68%;
}

/* ============================================
   BASE STYLES
   ============================================ */

body {
  margin: 0;
  padding: 0;
  min-height: 100dvh;
  width: 100dvw;
  display: flex;
  flex-direction: column;
  gap: 100px;
  justify-content: center;
  align-items: center;
  background: white;
}

/* ============================================
   KEYFRAME ANIMATIONS
   ============================================ */

/* Sine wave animations for organic motion */
@keyframes s1 {
  to {
    --s1: 360deg;
  }
}
@keyframes s2 {
  to {
    --s2: 360deg;
  }
}
@keyframes s3 {
  to {
    --s3: 360deg;
  }
}
@keyframes rotation {
  to {
    --rotation: 360deg;
  }
}

/* Mesh gradient color animation */
@keyframes mesh-gradient {
  0% {
    --mesh-x-0: 85%;
    --mesh-y-0: 80%;
    --mesh-c-1: hsla(220, 100%, 82%, 1);
    --mesh-x-1: 60%;
    --mesh-y-1: 24%;
    --mesh-x-2: 13%;
    --mesh-y-2: 82%;
    --mesh-x-3: 24%;
    --mesh-y-3: 7%;
  }
  100% {
    --mesh-x-0: 31%;
    --mesh-y-0: 94%;
    --mesh-c-1: hsla(220, 82%, 95%, 1);
    --mesh-x-1: 2%;
    --mesh-y-1: 25%;
    --mesh-x-2: 98%;
    --mesh-y-2: 20%;
    --mesh-x-3: 95%;
    --mesh-y-3: 92%;
  }
}

/* Film grain jitter effect */
@keyframes grain-jitter {
  0% {
    transform: translate(1px, 6px);
  }
  3.33% {
    transform: translate(-12px, 8px);
  }
  6.67% {
    transform: translate(15px, -10px);
  }
  10% {
    transform: translate(-8px, 14px);
  }
  13.33% {
    transform: translate(11px, -6px);
  }
  16.67% {
    transform: translate(-14px, -9px);
  }
  20% {
    transform: translate(9px, 13px);
  }
  23.33% {
    transform: translate(-7px, -15px);
  }
  26.67% {
    transform: translate(13px, 7px);
  }
  30% {
    transform: translate(-10px, -11px);
  }
  33.33% {
    transform: translate(6px, -8px);
  }
  36.67% {
    transform: translate(-15px, 12px);
  }
  40% {
    transform: translate(14px, -7px);
  }
  43.33% {
    transform: translate(-9px, 15px);
  }
  46.67% {
    transform: translate(8px, -13px);
  }
  50% {
    transform: translate(-13px, -6px);
  }
  53.33% {
    transform: translate(12px, 10px);
  }
  56.67% {
    transform: translate(-6px, -14px);
  }
  60% {
    transform: translate(10px, 9px);
  }
  63.33% {
    transform: translate(-11px, -12px);
  }
  66.67% {
    transform: translate(7px, 14px);
  }
  70% {
    transform: translate(-14px, -8px);
  }
  73.33% {
    transform: translate(15px, 11px);
  }
  76.67% {
    transform: translate(-8px, -15px);
  }
  80% {
    transform: translate(9px, 6px);
  }
  83.33% {
    transform: translate(-12px, -10px);
  }
  86.67% {
    transform: translate(13px, 15px);
  }
  90% {
    transform: translate(-10px, 7px);
  }
  93.33% {
    transform: translate(11px, -14px);
  }
  96.67% {
    transform: translate(-7px, 13px);
  }
  100% {
    transform: translate(14px, -9px);
  }
}

/* ============================================
   BLOB COMPONENT
   ============================================ */

.blob-wrapper {
  filter: url(#glow);
}

#filter-toggle:checked ~ .blob-wrapper {
  filter: url(#edge-displacement) url(#glow);
}

.blob {
  aspect-ratio: 1;
  width: 300px;
  overflow: hidden;

  /* Mesh gradient background */
  background-color: hsla(358, 0%, 100%, 1);
  background-image: radial-gradient(
      circle at var(--mesh-x-0) var(--mesh-y-0),
      var(--mesh-c-0) var(--mesh-s-start-0),
      transparent var(--mesh-s-end-0)
    ),
    radial-gradient(
      circle at var(--mesh-x-1) var(--mesh-y-1),
      var(--mesh-c-1) var(--mesh-s-start-1),
      transparent var(--mesh-s-end-1)
    ),
    radial-gradient(
      circle at var(--mesh-x-2) var(--mesh-y-2),
      var(--mesh-c-2) var(--mesh-s-start-2),
      transparent var(--mesh-s-end-2)
    ),
    radial-gradient(
      circle at var(--mesh-x-3) var(--mesh-y-3),
      var(--mesh-c-3) var(--mesh-s-start-3),
      transparent var(--mesh-s-end-3)
    );

  /* Audio reactivity depth parameter */
  --depth: 0.3;
  --rotation: 0deg;

  animation: s1 7s linear infinite, s2 11s linear infinite,
    s3 13s linear infinite, mesh-gradient 10s linear infinite alternate;
}

/* Blob shape using CSS shape() function */
.blob-shape {
  /* Granularity=7: 7 control points around circle */
  --angle0: 0deg;
  --p1-0: 0deg;
  --p2-0: 0deg;
  --p3-0: 0deg;
  --angle1: 51.43deg;
  --p1-1: 137.5deg;
  --p2-1: 222.5deg;
  --p3-1: 360.1deg;
  --angle2: 102.86deg;
  --p1-2: 275deg;
  --p2-2: 85deg;
  --p3-2: 80.2deg;
  --angle3: 154.29deg;
  --p1-3: 52.5deg;
  --p2-3: 307.5deg;
  --p3-3: 200.3deg;
  --angle4: 205.71deg;
  --p1-4: 190deg;
  --p2-4: 170deg;
  --p3-4: 320.4deg;
  --angle5: 257.14deg;
  --p1-5: 327.5deg;
  --p2-5: 32.5deg;
  --p3-5: 80.5deg;
  --angle6: 308.57deg;
  --p1-6: 105deg;
  --p2-6: 255deg;
  --p3-6: 200.6deg;

  /* Calculate radius for each point using combined sine waves */
  --rand0: calc(
    0.5 + 0.5 *
      (
        0.5 * sin(var(--s1) + var(--p1-0)) + 0.3 * sin(var(--s2) + var(--p2-0)) +
          0.2 * sin(var(--s3) + var(--p3-0))
      )
  );
  --d0: calc(50 * (1 - var(--depth)) + 50 * var(--rand0) * var(--depth));
  --x0: calc((50 + var(--d0) * cos(var(--rotation) + var(--angle0))) * 1%);
  --y0: calc((50 + var(--d0) * sin(var(--rotation) + var(--angle0))) * 1%);

  --rand1: calc(
    0.5 + 0.5 *
      (
        0.5 * sin(var(--s1) + var(--p1-1)) + 0.3 * sin(var(--s2) + var(--p2-1)) +
          0.2 * sin(var(--s3) + var(--p3-1))
      )
  );
  --d1: calc(50 * (1 - var(--depth)) + 50 * var(--rand1) * var(--depth));
  --x1: calc((50 + var(--d1) * cos(var(--rotation) + var(--angle1))) * 1%);
  --y1: calc((50 + var(--d1) * sin(var(--rotation) + var(--angle1))) * 1%);

  --rand2: calc(
    0.5 + 0.5 *
      (
        0.5 * sin(var(--s1) + var(--p1-2)) + 0.3 * sin(var(--s2) + var(--p2-2)) +
          0.2 * sin(var(--s3) + var(--p3-2))
      )
  );
  --d2: calc(50 * (1 - var(--depth)) + 50 * var(--rand2) * var(--depth));
  --x2: calc((50 + var(--d2) * cos(var(--rotation) + var(--angle2))) * 1%);
  --y2: calc((50 + var(--d2) * sin(var(--rotation) + var(--angle2))) * 1%);

  --rand3: calc(
    0.5 + 0.5 *
      (
        0.5 * sin(var(--s1) + var(--p1-3)) + 0.3 * sin(var(--s2) + var(--p2-3)) +
          0.2 * sin(var(--s3) + var(--p3-3))
      )
  );
  --d3: calc(50 * (1 - var(--depth)) + 50 * var(--rand3) * var(--depth));
  --x3: calc((50 + var(--d3) * cos(var(--rotation) + var(--angle3))) * 1%);
  --y3: calc((50 + var(--d3) * sin(var(--rotation) + var(--angle3))) * 1%);

  --rand4: calc(
    0.5 + 0.5 *
      (
        0.5 * sin(var(--s1) + var(--p1-4)) + 0.3 * sin(var(--s2) + var(--p2-4)) +
          0.2 * sin(var(--s3) + var(--p3-4))
      )
  );
  --d4: calc(50 * (1 - var(--depth)) + 50 * var(--rand4) * var(--depth));
  --x4: calc((50 + var(--d4) * cos(var(--rotation) + var(--angle4))) * 1%);
  --y4: calc((50 + var(--d4) * sin(var(--rotation) + var(--angle4))) * 1%);

  --rand5: calc(
    0.5 + 0.5 *
      (
        0.5 * sin(var(--s1) + var(--p1-5)) + 0.3 * sin(var(--s2) + var(--p2-5)) +
          0.2 * sin(var(--s3) + var(--p3-5))
      )
  );
  --d5: calc(50 * (1 - var(--depth)) + 50 * var(--rand5) * var(--depth));
  --x5: calc((50 + var(--d5) * cos(var(--rotation) + var(--angle5))) * 1%);
  --y5: calc((50 + var(--d5) * sin(var(--rotation) + var(--angle5))) * 1%);

  --rand6: calc(
    0.5 + 0.5 *
      (
        0.5 * sin(var(--s1) + var(--p1-6)) + 0.3 * sin(var(--s2) + var(--p2-6)) +
          0.2 * sin(var(--s3) + var(--p3-6))
      )
  );
  --d6: calc(50 * (1 - var(--depth)) + 50 * var(--rand6) * var(--depth));
  --x6: calc((50 + var(--d6) * cos(var(--rotation) + var(--angle6))) * 1%);
  --y6: calc((50 + var(--d6) * sin(var(--rotation) + var(--angle6))) * 1%);

  /* Midpoints for smooth curves */
  --mx0: calc((var(--x0) + var(--x1)) / 2);
  --my0: calc((var(--y0) + var(--y1)) / 2);
  --mx1: calc((var(--x1) + var(--x2)) / 2);
  --my1: calc((var(--y1) + var(--y2)) / 2);
  --mx2: calc((var(--x2) + var(--x3)) / 2);
  --my2: calc((var(--y2) + var(--y3)) / 2);
  --mx3: calc((var(--x3) + var(--x4)) / 2);
  --my3: calc((var(--y3) + var(--y4)) / 2);
  --mx4: calc((var(--x4) + var(--x5)) / 2);
  --my4: calc((var(--y4) + var(--y5)) / 2);
  --mx5: calc((var(--x5) + var(--x6)) / 2);
  --my5: calc((var(--y5) + var(--y6)) / 2);
  --mx6: calc((var(--x6) + var(--x0)) / 2);
  --my6: calc((var(--y6) + var(--y0)) / 2);

  /* Fallback: simple circle */
  clip-path: circle(50%);
  transform: scale(calc(0.5 + var(--depth) * 0.5));
}

/* Progressive enhancement: use fancy shape if supported */
@supports (clip-path: shape(from 0% 0%, move to 100% 100%)) {
  #shape-toggle:checked ~ .blob-wrapper .blob-shape {
    clip-path: content-box
      shape(
        from var(--mx6) var(--my6),
        curve to var(--mx0) var(--my0) with var(--x0) var(--y0),
        curve to var(--mx1) var(--my1) with var(--x1) var(--y1),
        curve to var(--mx2) var(--my2) with var(--x2) var(--y2),
        curve to var(--mx3) var(--my3) with var(--x3) var(--y3),
        curve to var(--mx4) var(--my4) with var(--x4) var(--y4),
        curve to var(--mx5) var(--my5) with var(--x5) var(--y5),
        curve to var(--mx6) var(--my6) with var(--x6) var(--y6)
      );
    border-radius: 0;
    transform: scale(calc(1 + var(--depth)));
  }
}

/* ============================================
   GRAIN OVERLAY
   ============================================ */

.grain-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  background: white;
  filter: url(#filmGrain);
  mix-blend-mode: multiply;
  opacity: 0;
  animation: grain-jitter 1s infinite steps(1);
}

#grain-toggle:checked ~ .blob-wrapper .grain-overlay {
  opacity: 0.4;
}

/* ============================================
   FIREFOX FALLBACK
   ============================================ */

@-moz-document url-prefix() {
  .blob-wrapper {
    filter: none;
  }
  .grain-overlay {
    filter: none;
  }
}

/* =========================================
   CONTROLS  =========================================
*/

.controls {
  display: flex;
  gap: 10px;
  align-items: center;
}

/* Shared button/label styles */
#playPauseBtn,
label[for$="-toggle"] {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  color: rgba(0, 0, 0, 0.3);
  transition: all 0.3s ease;
}

#playPauseBtn {
  background: none;
  border: none;
}

#playPauseBtn:hover,
label[for$="-toggle"]:hover {
  color: rgba(0, 0, 0, 1);
  transform: scale(1.05);
}

#playPauseBtn.active,
#filter-toggle:checked ~ .controls label[for="filter-toggle"],
#grain-toggle:checked ~ .controls label[for="grain-toggle"],
#shape-toggle:checked ~ .controls label[for="shape-toggle"] {
  color: rgba(0, 0, 0, 1);
}

#playPauseBtn svg,
label[for$="-toggle"] svg {
  width: 24px;
  height: 24px;
  pointer-events: none;
}

/* Hide toggle checkboxes */
input[type="checkbox"][id$="-toggle"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}