1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9420],{4863:(e,t,n)=>{n.d(t,{BI:()=>r,Df:()=>a,GE:()=>s});var o=n(7548);let i=[[168,216,232],[200,192,228],[248,200,160],[255,218,130],[168,216,176],[232,112,112]],r=[[74/255,138/255,154/255],[110/255,95/255,168/255],[210/255,88/255,52/255],[248/255,170/255,75/255],[74/255,138/255,90/255],[192/255,56/255,56/255]],a={None:{distortionAmp:-1,distortionSpeed:-1,distortionFreq:-1,breathRate:-1,breathDepth:-1,speechIntensity:-1,speechSpeed:-1,emissive:-1,tintIndex:-1},Calm:{distortionAmp:.01,distortionSpeed:.1,distortionFreq:.5,breathRate:.15,breathDepth:.1,speechIntensity:.008,speechSpeed:2,emissive:.1,tintIndex:0},Warmth:{distortionAmp:.03,distortionSpeed:.15,distortionFreq:.8,breathRate:.2,breathDepth:.1,speechIntensity:.015,speechSpeed:2.5,emissive:.25,tintIndex:3},Engagement:{distortionAmp:.06,distortionSpeed:.25,distortionFreq:1.2,breathRate:.5,breathDepth:.04,speechIntensity:.025,speechSpeed:4,emissive:.4,tintIndex:2},Alert:{distortionAmp:.08,distortionSpeed:.3,distortionFreq:1.5,breathRate:0,breathDepth:.01,speechIntensity:.03,speechSpeed:5,emissive:.6,tintIndex:5},Reflective:{distortionAmp:.04,distortionSpeed:.12,distortionFreq:.8,breathRate:.25,breathDepth:.06,speechIntensity:.01,speechSpeed:1.8,emissive:.15,tintIndex:1},Empathy:{distortionAmp:.02,distortionSpeed:.1,distortionFreq:.7,breathRate:.28,breathDepth:.06,speechIntensity:.012,speechSpeed:2.2,emissive:.2,tintIndex:4}};function s(){let e=i.length,t=new Uint8Array(256);for(let n=0;n<64;n++){let o=n/64*e,r=Math.floor(o)%e,a=(r+1)%e,s=o-Math.floor(o),l=s*s*(3-2*s);t[4*n]=Math.round(i[r][0]+(i[a][0]-i[r][0])*l),t[4*n+1]=Math.round(i[r][1]+(i[a][1]-i[r][1])*l),t[4*n+2]=Math.round(i[r][2]+(i[a][2]-i[r][2])*l),t[4*n+3]=255}let n=new o.DataTexture(t,64,1,o.RGBAFormat);return n.wrapS=o.RepeatWrapping,n.wrapT=o.RepeatWrapping,n.needsUpdate=!0,n}},9420:(e,t,n)=>{n.d(t,{r:()=>s});var o=n(7548),i=n(4863);let r="\n uniform vec3 uColsA[".concat(8,"];\n uniform float uPosA[").concat(8,"];\n uniform vec3 uColsB[").concat(8,"];\n uniform float uPosB[").concat(8,"];\n uniform float uMixT;\n uniform float uOffset;\n uniform float uSpan;\n uniform float uTime;\n uniform float uGlowFloor;\n uniform sampler2D uPlate;\n uniform float uPlateAmt;\n uniform float uPlateBand; // 0=bottom of view, 1=top, 2=fill\n varying vec3 vDirection;\n float hash(vec3 p) {\n p = fract(p * 0.3183099 + 0.1);\n p *= 17.0;\n return fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n }\n float noise3D(vec3 x) {\n vec3 i = floor(x);\n vec3 f = fract(x);\n f = f * f * (3.0 - 2.0 * f);\n return mix(mix(mix(hash(i), hash(i + vec3(1,0,0)), f.x),\n mix(hash(i + vec3(0,1,0)), hash(i + vec3(1,1,0)), f.x), f.y),\n mix(mix(hash(i + vec3(0,0,1)), hash(i + vec3(1,0,1)), f.x),\n mix(hash(i + vec3(0,1,1)), hash(i + vec3(1,1,1)), f.x), f.y), f.z);\n }\n float fbm(vec3 p) {\n float v = 0.0;\n float a = 0.5;\n for (int i = 0; i < 3; i++) { v += a * noise3D(p); p *= 2.0; a *= 0.5; }\n return v;\n }\n vec3 gradA(float t) {\n vec3 c = uColsA[0];\n for (int i = 1; i < ").concat(8,"; i++) {\n float a = uPosA[i - 1];\n float b = uPosA[i];\n float f = clamp((t - a) / max(b - a, 1e-4), 0.0, 1.0);\n c = mix(c, uColsA[i], step(a, t) * f);\n }\n return c;\n }\n vec3 gradB(float t) {\n vec3 c = uColsB[0];\n for (int i = 1; i < ").concat(8,';
1 i++) {\n float a = uPosB[i - 1];\n float b = uPosB[i];\n float f = clamp((t - a) / max(b - a, 1e-4), 0.0, 1.0);\n c = mix(c, uColsB[i], step(a, t) * f);\n }\n return c;\n }\n void main() {\n vec3 dir = normalize(vDirection);\n // world +y is up; page gradient runs top(0) -> bottom(1)\n float t = clamp(uOffset - dir.y * uSpan, 0.0, 1.0);\n vec3 color = mix(gradA(t), gradB(t), uMixT);\n // her own light is the floor: over dark skies the refracted interior\n // never drops below a warm dim â she reads as a lantern in the dark,\n // not a dead coal. No-op over bright skies.\n float L = dot(color, vec3(0.299, 0.587, 0.114));\n color += vec3(1.0, 0.82, 0.58) * max(0.0, uGlowFloor - L);\n // STRUCTURED light for her glass to catch (decision 14): a low sun with\n // halo + sun-lit cloud clumps. Smooth gradients gave her nothing to bend;\n // these give her real glints and moving bright shapes in the refraction.\n vec3 sunDir = normalize(vec3(0.55, 0.3, -0.62));\n float toSun = max(dot(dir, sunDir), 0.0);\n vec3 sunCol = vec3(1.0, 0.86, 0.6);\n color += sunCol * (pow(toSun, 320.0) * 2.4 + pow(toSun, 22.0) * 0.35);\n float clumps = smoothstep(0.55, 0.95, fbm(dir * 3.1 + vec3(uTime * 0.02, 0.0, uTime * 0.015)));\n color += sunCol * clumps * 0.24 * max(0.18, 1.0 - uMixT * 0.75);\n // THE WORLD ITSELF in her glass: the photographic plate the page shows\n // behind her is blended into the env so her refraction bends real hills/\n // clouds/corals, not just a gradient (the "illusion" â operator note).\n // seam behind the CAMERA (+z): refraction samples the -z hemisphere, so\n // atan(x, -z) centers the plate there and the wrap point never shows\n // through her glass (R2 finding 1). v-span reduced to dodge clamp bands.\n vec2 puv = vec2(atan(dir.x, -dir.z) / 6.2831853 + 0.5, clamp(0.5 - dir.y * 0.45, 0.03, 0.97));\n vec3 plate = texture2D(uPlate, puv).rgb;\n float band = uPlateBand < 0.5\n ? smoothstep(0.42, 0.8, puv.y)\n : (uPlateBand < 1.5 ? smoothstep(0.6, 0.22, puv.y) : 1.0);\n color = mix(color, plate, uPlateAmt * band);\n // cloud-like drift: gentle luminance variation, never structure\n float n = fbm(dir * 2.4 + vec3(uTime * 0.05, 0.0, uTime * 0.03));\n color *= 0.92 + n * 0.16;\n // she EMITS: her refracted world runs slightly brighter than the page\'s\n // sky so her body reads luminous over daylight, never duller than her\n // own setting (build R1 finding 7 â the no-JS orb was outshining her)\n color *= 1.32;\n // and she is WARM â everywhere. Whatever world she bends, a peach cast\n // pulls the interior toward her aura family so she never reads as a grey\n // stone in teal water (R2 finding 5): refraction is her material, not\n // her replacement.\n float Lc = dot(color, vec3(0.299, 0.587, 0.114));\n color = mix(color, vec3(1.0, 0.85, 0.66) * (Lc * 1.2 + 0.16), 0.38);\n gl_FragColor = vec4(color, 1.0);\n }\n'),a=[[0,"#9AA1C4"],[.22,"#A8B0CE"],[.42,"#E8C49E"],[.55,"#CBA589"],[.72,"#D99FC0"],[.86,"#E0ABC8"],[1,"#B98BAD"]];function s(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e.classList.add("laura"),"dark"===t.theme&&e.classList.add("laura--dark");let n=e.querySelector(".laura-glow");n||((n=document.createElement("span")).className="laura-glow",n.setAttribute("aria-hidden","true"),e.prepend(n));let s=e.querySelector(".laura-fo");s||((s=document.createElement("span")).className="laura-fo",s.setAttribute("aria-hidden","true"),e.appendChild(s));let l=()=>e.classList.add("laura--fallback"),m=null,c=window.matchMedia("(prefers-reduced-motion: reduce)").matches;if(!0!==t.forceFallback&&!c&&function(){try{let e=document.createElement("canvas"),t=e.getContext("webgl2")||e.getContext("webgl")||e.getContext("experimental-webgl");if(!t)return!1;let n=t.getExtension("WEBGL_debug_renderer_info"),o=n?String(t.getParameter(n.UNMASKED_RENDERER_WEBGL)):"";if(/swiftshader|llvmpipe|softpipe|software/i.test(o))return!1;return!0}catch(e){return!1}}())try{m=function(e){var t,n,s,l,m,c;let u,d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},{theme:h="light",emotion:p="None",envVisible:v=!1,interactive:f=!0,segments:g=128,morphScale:x=1,onContextLost:y=null}=d;try{u=new o.WebGLRenderer({antialias:1.5>(window.devicePixelRatio||1),powerPreference:"high-performance",alpha:!0})}catch(e){return null}if(!u.getContext())return u.dispose(),null;let w=Math.min(window.devicePixelRatio||1,1.5);u.setPixelRatio(w),u.toneMapping=o.NoToneMapping,u.domElement.style.cssText="position:absolute;inset:0;width:100%;height:100%;display:block",e.appendChild(u.domElement);let b=new o.Scene,_=new o.PerspectiveCamera(45,1,.1,100);_.position.set(0,0,4.6);let S=e=>{let t=e.slice(0,8);for(;t.length<8;)t.push(t[t.length-1]);return t},M=e=>({cols:S(e).map(e=>{let[,t]=e;return new o.Color(t)}),pos:S(e).map(e=>{let[t]=e;return t})}),k=M(null!=(t=d.sky)?t:a),A=M(null!=(s=null!=(n=d.skyNight)?n:d.sky)?s:a),D=new o.ShaderMaterial({vertexShader:"\n varying vec3 vDirection;\n void main() {\n vDirection = normalize(position);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0
1);\n }\n",fragmentShader:r,side:o.BackSide,depthWrite:!1,uniforms:{uColsA:{value:k.cols},uPosA:{value:k.pos},uColsB:{value:A.cols},uPosB:{value:A.pos},uMixT:{value:0},uOffset:{value:null!=(l=d.skyOffset)?l:.42},uSpan:{value:null!=(m=d.skySpan)?m:.35},uTime:{value:0},uGlowFloor:{value:null!=(c=d.glowFloor)?c:.5},uPlate:{value:new o.DataTexture(new Uint8Array([255,255,255,255]),1,1)},uPlateAmt:{value:0},uPlateBand:{value:2}}});D.uniforms.uPlate.value.needsUpdate=!0;let z={},C=new o.TextureLoader,P=new o.Mesh(new o.SphereGeometry(10,32,32),D);b.add(P);let R=(0,i.GE)(),I=new o.ShaderMaterial({vertexShader:"\n// Simplex 3D Noise â Ian McEwan, Ashima Arts (MIT License)\nvec4 permute(vec4 x){ return mod(((x * 34.0) + 1.0) * x, 289.0); }\nvec4 taylorInvSqrt(vec4 r){ return 1.79284291400159 - 0.85373472095314 * r; }\n\nfloat snoise(vec3 v){\n const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n vec3 i = floor(v + dot(v, C.yyy));\n vec3 x0 = v - i + dot(i, C.xxx);\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min(g.xyz, l.zxy);\n vec3 i2 = max(g.xyz, l.zxy);\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + 2.0 * C.xxx;\n vec3 x3 = x0 - 1.0 + 3.0 * C.xxx;\n i = mod(i, 289.0);\n vec4 p = permute(permute(permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0));\n float n_ = 1.0 / 7.0;\n vec3 ns = n_ * D.wyz - D.xzx;\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_);\n vec4 x = x_ * ns.x + ns.yyyy;\n vec4 y = y_ * ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n vec4 b0 = vec4(x.xy, y.xy);\n vec4 b1 = vec4(x.zw, y.zw);\n vec4 s0 = floor(b0) * 2.0 + 1.0;\n vec4 s1 = floor(b1) * 2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;\n vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;\n vec3 p0 = vec3(a0.xy, h.x);\n vec3 p1 = vec3(a0.zw, h.y);\n vec3 p2 = vec3(a1.xy, h.z);\n vec3 p3 = vec3(a1.zw, h.w);\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));\n p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w;\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot(m * m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));\n}\n\nvarying vec3 v_surfaceNormal;\nvarying vec3 v_eyeDir;\nvarying float v_morphFactor;\nvarying vec2 v_uv;\n\nuniform float u_time;\nuniform float u_clickTime;\nuniform float u_morphIntensity;\nuniform float u_morphDetail;\n// Phase accumulators (JS integrates phase += rate * delta) replace the older\n// u_time * speed pattern. When the speed register lerps between emotion\n// presets, multiplying it against u_time produced phase discontinuities â\n// the noise sample coordinate would jump non-monotonically and read as the\n// orb spinning/jittering during a color transition. Accumulating in JS means\n// rate changes only affect the increment, never the absolute phase.\nuniform float u_morphPhase;\nuniform float u_voiceIntensity;\nuniform float u_voicePhase;\nuniform vec3 u_axisScale;\nuniform vec2 u_cursor;\nuniform vec3 u_pointerLocal;\nuniform float u_pointerStrength;\nuniform float u_hoverAmp;\n\n// Domain-warped noise: pre-distorts sample coords for organic flow\nfloat warpedNoise(vec3 p, float detail, float phase) {\n vec3 q = p + snoise(p * 0.5 + phase * 0.3) * 0.4;\n return snoise(q * detail + vec3(0.0, 0.0, phase));\n}\n\n// Core surface displacement (also used by normal computation)\nfloat surfaceHeight(vec3 dir) {\n // Ambient organic morphing via domain-warped noise (subject to breathing)\n float ambient = warpedNoise(dir, u_morphDetail, u_morphPhase) * 0.7;\n\n // Pointer proximity warp (scales with u_hoverAmp, independent of breathing)\n float proximity = smoothstep(0.3, 1.0, dot(dir, normalize(u_pointerLocal)));\n float pointerWarp = snoise(dir * u_morphDetail * 2.0 + u_morphPhase * 3.0)\n * proximity * u_pointerStrength * 2.0;\n\n return ambient * u_morphIntensity + pointerWarp * u_hoverAmp;\n}\n\nvec3 deformSurface(vec3 p) {\n vec3 dir = normalize(p);\n float r = length(p);\n\n // Separate ambient (breathing-modulated) from interaction terms\n float ambient = warpedNoise(dir, u_morphDetail, u_morphPhase) * 0.7;\n\n float proximity = smoothstep(0.3, 1.0, dot(dir, normalize(u_pointerLocal)));\n float pointerWarp = snoise(dir * u_morphDetail * 2.0 + u_morphPhase * 3.0)\n * proximity * u_pointerStrength * 2.0;\n\n // Click wave â radial pulse from pointer contact (interaction term)\n float fromClick = dot(dir, normalize(u_pointerLocal));\n float clickAge = (u_time - u_clickTime) * 10.0;\n float wave = cos(fromClick * 4.71 + 3.14 + clickAge) * 6.0\n * smoothstep(4.71, 9.42, fromClick * 4.71 + clickAge)\n * smoothstep(9.42, 4.71, fromClick * 4.71 + clickAge);\n\n // Voice surface vibration (phase-accumulated, see u_voicePhase note)\n float voice = snoise(dir * 8.0 + vec3(u_voicePhase))\n + snoise(dir * 14.0 + vec3(u_voicePhase * 1.4)) * 0.5;\n\n // Interaction terms (pointer + ripple) scale with u_hoverAmp, independent of breathing\n // Ambient scales with u_morphIntensity (modulated by breathing in JS)\n float d = (pointerWarp + wave) * u_hoverAmp\n + ambient * u_morphIntensity\n + voice * u_voiceIntensity;\n\n return dir * (r + d);\n}\n\n// Normal via forward-difference on tangent frame (Gram-Schmidt from up-vector)\nvec3 computeDeformedNormal(vec3 pos, vec3 deformedPos) {\n vec3 n = normalize(pos);\n vec3 up = abs(n.y) < 0.99 ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0);\n vec3 t1 = normalize(cross(up, n));\n vec3 t2 = cross(n, t1);\n\n float h = 0.1;
1\n vec3 neighbor1 = deformSurface(pos + t1 * h) * u_axisScale;\n vec3 neighbor2 = deformSurface(pos + t2 * h) * u_axisScale;\n return normalize(cross(neighbor1 - deformedPos, neighbor2 - deformedPos));\n}\n\nvoid main() {\n vec3 deformed = deformSurface(position);\n // A6 Squash & Stretch: axis scaling after deformation\n deformed *= u_axisScale;\n vec3 deformedN = computeDeformedNormal(position, deformed);\n\n vec4 worldPos = modelMatrix * vec4(deformed, 1.0);\n\n v_eyeDir = normalize(worldPos.xyz - cameraPosition);\n v_surfaceNormal = normalize(modelViewMatrix * vec4(deformedN, 0.0)).xyz;\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(deformed, 1.0);\n\n v_morphFactor = clamp(1.0 - distance(position, deformed), 0.0, 1.0);\n v_uv = uv;\n}\n",fragmentShader:"\n#define PI 3.1415926538\n\n// Simplex 3D Noise â Ian McEwan, Ashima Arts (MIT License)\nvec4 permute(vec4 x){ return mod(((x * 34.0) + 1.0) * x, 289.0); }\nvec4 taylorInvSqrt(vec4 r){ return 1.79284291400159 - 0.85373472095314 * r; }\n\nfloat snoise(vec3 v){\n const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n vec3 i = floor(v + dot(v, C.yyy));\n vec3 x0 = v - i + dot(i, C.xxx);\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min(g.xyz, l.zxy);\n vec3 i2 = max(g.xyz, l.zxy);\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + 2.0 * C.xxx;\n vec3 x3 = x0 - 1.0 + 3.0 * C.xxx;\n i = mod(i, 289.0);\n vec4 p = permute(permute(permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0));\n float n_ = 1.0 / 7.0;\n vec3 ns = n_ * D.wyz - D.xzx;\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_);\n vec4 x = x_ * ns.x + ns.yyyy;\n vec4 y = y_ * ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n vec4 b0 = vec4(x.xy, y.xy);\n vec4 b1 = vec4(x.zw, y.zw);\n vec4 s0 = floor(b0) * 2.0 + 1.0;\n vec4 s1 = floor(b1) * 2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;\n vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;\n vec3 p0 = vec3(a0.xy, h.x);\n vec3 p1 = vec3(a0.zw, h.y);\n vec3 p2 = vec3(a1.xy, h.z);\n vec3 p3 = vec3(a1.zw, h.w);\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3)));\n p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w;\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot(m * m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3)));\n}\n\nuniform sampler2D u_sceneTex;\nuniform vec2 u_viewport;\nuniform float u_time;\nuniform float u_glassStrength;\nuniform float u_glassIOR;\nuniform float u_noiseGrain;\nuniform sampler2D u_shimmerRamp;\nuniform float u_shimmerGain;\nuniform float u_shimmerSpeed;\nuniform vec3 u_tintColor;\nuniform float u_tintWeight;\nuniform float u_pastelBlend;\nuniform float u_invertMix;\nuniform float u_emissiveGlow;\n// Light-mode weight (1.0 = light, 0.0 = dark). Gates the warm-sun treatment\n// below so the orb reads as a saturated warm-gold sphere over the bright\n// light-mode sky instead of a washed-out translucent bubble. Dark mode passes\n// 0.0, leaving the original math bit-for-bit unchanged. Defaults to 0.0 when a\n// material never sets it (safe = original behavior).\nuniform float u_lightMode;\n\nvarying vec3 v_surfaceNormal;\nvarying vec3 v_eyeDir;\nvarying float v_morphFactor;\nvarying vec2 v_uv;\n\n// Subtle dither grain\nvec2 grain(vec2 p) {\n vec3 a = fract(vec3(p.xyx) * vec3(0.1031, 0.1030, 0.0973));\n a += dot(a, a.yzx + 33.33);\n return fract((a.xx + a.yz) * a.zy);\n}\n\nvoid main() {\n // Perturb normal with high-freq noise for micro-detail\n vec3 N = normalize(v_surfaceNormal + snoise(v_surfaceNormal * 5.0) * vec3(0.2, 0.2, 0.0));\n vec2 uv = gl_FragCoord.xy / u_viewport;\n\n // Subtle grain to break banding\n uv += (grain(uv * 100.0) * 2.0 - 1.0) * 0.001 * v_morphFactor * u_noiseGrain;\n\n // Fresnel rim â drives shimmer intensity and dispersion spread\n float NdotV = abs(dot(N, normalize(cameraPosition)));\n float rim = 1.0 - NdotV;\n\n // Chromatic dispersion: offset UVs along normal's screen projection\n // Red bends least, blue bends most (wavelength-dependent glass)\n vec2 screenN = N.xy;\n float spread = rim * u_glassStrength;\n\n // Damp dispersion near the scene-texture edges (marketing funnels park the\n // orb near screen edges; offset samples past the clamped border smear the\n // last texel row into a blown streak). No-op for centered orbs.\n float edgeDamp = min(min(uv.x, 1.0 - uv.x), min(uv.y, 1.0 - uv.y));\n spread *= smoothstep(0.0, 0.12, edgeDamp);\n\n vec2 uvR = uv + screenN * spread * (u_glassIOR - 0.04);\n vec2 uvG = uv + screenN * spread * u_glassIOR;\n vec2 uvB = uv + screenN * spread * (u_glassIOR + 0.04);\n\n vec3 refracted = vec3(\n texture2D(u_sceneTex, uvR).r,\n texture2D(u_sceneTex, uvG).g,\n texture2D(u_sceneTex, uvB).b\n );\n\n // View-dependent shading: center sees through, edges fade\n float viewFade = smoothstep(0.0, 0.8, NdotV);\n vec3 glassBody = refracted * viewFade;\n\n // Light/dark mode inversion\n glassBody = mix(vec3(1.0) - (vec3(1.0) - refracted) * viewFade, glassBody, u_invertMix);\n\n // âââ Light-mode translucent glass body (iOS parity, iteration 3) âââââââââââ\n // Gated on u_lightMode; dark mode = 0.0 â glassBody untouched (bit-for-bit).\n //\n // The refracted scene behind the orb is ALREADY pale over the bright light sky\n // â that's the translucency, and it's what iOS shows: a pale frosted sphere you\n // see the sky/clouds THROUGH, with the warmth carried by the RIM, not the body.\n // The two prior passes fought this: round-1 washed the body to invisible white;\n // round-2 multiplied it by a SATURATED orange hue (~(1.36,0.93,0.41) for the\n // Sunrise/Warmth tint) at 36â58% â a flat opaque LEMON ball, worst over the\n // clear-sky centre on Journey (no cloud texture there to preserve, so the whole\n // disc went uniform yellow). This pass keeps the body PALE + LOW-SATURATION +\n // SEE-THROUGH and lets the gold rim define the sphere.\n vec3 warmTint = u_tintColor; // feeds the warm rim below (kept for parity)\n float baseLuma = dot(warmTint, vec3(0.299, 0.587, 0.114));\n warmTint = clamp(mix(vec3(baseLuma), warmTint, 1.2), 0.0, 1.0); // gentle sat lift for the rim\n // Register temperature: warm tints (r>b) â 1, cool (r<b) â 0. Hoisted here so\n // the cool-register limb darkening (below) AND the rim can key off it â cool\n // orbs need a DEFINED edge over the bright cream sky, not a brighter one\n // (the light-mode washout: a pale-cyan Calm rim dissolving into cream).\n float tintWarmth = smoothstep(0.0, 0.25, u_tintColor.r - u_tintColor.b);\n // 1) Knock most of the chroma out of the refracted sky. The pastel rainbow\n // (cyan/pink) muddies under any warm cast and reads as a saturated ball; the\n // iOS interior is near-neutral pale. Keep a little of the sky's own hue so it\n // stays pale BLUE-white over open sky (session-voice) and pale PEACH over\n // warm cloud (patterns/journey), never a flat monochrome disc.\n float bodyLuma = dot(glassBody, vec3(0.299, 0.587, 0.114));\n vec3 paleBody = mix(glassBody, vec3(bodyLuma), 0.58);\n // 2) A small step toward a frosted pale white so it reads as luminous glass, not\n // a dull grey disc â kept low so it never washes out to invisible (round-1).\n paleBody = mix(paleBody, vec3(0.94, 0.95, 0.97), 0.14);\n // 3) A WHISPER of warm peach: a NEAR-WHITE warm multiply (not a saturated hue),\n // a hair stronger toward the silhouette for spherical warmth. The gold rim,\n // not this, is the \"warm orb\" read.\n vec3 peachTint = vec3(1.0, 0.93, 0.84);\n float bodyWarm = mix(0.12, 0.34, 1.0 - NdotV);\n vec3 warmBody = paleBody * mix(vec3(1.0), peachTint, bodyWarm);\n // 4) Gentle limb darkening just inside the rim â 3D spherical form, and it\n // separates the pale body from the bright rim so a translucent sphere reads\n // even where the body luma â the sky luma (prevents the round-1 wash-out).\n // Cool registers get a deeper limb (0.72 â ~28% darkened) so a soft dark ring\n // just inside the silhouette separates the pale body from the cream sky; warm\n // stays ~0.85 (its gold rim already carries the edge). Interior chroma\n // untouched (no round-2 lemon ball); darkens rather than lifts (no round-1 wash).\n warmBody *= mix(1.0, mix(0.72, 0.86, tintWarmth), smoothstep(0.35, 0.95, rim));\n glassBody = mix(glassBody, warmBody, u_lightMode);\n\n // Shimmer: Fresnel power curve drives palette ramp sampling\n float fresnelCurve = pow(rim, 2.5);\n vec3 shimmer = texture2D(u_shimmerRamp, vec2(fract(fresnelCurve * 3.0 + u_time * u_shimmerSpeed), 0.5)).rgb;\n shimmer = mix(shimmer, u_tintColor * 1.5, u_tintWeight);\n shimmer *= shimmer; // saturate toward richer hues\n // Pastel softening â blend toward white to reduce neon intensity\n shimmer = mix(shimmer, vec3(1.0), u_pastelBlend);\n\n // Rim blend: shimmer at glancing angles, glass body at center.\n float rimBlend = pow(rim, 1.8);\n // Light mode: keep a defined bright ring that hugs the silhouette â slightly\n // tighter than dark, but NOT the pinched pow(2.6) the over-correction used\n // (which nearly erased the rim and left only the flat body).\n rimBlend = mix(rimBlend, pow(rim, 2.0), u_lightMode);\n\n vec3 rimGlow = shimmer * u_shimmerGain;\n // Light-mode rim, two families by register temperature (iOS parity):\n // WARM tints (Warmth/Noticing/Alert) get the luminous peach-gold ring â G 1.08\n // (not 1.15) keeps it orange-peach rather than yellow, B 0.94 lands B/R at\n // iOS's pastel-peach ratio, and the clamp stops it ever going yellow-white and\n // flooding the body (the round-2 failure). COOL tints (Calm/Reflective/Empathy)\n // must KEEP their hue â the warm multipliers turned Calm's teal rim seafoam-\n // green â so they take a hue-preserving bright ring off the sat-lifted tint\n // instead. Dark mode keeps its full additive shimmer glow unchanged.\n vec3 warmGold = warmTint * vec3(1.12, 1.08, 0.94) + vec3(0.12, 0.06, 0.0);\n warmGold = min(warmGold, vec3(1.2, 1.0, 0.62));\n // COOL rim: saturate, don't brighten. The old warmTint*1.35 + 0.10 produced a\n // pale bright cyan (luma ~0.74 ~ the cream sky) that vanished â the washout.\n // Hold luma at the tint's own level and push CHROMA up instead, so the cool orb\n // reads by hue AND tone the way the warm gold rim does, hue preserved. (tintWarmth\n // is hoisted up in the body section now â do not redeclare here.)\n float coolLuma = dot(warmTint, vec3(0.299, 0.587, 0.114));\n vec3 coolRim = clamp(mix(vec3(coolLuma), warmTint, 1.7), 0.0, 1.0);\n vec3 warmRim = mix(coolRim, warmGold, tintWarmth);\n rimGlow = mix(rimGlow, warmRim, u_lightMode);
1\n gl_FragColor.rgb = mix(glassBody, rimGlow, rimBlend);\n // Dark-mode ember edge (iOS Orb.metal warmEdge): a register-independent\n // warm-gold rim so the dark orb reads as a lit ember against the night sky,\n // not a pale moon. Additive, silhouette-concentrated, off in light mode.\n gl_FragColor.rgb += vec3(1.00, 0.66, 0.40) * pow(rim, 2.35) * 0.30 * (1.0 - u_lightMode);\n\n // Emissive inner glow â palette color radiates from core. In light mode this is\n // a SATURATED tint added right at the centre (NdotVâ1), so at full strength it\n // planted a warm-orange hotspot in the body â a chunk of the \"too yellow\" read.\n // The iOS interior core is pale, so damp it hard in light mode (0.3\xd7). Dark mode\n // (u_lightMode 0) keeps its full core glow, unchanged.\n gl_FragColor.rgb += u_tintColor * u_emissiveGlow * NdotV * mix(1.0, 0.3, u_lightMode);\n // Dark-mode warm inner radiance (iOS livingCore/caustic analog): bounded,\n // center-weighted warm glow so the dark interior reads molten rather than\n // cool-faint. Dark-only; the light path keeps its damped core untouched.\n gl_FragColor.rgb += vec3(1.00, 0.60, 0.34) * pow(NdotV, 1.5) * 0.12 * (1.0 - u_lightMode);\n\n gl_FragColor.a = 1.0;\n}\n",uniforms:{u_sceneTex:{value:null},u_viewport:{value:new o.Vector2(1920,1080)},u_time:{value:0},u_clickTime:{value:0},u_glassStrength:{value:.15},u_glassIOR:{value:.9},u_morphIntensity:{value:.06},u_morphPhase:{value:0},u_morphDetail:{value:1},u_noiseGrain:{value:1.2},u_shimmerGain:{value:1.5},u_pastelBlend:{value:.5},u_shimmerSpeed:{value:.1},u_shimmerRamp:{value:R},u_tintColor:{value:new o.Vector3(.29,.54,.6)},u_tintWeight:{value:1},u_invertMix:{value:0},u_lightMode:{value:+("dark"!==h)},u_emissiveGlow:{value:0},u_voiceIntensity:{value:0},u_voicePhase:{value:0},u_axisScale:{value:new o.Vector3(1,1,1)},u_cursor:{value:new o.Vector2(0,0)},u_pointerLocal:{value:new o.Vector3(0,0,1)},u_pointerStrength:{value:0},u_hoverAmp:{value:.15}}}),T=new o.SphereGeometry(1.3,g,g),B=new o.Mesh(T,I);b.add(B);let E=window.matchMedia("(pointer: coarse)").matches?.5:1,L=null,N=new o.Clock,F=new o.Raycaster,G={distortionAmp:.06,distortionSpeed:.17,distortionFreq:1,breathRate:.28,breathDepth:.1,speechIntensity:.015,speechSpeed:3,emissive:0,tintR:.29,tintG:.54,tintB:.6,init:!1},O={stretch:0,vel:0,angle:0},W={velocity:0},q={emotion:p,theme:h,velocity:{x:0,y:0},voiceEnvelope:0,position:{x:0,y:0,z:0},scale:1,paused:!1,disposed:!1,mouseOnPage:!1,hover:!1},V={amplitude:.032,speed:.17,frequency:1},j={enabled:!0,rate:.28,depth:.055},H=0,U=0,J=0,K=new o.Vector2(0,0),Y=new o.Vector2(0,0),X=new o.Vector3(0,0,1),Q=new o.Vector3,Z=new o.Vector3,$=new o.Vector3;function ee(e){q.mouseOnPage=!0;let t=u.domElement.getBoundingClientRect();0!==t.width&&0!==t.height&&K.set((e.clientX-t.left)/t.width*2-1,-(2*((e.clientY-t.top)/t.height))+1)}function et(){q.mouseOnPage=!1}function en(e){let t=u.domElement.getBoundingClientRect();if(0===t.width||0===t.height)return;let n=new o.Vector2((e.clientX-t.left)/t.width*2-1,-(2*((e.clientY-t.top)/t.height))+1);F.setFromCamera(n,_);let i=F.intersectObject(B,!1),r=I.uniforms.u_time.value;i.length>0&&I.uniforms.u_clickTime.value<r-.9&&(I.uniforms.u_clickTime.value=r,X.copy(i[0].point))}f&&(window.addEventListener("pointermove",ee,{passive:!0}),document.addEventListener("pointerleave",et),window.addEventListener("pointerdown",en,{passive:!0}));let eo=!1;function ei(e){e.preventDefault(),eo=!0,y&&y()}function er(){"visible"===document.visibilityState?(N.getDelta(),q.paused=!1):q.paused=!0}function ea(){let t=e.clientWidth||1,n=e.clientHeight||1;u.setSize(t,n,!1),_.aspect=t/n,_.updateProjectionMatrix(),L&&L.dispose(),L=new o.WebGLRenderTarget(Math.max(1,Math.round(t*w*E)),Math.max(1,Math.round(n*w*E)),{minFilter:o.LinearFilter,magFilter:o.LinearFilter})}u.domElement.addEventListener("webglcontextlost",ei),document.addEventListener("visibilitychange",er);let es=new ResizeObserver(ea);es.observe(e),ea();let el=requestAnimationFrame(function t(){let n,o,r;if(q.disposed||(el=requestAnimationFrame(t),q.paused||eo))return;let a=Math.min(N.getDelta(),.1),s=N.elapsedTime;B.visible=!1,P.visible=!0,u.setRenderTarget(L),u.clear(),u.render(b,_),u.setRenderTarget(null),B.visible=!0,P.visible=v,I.uniforms.u_sceneTex.value=L.texture;let l=e.clientWidth||1,m=e.clientHeight||1;I.uniforms.u_viewport.value.set(l*w,m*w),I.uniforms.u_time.value=s,B.getWorldPosition(Z);let c=B.matrixWorld.getMaxScaleOnAxis();$.set(Z.x,Z.y+1.3*c,Z.z),Z.project(_),$.project(_);let d=Z.x,h=Z.y,p=Math.abs($.y-h),g=K.x-d,y=K.y-h,S=Math.sqrt(g*g+y*y),M=p+.04,k=f?Math.max(0,1-Math.max(0,(S-M)/.03)):0;if(q.hover=f&&q.mouseOnPage&&S<M,f&&q.mouseOnPage){F.setFromCamera(K,_);let e=F.intersectObject(B,!1);e.length>0&&X.copy(e[0].point)}let A=I.uniforms.u_cursor.value;A.x+=(K.x*k-A.x)*.1,A.y+=(K.y*k-A.y)*.1;let z=i.Df[q.emotion]||i.Df.None,C="None"!==q.emotion&&z,R={distortionAmp:C?z.distortionAmp:V.amplitude,distortionSpeed:C?z.distortionSpeed:V.speed,distortionFreq:C?z.distortionFreq:V.frequency,breathRate:C?z.breathRate:j.rate,breathDepth:C?z.breathDepth:j.depth,speechIntensity:C?z.speechIntensity:.015,speechSpeed:C?z.speechSpeed:3,emissive:C?z.emissive:0};if(C&&z.tintIndex>=0)[n,o,r]=i.BI[z.tintIndex];else{let e=i.BI.length,t=j.enabled?j.rate/e:.09,a=s*t%1*e,l=Math.floor(a)%e,m=(l+1)%e,c=a-Math.floor(a),u=c*c*(3-2*c);n=i.BI[l][0]+(i.BI[m][0]-i.BI[l][0])*u,o=i.BI[l][1]+(i.BI[m][1]-i.BI[l][1])*u,r=i.BI[l][2]+(i.BI[m][2]-i.BI[l][2])*u}if(G.init){let e=1-Math.exp(-2.5*a);G.distortionAmp+=(R.distortionAmp-G.distortionAmp)*e,G.distortionSpeed+=(R.distortionSpeed-G.distortionSpeed)*e,G.distortionFreq+=(R.distortionFreq-G.distortionFreq)*e,G.breathRate+=(R.breathRate-G.breathRate)*e,G.breathDepth+=(R.breathDepth-G.breathDepth)*e,G.speechIntensity+=(R.speechIntensity-G.speechIntensity)*e,G.speechSpeed+=(R.speechSpeed-G.speechSpeed)*e,G.emissive+=(R.emissive-G.emissive)*e,G.tintR+=(n-G.tintR)*e,G.tintG+=(o-G.tintG)*e,G.tintB+=(r-G.tintB)*e}else Object.assign(G,R,{tintR:n,tintG:o,tintB:r,init:!0});J+=G.breathRate*Math.PI*2*a;let T=j.enabled?Math.sin(J)*G.breathDepth:0;I.uniforms.u_morphIntensity.value=(G.distortionAmp+T)*x,H+=G.distortionSpeed*a,I.uniforms.u_morphPhase.value=H,I.uniforms.u_morphDetail.value=G.distortionFreq;let E=+("dark"!==q.theme);I.uniforms.u_lightMode.value+=(E-I.uniforms.u_lightMode.value)*(1-Math.exp(-6*a)),I.uniforms.u_invertMix.value=(1-I.uniforms.u_lightMode.value)*.85,I.uniforms.u_emissiveGlow.value=G.emissive;
1let ee=f?Math.max(0,1-Math.max(0,(S-(p+.08))/.05)):0,et=q.mouseOnPage?.7*K.x*ee:0,en=q.mouseOnPage?.4*K.y*ee:0;Y.x+=(et-Y.x)*.02,Y.y+=(en-Y.y)*.02,B.position.set(q.position.x+.1*Y.x*q.scale,q.position.y+.1*Y.y*q.scale,q.position.z),B.scale.setScalar(q.scale),q.velocity.x*=Math.exp(-2.5*a),q.velocity.y*=Math.exp(-2.5*a);let ei=q.velocity.x,er=q.velocity.y,ea=ei*ei+er*er,es=ea>.01,em=es?Math.min(.2*Math.sqrt(ea),.4):0,ec=-14*(O.stretch-em)-3*O.vel;if(O.vel+=ec*a,O.stretch+=O.vel*a,es){let e=Math.atan2(er,ei)-O.angle;e>Math.PI&&(e-=2*Math.PI),e<-Math.PI&&(e+=2*Math.PI),O.angle+=e*Math.min(1,6*a)}if(Math.abs(O.stretch)>.001||Math.abs(O.vel)>.001){let e=Math.cos(O.angle),t=Math.sin(O.angle),n=O.stretch,o=1/Math.sqrt(Math.max(1+n,.3));I.uniforms.u_axisScale.value.set(1+n*e*e+(o-1)*t*t,1+n*t*t+(o-1)*e*e,o)}else I.uniforms.u_axisScale.value.set(1,1,1);U+=G.speechSpeed*a,I.uniforms.u_voicePhase.value=U,I.uniforms.u_voiceIntensity.value=q.voiceEnvelope*G.speechIntensity,I.uniforms.u_tintColor.value.set(G.tintR,G.tintG,G.tintB);let eu=1*!!q.hover,ed=I.uniforms.u_pointerStrength.value,eh=(.92*W.velocity+(eu-ed)*.004)*.97;1e-5>Math.abs(eh)?(W.velocity=0,I.uniforms.u_pointerStrength.value=eu):(W.velocity=eh,I.uniforms.u_pointerStrength.value+=eh),Q.copy(X),B.worldToLocal(Q),Q.normalize(),I.uniforms.u_pointerLocal.value.lerp(Q,.04),I.uniforms.u_hoverAmp.value=.15,D.uniforms.uTime.value=s,u.render(b,_)});return{setPosition(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0;q.position.x=e,q.position.y=t,q.position.z=n},setScale(e){q.scale=e},setVelocity(e,t){q.velocity.x=e,q.velocity.y=t},setEmotion(e){i.Df[e]&&(q.emotion=e)},setTheme(e){q.theme="dark"===e?"dark":"light"},setVoiceEnvelope(e){q.voiceEnvelope=Math.max(0,Math.min(1,e))},setSkyMix(e){D.uniforms.uMixT.value=Math.max(0,Math.min(1,e))},setSkyOffset(e){D.uniforms.uOffset.value=Math.max(0,Math.min(1,e))},setPlate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"bottom",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:.5,i="top"===t?1:2*("fill"===t);if(!e){D.uniforms.uPlateAmt.value=0;return}let r=e=>{e.colorSpace=o.SRGBColorSpace,e.wrapS=o.MirroredRepeatWrapping,e.wrapT=o.ClampToEdgeWrapping,D.uniforms.uPlate.value=e,D.uniforms.uPlateBand.value=i,D.uniforms.uPlateAmt.value=n};z[e]?r(z[e]):C.load(e,t=>{z[e]=t,r(t)})},setSky(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"a",n=M(e),o="b"===t?D.uniforms.uColsB:D.uniforms.uColsA,i="b"===t?D.uniforms.uPosB:D.uniforms.uPosA;o.value=n.cols,i.value=n.pos},ripple(){let e=I.uniforms.u_time.value;I.uniforms.u_clickTime.value<e-.9&&(I.uniforms.u_clickTime.value=e,B.getWorldPosition(X))},pause(){q.paused=!0},resume(){N.getDelta(),q.paused=!1},get element(){return u.domElement},get contextLost(){return eo},dispose(){q.disposed=!0,cancelAnimationFrame(el),es.disconnect(),document.removeEventListener("visibilitychange",er),u.domElement.removeEventListener("webglcontextlost",ei),f&&(window.removeEventListener("pointermove",ee),document.removeEventListener("pointerleave",et),window.removeEventListener("pointerdown",en)),T.dispose(),I.dispose(),R.dispose(),P.geometry.dispose(),D.dispose(),L&&L.dispose(),u.dispose(),u.domElement.remove()}}}(e,{...t,onContextLost:l})}catch(e){m=null}return m?e.classList.remove("laura--fallback"):l(),{tier:m?"webgl":"css",orb:m,host:e,setDark(t){e.classList.toggle("laura--dark",!!t),m&&m.setTheme(t?"dark":"light")},dispose(){m&&m.dispose()}}}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.