{
  "name": "fridge",
  "title": "Fridge",
  "type": "registry:component",
  "description": "A kitchen fridge with a top or bottom freezer or one tall door, bar handles, and a seeded enamel or steel finish.",
  "dependencies": [
    "@react-three/drei@^10.7.7",
    "@react-three/rapier@^2.2.0",
    "@runek/core@^0.13.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "Fridge.tsx",
      "content": "import { RoundedBox } from '@react-three/drei'\nimport { CuboidCollider, RigidBody } from '@react-three/rapier'\nimport { pick, rng, sub, useWorld, type WorldComponentProps } from '@runek/core'\nimport { useMemo } from 'react'\n\n/** Freezer drawer on `top` or `bottom`, or a `single` full-height door. */\nexport type FridgeLayout = 'top' | 'bottom' | 'single'\n\nexport interface FridgeProps extends WorldComponentProps {\n  width?: number\n  height?: number\n  depth?: number\n  /** Seeded when unset. */\n  layout?: FridgeLayout\n  /** Body color. Seeded between an enamel white and brushed steel when unset. */\n  color?: string\n  /** Handles; defaults to the palette's `metal`. */\n  handleColor?: string\n}\n\nconst FINISHES = ['#ecebe7', '#ecebe7', '#b9bdc1', '#e4ded2']\n\n/**\n * A kitchen fridge: a rounded cabinet with its door split for a freezer (top or bottom) or one\n * tall door, long bar handles on the opening side, and a kick plate. Doors face local +Z. One\n * cuboid collider.\n */\nexport function Fridge({\n  position = [0, 0, 0],\n  rotation = [0, 0, 0],\n  seed = 1,\n  width = 0.7,\n  height = 1.8,\n  depth = 0.68,\n  layout,\n  color,\n  handleColor,\n}: FridgeProps) {\n  const { unit, palette } = useWorld()\n  const W = width * unit\n  const H = height * unit\n  const D = depth * unit\n  const metal = handleColor ?? palette.metal\n\n  const look = useMemo(() => {\n    const r = rng(sub(seed, 0))\n    const rolled = {\n      layout: pick<FridgeLayout>(r, ['top', 'bottom', 'bottom', 'single']),\n      finish: pick(r, FINISHES),\n      right: r() < 0.5,\n    }\n    return {\n      layout: layout ?? rolled.layout,\n      body: color ?? rolled.finish,\n      // Handles go on the side the door opens from.\n      side: rolled.right ? 1 : -1,\n    }\n  }, [seed, layout, color])\n\n  const kick = 0.06 * unit\n  const gap = 0.008 * unit\n  const doorT = 0.04 * unit\n  const usable = H - kick\n  const split =\n    look.layout === 'top'\n      ? kick + usable * 0.7\n      : look.layout === 'bottom'\n        ? kick + usable * 0.33\n        : 0\n  // Doors as [bottom, top] spans in Y.\n  const doors: [number, number][] = split\n    ? [\n        [kick + gap, split - gap / 2],\n        [split + gap / 2, H - gap],\n      ]\n    : [[kick + gap, H - gap]]\n  const hx = look.side * (W / 2 - 0.06 * unit)\n\n  return (\n    <RigidBody type=\"fixed\" colliders={false} position={position} rotation={rotation}>\n      <CuboidCollider args={[W / 2, H / 2, D / 2]} position={[0, H / 2, 0]} />\n      <RoundedBox\n        args={[W, H - kick, D - doorT]}\n        radius={0.02 * unit}\n        smoothness={2}\n        position={[0, kick + (H - kick) / 2, -doorT / 2]}\n        castShadow\n        receiveShadow\n      >\n        <meshStandardMaterial color={look.body} roughness={0.35} metalness={0.15} />\n      </RoundedBox>\n      <mesh position={[0, kick / 2, -0.03 * unit]}>\n        <boxGeometry args={[W - 0.04 * unit, kick, D - 0.08 * unit]} />\n        <meshStandardMaterial color=\"#2a2a2c\" roughness={0.8} />\n      </mesh>\n      {doors.map(([y0, y1]) => {\n        const h = y1 - y0\n        // A short freezer door gets a horizontal handle along its top edge; tall doors a long bar.\n        const short = h < usable * 0.4\n        return (\n          <group key={y0} position={[0, (y0 + y1) / 2, D / 2 - doorT / 2]}>\n            <RoundedBox\n              args={[W - 0.01 * unit, h, doorT]}\n              radius={0.015 * unit}\n              smoothness={2}\n              castShadow\n            >\n              <meshStandardMaterial color={look.body} roughness={0.3} metalness={0.15} />\n            </RoundedBox>\n            {(short\n              ? [-1, 1].map((k) => [\n                  k * W * 0.28,\n                  (look.layout === 'bottom' ? 1 : -1) * (h / 2 - 0.06 * unit),\n                ])\n              : [-1, 1].map((k) => [hx, ((k * Math.min(h * 0.55, 0.6 * unit)) / 2) * 0.9])\n            ).map(([px, py]) => (\n              <mesh key={`${px}:${py}`} position={[px, py, doorT / 2 + 0.0125 * unit]}>\n                <boxGeometry args={[0.014 * unit, 0.014 * unit, 0.025 * unit]} />\n                <meshStandardMaterial color={metal} roughness={0.25} metalness={0.8} />\n              </mesh>\n            ))}\n            {short ? (\n              <mesh\n                position={[\n                  0,\n                  (look.layout === 'bottom' ? 1 : -1) * (h / 2 - 0.06 * unit),\n                  doorT / 2 + 0.025 * unit,\n                ]}\n                rotation={[0, 0, Math.PI / 2]}\n                castShadow\n              >\n                <cylinderGeometry args={[0.012 * unit, 0.012 * unit, W * 0.6, 10]} />\n                <meshStandardMaterial color={metal} roughness={0.25} metalness={0.8} />\n              </mesh>\n            ) : (\n              <mesh position={[hx, 0, doorT / 2 + 0.025 * unit]} castShadow>\n                <cylinderGeometry\n                  args={[0.012 * unit, 0.012 * unit, Math.min(h * 0.55, 0.6 * unit), 10]}\n                />\n                <meshStandardMaterial color={metal} roughness={0.25} metalness={0.8} />\n              </mesh>\n            )}\n          </group>\n        )\n      })}\n    </RigidBody>\n  )\n}\n\nFridge.groundSitting = true\n",
      "type": "registry:component"
    }
  ]
}
