{
  "name": "desklamp",
  "title": "DeskLamp",
  "type": "registry:component",
  "description": "A banker's desk lamp: a brass base and stem under a cased glass shade with a pull chain, pooling light on the desk. Can light only after dusk.",
  "dependencies": [
    "@runek/core@^0.15.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "DeskLamp.tsx",
      "content": "import { pick, rng, sub, useSun, useWorld, type WorldComponentProps } from '@runek/core'\nimport { useMemo } from 'react'\n\nexport interface DeskLampProps extends WorldComponentProps {\n  /** Shade width, in units. */\n  width?: number\n  /** The glass shade. Seeded (mostly library green) when unset. */\n  shadeColor?: string\n  /** Base, stem, and harp; defaults to the palette's `accent` (brass). */\n  color?: string\n  /** The light and the glowing bulb. */\n  lightColor?: string\n  /** Light strength. */\n  intensity?: number\n  /** Switched on. */\n  on?: boolean\n  /** Light only while the world's sun is down. */\n  nightOnly?: boolean\n}\n\nconst SHADES = ['#1f6b47', '#1f6b47', '#1f6b47', '#2b4f8a', '#8a2b2b', '#b8862f']\n\n/**\n * A banker's desk lamp: a brass base and stem holding a cased glass shade over the work, with a\n * pull chain. Its origin is the foot, so it sits on a `Desk` or `Table` top, and its small light\n * pools on the desk below. `nightOnly` lights it with the world's dusk. Decorative: no collider.\n */\nexport function DeskLamp({\n  position = [0, 0, 0],\n  rotation = [0, 0, 0],\n  seed = 1,\n  width = 0.3,\n  shadeColor,\n  color,\n  lightColor = '#ffe2b0',\n  intensity = 3,\n  on = true,\n  nightOnly = false,\n}: DeskLampProps) {\n  const { unit, palette } = useWorld()\n  const sun = useSun()\n  const lit = on && (!nightOnly || !sun.day)\n  const brass = color ?? palette.accent\n  const W = width * unit\n  const shadeR = W * 0.3\n  const stemH = W * 1.05\n\n  const shade = useMemo(() => shadeColor ?? pick(rng(sub(seed, 0)), SHADES), [seed, shadeColor])\n\n  const metal = <meshStandardMaterial color={brass} metalness={0.75} roughness={0.3} />\n  const baseH = 0.025 * unit\n\n  return (\n    <group position={position} rotation={rotation}>\n      {/* an oval base: a cylinder squashed front to back */}\n      <mesh position={[0, baseH / 2, 0]} scale={[1, 1, 0.62]} castShadow receiveShadow>\n        <cylinderGeometry args={[W * 0.36, W * 0.4, baseH, 28]} />\n        {metal}\n      </mesh>\n      <mesh position={[0, stemH / 2, -W * 0.06]} castShadow>\n        <cylinderGeometry args={[0.008 * unit, 0.01 * unit, stemH, 10]} />\n        {metal}\n      </mesh>\n      {/* the harp: a bar across under the shade, a short arm forward to it */}\n      <mesh position={[0, stemH, 0]} rotation={[Math.PI / 2, 0, 0]}>\n        <cylinderGeometry args={[0.006 * unit, 0.006 * unit, W * 0.14, 8]} />\n        {metal}\n      </mesh>\n      <group position={[0, stemH + shadeR * 0.2, W * 0.08]} rotation={[-0.18, 0, 0]}>\n        {/* cased glass: a half tube lying along X, opening downward, with end caps */}\n        <mesh rotation={[0, 0, Math.PI / 2]} castShadow>\n          <cylinderGeometry args={[shadeR, shadeR, W, 24, 1, true, 0, Math.PI]} />\n          <meshStandardMaterial\n            color={shade}\n            roughness={0.15}\n            metalness={0.1}\n            emissive={shade}\n            emissiveIntensity={lit ? 0.25 : 0}\n            side={2}\n          />\n        </mesh>\n        {[-1, 1].map((s) => (\n          <mesh key={s} position={[(s * W) / 2, 0, 0]} rotation={[0, (s * Math.PI) / 2, 0]}>\n            <circleGeometry args={[shadeR, 24, 0, Math.PI]} />\n            {metal}\n          </mesh>\n        ))}\n        <mesh position={[0, -shadeR * 0.35, 0]} rotation={[0, 0, Math.PI / 2]}>\n          <cylinderGeometry args={[0.012 * unit, 0.012 * unit, W * 0.7, 10]} />\n          <meshStandardMaterial\n            color=\"#fff6e0\"\n            emissive={lightColor}\n            emissiveIntensity={lit ? 2 : 0}\n            toneMapped={!lit}\n          />\n        </mesh>\n        <mesh position={[W * 0.2, -shadeR * 0.6, shadeR * 0.95]}>\n          <cylinderGeometry args={[0.002 * unit, 0.002 * unit, shadeR * 1.2, 4]} />\n          {metal}\n        </mesh>\n        <mesh position={[W * 0.2, -shadeR * 1.22, shadeR * 0.95]}>\n          <sphereGeometry args={[0.007 * unit, 8, 6]} />\n          {metal}\n        </mesh>\n        {lit && (\n          <pointLight\n            position={[0, -shadeR * 0.8, 0]}\n            color={lightColor}\n            intensity={intensity}\n            distance={3 * unit}\n            decay={2}\n          />\n        )}\n      </group>\n    </group>\n  )\n}\n",
      "type": "registry:component"
    }
  ]
}
