{
  "streamed": true,
  "usage": {
    "prompt_tokens": 160,
    "completion_tokens": 5871,
    "total_tokens": 6031,
    "cost": 0.147575,
    "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.147575,
      "upstream_inference_prompt_cost": 0.0008,
      "upstream_inference_completions_cost": 0.146775
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0,
      "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.0\">\n<title>Big Mac 3D</title>\n<style>\n    html, body {\n        margin: 0;\n        padding: 0;\n        width: 100%;\n        height: 100%;\n        overflow: hidden;\n        background: #1a1a1a;\n    }\n    #info {\n        position: absolute;\n        top: 12px;\n        left: 12px;\n        color: rgba(255,255,255,0.55);\n        font-family: -apple-system, Helvetica, Arial, sans-serif;\n        font-size: 13px;\n        pointer-events: none;\n        user-select: none;\n    }\n</style>\n</head>\n<body>\n<div id=\"info\">Drag to orbit · Scroll to zoom</div>\n<script type=\"importmap\">\n{\n    \"imports\": {\n        \"three\": \"https://cdnjs.cloudflare.com/ajax/libs/three.js/0.160.0/three.module.min.js\",\n        \"three/addons/\": \"https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/\"\n    }\n}\n</script>\n<script type=\"module\">\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\nimport { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';\n\n// ---------- Renderer ----------\nconst renderer = new THREE.WebGLRenderer({ antialias: true });\nrenderer.setSize(window.innerWidth, window.innerHeight);\nrenderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\nrenderer.shadowMap.enabled = true;\nrenderer.shadowMap.type = THREE.PCFSoftShadowMap;\nrenderer.toneMapping = THREE.ACESFilmicToneMapping;\nrenderer.toneMappingExposure = 1.05;\nrenderer.outputColorSpace = THREE.SRGBColorSpace;\ndocument.body.appendChild(renderer.domElement);\n\n// ---------- Scene ----------\nconst scene = new THREE.Scene();\nscene.background = new THREE.Color(0x20222b);\n\n// Environment for realistic PBR reflections\nconst pmrem = new THREE.PMREMGenerator(renderer);\nconst envTex = pmrem.fromScene(new RoomEnvironment(), 0.04).texture;\nscene.environment = envTex;\n\n// ---------- Camera ----------\nconst camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);\ncamera.position.set(4.5, 3.2, 5.5);\n\n// ---------- Controls ----------\nconst controls = new OrbitControls(camera, renderer.domElement);\ncontrols.enableDamping = true;\ncontrols.dampingFactor = 0.07;\ncontrols.minDistance = 3;\ncontrols.maxDistance = 14;\ncontrols.maxPolarAngle = Math.PI * 0.52;\ncontrols.target.set(0, 0.6, 0);\n\n// ---------- Lights ----------\nconst hemi = new THREE.HemisphereLight(0xffffff, 0x444455, 0.4);\nscene.add(hemi);\n\nconst keyLight = new THREE.DirectionalLight(0xfff3e0, 2.4);\nkeyLight.position.set(5, 8, 4);\nkeyLight.castShadow = true;\nkeyLight.shadow.mapSize.set(2048, 2048);\nkeyLight.shadow.camera.near = 1;\nkeyLight.shadow.camera.far = 30;\nkeyLight.shadow.camera.left = -6;\nkeyLight.shadow.camera.right = 6;\nkeyLight.shadow.camera.top = 6;\nkeyLight.shadow.camera.bottom = -6;\nkeyLight.shadow.bias = -0.0004;\nkeyLight.shadow.radius = 4;\nscene.add(keyLight);\n\nconst fillLight = new THREE.DirectionalLight(0xbfd4ff, 0.6);\nfillLight.position.set(-6, 4, -3);\nscene.add(fillLight);\n\nconst rimLight = new THREE.DirectionalLight(0xffffff, 0.9);\nrimLight.position.set(-2, 5, -6);\nscene.add(rimLight);\n\n// ---------- Ground ----------\nconst groundMat = new THREE.MeshStandardMaterial({ color: 0x2a2d38, roughness: 0.85, metalness: 0.0 });\nconst ground = new THREE.Mesh(new THREE.CircleGeometry(20, 64), groundMat);\nground.rotation.x = -Math.PI / 2;\nground.position.y = -0.02;\nground.receiveShadow = true;\nscene.add(ground);\n\n// ---------- Procedural textures ----------\nfunction makeBunTexture() {\n    const c = document.createElement('canvas');\n    c.width = c.height = 512;\n    const ctx = c.getContext('2d');\n    // base warm bun color\n    const g = ctx.createRadialGradient(256, 256, 40, 256, 256, 300);\n    g.addColorStop(0, '#e8a95c');\n    g.addColorStop(0.6, '#d9954a');\n    g.addColorStop(1, '#b9722f');\n    ctx.fillStyle = g;\n    ctx.fillRect(0, 0, 512, 512);\n    // mottled shading\n    for (let i = 0; i < 4000; i++) {\n        const x = Math.random() * 512, y = Math.random() * 512;\n        const r = Math.random() * 6 + 1;\n        const shade = Math.random();\n        ctx.fillStyle = shade > 0.5\n            ? `rgba(255,220,160,${Math.random()*0.15})`\n            : `rgba(120,70,25,${Math.random()*0.15})`;\n        ctx.beginPath();\n        ctx.arc(x, y, r, 0, Math.PI*2);\n        ctx.fill();\n    }\n    const t = new THREE.CanvasTexture(c);\n    t.colorSpace = THREE.SRGBColorSpace;\n    return t;\n}\n\nfunction makeBunBumpTexture() {\n    const c = document.createElement('canvas');\n    c.width = c.height = 512;\n    const ctx = c.getContext('2d');\n    ctx.fillStyle = '#808080';\n    ctx.fillRect(0, 0, 512, 512);\n    for (let i = 0; i < 6000; i++) {\n        const x = Math.random() * 512, y = Math.random() * 512;\n        const r = Math.random() * 4 + 1;\n        const v = Math.random() > 0.5 ? 255 : 0;\n        ctx.fillStyle = `rgba(${v},${v},${v},${Math.random()*0.4})`;\n        ctx.beginPath();\n        ctx.arc(x, y, r, 0, Math.PI*2);\n        ctx.fill();\n    }\n    return new THREE.CanvasTexture(c);\n}\n\nconst bunTex = makeBunTexture();\nconst bunBump = makeBunBumpTexture();\n\n// ---------- Materials ----------\nconst bunMat = new THREE.MeshStandardMaterial({\n    map: bunTex,\n    bumpMap: bunBump,\n    bumpScale: 0.015,\n    color: 0xffffff,\n    roughness: 0.75,\n    metalness: 0.0\n});\n\nconst pattyMat = new THREE.MeshStandardMaterial({\n    color: 0x4a2c1a,\n    roughness: 0.85,\n    metalness: 0.0,\n    bumpMap: bunBump,\n    bumpScale: 0.02\n});\n\nconst cheeseMat = new THREE.MeshStandardMaterial({\n    color: 0xf2a92b,\n    roughness: 0.4,\n    metalness: 0.0\n});\n\nconst lettuceMat = new THREE.MeshStandardMaterial({\n    color: 0x6ba832,\n    roughness: 0.6,\n    metalness: 0.0,\n    side: THREE.DoubleSide\n});\n\nconst sauceMat = new THREE.MeshStandardMaterial({\n    color: 0xf5d97a,\n    roughness: 0.35,\n    metalness: 0.0\n});\n\nconst onionMat = new THREE.MeshStandardMaterial({\n    color: 0xf3ead6,\n    roughness: 0.5,\n    metalness: 0.0,\n    transparent: true,\n    opacity: 0.95\n});\n\nconst pickleMat = new THREE.MeshStandardMaterial({\n    color: 0x7ba33a,\n    roughness: 0.45,\n    metalness: 0.0\n});\n\nconst sesameMat = new THREE.MeshStandardMaterial({\n    color: 0xf5e6b8,\n    roughness: 0.5,\n    metalness: 0.0\n});\n\n// ---------- Burger group ----------\nconst burger = new THREE.Group();\nscene.add(burger);\n\nconst R = 2.0; // base radius\n\nfunction addLayer(mesh, y) {\n    mesh.position.y = y;\n    mesh.castShadow = true;\n    mesh.receiveShadow = true;\n    burger.add(mesh);\n    return mesh;\n}\n\n// Bottom bun (flat disk with slightly domed shape)\n{\n    const geo = new THREE.CylinderGeometry(R, R * 0.92, 0.5, 64, 1);\n    addLayer(new THREE.Mesh(geo, bunMat), 0.25);\n}\n\nlet y = 0.5;\n\n// Patty 1\n{\n    const geo = new THREE.CylinderGeometry(R * 1.02, R * 1.02, 0.28, 64);\n    y += 0.14;\n    addLayer(new THREE.Mesh(geo, pattyMat), y);\n    y += 0.14;\n}\n\n// Onions (small chopped bits) - ring of little cubes\nfunction addOnions(baseY) {\n    for (let i = 0; i < 40; i++) {\n        const s = 0.12 + Math.random() * 0.08;\n        const g = new THREE.BoxGeometry(s, 0.04, s);\n        const m = new THREE.Mesh(g, onionMat);\n        const ang = Math.random() * Math.PI * 2;\n        const rad = Math.random() * R * 0.85;\n        m.position.set(Math.cos(ang) * rad, baseY, Math.sin(ang) * rad);\n        m.rotation.y = Math.random() * Math.PI;\n        m.castShadow = true;\n        burger.add(m);\n    }\n}\naddOnions(y + 0.02);\n\n// Cheese slice (square-ish with drooping corners) using a thin box, rotated 45\n{\n    const geo = new THREE.BoxGeometry(R * 1.9, 0.06, R * 1.9);\n    const cheese = new THREE.Mesh(geo, cheeseMat);\n    y += 0.08;\n    cheese.position.y = y;\n    cheese.rotation.y = Math.PI / 4;\n    cheese.castShadow = true;\n    cheese.receiveShadow = true;\n    burger.add(cheese);\n    y += 0.05;\n}\n\n// Middle bun (the club layer)\n{\n    const geo = new THREE.CylinderGeometry(R * 0.98, R * 0.98, 0.35, 64);\n    y += 0.175;\n    addLayer(new THREE.Mesh(geo, bunMat), y);\n    y += 0.175;\n}\n\n// Sauce layer (bumpy blob)\n{\n    const geo = new THREE.CylinderGeometry(R * 1.05, R * 1.0, 0.1, 64);\n    y += 0.05;\n    const sauce = new THREE.Mesh(geo, sauceMat);\n    sauce.position.y = y;\n    sauce.castShadow = true;\n    burger.add(sauce);\n    y += 0.05;\n}\n\n// Pickles\nfunction addPickles(baseY) {\n    for (let i = 0; i < 4; i++) {\n        const g = new THREE.CylinderGeometry(0.35, 0.35, 0.06, 24);\n        const m = new THREE.Mesh(g, pickleMat);\n        const ang = (i / 4) * Math.PI * 2 + 0.4;\n        const rad = R * 0.5;\n        m.position.set(Math.cos(ang) * rad, baseY, Math.sin(ang) * rad);\n        m.castShadow = true;\n        burger.add(m);\n    }\n}\naddPickles(y + 0.03);\n\n// Lettuce - ruffled ring using many small folded planes\nfunction addLettuce(baseY) {\n    const count = 60;\n    for (let i = 0; i < count; i++) {\n        const ang = (i / count) * Math.PI * 2;\n        const rad = R * (0.95 + Math.random() * 0.15);\n        const w = 0.4 + Math.random() * 0.2;\n        const geo = new THREE.PlaneGeometry(w, 0.35, 3, 2);\n        // ruffle vertices\n        const pos = geo.attributes.position;\n        for (let v = 0; v < pos.count; v++) {\n            pos.setZ(v, pos.getZ(v) + (Math.random() - 0.5) * 0.18);\n        }\n        geo.computeVertexNormals();\n        const shade = 0.75 + Math.random() * 0.5;\n        const m = new THREE.Mesh(geo, lettuceMat.clone());\n        m.material.color.setRGB(0.42 * shade, 0.66 * shade, 0.2 * shade);\n        m.position.set(Math.cos(ang) * rad, baseY + (Math.random()-0.5)*0.1, Math.sin(ang) * rad);\n        m.rotation.y = -ang + Math.PI/2;\n        m.rotation.x = (Math.random() - 0.5) * 0.6;\n        m.rotation.z = (Math.random() - 0.5) * 0.6;\n        m.castShadow = true;\n        burger.add(m);\n    }\n}\naddLettuce(y + 0.05);\ny += 0.1;\n\n// Patty 2\n{\n    const geo = new THREE.CylinderGeometry(R * 1.02, R * 1.02, 0.28, 64);\n    y += 0.14;\n    addLayer(new THREE.Mesh(geo, pattyMat), y);\n    y += 0.14;\n}\n\n// Top bun (dome)\n{\n    const domeGeo = new THREE.SphereGeometry(R, 64, 32, 0, Math.PI * 2, 0, Math.PI / 2);\n    // scale to bun-like dome\n    domeGeo.scale(1, 0.75, 1);\n    y += 0.02;\n    const topBun = new THREE.Mesh(domeGeo, bunMat);\n    topBun.position.y = y;\n    topBun.castShadow = true;\n    topBun.receiveShadow = true;\n    burger.add(topBun);\n\n    // Slight lower lip so it isn't hollow underneath\n    const lip = new THREE.Mesh(new THREE.CylinderGeometry(R, R * 0.95, 0.15, 64), bunMat);\n    lip.position.y = y + 0.02;\n    lip.castShadow = true;\n    burger.add(lip);\n\n    const domeTopY = y;\n    const domeHeight = R * 0.75;\n\n    // Sesame seeds scattered on dome\n    const seedGeo = new THREE.SphereGeometry(0.05, 8, 6);\n    seedGeo.scale(1, 0.5, 1.6);\n    for (let i = 0; i < 90; i++) {\n        // random point on upper hemisphere\n        const u = Math.random();\n        const theta = Math.acos(1 - u * 0.85); // bias toward top\n        const phi = Math.random() * Math.PI * 2;\n        const sx = Math.sin(theta) * Math.cos(phi);\n        const sz = Math.sin(theta) * Math.sin(phi);\n        const sy = Math.cos(theta);\n        const seed = new THREE.Mesh(seedGeo, sesameMat);\n        seed.position.set(sx * R * 1.0, domeTopY + sy * domeHeight, sz * R * 1.0);\n        // orient tangent to surface\n        seed.lookAt(seed.position.x * 2, seed.position.y + 2, seed.position.z * 2);\n        seed.rotation.z = Math.random() * Math.PI;\n        seed.castShadow = true;\n        burger.add(seed);\n    }\n}\n\n// Center the burger vertically-ish around target\nburger.position.y = 0;\n\n// ---------- Resize ----------\nwindow.addEventListener('resize', () => {\n    camera.aspect = window.innerWidth / window.innerHeight;\n    camera.updateProjectionMatrix();\n    renderer.setSize(window.innerWidth, window.innerHeight);\n});\n\n// ---------- Animate ----------\nconst clock = new THREE.Clock();\nfunction animate() {\n    requestAnimationFrame(animate);\n    const dt = clock.getDelta();\n    burger.rotation.y += dt * 0.35;\n    controls.update();\n    renderer.render(scene, camera);\n}\nanimate();\n</script>\n</body>\n</html>\n```"
}