{
  "streamed": true,
  "usage": {
    "prompt_tokens": 108,
    "completion_tokens": 11970,
    "total_tokens": 12078,
    "cost": 0.35964,
    "is_byok": false,
    "prompt_tokens_details": {
      "cached_tokens": 0,
      "cache_write_tokens": 0,
      "audio_tokens": 0,
      "video_tokens": 0
    },
    "cost_details": {
      "upstream_inference_cost": 0.35964,
      "upstream_inference_prompt_cost": 0.00054,
      "upstream_inference_completions_cost": 0.3591
    },
    "completion_tokens_details": {
      "reasoning_tokens": 4188,
      "image_tokens": 0,
      "audio_tokens": 0
    }
  },
  "finishReason": "stop",
  "content": "```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n  <title>Big Mac — Three.js</title>\n  <style>\n    * { box-sizing: border-box; }\n    html, body {\n      width: 100%;\n      height: 100%;\n      margin: 0;\n      overflow: hidden;\n      background: #100d0b;\n    }\n    canvas {\n      display: block;\n      width: 100%;\n      height: 100%;\n      touch-action: none;\n    }\n    .vignette {\n      position: fixed;\n      inset: 0;\n      pointer-events: none;\n      background:\n        radial-gradient(circle at 50% 43%, transparent 38%, rgba(5,3,2,.18) 72%, rgba(0,0,0,.48) 115%);\n      z-index: 2;\n    }\n  </style>\n  <script type=\"importmap\">\n    {\n      \"imports\": {\n        \"three\": \"https://cdn.jsdelivr.net/npm/three@0.161.0/build/three.module.js\",\n        \"three/addons/\": \"https://cdn.jsdelivr.net/npm/three@0.161.0/examples/jsm/\"\n      }\n    }\n  </script>\n</head>\n<body>\n  <div class=\"vignette\"></div>\n\n  <script type=\"module\">\n    import * as THREE from 'three';\n    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n\n    THREE.ColorManagement.enabled = true;\n\n    const scene = new THREE.Scene();\n    scene.fog = new THREE.FogExp2(0x17110d, 0.022);\n\n    const camera = new THREE.PerspectiveCamera(38, innerWidth / innerHeight, 0.1, 100);\n    camera.position.set(10.2, 4.8, 12.2);\n\n    const renderer = new THREE.WebGLRenderer({\n      antialias: true,\n      alpha: false,\n      powerPreference: 'high-performance'\n    });\n    renderer.setPixelRatio(Math.min(devicePixelRatio, 2));\n    renderer.setSize(innerWidth, innerHeight);\n    renderer.shadowMap.enabled = true;\n    renderer.shadowMap.type = THREE.PCFSoftShadowMap;\n    renderer.outputColorSpace = THREE.SRGBColorSpace;\n    renderer.toneMapping = THREE.ACESFilmicToneMapping;\n    renderer.toneMappingExposure = 1.12;\n    document.body.prepend(renderer.domElement);\n\n    const controls = new OrbitControls(camera, renderer.domElement);\n    controls.target.set(0, -0.12, 0);\n    controls.enableDamping = true;\n    controls.dampingFactor = 0.055;\n    controls.enablePan = false;\n    controls.minDistance = 8;\n    controls.maxDistance = 22;\n    controls.minPolarAngle = 0.38;\n    controls.maxPolarAngle = Math.PI * 0.49;\n\n    function mulberry32(seed) {\n      return function () {\n        let t = seed += 0x6D2B79F5;\n        t = Math.imul(t ^ t >>> 15, t | 1);\n        t ^= t + Math.imul(t ^ t >>> 7, t | 61);\n        return ((t ^ t >>> 14) >>> 0) / 4294967296;\n      };\n    }\n\n    const random = mulberry32(947213);\n\n    function hash(x, y, z = 0) {\n      const n = Math.sin(x * 127.1 + y * 311.7 + z * 74.7) * 43758.5453123;\n      return n - Math.floor(n);\n    }\n\n    function makeTexture(type, size = 384) {\n      const canvas = document.createElement('canvas');\n      canvas.width = canvas.height = size;\n      const ctx = canvas.getContext('2d');\n      const image = ctx.createImageData(size, size);\n      const data = image.data;\n      const rng = mulberry32(type === 'bun' ? 141 : type === 'patty' ? 277 : 419);\n\n      for (let y = 0; y < size; y++) {\n        for (let x = 0; x < size; x++) {\n          const i = (y * size + x) * 4;\n          const coarse =\n            Math.sin(x * 0.075) * 0.25 +\n            Math.sin(y * 0.091) * 0.22 +\n            Math.sin((x + y) * 0.035) * 0.18;\n          const grain = (rng() - 0.5) * 2;\n\n          let r, g, b;\n          if (type === 'bun') {\n            const v = grain * 9 + coarse * 8;\n            r = 190 + v;\n            g = 103 + v * 0.72;\n            b = 39 + v * 0.35;\n          } else if (type === 'patty') {\n            const v = grain * 15 + coarse * 8;\n            r = 55 + v;\n            g = 28 + v * 0.58;\n            b = 17 + v * 0.38;\n          } else {\n            const v = 126 + grain * 48 + coarse * 24;\n            r = g = b = v;\n          }\n\n          data[i] = Math.max(0, Math.min(255, r));\n          data[i + 1] = Math.max(0, Math.min(255, g));\n          data[i + 2] = Math.max(0, Math.min(255, b));\n          data[i + 3] = 255;\n        }\n      }\n      ctx.putImageData(image, 0, 0);\n\n      if (type === 'bun') {\n        for (let i = 0; i < 350; i++) {\n          const x = rng() * size;\n          const y = rng() * size;\n          const radius = 0.4 + rng() * 1.5;\n          ctx.fillStyle = `rgba(85,37,13,${0.05 + rng() * 0.14})`;\n          ctx.beginPath();\n          ctx.arc(x, y, radius, 0, Math.PI * 2);\n          ctx.fill();\n        }\n      } else if (type === 'patty') {\n        for (let i = 0; i < 900; i++) {\n          const x = rng() * size;\n          const y = rng() * size;\n          const radius = 0.4 + rng() * 2.1;\n          const light = rng() > 0.72;\n          ctx.fillStyle = light\n            ? `rgba(126,67,34,${0.08 + rng() * 0.2})`\n            : `rgba(9,4,2,${0.08 + rng() * 0.28})`;\n          ctx.beginPath();\n          ctx.arc(x, y, radius, 0, Math.PI * 2);\n          ctx.fill();\n        }\n      }\n\n      const texture = new THREE.CanvasTexture(canvas);\n      texture.wrapS = texture.wrapT = THREE.RepeatWrapping;\n      texture.repeat.set(type === 'patty' ? 5 : 3.2, type === 'patty' ? 1.8 : 1.35);\n      texture.anisotropy = renderer.capabilities.getMaxAnisotropy();\n      if (type !== 'bump') texture.colorSpace = THREE.SRGBColorSpace;\n      return texture;\n    }\n\n    const bunMap = makeTexture('bun');\n    const bunBump = makeTexture('bump');\n    const pattyMap = makeTexture('patty');\n    const pattyBump = makeTexture('bump');\n\n    const bunMaterial = new THREE.MeshPhysicalMaterial({\n      color: 0xd27a2c,\n      map: bunMap,\n      bumpMap: bunBump,\n      bumpScale: 0.045,\n      roughness: 0.72,\n      metalness: 0,\n      clearcoat: 0.04,\n      clearcoatRoughness: 0.85\n    });\n\n    const pattyMaterial = new THREE.MeshPhysicalMaterial({\n      color: 0x5b2d19,\n      map: pattyMap,\n      bumpMap: pattyBump,\n      bumpScale: 0.11,\n      roughness: 0.88,\n      metalness: 0,\n      clearcoat: 0.025,\n      clearcoatRoughness: 0.55\n    });\n\n    const burger = new THREE.Group();\n    burger.rotation.y = -0.28;\n    scene.add(burger);\n\n    function roughenRadialGeometry(geometry, amount = 0.01, verticalAmount = 0.008) {\n      const p = geometry.attributes.position;\n      const v = new THREE.Vector3();\n\n      for (let i = 0; i < p.count; i++) {\n        v.fromBufferAttribute(p, i);\n        const radius = Math.hypot(v.x, v.z);\n\n        if (radius > 0.03) {\n          const angle = Math.atan2(v.z, v.x);\n          const noise =\n            Math.sin(angle * 7.0 + v.y * 5.2) * 0.42 +\n            Math.sin(angle * 13.0 - v.y * 7.3) * 0.25 +\n            (hash(angle, v.y, i) - 0.5) * 0.75;\n          const factor = 1 + noise * amount;\n          v.x *= factor;\n          v.z *= factor;\n          v.y += (hash(v.x * 2, v.z * 2, i) - 0.5) * verticalAmount;\n          p.setXYZ(i, v.x, v.y, v.z);\n        }\n      }\n\n      p.needsUpdate = true;\n      geometry.computeVertexNormals();\n    }\n\n    function makeBun(profile, seedOffset = 0) {\n      const points = profile.map(([r, y]) => new THREE.Vector2(r, y));\n      const geometry = new THREE.LatheGeometry(points, 128);\n      roughenRadialGeometry(geometry, 0.008 + seedOffset * 0.0002, 0.012);\n      const mesh = new THREE.Mesh(geometry, bunMaterial);\n      mesh.castShadow = true;\n      mesh.receiveShadow = true;\n      burger.add(mesh);\n      return mesh;\n    }\n\n    makeBun([\n      [0.00, -3.15],\n      [2.35, -3.15],\n      [3.02, -3.04],\n      [3.38, -2.78],\n      [3.48, -2.55],\n      [3.37, -2.39],\n      [2.96, -2.30],\n      [0.00, -2.27]\n    ], 1);\n\n    makeBun([\n      [0.00, -1.49],\n      [2.62, -1.49],\n      [3.18, -1.43],\n      [3.43, -1.28],\n      [3.47, -1.07],\n      [3.31, -0.79],\n      [2.88, -0.63],\n      [0.00, -0.59]\n    ], 2);\n\n    const topBun = makeBun([\n      [0.00, 0.40],\n      [2.68, 0.40],\n      [3.22, 0.47],\n      [3.48, 0.68],\n      [3.54, 0.96],\n      [3.39, 1.43],\n      [3.08, 1.98],\n      [2.57, 2.43],\n      [1.89, 2.75],\n      [1.05, 2.91],\n      [0.00, 2.96]\n    ], 3);\n\n    const toastedMaterial = new THREE.MeshStandardMaterial({\n      color: 0x8e4217,\n      roughness: 0.78\n    });\n\n    function addToastedRim(radius, tube, y) {\n      const rim = new THREE.Mesh(\n        new THREE.TorusGeometry(radius, tube, 10, 112),\n        toastedMaterial\n      );\n      rim.rotation.x = Math.PI / 2;\n      rim.position.y = y;\n      rim.scale.y = 0.66;\n      rim.castShadow = true;\n      burger.add(rim);\n    }\n\n    addToastedRim(3.27, 0.07, -2.39);\n    addToastedRim(3.29, 0.065, -0.73);\n    addToastedRim(3.31, 0.072, 0.60);\n\n    function createPatty(y, seed) {\n      const geometry = new THREE.CylinderGeometry(3.28, 3.32, 0.67, 112, 10, false);\n      const p = geometry.attributes.position;\n      const v = new THREE.Vector3();\n\n      for (let i = 0; i < p.count; i++) {\n        v.fromBufferAttribute(p, i);\n        const radius = Math.hypot(v.x, v.z);\n        const a = Math.atan2(v.z, v.x);\n\n        if (radius > 0.05) {\n          const edgeNoise =\n            Math.sin(a * 9 + seed) * 0.019 +\n            Math.sin(a * 23 - seed * 2) * 0.012 +\n            (hash(a, v.y, i + seed) - 0.5) * 0.055;\n          const factor = 1 + edgeNoise;\n          v.x *= factor;\n          v.z *= factor;\n        }\n        v.y += (hash(v.x * 3, v.z * 3, seed + i) - 0.5) * 0.075;\n        p.setXYZ(i, v.x, v.y, v.z);\n      }\n\n      p.needsUpdate = true;\n      geometry.computeVertexNormals();\n\n      const patty = new THREE.Mesh(geometry, pattyMaterial);\n      patty.position.y = y;\n      patty.castShadow = true;\n      patty.receiveShadow = true;\n      burger.add(patty);\n\n      const crumbGeometry = new THREE.IcosahedronGeometry(0.075, 0);\n      const crumbMaterial = new THREE.MeshStandardMaterial({\n        color: 0x482115,\n        roughness: 0.94,\n        vertexColors: true\n      });\n      const count = 145;\n      const crumbs = new THREE.InstancedMesh(crumbGeometry, crumbMaterial, count);\n      const matrix = new THREE.Matrix4();\n      const quaternion = new THREE.Quaternion();\n      const scale = new THREE.Vector3();\n\n      for (let i = 0; i < count; i++) {\n        const angle = random() * Math.PI * 2;\n        const radius = 3.27 + random() * 0.16;\n        const py = y + (random() - 0.5) * 0.58;\n        const size = 0.45 + random() * 1.25;\n        quaternion.setFromEuler(new THREE.Euler(random() * 3, random() * 3, random() * 3));\n        scale.set(size, 0.65 + random() * 1.2, size);\n        matrix.compose(\n          new THREE.Vector3(Math.cos(angle) * radius, py, Math.sin(angle) * radius),\n          quaternion,\n          scale\n        );\n        crumbs.setMatrixAt(i, matrix);\n        crumbs.setColorAt(i, new THREE.Color().setHSL(\n          0.055 + random() * 0.025,\n          0.48 + random() * 0.18,\n          0.10 + random() * 0.12\n        ));\n      }\n\n      crumbs.instanceMatrix.needsUpdate = true;\n      crumbs.instanceColor.needsUpdate = true;\n      crumbs.castShadow = true;\n      crumbs.receiveShadow = true;\n      burger.add(crumbs);\n    }\n\n    createPatty(-1.95, 12);\n    createPatty(-0.20, 37);\n\n    const lettuceMaterials = [\n      new THREE.MeshPhysicalMaterial({\n        color: 0x6c9826,\n        roughness: 0.87,\n        side: THREE.DoubleSide,\n        clearcoat: 0.03,\n        clearcoatRoughness: 0.8\n      }),\n      new THREE.MeshPhysicalMaterial({\n        color: 0x92b936,\n        roughness: 0.9,\n        side: THREE.DoubleSide\n      })\n    ];\n\n    function makeLettuce(y, rotation, colorIndex, outerRadius = 3.76, seed = 0) {\n      const segments = 128;\n      const rings = 6;\n      const positions = [];\n      const uvs = [];\n      const indices = [];\n\n      for (let ring = 0; ring < rings; ring++) {\n        const t = ring / (rings - 1);\n\n        for (let i = 0; i <= segments; i++) {\n          const angle = (i / segments) * Math.PI * 2;\n          const irregular =\n            Math.sin(angle * 5 + seed) * 0.13 +\n            Math.sin(angle * 11 - seed * 0.7) * 0.10 +\n            Math.sin(angle * 19 + seed * 1.7) * 0.055;\n          const outer = outerRadius + irregular;\n          const radius = THREE.MathUtils.lerp(1.75, outer, t);\n\n          const ripple =\n            Math.sin(angle * 8 + seed + t * 2.4) * 0.045 * t +\n            Math.sin(angle * 17 - seed) * 0.055 * t * t +\n            (hash(angle, ring, seed) - 0.5) * 0.025 * t;\n\n          positions.push(\n            Math.cos(angle) * radius,\n            y + ripple,\n            Math.sin(angle) * radius\n          );\n          uvs.push(i / segments, t);\n        }\n      }\n\n      for (let ring = 0; ring < rings - 1; ring++) {\n        for (let i = 0; i < segments; i++) {\n          const a = ring * (segments + 1) + i;\n          const b = a + segments + 1;\n          indices.push(a, b, a + 1, b, b + 1, a + 1);\n        }\n      }\n\n      const geometry = new THREE.BufferGeometry();\n      geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n      geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));\n      geometry.setIndex(indices);\n      geometry.computeVertexNormals();\n\n      const lettuce = new THREE.Mesh(geometry, lettuceMaterials[colorIndex]);\n      lettuce.rotation.y = rotation;\n      lettuce.castShadow = true;\n      lettuce.receiveShadow = true;\n      burger.add(lettuce);\n    }\n\n    makeLettuce(-2.29, 0.10, 0, 3.73, 1.2);\n    makeLettuce(-2.25, 0.58, 1, 3.62, 4.8);\n    makeLettuce(-0.55, 0.36, 0, 3.72, 2.6);\n    makeLettuce(0.29, -0.18, 1, 3.82, 7.7);\n    makeLettuce(0.33, 0.42, 0, 3.68, 9.2);\n\n    function makeCheese(y) {\n      const divisions = 18;\n      const extent = 3.35;\n      const positions = [];\n      const uvs = [];\n      const indices = [];\n\n      for (let iz = 0; iz <= divisions; iz++) {\n        for (let ix = 0; ix <= divisions; ix++) {\n          const x = THREE.MathUtils.lerp(-extent, extent, ix / divisions);\n          const z = THREE.MathUtils.lerp(-extent, extent, iz / divisions);\n          const radius = Math.hypot(x, z);\n          const edge = THREE.MathUtils.smoothstep(radius, 2.65, 4.65);\n          const droop = edge * (\n            0.12 +\n            0.24 * Math.pow(Math.abs(x * z) / (extent * extent), 0.7)\n          );\n          positions.push(\n            x,\n            -droop + Math.sin(x * 1.8 + z * 1.2) * 0.012,\n            z\n          );\n          uvs.push(ix / divisions, iz / divisions);\n        }\n      }\n\n      for (let iz = 0; iz < divisions; iz++) {\n        for (let ix = 0; ix < divisions; ix++) {\n          const a = iz * (divisions + 1) + ix;\n          const b = a + divisions + 1;\n          indices.push(a, b, a + 1, b, b + 1, a + 1);\n        }\n      }\n\n      const geometry = new THREE.BufferGeometry();\n      geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));\n      geometry.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));\n      geometry.setIndex(indices);\n      geometry.computeVertexNormals();\n\n      const material = new THREE.MeshPhysicalMaterial({\n        color: 0xf4b51e,\n        roughness: 0.62,\n        side: THREE.DoubleSide,\n        clearcoat: 0.08,\n        clearcoatRoughness: 0.75\n      });\n\n      const cheese = new THREE.Mesh(geometry, material);\n      cheese.position.y = y;\n      cheese.rotation.y = 0.44;\n      cheese.castShadow = true;\n      cheese.receiveShadow = true;\n      burger.add(cheese);\n    }\n\n    makeCheese(-1.57);\n\n    const sauceMaterial = new THREE.MeshPhysicalMaterial({\n      color: 0xd98751,\n      roughness: 0.54,\n      clearcoat: 0.22,\n      clearcoatRoughness: 0.44\n    });\n\n    function makeSauceLayer(y, seed) {\n      const ring = new THREE.Mesh(\n        new THREE.TorusGeometry(3.03, 0.15, 12, 120),\n        sauceMaterial\n      );\n      ring.rotation.x = Math.PI / 2;\n      ring.position.y = y;\n      ring.scale.set(1.02, 0.42, 1);\n      ring.castShadow = true;\n      burger.add(ring);\n\n      const blobGeometry = new THREE.SphereGeometry(0.18, 12, 8);\n      const count = 28;\n      const blobs = new THREE.InstancedMesh(blobGeometry, sauceMaterial, count);\n      const matrix = new THREE.Matrix4();\n      const quaternion = new THREE.Quaternion();\n      const scale = new THREE.Vector3();\n\n      for (let i = 0; i < count; i++) {\n        const angle = random() * Math.PI * 2;\n        const radius = 2.88 + random() * 0.58;\n        quaternion.setFromEuler(new THREE.Euler(\n          random() * Math.PI,\n          random() * Math.PI,\n          random() * Math.PI\n        ));\n        scale.set(\n          0.55 + random() * 1.2,\n          0.22 + random() * 0.42,\n          0.55 + random() * 1.35\n        );\n        matrix.compose(\n          new THREE.Vector3(\n            Math.cos(angle) * radius,\n            y + (random() - 0.5) * 0.08,\n            Math.sin(angle) * radius\n          ),\n          quaternion,\n          scale\n        );\n        blobs.setMatrixAt(i, matrix);\n      }\n\n      blobs.instanceMatrix.needsUpdate = true;\n      blobs.castShadow = true;\n      burger.add(blobs);\n    }\n\n    makeSauceLayer(-1.50, 2);\n    makeSauceLayer(0.19, 8);\n\n    const pickleMaterial = new THREE.MeshPhysicalMaterial({\n      color: 0x668b26,\n      roughness: 0.7,\n      clearcoat: 0.14,\n      clearcoatRoughness: 0.55\n    });\n    const pickleInnerMaterial = new THREE.MeshStandardMaterial({\n      color: 0x93a944,\n      roughness: 0.82\n    });\n\n    function addPickles() {\n      const locations = [\n        [-2.62, 0.36, -1.35, 0.18],\n        [ 2.48, 0.37,  1.54, -0.32],\n        [-1.28, 0.37,  2.63, 0.28],\n        [ 1.48, 0.36, -2.48, -0.12],\n        [ 2.86, 0.36, -0.36, 0.42]\n      ];\n\n      for (const [x, y, z, ry] of locations) {\n        const pickle = new THREE.Group();\n\n        const outer = new THREE.Mesh(\n          new THREE.CylinderGeometry(0.55, 0.55, 0.09, 36),\n          pickleMaterial\n        );\n        const inner = new THREE.Mesh(\n          new THREE.CylinderGeometry(0.43, 0.43, 0.096, 32),\n          pickleInnerMaterial\n        );\n\n        outer.castShadow = inner.castShadow = true;\n        outer.receiveShadow = inner.receiveShadow = true;\n        pickle.add(outer, inner);\n        pickle.position.set(x, y, z);\n        pickle.rotation.y = ry;\n        pickle.rotation.x = (random() - 0.5) * 0.08;\n        pickle.rotation.z = (random() - 0.5) * 0.08;\n        burger.add(pickle);\n      }\n    }\n\n    addPickles();\n\n    const onionMaterial = new THREE.MeshPhysicalMaterial({\n      color: 0xf0e2c8,\n      roughness: 0.66,\n      transparent: true,\n      opacity: 0.92\n    });\n\n    function addOnions() {\n      for (let i = 0; i < 18; i++) {\n        const arc = new THREE.Mesh(\n          new THREE.TorusGeometry(\n            0.15 + random() * 0.22,\n            0.022 + random() * 0.018,\n            6,\n            14,\n            1.3 + random() * 1.6\n          ),\n          onionMaterial\n        );\n\n        const angle = random() * Math.PI * 2;\n        const radius = 2.35 + random() * 1.05;\n        arc.rotation.x = Math.PI / 2 + (random() - 0.5) * 0.18;\n        arc.rotation.y = random() * Math.PI * 2;\n        arc.position.set(\n          Math.cos(angle) * radius,\n          0.37 + random() * 0.06,\n          Math.sin(angle) * radius\n        );\n        arc.castShadow = true;\n        burger.add(arc);\n      }\n    }\n\n    addOnions();\n\n    function addSesameSeeds() {\n      const seedGeometry = new THREE.SphereGeometry(1, 10, 7);\n      const seedMaterial = new THREE.MeshPhysicalMaterial({\n        color: 0xf3d8a3,\n        roughness: 0.66,\n        clearcoat: 0.05,\n        vertexColors: true\n      });\n\n      const count = 105;\n      const seeds = new THREE.InstancedMesh(seedGeometry, seedMaterial, count);\n      const matrix = new THREE.Matrix4();\n      const rotationMatrix = new THREE.Matrix4();\n      const quaternion = new THREE.Quaternion();\n      const normal = new THREE.Vector3();\n      const tangentA = new THREE.Vector3();\n      const tangentB = new THREE.Vector3();\n      const longAxis = new THREE.Vector3();\n      const widthAxis = new THREE.Vector3();\n\n      for (let i = 0; i < count; i++) {\n        const angle = random() * Math.PI * 2;\n        const radius = 2.88 * Math.sqrt(random());\n        const x = Math.cos(angle) * radius;\n        const z = Math.sin(angle) * radius;\n        const y = 0.74 + 2.22 * Math.sqrt(Math.max(0, 1 - (radius * radius) / (3.55 * 3.55)));\n\n        normal.set(\n          x / (3.55 * 3.55),\n          (y - 0.74) / (2.22 * 2.22),\n          z / (3.55 * 3.55)\n        ).normalize();\n\n        tangentA.set(-z, 0, x);\n        if (tangentA.lengthSq() < 0.001) tangentA.set(1, 0, 0);\n        tangentA.normalize();\n        tangentB.crossVectors(normal, tangentA).normalize();\n\n        const twist = random() * Math.PI * 2;\n        longAxis.copy(tangentA).multiplyScalar(Math.cos(twist))\n          .addScaledVector(tangentB, Math.sin(twist)).normalize();\n        widthAxis.crossVectors(normal, longAxis).normalize();\n\n        rotationMatrix.makeBasis(widthAxis, normal, longAxis);\n        quaternion.setFromRotationMatrix(rotationMatrix);\n\n        matrix.compose(\n          new THREE.Vector3(x, y, z).addScaledVector(normal, 0.025),\n          quaternion,\n          new THREE.Vector3(\n            0.045 + random() * 0.018,\n            0.021 + random() * 0.009,\n            0.125 + random() * 0.055\n          )\n        );\n\n        seeds.setMatrixAt(i, matrix);\n        seeds.setColorAt(i, new THREE.Color().setHSL(\n          0.105 + random() * 0.025,\n          0.42 + random() * 0.18,\n          0.70 + random() * 0.14\n        ));\n      }\n\n      seeds.instanceMatrix.needsUpdate = true;\n      seeds.instanceColor.needsUpdate = true;\n      seeds.castShadow = true;\n      seeds.receiveShadow = true;\n      burger.add(seeds);\n    }\n\n    addSesameSeeds();\n\n    const backdrop = new THREE.Mesh(\n      new THREE.SphereGeometry(38, 48, 24),\n      new THREE.ShaderMaterial({\n        side: THREE.BackSide,\n        depthWrite: false,\n        uniforms: {\n          topColor: { value: new THREE.Color(0x16191d) },\n          middleColor: { value: new THREE.Color(0x21170f) },\n          bottomColor: { value: new THREE.Color(0x090706) }\n        },\n        vertexShader: `\n          varying vec3 vWorld;\n          void main() {\n            vec4 world = modelMatrix * vec4(position, 1.0);\n            vWorld = normalize(world.xyz);\n            gl_Position = projectionMatrix * viewMatrix * world;\n          }\n        `,\n        fragmentShader: `\n          varying vec3 vWorld;\n          uniform vec3 topColor;\n          uniform vec3 middleColor;\n          uniform vec3 bottomColor;\n          void main() {\n            float h = vWorld.y * 0.5 + 0.5;\n            vec3 color = mix(bottomColor, middleColor, smoothstep(0.15, 0.55, h));\n            color = mix(color, topColor, smoothstep(0.53, 0.92, h));\n            gl_FragColor = vec4(color, 1.0);\n          }\n        `\n      })\n    );\n    scene.add(backdrop);\n\n    const floorMaterial = new THREE.MeshPhysicalMaterial({\n      color: 0x211914,\n      roughness: 0.92,\n      metalness: 0.01\n    });\n\n    const floor = new THREE.Mesh(\n      new THREE.PlaneGeometry(60, 60),\n      floorMaterial\n    );\n    floor.rotation.x = -Math.PI / 2;\n    floor.position.y = -3.19;\n    floor.receiveShadow = true;\n    scene.add(floor);\n\n    function makeContactShadow() {\n      const canvas = document.createElement('canvas');\n      canvas.width = canvas.height = 256;\n      const ctx = canvas.getContext('2d');\n      const gradient = ctx.createRadialGradient(128, 128, 4, 128, 128, 125);\n      gradient.addColorStop(0, 'rgba(0,0,0,0.75)');\n      gradient.addColorStop(0.3, 'rgba(0,0,0,0.43)');\n      gradient.addColorStop(0.72, 'rgba(0,0,0,0.12)');\n      gradient.addColorStop(1, 'rgba(0,0,0,0)');\n      ctx.fillStyle = gradient;\n      ctx.fillRect(0, 0, 256, 256);\n\n      const texture = new THREE.CanvasTexture(canvas);\n      const shadow = new THREE.Mesh(\n        new THREE.PlaneGeometry(9.6, 7.6),\n        new THREE.MeshBasicMaterial({\n          map: texture,\n          transparent: true,\n          opacity: 0.55,\n          depthWrite: false,\n          blending: THREE.MultiplyBlending\n        })\n      );\n      shadow.rotation.x = -Math.PI / 2;\n      shadow.position.y = -3.18;\n      scene.add(shadow);\n    }\n\n    makeContactShadow();\n\n    const hemisphere = new THREE.HemisphereLight(0x91a5c2, 0x3a1d0d, 1.7);\n    scene.add(hemisphere);\n\n    const keyLight = new THREE.SpotLight(0xffd7ac, 1450, 35, 0.58, 0.75, 1.25);\n    keyLight.position.set(5.5, 11.5, 7.2);\n    keyLight.target.position.set(0, -0.1, 0);\n    keyLight.castShadow = true;\n    keyLight.shadow.mapSize.set(2048, 2048);\n    keyLight.shadow.bias = -0.00035;\n    keyLight.shadow.normalBias = 0.035;\n    keyLight.shadow.camera.near = 2;\n    keyLight.shadow.camera.far = 28;\n    scene.add(keyLight, keyLight.target);\n\n    const fillLight = new THREE.DirectionalLight(0xb9d5ff, 2.25);\n    fillLight.position.set(-8, 5, 6);\n    scene.add(fillLight);\n\n    const rimLight = new THREE.SpotLight(0xff7c3c, 580, 28, 0.72, 0.85, 1.4);\n    rimLight.position.set(-6.5, 5.2, -7.5);\n    rimLight.target.position.set(0, 0.2, 0);\n    scene.add(rimLight, rimLight.target);\n\n    const frontGlow = new THREE.PointLight(0xffc58e, 45, 10, 2);\n    frontGlow.position.set(1.5, 0.8, 6.5);\n    scene.add(frontGlow);\n\n    window.addEventListener('resize', () => {\n      camera.aspect = innerWidth / innerHeight;\n      camera.updateProjectionMatrix();\n      renderer.setPixelRatio(Math.min(devicePixelRatio, 2));\n      renderer.setSize(innerWidth, innerHeight);\n    });\n\n    const clock = new THREE.Clock();\n\n    renderer.setAnimationLoop(() => {\n      const delta = Math.min(clock.getDelta(), 0.05);\n      burger.rotation.y += delta * 0.075;\n      controls.update();\n      renderer.render(scene, camera);\n    });\n  </script>\n</body>\n</html>\n```"
}