{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"liquid-morphology-slideshow","title":"Liquid Morphology Slideshow","author":"CoDesign-Spa27","description":"A WebGL image slideshow with liquid, frost, ripple, plasma, and timeshift transitions.","dependencies":["three"],"devDependencies":["@types/three"],"files":[{"path":"components/ui-components/liquid-morphology-slideshow.tsx","content":"\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nexport type LiquidMorphologyEffect = \"glass\" | \"frost\" | \"ripple\" | \"plasma\" | \"timeshift\";\n\nexport type LiquidMorphologySlide = {\n  title: string;\n  src: string;\n  alt?: string;\n  category?: string;\n  description?: string;\n};\n\nexport type LiquidMorphologyNavItem = {\n  label: string;\n  href?: string;\n};\n\nexport type LiquidMorphologyProfileCard = {\n  name: string;\n  role: string;\n  image?: string;\n  imageAlt?: string;\n};\n\ntype LiquidMorphologySlideshowProps = {\n  slides?: LiquidMorphologySlide[];\n  effect?: LiquidMorphologyEffect;\n  initialIndex?: number;\n  autoPlay?: boolean;\n  interval?: number;\n  transitionDuration?: number;\n  showNavigation?: boolean;\n  showCounters?: boolean;\n  showHelp?: boolean;\n  clickToAdvance?: boolean;\n  keyboardControls?: boolean;\n  brandName?: string;\n  navItems?: LiquidMorphologyNavItem[];\n  kicker?: string;\n  headline?: string;\n  description?: string;\n  ctaLabel?: string;\n  ctaHref?: string;\n  profileCard?: LiquidMorphologyProfileCard;\n  footerLabel?: string;\n  className?: string;\n  overlayClassName?: string;\n  onSlideChange?: (index: number) => void;\n};\n\ntype ThreeModule = typeof import(\"three\");\ntype Texture = import(\"three\").Texture;\ntype ShaderMaterial = import(\"three\").ShaderMaterial;\ntype WebGLRenderer = import(\"three\").WebGLRenderer;\ntype OrthographicCamera = import(\"three\").OrthographicCamera;\ntype Scene = import(\"three\").Scene;\ntype PlaneGeometry = import(\"three\").PlaneGeometry;\n\ntype TextureWithSize = Texture & {\n  userData: {\n    size: import(\"three\").Vector2;\n  };\n};\n\ntype ThreeRuntime = {\n  THREE: ThreeModule;\n  renderer: WebGLRenderer;\n  scene: Scene;\n  camera: OrthographicCamera;\n  material: ShaderMaterial;\n  geometry: PlaneGeometry;\n  textures: TextureWithSize[];\n};\n\ntype UniformValue = {\n  value: number | Texture | import(\"three\").Vector2 | null;\n};\n\ntype ShaderUniforms = Record<string, UniformValue>;\n\nconst DEFAULT_SLIDES: LiquidMorphologySlide[] = [\n  {\n    title: \"Ethereal Glow\",\n    src: \"/assets/images/image.jpg\",\n    alt: \"Warm editorial scene with layered light\",\n    category: \"Strategy\",\n    description: \"Videography\",\n  },\n  {\n    title: \"Rose Mirage\",\n    src: \"/assets/images/image2.jpg\",\n    alt: \"Soft cinematic frame with muted tones\",\n    category: \"Motion\",\n    description: \"Art direction\",\n  },\n  {\n    title: \"Velvet Mystique\",\n    src: \"/assets/images/image3.jpg\",\n    alt: \"Textured image with rich light and shadow\",\n    category: \"Branding\",\n    description: \"Identity systems\",\n  },\n  {\n    title: \"Golden Hour\",\n    src: \"/assets/images/image4.jpg\",\n    alt: \"Wide atmospheric scene with natural contrast\",\n    category: \"Editorial\",\n    description: \"Campaign imagery\",\n  },\n  {\n    title: \"Midnight Dreams\",\n    src: \"/assets/images/image5.jpg\",\n    alt: \"Moody image with clean composition\",\n    category: \"Digital\",\n    description: \"Launch systems\",\n  },\n  {\n    title: \"Silver Light\",\n    src: \"/assets/images/image6.jpg\",\n    alt: \"Quiet image with bright highlights\",\n    category: \"Production\",\n    description: \"Post work\",\n  },\n];\n\nconst DEFAULT_NAV_ITEMS: LiquidMorphologyNavItem[] = [\n  { label: \"Home\", href: \"#\" },\n  { label: \"Work\", href: \"#\" },\n  { label: \"About\", href: \"#\" },\n  { label: \"Contact\", href: \"#\" },\n];\n\nconst DEFAULT_PROFILE_CARD: LiquidMorphologyProfileCard = {\n  name: \"Sandeep\",\n  role: \"@roohbuilds\",\n  image: \"/pfp.png\",\n  imageAlt: \"Portrait crop from the active visual campaign\",\n};\n\nconst EFFECT_INDEX: Record<LiquidMorphologyEffect, number> = {\n  glass: 0,\n  frost: 1,\n  ripple: 2,\n  plasma: 3,\n  timeshift: 4,\n};\n\nconst DEFAULT_SETTINGS = {\n  globalIntensity: 1,\n  speedMultiplier: 1,\n  distortionStrength: 1,\n  colorEnhancement: 1,\n  glassRefractionStrength: 1,\n  glassChromaticAberration: 1,\n  glassBubbleClarity: 1,\n  glassEdgeGlow: 1,\n  glassLiquidFlow: 1,\n  frostIntensity: 1.5,\n  frostCrystalSize: 1,\n  frostIceCoverage: 1,\n  frostTemperature: 1,\n  frostTexture: 1,\n  rippleFrequency: 25,\n  rippleAmplitude: 0.08,\n  rippleWaveSpeed: 1,\n  rippleRippleCount: 1,\n  rippleDecay: 1,\n  plasmaIntensity: 1.2,\n  plasmaSpeed: 0.8,\n  plasmaEnergyIntensity: 0.4,\n  plasmaContrastBoost: 0.3,\n  plasmaTurbulence: 1,\n  timeshiftDistortion: 1.6,\n  timeshiftBlur: 1.5,\n  timeshiftFlow: 1.4,\n  timeshiftChromatic: 1.5,\n  timeshiftTurbulence: 1.4,\n};\n\nconst vertexShader = `\n  varying vec2 vUv;\n\n  void main() {\n    vUv = uv;\n    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n  }\n`;\n\nconst fragmentShader = `\n  uniform sampler2D uTexture1;\n  uniform sampler2D uTexture2;\n  uniform float uProgress;\n  uniform vec2 uResolution;\n  uniform vec2 uTexture1Size;\n  uniform vec2 uTexture2Size;\n  uniform int uEffectType;\n  uniform float uGlobalIntensity;\n  uniform float uSpeedMultiplier;\n  uniform float uDistortionStrength;\n  uniform float uColorEnhancement;\n  uniform float uGlassRefractionStrength;\n  uniform float uGlassChromaticAberration;\n  uniform float uGlassBubbleClarity;\n  uniform float uGlassEdgeGlow;\n  uniform float uGlassLiquidFlow;\n  uniform float uFrostIntensity;\n  uniform float uFrostCrystalSize;\n  uniform float uFrostIceCoverage;\n  uniform float uFrostTemperature;\n  uniform float uFrostTexture;\n  uniform float uRippleFrequency;\n  uniform float uRippleAmplitude;\n  uniform float uRippleWaveSpeed;\n  uniform float uRippleRippleCount;\n  uniform float uRippleDecay;\n  uniform float uPlasmaIntensity;\n  uniform float uPlasmaSpeed;\n  uniform float uPlasmaEnergyIntensity;\n  uniform float uPlasmaContrastBoost;\n  uniform float uPlasmaTurbulence;\n  uniform float uTimeshiftDistortion;\n  uniform float uTimeshiftBlur;\n  uniform float uTimeshiftFlow;\n  uniform float uTimeshiftChromatic;\n  uniform float uTimeshiftTurbulence;\n\n  varying vec2 vUv;\n\n  vec2 getCoverUV(vec2 uv, vec2 textureSize) {\n    vec2 safeTextureSize = max(textureSize, vec2(1.0));\n    vec2 s = uResolution / safeTextureSize;\n    float scale = max(s.x, s.y);\n    vec2 scaledSize = safeTextureSize * scale;\n    vec2 offset = (uResolution - scaledSize) * 0.5;\n    return (uv * uResolution - offset) / scaledSize;\n  }\n\n  float noise(vec2 p) {\n    return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);\n  }\n\n  float smoothNoise(vec2 p) {\n    vec2 i = floor(p);\n    vec2 f = fract(p);\n    f = f * f * (3.0 - 2.0 * f);\n\n    return mix(\n      mix(noise(i), noise(i + vec2(1.0, 0.0)), f.x),\n      mix(noise(i + vec2(0.0, 1.0)), noise(i + vec2(1.0, 1.0)), f.x),\n      f.y\n    );\n  }\n\n  float rand(vec2 uv) {\n    float a = dot(uv, vec2(92.0, 80.0));\n    float b = dot(uv, vec2(41.0, 62.0));\n    return fract(sin(a) + cos(b) * 51.0);\n  }\n\n  vec3 enhanceColor(vec3 color) {\n    float amount = clamp((uColorEnhancement - 1.0) * 0.5, -0.4, 0.7);\n    return mix(color, color * 1.2, amount);\n  }\n\n  vec4 glassEffect(vec2 uv, float progress) {\n    float glassStrength = 0.08 * uGlassRefractionStrength * uDistortionStrength * uGlobalIntensity;\n    float chromaticAberration = 0.02 * uGlassChromaticAberration * uGlobalIntensity;\n    float waveDistortion = 0.025 * uDistortionStrength;\n    float clearCenterSize = 0.3 * uGlassBubbleClarity;\n    float surfaceRipples = 0.004 * uDistortionStrength;\n    float liquidFlow = 0.015 * uGlassLiquidFlow * uSpeedMultiplier;\n\n    vec2 center = vec2(0.5);\n    vec2 p = uv * uResolution;\n    vec2 uv1 = getCoverUV(uv, uTexture1Size);\n    vec2 uv2 = getCoverUV(uv, uTexture2Size);\n    float maxRadius = length(uResolution) * 0.85;\n    float bubbleRadius = progress * maxRadius;\n    vec2 sphereCenter = center * uResolution;\n    float dist = length(p - sphereCenter);\n    float normalizedDist = dist / max(bubbleRadius, 0.001);\n    vec2 direction = dist > 0.0 ? (p - sphereCenter) / dist : vec2(0.0);\n    float inside = smoothstep(bubbleRadius + 3.0, bubbleRadius - 3.0, dist);\n    float distanceFactor = smoothstep(clearCenterSize, 1.0, normalizedDist);\n    float time = progress * 5.0 * uSpeedMultiplier;\n\n    vec2 liquidSurface = vec2(\n      smoothNoise(uv * 100.0 + time * 0.3),\n      smoothNoise(uv * 100.0 + time * 0.2 + 50.0)\n    ) - 0.5;\n    liquidSurface *= surfaceRipples * distanceFactor;\n\n    vec2 distortedUV = uv2;\n    if (inside > 0.0) {\n      vec2 flowDirection = normalize(direction + vec2(sin(time), cos(time * 0.7)) * 0.3);\n      distortedUV -= flowDirection * glassStrength * pow(distanceFactor, 1.5);\n      float wave1 = sin(normalizedDist * 22.0 - time * 3.5);\n      float wave2 = sin(normalizedDist * 35.0 + time * 2.8) * 0.7;\n      float wave3 = sin(normalizedDist * 50.0 - time * 4.2) * 0.5;\n      distortedUV -= direction * ((wave1 + wave2 + wave3) / 3.0) * waveDistortion * distanceFactor + liquidSurface;\n      distortedUV += vec2(\n        sin(time + normalizedDist * 10.0),\n        cos(time * 0.8 + normalizedDist * 8.0)\n      ) * liquidFlow * distanceFactor * inside;\n    }\n\n    vec4 newImg;\n    if (inside > 0.0) {\n      float aberrationOffset = chromaticAberration * pow(distanceFactor, 1.2);\n      float r = texture2D(uTexture2, distortedUV + direction * aberrationOffset * 1.2).r;\n      float g = texture2D(uTexture2, distortedUV + direction * aberrationOffset * 0.2).g;\n      float b = texture2D(uTexture2, distortedUV - direction * aberrationOffset * 0.8).b;\n      newImg = vec4(r, g, b, 1.0);\n    } else {\n      newImg = texture2D(uTexture2, uv2);\n    }\n\n    float rim = smoothstep(0.95, 1.0, normalizedDist) * (1.0 - smoothstep(1.0, 1.01, normalizedDist));\n    newImg.rgb += rim * 0.08 * (1.0 - smoothstep(0.8, 1.0, progress)) * uGlassEdgeGlow * uGlobalIntensity;\n    newImg.rgb = enhanceColor(newImg.rgb);\n\n    if (progress > 0.95) {\n      newImg = mix(newImg, texture2D(uTexture2, uv2), (progress - 0.95) / 0.05);\n    }\n\n    return mix(texture2D(uTexture1, uv1), newImg, inside);\n  }\n\n  vec4 frostEffect(vec2 uv, float progress) {\n    vec4 currentImg = texture2D(uTexture1, getCoverUV(uv, uTexture1Size));\n    vec4 newImg = texture2D(uTexture2, getCoverUV(uv, uTexture2Size));\n    float effectiveIntensity = uFrostIntensity * uGlobalIntensity;\n    float crystalScale = 80.0 / max(uFrostCrystalSize, 0.1);\n    float frost = (\n      smoothNoise(uv * crystalScale * uFrostTexture) +\n      smoothNoise(uv * 40.0 / max(uFrostCrystalSize, 0.1) + 50.0) * 0.7 +\n      smoothNoise(uv * crystalScale * 2.0 + 100.0) * 0.3\n    ) / 2.0;\n    vec2 rnd = vec2(rand(uv + frost * 0.1), rand(uv + frost * 0.1 + 0.5));\n    float size = mix(progress, sqrt(progress), 0.5) * 1.12 * clamp(uFrostIceCoverage, 0.1, 2.5) + 0.000001;\n    vec2 lens = vec2(size, clamp(pow(size, 4.0) / 2.0, size * 0.1, size * 8.0));\n    float dist = distance(uv, vec2(0.5));\n    float vignette = pow(1.0 - smoothstep(lens.x, lens.y, dist), 2.0);\n    rnd *= frost * vignette * 0.8 * effectiveIntensity * uDistortionStrength * (1.0 - floor(vignette));\n\n    vec4 frozen = texture2D(uTexture2, getCoverUV(uv + rnd * 0.06, uTexture2Size));\n    float tempShift = clamp(uFrostTemperature * 0.15, 0.0, 0.3);\n    frozen *= vec4(clamp(0.85 + tempShift, 0.7, 1.2), 0.9, clamp(1.2 - tempShift, 0.8, 1.3), 1.0);\n    frozen = mix(frozen, vec4(0.9, 0.95, 1.1, 1.0), clamp(0.1 * uFrostTemperature, 0.0, 0.25));\n\n    float icespread = smoothNoise(uv * 25.0 / max(uFrostCrystalSize, 0.1) + 200.0);\n    float frostMask = smoothstep(icespread * 0.8, 1.0, pow(vignette, 1.5));\n    vec4 finalFrost = mix(frozen, newImg, frostMask);\n    finalFrost = mix(finalFrost, newImg, smoothstep(mix(0.85, 0.7, clamp(effectiveIntensity - 1.0, 0.0, 1.0)), 1.0, progress));\n    finalFrost.rgb = enhanceColor(finalFrost.rgb);\n    return mix(currentImg, finalFrost, smoothstep(0.0, 1.0, progress));\n  }\n\n  vec4 rippleEffect(vec2 uv, float progress) {\n    vec4 currentImg = texture2D(uTexture1, getCoverUV(uv, uTexture1Size));\n    vec4 newImg = texture2D(uTexture2, getCoverUV(uv, uTexture2Size));\n    vec2 center = vec2(0.5);\n    float dist = distance(uv, center);\n    float waveRadius = progress * 1.2 * uRippleWaveSpeed * uSpeedMultiplier;\n    float ripple1 = sin((dist - waveRadius) * uRippleFrequency) * exp(-abs(dist - waveRadius) * 8.0 * uRippleDecay);\n    float ripple2 = sin((dist - waveRadius * 0.7) * uRippleFrequency * 1.3) * exp(-abs(dist - waveRadius * 0.7) * 6.0 * uRippleDecay) * 0.6 * uRippleRippleCount;\n    float ripple3 = sin((dist - waveRadius * 0.4) * uRippleFrequency * 1.8) * exp(-abs(dist - waveRadius * 0.4) * 4.0 * uRippleDecay) * 0.3 * uRippleRippleCount;\n    vec2 normal = normalize(uv - center);\n    vec2 distortedUV = getCoverUV(uv + normal * (ripple1 + ripple2 + ripple3) * uRippleAmplitude * uDistortionStrength * uGlobalIntensity, uTexture2Size);\n    vec4 rippleResult = mix(newImg, texture2D(uTexture2, distortedUV), smoothstep(0.8, 0.72, dist));\n    float mask = smoothstep(0.0, 0.3, progress) * (1.0 - smoothstep(0.7, 1.0, progress));\n    rippleResult = mix(newImg, rippleResult, mask);\n    rippleResult.rgb = enhanceColor(rippleResult.rgb);\n    return mix(currentImg, rippleResult, smoothstep(0.0, 1.0, progress));\n  }\n\n  vec4 plasmaEffect(vec2 uv, float progress) {\n    vec4 currentImg = texture2D(uTexture1, getCoverUV(uv, uTexture1Size));\n    vec4 newImg = texture2D(uTexture2, getCoverUV(uv, uTexture2Size));\n    float time = progress * 8.0 * uPlasmaSpeed * uSpeedMultiplier;\n    float plasma1 = sin(uv.x * 10.0 + time) * cos(uv.y * 8.0 + time * 0.7);\n    float plasma2 = sin((uv.x + uv.y) * 12.0 + time * 1.3) * cos((uv.x - uv.y) * 15.0 + time * 0.9);\n    float plasma3 = sin(length(uv - vec2(0.5)) * 20.0 + time * 1.8);\n    float turbulence = (\n      smoothNoise(uv * 15.0 * uPlasmaTurbulence + vec2(time * 0.5, time * 0.3)) +\n      smoothNoise(uv * 25.0 * uPlasmaTurbulence + vec2(time * 0.8, -time * 0.4)) * 0.7 +\n      smoothNoise(uv * 40.0 * uPlasmaTurbulence + vec2(-time * 0.6, time * 0.9)) * 0.4\n    ) / 2.1;\n    float plasma = sin(((plasma1 + plasma2 + plasma3) * 0.333 + turbulence * 0.5) * 3.14159);\n    float phase = smoothstep(0.0, 0.3, progress) * (1.0 - smoothstep(0.7, 1.0, progress));\n    float intensity = uPlasmaIntensity * uGlobalIntensity;\n    vec2 electricField = vec2(sin(plasma * 6.28 + time), cos(plasma * 4.71 + time * 1.1)) * 0.02 * intensity * phase * uDistortionStrength;\n    vec4 distortedCurrent = texture2D(uTexture1, getCoverUV(uv + electricField, uTexture1Size));\n    vec4 distortedNew = texture2D(uTexture2, getCoverUV(uv + electricField, uTexture2Size));\n    vec3 color = mix(distortedCurrent.rgb, distortedNew.rgb, progress);\n    float energyMask = abs(plasma) * phase * intensity;\n    float contrast = 1.0 + energyMask * uPlasmaContrastBoost;\n    color = (color - 0.5) * contrast + 0.5;\n    color += vec3(0.9, 0.95, 1.0) * energyMask * uPlasmaEnergyIntensity * (0.7 + (sin(time * 4.0) * 0.5 + 0.5) * 0.3);\n    color += vec3(1.0) * smoothstep(0.85, 1.0, smoothNoise(uv * 50.0 + time * 2.0)) * energyMask * uPlasmaEnergyIntensity * 0.5;\n    color = enhanceColor(color);\n\n    vec4 plasmaResult = vec4(color, 1.0);\n    if (progress > 0.85) {\n      plasmaResult = mix(plasmaResult, newImg, (progress - 0.85) / 0.15);\n    }\n    return mix(currentImg, plasmaResult, smoothstep(0.0, 1.0, progress));\n  }\n\n  vec4 timeshiftEffect(vec2 uv, float progress) {\n    vec2 uv1 = getCoverUV(uv, uTexture1Size);\n    vec2 uv2 = getCoverUV(uv, uTexture2Size);\n    vec4 currentImg = texture2D(uTexture1, uv1);\n    vec4 newImg = texture2D(uTexture2, uv2);\n    vec2 center = vec2(0.5);\n    vec2 p = uv * uResolution;\n    float circleRadius = progress * length(uResolution) * 0.85;\n    float dist = length(p - center * uResolution);\n    float normalizedDist = dist / max(circleRadius, 0.001);\n    float inside = smoothstep(\n      circleRadius + circleRadius * 0.2 * uTimeshiftBlur,\n      circleRadius - circleRadius * 0.2 * uTimeshiftBlur,\n      dist\n    );\n\n    vec4 finalColor = inside >= 0.99 ? newImg : currentImg;\n    if (inside > 0.01 && inside < 0.99) {\n      vec2 fromCenter = uv - center;\n      float radius = length(fromCenter);\n      vec2 direction = radius > 0.0 ? fromCenter / radius : vec2(0.0);\n      float boundaryStrength = smoothstep(0.0, 0.3, inside) * smoothstep(1.0, 0.7, inside);\n      float time = progress * 6.28 * uTimeshiftFlow * uSpeedMultiplier;\n      float turb1 = smoothNoise(uv * 12.0 * uTimeshiftTurbulence + time * 0.4);\n      float turb2 = smoothNoise(uv * 20.0 * uTimeshiftTurbulence - time * 0.5);\n      float turb3 = smoothNoise(uv * 35.0 * uTimeshiftTurbulence + time * 0.7);\n      vec2 turbulence = vec2((turb1 - 0.5) * 1.2 + (turb2 - 0.5) * 0.8, (turb2 - 0.5) * 1.2 + (turb3 - 0.5) * 0.8);\n      vec2 perpendicular = vec2(-direction.y, direction.x);\n      vec2 displacement = turbulence * 0.18 * uTimeshiftDistortion * uDistortionStrength * uGlobalIntensity * boundaryStrength;\n      displacement += direction * sin(normalizedDist * 12.0 - time * 2.5) * 0.05 * uTimeshiftDistortion * boundaryStrength;\n      displacement += perpendicular * sin(time * 2.5 + normalizedDist * 10.0) * 0.06 * uTimeshiftFlow * boundaryStrength;\n\n      vec4 oldColor = texture2D(uTexture1, getCoverUV(uv + displacement, uTexture1Size));\n      vec4 newColor = texture2D(uTexture2, getCoverUV(uv + displacement, uTexture2Size));\n      float chromatic = boundaryStrength * 0.03 * uTimeshiftChromatic * uGlobalIntensity;\n      if (chromatic > 0.01) {\n        oldColor = vec4(\n          texture2D(uTexture1, getCoverUV(uv + displacement + direction * chromatic * 2.0, uTexture1Size)).r,\n          oldColor.g,\n          texture2D(uTexture1, getCoverUV(uv + displacement - direction * chromatic * 1.2, uTexture1Size)).b,\n          1.0\n        );\n        newColor = vec4(\n          texture2D(uTexture2, getCoverUV(uv + displacement + direction * chromatic * 2.0, uTexture2Size)).r,\n          newColor.g,\n          texture2D(uTexture2, getCoverUV(uv + displacement - direction * chromatic * 1.2, uTexture2Size)).b,\n          1.0\n        );\n      }\n      finalColor = mix(oldColor, newColor, inside);\n    }\n\n    finalColor.rgb = enhanceColor(finalColor.rgb);\n    if (progress > 0.95) {\n      finalColor = mix(finalColor, newImg, (progress - 0.95) / 0.05);\n    }\n    return mix(currentImg, finalColor, smoothstep(0.0, 1.0, progress));\n  }\n\n  void main() {\n    if (uEffectType == 0) {\n      gl_FragColor = glassEffect(vUv, uProgress);\n    } else if (uEffectType == 1) {\n      gl_FragColor = frostEffect(vUv, uProgress);\n    } else if (uEffectType == 2) {\n      gl_FragColor = rippleEffect(vUv, uProgress);\n    } else if (uEffectType == 3) {\n      gl_FragColor = plasmaEffect(vUv, uProgress);\n    } else {\n      gl_FragColor = timeshiftEffect(vUv, uProgress);\n    }\n  }\n`;\n\nfunction formatSlideNumber(index: number) {\n  return String(index + 1).padStart(2, \"0\");\n}\n\nfunction clampIndex(index: number, length: number) {\n  if (length <= 0) return 0;\n  return Math.min(Math.max(index, 0), length - 1);\n}\n\nfunction easeInOutCubic(value: number) {\n  return value < 0.5 ? 4 * value * value * value : 1 - (-2 * value + 2) ** 3 / 2;\n}\n\nfunction isNavigationTarget(target: EventTarget | null) {\n  return target instanceof Element && Boolean(target.closest(\"[data-liquid-morphology-nav]\"));\n}\n\nfunction useReducedMotionPreference() {\n  const [shouldReduceMotion, setShouldReduceMotion] = useState(false);\n\n  useEffect(() => {\n    const mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n    const updatePreference = () => setShouldReduceMotion(mediaQuery.matches);\n\n    updatePreference();\n    mediaQuery.addEventListener(\"change\", updatePreference);\n\n    return () => mediaQuery.removeEventListener(\"change\", updatePreference);\n  }, []);\n\n  return shouldReduceMotion;\n}\n\nfunction createUniforms(THREE: ThreeModule, effect: LiquidMorphologyEffect): ShaderUniforms {\n  return {\n    uTexture1: { value: null },\n    uTexture2: { value: null },\n    uProgress: { value: 0 },\n    uResolution: { value: new THREE.Vector2(1, 1) },\n    uTexture1Size: { value: new THREE.Vector2(1, 1) },\n    uTexture2Size: { value: new THREE.Vector2(1, 1) },\n    uEffectType: { value: EFFECT_INDEX[effect] },\n    uGlobalIntensity: { value: DEFAULT_SETTINGS.globalIntensity },\n    uSpeedMultiplier: { value: DEFAULT_SETTINGS.speedMultiplier },\n    uDistortionStrength: { value: DEFAULT_SETTINGS.distortionStrength },\n    uColorEnhancement: { value: DEFAULT_SETTINGS.colorEnhancement },\n    uGlassRefractionStrength: { value: DEFAULT_SETTINGS.glassRefractionStrength },\n    uGlassChromaticAberration: { value: DEFAULT_SETTINGS.glassChromaticAberration },\n    uGlassBubbleClarity: { value: DEFAULT_SETTINGS.glassBubbleClarity },\n    uGlassEdgeGlow: { value: DEFAULT_SETTINGS.glassEdgeGlow },\n    uGlassLiquidFlow: { value: DEFAULT_SETTINGS.glassLiquidFlow },\n    uFrostIntensity: { value: DEFAULT_SETTINGS.frostIntensity },\n    uFrostCrystalSize: { value: DEFAULT_SETTINGS.frostCrystalSize },\n    uFrostIceCoverage: { value: DEFAULT_SETTINGS.frostIceCoverage },\n    uFrostTemperature: { value: DEFAULT_SETTINGS.frostTemperature },\n    uFrostTexture: { value: DEFAULT_SETTINGS.frostTexture },\n    uRippleFrequency: { value: DEFAULT_SETTINGS.rippleFrequency },\n    uRippleAmplitude: { value: DEFAULT_SETTINGS.rippleAmplitude },\n    uRippleWaveSpeed: { value: DEFAULT_SETTINGS.rippleWaveSpeed },\n    uRippleRippleCount: { value: DEFAULT_SETTINGS.rippleRippleCount },\n    uRippleDecay: { value: DEFAULT_SETTINGS.rippleDecay },\n    uPlasmaIntensity: { value: DEFAULT_SETTINGS.plasmaIntensity },\n    uPlasmaSpeed: { value: DEFAULT_SETTINGS.plasmaSpeed },\n    uPlasmaEnergyIntensity: { value: DEFAULT_SETTINGS.plasmaEnergyIntensity },\n    uPlasmaContrastBoost: { value: DEFAULT_SETTINGS.plasmaContrastBoost },\n    uPlasmaTurbulence: { value: DEFAULT_SETTINGS.plasmaTurbulence },\n    uTimeshiftDistortion: { value: DEFAULT_SETTINGS.timeshiftDistortion },\n    uTimeshiftBlur: { value: DEFAULT_SETTINGS.timeshiftBlur },\n    uTimeshiftFlow: { value: DEFAULT_SETTINGS.timeshiftFlow },\n    uTimeshiftChromatic: { value: DEFAULT_SETTINGS.timeshiftChromatic },\n    uTimeshiftTurbulence: { value: DEFAULT_SETTINGS.timeshiftTurbulence },\n  };\n}\n\nasync function loadTexture(THREE: ThreeModule, loader: import(\"three\").TextureLoader, src: string) {\n  return new Promise<TextureWithSize>((resolve, reject) => {\n    const timeout = window.setTimeout(() => reject(new Error(`Timed out loading ${src}`)), 10000);\n\n    loader.load(\n      src,\n      (texture) => {\n        window.clearTimeout(timeout);\n        texture.colorSpace = THREE.SRGBColorSpace;\n        texture.minFilter = THREE.LinearFilter;\n        texture.magFilter = THREE.LinearFilter;\n        texture.wrapS = THREE.ClampToEdgeWrapping;\n        texture.wrapT = THREE.ClampToEdgeWrapping;\n        texture.userData.size = new THREE.Vector2(\n          texture.image?.width || 1,\n          texture.image?.height || 1,\n        );\n        resolve(texture as TextureWithSize);\n      },\n      undefined,\n      (error) => {\n        window.clearTimeout(timeout);\n        reject(error);\n      },\n    );\n  });\n}\n\nexport function LiquidMorphologySlideshow({\n  slides = DEFAULT_SLIDES,\n  effect = \"glass\",\n  initialIndex = 0,\n  autoPlay = true,\n  interval = 1000,\n  transitionDuration = 2.5,\n\n  showHelp = false,\n  clickToAdvance = true,\n  keyboardControls = true,\n  brandName = \"Skecher\",\n  navItems = DEFAULT_NAV_ITEMS,\n  kicker = \"Skecher UI\",\n  headline = \"Where colors and chaos shape tomorrow’s textures.\",\n  description = \"Dive into a living canvas: morph, mutate, and let morphologies flow with your wildest ideas.\",\n  ctaLabel = \"See the magic\",\n  ctaHref = \"#\",\n  profileCard = DEFAULT_PROFILE_CARD,\n\n  className,\n  overlayClassName,\n  onSlideChange,\n}: LiquidMorphologySlideshowProps) {\n  const shouldReduceMotion = useReducedMotionPreference();\n  const safeSlides = useMemo(() => (slides.length > 0 ? slides : DEFAULT_SLIDES), [slides]);\n  const safeInitialIndex = clampIndex(initialIndex, safeSlides.length);\n\n  const rootRef = useRef<HTMLDivElement | null>(null);\n  const canvasRef = useRef<HTMLCanvasElement | null>(null);\n  const runtimeRef = useRef<ThreeRuntime | null>(null);\n  const renderFrameRef = useRef<number | null>(null);\n  const transitionFrameRef = useRef<number | null>(null);\n  const progressFrameRef = useRef<number | null>(null);\n  const progressStartedAtRef = useRef(0);\n  const activeIndexRef = useRef(safeInitialIndex);\n  const isTransitioningRef = useRef(false);\n  const touchStartXRef = useRef(0);\n  const onSlideChangeRef = useRef(onSlideChange);\n\n  const [activeIndex, setActiveIndex] = useState(safeInitialIndex);\n  // const [progress, setProgress] = useState(0);\n  const [isReady, setIsReady] = useState(false);\n  const [hasWebGLError, setHasWebGLError] = useState(false);\n\n  const canAnimate = !shouldReduceMotion && safeSlides.length > 1;\n\n  useEffect(() => {\n    onSlideChangeRef.current = onSlideChange;\n  }, [onSlideChange]);\n\n  const resetProgressIndicator = useCallback(() => {\n    progressStartedAtRef.current = performance.now();\n    // setProgress(0);\n  }, []);\n\n  const cancelProgressLoop = useCallback(() => {\n    if (progressFrameRef.current !== null) {\n      window.cancelAnimationFrame(progressFrameRef.current);\n      progressFrameRef.current = null;\n    }\n    resetProgressIndicator();\n  }, [resetProgressIndicator]);\n\n  const applyTexturePair = useCallback((index: number, nextIndex: number) => {\n    const runtime = runtimeRef.current;\n    if (!runtime) return false;\n\n    const currentTexture = runtime.textures[index];\n    const nextTexture = runtime.textures[nextIndex];\n    if (!currentTexture || !nextTexture) return false;\n\n    runtime.material.uniforms.uTexture1.value = currentTexture;\n    runtime.material.uniforms.uTexture2.value = nextTexture;\n    runtime.material.uniforms.uTexture1Size.value = currentTexture.userData.size;\n    runtime.material.uniforms.uTexture2Size.value = nextTexture.userData.size;\n\n    return true;\n  }, []);\n\n  const completeSlideChange = useCallback((targetIndex: number) => {\n    const runtime = runtimeRef.current;\n    if (!runtime) return;\n\n    const targetTexture = runtime.textures[targetIndex];\n    if (!targetTexture) return;\n\n    runtime.material.uniforms.uProgress.value = 0;\n    runtime.material.uniforms.uTexture1.value = targetTexture;\n    runtime.material.uniforms.uTexture1Size.value = targetTexture.userData.size;\n    activeIndexRef.current = targetIndex;\n    progressStartedAtRef.current = performance.now();\n    setActiveIndex(targetIndex);\n    // setProgress(0);\n    onSlideChangeRef.current?.(targetIndex);\n  }, []);\n\n  const navigateToSlide = useCallback(\n    (targetIndex: number) => {\n      const runtime = runtimeRef.current;\n      if (!runtime || runtime.textures.length < 1 || isTransitioningRef.current) {\n        return;\n      }\n\n      const safeTargetIndex = clampIndex(targetIndex, runtime.textures.length);\n      const currentIndex = activeIndexRef.current;\n      if (safeTargetIndex === currentIndex) {\n        return;\n      }\n\n      resetProgressIndicator();\n\n      if (!applyTexturePair(currentIndex, safeTargetIndex)) {\n        return;\n      }\n\n      if (!canAnimate) {\n        completeSlideChange(safeTargetIndex);\n        return;\n      }\n\n      isTransitioningRef.current = true;\n      const startedAt = performance.now();\n      const durationMs = Math.max(0.1, transitionDuration) * 1000;\n\n      if (transitionFrameRef.current !== null) {\n        window.cancelAnimationFrame(transitionFrameRef.current);\n      }\n\n      const animateTransition = (timestamp: number) => {\n        const elapsed = timestamp - startedAt;\n        const nextProgress = Math.min(elapsed / durationMs, 1);\n        runtime.material.uniforms.uProgress.value = easeInOutCubic(nextProgress);\n\n        if (nextProgress < 1) {\n          transitionFrameRef.current = window.requestAnimationFrame(animateTransition);\n          return;\n        }\n\n        transitionFrameRef.current = null;\n        isTransitioningRef.current = false;\n        completeSlideChange(safeTargetIndex);\n      };\n\n      transitionFrameRef.current = window.requestAnimationFrame(animateTransition);\n    },\n    [applyTexturePair, canAnimate, completeSlideChange, resetProgressIndicator, transitionDuration],\n  );\n\n  const goNext = useCallback(() => {\n    navigateToSlide((activeIndexRef.current + 1) % safeSlides.length);\n  }, [navigateToSlide, safeSlides.length]);\n\n  const goPrevious = useCallback(() => {\n    navigateToSlide((activeIndexRef.current - 1 + safeSlides.length) % safeSlides.length);\n  }, [navigateToSlide, safeSlides.length]);\n\n  useEffect(() => {\n    activeIndexRef.current = safeInitialIndex;\n    setActiveIndex(safeInitialIndex);\n  }, [safeInitialIndex]);\n\n  useEffect(() => {\n    const runtime = runtimeRef.current;\n    if (!runtime) return;\n\n    runtime.material.uniforms.uEffectType.value = EFFECT_INDEX[effect];\n  }, [effect]);\n\n  useEffect(() => {\n    if (!autoPlay || !isReady || !canAnimate) {\n      cancelProgressLoop();\n      return;\n    }\n\n    progressStartedAtRef.current = performance.now();\n    const durationMs = Math.max(1000, interval);\n\n    const tick = (timestamp: number) => {\n      if (isTransitioningRef.current) {\n        progressFrameRef.current = window.requestAnimationFrame(tick);\n        return;\n      }\n\n      const startedAt = progressStartedAtRef.current || timestamp;\n      const nextProgress = Math.min(((timestamp - startedAt) / durationMs) * 100, 100);\n      // setProgress(nextProgress);\n\n      if (nextProgress >= 100) {\n        progressStartedAtRef.current = timestamp;\n        goNext();\n        // setProgress(0);\n      }\n\n      progressFrameRef.current = window.requestAnimationFrame(tick);\n    };\n\n    progressFrameRef.current = window.requestAnimationFrame(tick);\n\n    return cancelProgressLoop;\n  }, [autoPlay, canAnimate, cancelProgressLoop, goNext, interval, isReady]);\n\n  useEffect(() => {\n    let isMounted = true;\n    const canvas = canvasRef.current;\n    const root = rootRef.current;\n\n    if (!canvas || !root) return;\n    const activeCanvas = canvas;\n    const activeRoot = root;\n\n    async function setupRenderer() {\n      try {\n        const THREE = await import(\"three\");\n        if (!isMounted) return;\n\n        const scene = new THREE.Scene();\n        const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n        const renderer = new THREE.WebGLRenderer({\n          canvas: activeCanvas,\n          antialias: false,\n          alpha: false,\n        });\n        renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));\n\n        const material = new THREE.ShaderMaterial({\n          uniforms: createUniforms(THREE, effect),\n          vertexShader,\n          fragmentShader,\n        });\n        const geometry = new THREE.PlaneGeometry(2, 2);\n        const mesh = new THREE.Mesh(geometry, material);\n        scene.add(mesh);\n\n        const loader = new THREE.TextureLoader();\n        loader.setCrossOrigin(\"anonymous\");\n        const loadedTextures = await Promise.allSettled(\n          safeSlides.map((slide) => loadTexture(THREE, loader, slide.src)),\n        );\n\n        if (!isMounted) {\n          renderer.dispose();\n          material.dispose();\n          geometry.dispose();\n          return;\n        }\n\n        const textures = loadedTextures\n          .filter(\n            (result): result is PromiseFulfilledResult<TextureWithSize> =>\n              result.status === \"fulfilled\",\n          )\n          .map((result) => result.value);\n\n        if (!textures.length) {\n          throw new Error(\"No slideshow textures loaded.\");\n        }\n\n        runtimeRef.current = {\n          THREE,\n          renderer,\n          scene,\n          camera,\n          material,\n          geometry,\n          textures,\n        };\n\n        const safeIndex = clampIndex(safeInitialIndex, textures.length);\n        const nextIndex = textures.length > 1 ? (safeIndex + 1) % textures.length : safeIndex;\n        activeIndexRef.current = safeIndex;\n        setActiveIndex(safeIndex);\n        applyTexturePair(safeIndex, nextIndex);\n\n        const resize = () => {\n          const rect = activeRoot.getBoundingClientRect();\n          const width = Math.max(1, Math.floor(rect.width));\n          const height = Math.max(1, Math.floor(rect.height));\n          renderer.setSize(width, height, false);\n          material.uniforms.uResolution.value.set(width, height);\n        };\n\n        const resizeObserver = new ResizeObserver(resize);\n        resizeObserver.observe(activeRoot);\n        resize();\n\n        const render = () => {\n          renderer.render(scene, camera);\n          renderFrameRef.current = window.requestAnimationFrame(render);\n        };\n        renderFrameRef.current = window.requestAnimationFrame(render);\n\n        setHasWebGLError(false);\n        setIsReady(true);\n\n        return () => {\n          resizeObserver.disconnect();\n        };\n      } catch (error) {\n        if (!isMounted) return;\n        console.warn(\"LiquidMorphologySlideshow failed to initialize.\", error);\n        setHasWebGLError(true);\n      }\n    }\n\n    let cleanupResize: VoidFunction | undefined;\n    setupRenderer().then((cleanup) => {\n      cleanupResize = cleanup;\n    });\n\n    return () => {\n      isMounted = false;\n      cleanupResize?.();\n      setIsReady(false);\n      cancelProgressLoop();\n\n      if (renderFrameRef.current !== null) {\n        window.cancelAnimationFrame(renderFrameRef.current);\n        renderFrameRef.current = null;\n      }\n\n      if (transitionFrameRef.current !== null) {\n        window.cancelAnimationFrame(transitionFrameRef.current);\n        transitionFrameRef.current = null;\n      }\n\n      const runtime = runtimeRef.current;\n      runtimeRef.current = null;\n\n      if (runtime) {\n        // biome-ignore lint/suspicious/useIterableCallbackReturn: <explanation>\n        runtime.textures.forEach((texture) => texture.dispose());\n        runtime.geometry.dispose();\n        runtime.material.dispose();\n        runtime.renderer.dispose();\n        runtime.renderer.forceContextLoss();\n      }\n    };\n  }, [applyTexturePair, cancelProgressLoop, effect, safeInitialIndex, safeSlides]);\n\n  function handleClick(event: React.MouseEvent<HTMLDivElement>) {\n    if (!clickToAdvance || isNavigationTarget(event.target)) {\n      return;\n    }\n\n    goNext();\n  }\n\n  function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n    if (!keyboardControls || isNavigationTarget(event.target)) {\n      return;\n    }\n\n    if (event.code === \"Space\" || event.code === \"ArrowRight\") {\n      event.preventDefault();\n      goNext();\n    }\n\n    if (event.code === \"ArrowLeft\") {\n      event.preventDefault();\n      goPrevious();\n    }\n  }\n\n  function handleTouchStart(event: React.TouchEvent<HTMLDivElement>) {\n    touchStartXRef.current = event.changedTouches[0]?.screenX ?? 0;\n  }\n\n  function handleTouchEnd(event: React.TouchEvent<HTMLDivElement>) {\n    const touchEndX = event.changedTouches[0]?.screenX ?? 0;\n    const delta = touchEndX - touchStartXRef.current;\n\n    if (Math.abs(delta) < 50) {\n      return;\n    }\n\n    if (delta < 0) {\n      goNext();\n    } else {\n      goPrevious();\n    }\n  }\n\n  const activeSlide = safeSlides[activeIndex] ?? safeSlides[0];\n  // const displayTotal = formatSlideNumber(safeSlides.length - 1);\n  const profileImage = profileCard.image ?? activeSlide?.src ?? DEFAULT_PROFILE_CARD.image;\n\n  return (\n    // biome-ignore lint/a11y/useSemanticElements: <explanation>\n    <div\n      ref={rootRef}\n      aria-label=\"Liquid morphology landing slideshow\"\n      className={cn(\n        \"group/liquid-morphology relative isolate h-auto w-full max-w-7xl overflow-hidden rounded-xl bg-black text-white outline-none\",\n        clickToAdvance && \"cursor-pointer\",\n        className,\n      )}\n      onClick={handleClick}\n      onKeyDown={handleKeyDown}\n      onTouchEnd={handleTouchEnd}\n      onTouchStart={handleTouchStart}\n      role=\"region\"\n      tabIndex={keyboardControls ? 0 : undefined}\n    >\n      <canvas\n        ref={canvasRef}\n        aria-label={activeSlide?.alt ?? activeSlide?.title ?? \"Liquid slideshow image\"}\n        className={cn(\n          \"block h-full w-full transition-opacity duration-700 ease-[cubic-bezier(0.23,1,0.32,1)] rounded-xl\",\n          isReady ? \"opacity-100\" : \"opacity-0\",\n        )}\n      />\n\n      <div className=\"pointer-events-none absolute inset-0 bg-[linear-gradient(90deg,rgba(0,0,0,0.52)_0%,rgba(0,0,0,0.08)_34%,rgba(0,0,0,0.08)_60%,rgba(0,0,0,0.46)_100%)] rounded-xl\" />\n      <div className=\"pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_50%_25%,rgba(255,255,255,0.13)_0%,transparent_30%),radial-gradient(circle_at_50%_115%,rgba(0,0,0,0.58)_0%,rgba(0,0,0,0.2)_38%,transparent_62%)] rounded-xl\" />\n\n      {hasWebGLError ? (\n        <div\n          className=\"absolute inset-0 bg-cover bg-center rounded-xl\"\n          style={{ backgroundImage: `url(${activeSlide?.src ?? DEFAULT_SLIDES[0].src})` }}\n        />\n      ) : null}\n\n      <div\n        className={cn(\n          \"pointer-events-none absolute inset-0 z-10 flex min-h-full flex-col justify-between overflow-hidden px-4 py-4 text-white sm:px-6 sm:py-6 lg:px-8 lg:py-7 rounded-xl\",\n          overlayClassName,\n        )}\n      >\n        <header className=\"grid items-start gap-5 sm:grid-cols-[1fr_auto_1fr]\">\n          <a\n            aria-label={`${brandName} home`}\n            className=\"pointer-events-auto flex w-fit items-center gap-2 text-sm font-black tracking-[-0.02em] text-white outline-none transition-opacity duration-200 hover:opacity-80 focus-visible:ring-2 focus-visible:ring-white/80\"\n            data-liquid-morphology-nav\n            href=\"#brand\"\n          >\n            <span className=\"grid size-4 grid-cols-2 gap-1\" aria-hidden=\"true\">\n              <span className=\"bg-white\" />\n              <span className=\"bg-white\" />\n              <span className=\"bg-white\" />\n              <span className=\"bg-white/75\" />\n            </span>\n            {brandName}\n          </a>\n\n          <nav\n            aria-label=\"Landing\"\n            className=\"pointer-events-auto order-3 flex flex-wrap gap-x-5 gap-y-2 text-[13px] font-medium text-white/82 sm:order-none sm:justify-center sm:gap-x-9\"\n            data-liquid-morphology-nav\n          >\n            {navItems.map((item, index) => (\n              <a\n                className=\"group/nav relative outline-none transition-colors duration-200 hover:text-white focus-visible:ring-2 focus-visible:ring-white/80\"\n                href={item.href ?? \"#\"}\n                key={`${item.label}-${index}`}\n              >\n                <span>{item.label}</span>\n                <span className=\"ml-2 align-super text-[9px] text-white/50\">\n                  {formatSlideNumber(index)}\n                </span>\n                <span className=\"absolute -bottom-1 left-0 h-px w-full scale-x-0 bg-white/80 transition-transform duration-200 group-hover/nav:scale-x-100 group-focus-visible/nav:scale-x-100\" />\n              </a>\n            ))}\n          </nav>\n\n          {profileCard ? (\n            <aside\n              className=\"pointer-events-auto ml-auto hidden w-full max-w-[25.5rem] items-center gap-3 rounded-sm bg-white p-2 text-black shadow-[0_10px_24px_rgba(0,0,0,0.18)] md:flex\"\n              data-liquid-morphology-nav\n            >\n              {profileImage ? (\n                // eslint-disable-next-line @next/next/no-img-element\n                <img\n                  alt={profileCard.imageAlt ?? profileCard.name}\n                  className=\"h-14 w-14 rounded-sm object-cover\"\n                  src={profileImage}\n                />\n              ) : null}\n              <div className=\"min-w-0 flex-1\">\n                <p className=\"truncate text-base font-semibold tracking-[-0.02em]\">\n                  {profileCard.name}\n                </p>\n                <p className=\"mt-1 truncate text-xs font-medium text-black/72\">\n                  {profileCard.role}\n                </p>\n              </div>\n              <span className=\"grid size-5 grid-cols-2 gap-1 self-start\" aria-hidden=\"true\">\n                <span className=\"bg-black\" />\n                <span className=\"bg-black\" />\n                <span />\n                <span className=\"bg-black\" />\n              </span>\n            </aside>\n          ) : null}\n        </header>\n\n        {showHelp ? (\n          <p className=\"absolute left-4 top-20 max-w-[calc(100%-2rem)] text-xs font-medium text-white/70 sm:left-8\">\n            Space/Right: Next - Left: Previous - Click to Advance\n          </p>\n        ) : null}\n\n        <main className=\"grid flex-1 items-end gap-8 pb-24 pt-10 sm:pb-28 lg:grid-cols-[minmax(15rem,24rem)_1fr_minmax(14rem,22rem)] lg:pb-20 lg:pt-16\">\n          <section className=\"max-w-[22rem] self-center lg:self-auto\">\n            <p className=\"mb-4 text-xs font-semibold text-white/70\">{kicker}</p>\n            <h1 className=\"max-w-[18rem] text-xl font-semibold leading-[1.05] tracking-[-0.02em] text-white text-balance sm:text-2xl\">\n              {headline}\n            </h1>\n            <p className=\"mt-3 max-w-[18rem] text-sm leading-5 text-white/72 text-pretty\">\n              {description}\n            </p>\n            <a\n              className=\"pointer-events-auto mt-9 flex w-full max-w-[15.5rem] items-center justify-between border-b border-white/88 pb-3 text-base font-semibold text-white outline-none transition-[max-width,opacity] duration-300 hover:max-w-[17rem] hover:opacity-[0.82] focus-visible:ring-2 focus-visible:ring-white/80\"\n              data-liquid-morphology-nav\n              href={ctaHref}\n            >\n              <span>{ctaLabel}</span>\n              <span className=\"relative size-4 border-r border-t border-white\" aria-hidden=\"true\" />\n            </a>\n          </section>\n\n          <section className=\"relative hidden min-h-[18rem] self-end lg:block\" aria-hidden=\"true\">\n            <div className=\"absolute left-[10%] top-[22%] size-4\">\n              <span className=\"absolute left-1/2 top-0 h-full w-px -translate-x-1/2 bg-white/75\" />\n              <span className=\"absolute left-0 top-1/2 h-px w-full -translate-y-1/2 bg-white/75\" />\n            </div>\n            <div className=\"absolute right-[18%] top-[2%] size-4\">\n              <span className=\"absolute left-1/2 top-0 h-full w-px -translate-x-1/2 bg-white/70\" />\n              <span className=\"absolute left-0 top-1/2 h-px w-full -translate-y-1/2 bg-white/70\" />\n            </div>\n            <div className=\"absolute right-[5%] bottom-[34%] size-4\">\n              <span className=\"absolute left-1/2 top-0 h-full w-px -translate-x-1/2 bg-white/70\" />\n              <span className=\"absolute left-0 top-1/2 h-px w-full -translate-y-1/2 bg-white/70\" />\n            </div>\n            <div className=\"absolute bottom-0 left-0\">\n              <p className=\"mb-5 text-base font-semibold leading-6 text-white\">\n                <span className=\"text-white/52\">{formatSlideNumber(activeIndex)} / </span>\n                {activeSlide?.category ?? \"Motion\"}\n                <br />\n                {activeSlide?.description ?? activeSlide?.title}\n                <br />\n                {activeSlide?.title}\n              </p>\n            </div>\n          </section>\n        </main>\n\n        <div\n          aria-hidden=\"true\"\n          className=\"pointer-events-none absolute bottom-3 left-[51%] hidden select-none text-[clamp(5rem,16vw,14rem)] font-extralight font-raleway leading-[0.76] tracking-[-0.04em] text-white/94 mix-blend-screen lg:block\"\n        >\n          {brandName}\n        </div>\n      </div>\n    </div>\n  );\n}\n","type":"registry:ui"}],"categories":["slideshow","shader"],"type":"registry:ui"}