{
  "name": "pool",
  "title": "Pool",
  "type": "registry:component",
  "description": "A built swimming pool flush with the deck: coping rim, walkable plastered basin with corner exit steps, and a translucent water surface.",
  "dependencies": [
    "@react-three/rapier@^2.2.0",
    "@runek/core@^0.12.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "Pool.tsx",
      "content": "import { CuboidCollider, RigidBody } from '@react-three/rapier'\nimport { useWorld, type WorldComponentProps } from '@runek/core'\n\nexport interface PoolProps extends WorldComponentProps {\n  /** Water surface `[width, depth]`, in units. */\n  size?: [number, number]\n  /** Basin depth below the deck, in units. */\n  depth?: number\n  /** Coping ledge width around the rim, in units. */\n  coping?: number\n  /** Build exit steps into one corner of the basin. */\n  steps?: boolean\n  /** Coping color; defaults to the world palette's `wall` slot. */\n  copingColor?: string\n  /** Basin plaster color. */\n  basinColor?: string\n  /** Defaults to the world palette's `waterShallow` slot. */\n  waterColor?: string\n}\n\n/**\n * A built swimming pool, flush with the deck: a raised coping rim, a plastered basin you can\n * walk (and jump) into, and a still translucent water surface just below the lip. The rim's top\n * ledge sits at the component origin, so it drops into any `Slab`/`Floor` terrace at deck Y.\n * For natural water, use `Lake`; for open sea, `Ocean`.\n */\nexport function Pool({\n  position = [0, 0, 0],\n  rotation = [0, 0, 0],\n  size = [6, 3.5],\n  depth = 1.6,\n  coping = 0.35,\n  steps = true,\n  copingColor,\n  basinColor = '#bfe0e6',\n  waterColor,\n}: PoolProps) {\n  const { unit, palette } = useWorld()\n  const rim = copingColor ?? palette.wall\n  const water = waterColor ?? palette.waterShallow\n  const w = size[0] * unit\n  const d = size[1] * unit\n  const dep = depth * unit\n  const c = coping * unit\n  const lip = 0.07 * unit\n  const wallT = 0.12 * unit\n  const halfW = w / 2\n  const halfD = d / 2\n\n  const copingRun = [\n    // [x, z, length, depth-extent, rotY] — four ledge boxes framing the water\n    { x: 0, z: -halfD - c / 2, w: w + c * 2, d: c },\n    { x: 0, z: halfD + c / 2, w: w + c * 2, d: c },\n    { x: -halfW - c / 2, z: 0, w: c, d },\n    { x: halfW + c / 2, z: 0, w: c, d },\n  ]\n\n  return (\n    <RigidBody type=\"fixed\" colliders={false} position={position} rotation={rotation}>\n      {copingRun.map((s) => (\n        <mesh\n          key={`${s.x.toFixed(3)}:${s.z.toFixed(3)}`}\n          castShadow\n          receiveShadow\n          position={[s.x, 0, s.z]}\n        >\n          <boxGeometry args={[s.w, lip * 2, s.d]} />\n          <meshStandardMaterial color={rim} />\n        </mesh>\n      ))}\n      {/* basin walls */}\n      {[\n        { x: 0, z: -halfD + wallT / 2, w, d: wallT },\n        { x: 0, z: halfD - wallT / 2, w, d: wallT },\n        { x: -halfW + wallT / 2, z: 0, w: wallT, d },\n        { x: halfW - wallT / 2, z: 0, w: wallT, d },\n      ].map((s) => (\n        <mesh\n          key={`b${s.x.toFixed(3)}:${s.z.toFixed(3)}`}\n          receiveShadow\n          position={[s.x, -dep / 2, s.z]}\n        >\n          <boxGeometry args={[s.w, dep, s.d]} />\n          <meshStandardMaterial color={basinColor} />\n        </mesh>\n      ))}\n      {/* basin floor */}\n      <mesh receiveShadow position={[0, -dep + wallT / 2, 0]}>\n        <boxGeometry args={[w, wallT, d]} />\n        <meshStandardMaterial color={basinColor} />\n      </mesh>\n      {/* water, just under the lip */}\n      <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.14 * unit, 0]}>\n        <planeGeometry args={[w - wallT * 2, d - wallT * 2]} />\n        <meshStandardMaterial color={water} transparent opacity={0.55} roughness={0.05} />\n      </mesh>\n      {steps &&\n        [0, 1, 2].map((i) => {\n          // Corner stack descending into the basin: tread i tops out at -stepH·(i+1)\n          // and drops to the floor, so each box doubles as its own riser.\n          const stepH = dep / 4\n          const run = 0.4 * unit\n          const top = -stepH * (i + 1)\n          const boxH = dep - stepH * (i + 1)\n          const x = halfW - wallT - run * (i + 0.5)\n          const z = halfD - wallT - run\n          return (\n            <group key={`s${i}`}>\n              <mesh receiveShadow position={[x, top - boxH / 2, z]}>\n                <boxGeometry args={[run, boxH, run * 2]} />\n                <meshStandardMaterial color={basinColor} />\n              </mesh>\n              <CuboidCollider args={[run / 2, boxH / 2, run]} position={[x, top - boxH / 2, z]} />\n            </group>\n          )\n        })}\n      <CuboidCollider args={[w / 2, wallT / 2, d / 2]} position={[0, -dep + wallT / 2, 0]} />\n      <CuboidCollider args={[w / 2 + c, lip, c / 2]} position={[0, 0, -halfD - c / 2]} />\n      <CuboidCollider args={[w / 2 + c, lip, c / 2]} position={[0, 0, halfD + c / 2]} />\n      <CuboidCollider args={[c / 2, lip, d / 2]} position={[-halfW - c / 2, 0, 0]} />\n      <CuboidCollider args={[c / 2, lip, d / 2]} position={[halfW + c / 2, 0, 0]} />\n    </RigidBody>\n  )\n}\n",
      "type": "registry:component"
    }
  ]
}
