{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hotel-booking-reservation",
  "title": "Hotel Booking Reservation",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/hotel-booking-reservation/HotelBookingReservation.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Bath,\n  BedDouble,\n  Building2,\n  Calendar,\n  CalendarDays,\n  Check,\n  CheckCircle2,\n  Coffee,\n  CreditCard,\n  Heart,\n  Info,\n  Lock,\n  MapPin,\n  Maximize2,\n  Minus,\n  Plus,\n  RotateCcw,\n  Share2,\n  ShieldCheck,\n  Star,\n  Users,\n  Baby,\n  Waves,\n  Wifi,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport { Input } from '@/components/ui/input'\nimport { Separator } from '@/components/ui/separator'\n\nexport interface HotelBookingReservationProps {\n  className?: string\n  roomTitle?: string\n  hotelName?: string\n  location?: string\n  rating?: number\n  reviewsCount?: number\n  basePrice?: number\n  initialCheckIn?: string\n  initialCheckOut?: string\n  initialAdults?: number\n  initialChildren?: number\n  initialRooms?: number\n}\n\nconst roomPhotos = [\n  {\n    url: 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=1200&auto=format&fit=crop&q=80',\n    title: 'King Master Suite & Ocean Balcony',\n  },\n  {\n    url: 'https://images.unsplash.com/photo-1571896349842-33c89424de2d?w=800&auto=format&fit=crop&q=80',\n    title: 'Atlantic Ocean Sunrise Balcony',\n  },\n  {\n    url: 'https://images.unsplash.com/photo-1584622650111-993a426fbf0a?w=800&auto=format&fit=crop&q=80',\n    title: 'Italian Marble Spa Bathroom',\n  },\n  {\n    url: 'https://images.unsplash.com/photo-1540541338287-41700207dee6?w=800&auto=format&fit=crop&q=80',\n    title: 'Private Beach Club & Ocean Cabanas',\n  },\n]\n\nexport function HotelBookingReservation({\n  className,\n  roomTitle = 'Deluxe Ocean View King Suite',\n  hotelName = 'The Ritz-Carlton Bal Harbour, Miami',\n  location = 'Bal Harbour, Miami Beach, FL',\n  rating = 5.0,\n  reviewsCount = 120,\n  basePrice = 485,\n  initialCheckIn = '2026-08-24',\n  initialCheckOut = '2026-08-29',\n  initialAdults = 2,\n  initialChildren = 1,\n  initialRooms = 1,\n}: HotelBookingReservationProps) {\n  const [checkInDate, setCheckInDate] = React.useState(initialCheckIn)\n  const [checkOutDate, setCheckOutDate] = React.useState(initialCheckOut)\n  const [adults, setAdults] = React.useState(initialAdults)\n  const [children, setChildren] = React.useState(initialChildren)\n  const [rooms, setRooms] = React.useState(initialRooms)\n  const [specialRequests, setSpecialRequests] = React.useState('')\n  const [isBooked, setIsBooked] = React.useState(false)\n  const [isSaved, setIsSaved] = React.useState(false)\n  const [activePhotoIndex, setActivePhotoIndex] = React.useState(0)\n\n  // Upgrades state: Oceanfront balcony and Daily Breakfast are checked by default\n  const [selectedUpgrades, setSelectedUpgrades] = React.useState<string[]>(['balcony', 'breakfast'])\n  const [breakfastGuests, setBreakfastGuests] = React.useState(1)\n\n  function toggleUpgrade(id: string) {\n    setSelectedUpgrades((prev) => (prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]))\n  }\n\n  // Date calculations\n  const nights = React.useMemo(() => {\n    if (!checkInDate || !checkOutDate) return 5\n    const start = new Date(checkInDate).getTime()\n    const end = new Date(checkOutDate).getTime()\n    const diffDays = Math.round((end - start) / (1000 * 60 * 60 * 24))\n    return diffDays > 0 ? diffDays : 1\n  }, [checkInDate, checkOutDate])\n\n  function setDuration(presetNights: number) {\n    if (!checkInDate) return\n    const start = new Date(checkInDate + 'T00:00:00')\n    start.setDate(start.getDate() + presetNights)\n    const y = start.getFullYear()\n    const m = String(start.getMonth() + 1).padStart(2, '0')\n    const d = String(start.getDate()).padStart(2, '0')\n    setCheckOutDate(`${y}-${m}-${d}`)\n  }\n\n  function formatDateDisplay(dateStr: string) {\n    if (!dateStr) return ''\n    const [year, month, day] = dateStr.split('-').map(Number)\n    if (!year || !month || !day) return dateStr\n    const date = new Date(year, month - 1, day)\n    return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })\n  }\n\n  const formattedRange = React.useMemo(() => {\n    return `${formatDateDisplay(checkInDate)} → ${formatDateDisplay(checkOutDate)} · ${nights} ${nights === 1 ? 'Night' : 'Nights'}`\n  }, [checkInDate, checkOutDate, nights])\n\n  const cancellationDeadline = React.useMemo(() => {\n    if (!checkInDate) return '48 hours prior to arrival'\n    const start = new Date(checkInDate + 'T00:00:00')\n    start.setDate(start.getDate() - 2)\n    const y = start.getFullYear()\n    const m = String(start.getMonth() + 1).padStart(2, '0')\n    const d = String(start.getDate()).padStart(2, '0')\n    return formatDateDisplay(`${y}-${m}-${d}`)\n  }, [checkInDate])\n\n  // Financial calculations\n  const roomSubtotal = basePrice * nights * rooms\n  const balconyCost = selectedUpgrades.includes('balcony') ? 50 * nights * rooms : 0\n  const breakfastCost = selectedUpgrades.includes('breakfast') ? 35 * breakfastGuests * nights : 0\n  const chauffeurCost = selectedUpgrades.includes('chauffeur') ? 120 : 0\n  const spaCost = selectedUpgrades.includes('spa') ? 65 * adults : 0\n  const selectedAddonsTotal = balconyCost + breakfastCost + chauffeurCost + spaCost\n  const resortFee = 30 * nights * rooms\n  const taxableSubtotal = roomSubtotal + selectedAddonsTotal + resortFee\n  const estimatedTaxes = Math.round(taxableSubtotal * 0.14 * 100) / 100\n  const totalStayPrice = taxableSubtotal + estimatedTaxes\n\n  function formatCurrency(val: number) {\n    return new Intl.NumberFormat('en-US', {\n      style: 'currency',\n      currency: 'USD',\n      minimumFractionDigits: 2,\n      maximumFractionDigits: 2,\n    }).format(val)\n  }\n\n  // Stepper modifiers\n  function updateAdults(delta: number) {\n    setAdults((prev) => {\n      const next = prev + delta\n      if (next >= 1 && next <= 8) {\n        if (breakfastGuests > next) {\n          setBreakfastGuests(next)\n        }\n        return next\n      }\n      return prev\n    })\n  }\n\n  function updateChildren(delta: number) {\n    setChildren((prev) => {\n      const next = prev + delta\n      if (next >= 0 && next <= 6) return next\n      return prev\n    })\n  }\n\n  function updateRooms(delta: number) {\n    setRooms((prev) => {\n      const next = prev + delta\n      if (next >= 1 && next <= 4) return next\n      return prev\n    })\n  }\n\n  return (\n    <div\n      data-slot=\"hotel-booking-reservation\"\n      className={cn('mx-auto w-full max-w-6xl space-y-8 p-4 sm:p-6 lg:p-8', className)}\n    >\n      {/* Confirmation Banner (Visible when booked) */}\n      {isBooked && (\n        <div className=\"border-success/30 bg-success/10 bg-success/15 relative flex flex-col gap-4 rounded-xl border p-5 sm:flex-row sm:items-center sm:justify-between\">\n          <div className=\"flex flex-wrap items-start gap-3.5\">\n            <div className=\"bg-success/20 text-success mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-full\">\n              <CheckCircle2 className=\"size-5\" />\n            </div>\n            <div className=\"space-y-1\">\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <h3 className=\"text-foreground text-base font-semibold\">\n                  Reservation Confirmed · Reference #RC-884920\n                </h3>\n                <Badge wrap variant=\"outline\" className=\"border-success/40 text-success text-xs font-semibold\">\n                  Guaranteed Direct\n                </Badge>\n              </div>\n              <p className=\"text-muted-foreground text-xs sm:text-sm\">\n                A confirmation voucher and check-in barcode have been sent to your registered email. No cancellation\n                penalty applies before {cancellationDeadline}.\n              </p>\n            </div>\n          </div>\n          <Button variant=\"outline\" size=\"sm\" className=\"shrink-0 font-medium\" onClick={() => setIsBooked(false)}>\n            <RotateCcw className=\"size-3.5\" />\n            Modify Reservation\n          </Button>\n        </div>\n      )}\n\n      {/* Room Hero Header Card */}\n      <Card className=\"border-border overflow-hidden shadow-xs\">\n        <div className=\"grid grid-cols-1 gap-6 p-5 sm:p-6 lg:grid-cols-12 lg:gap-8\">\n          {/* Room Photo Showcase */}\n          <div className=\"space-y-3 lg:col-span-6\">\n            <div className=\"border-border bg-muted/40 relative aspect-16/10 w-full overflow-hidden rounded-xl border\">\n              <img\n                src={roomPhotos[activePhotoIndex]?.url}\n                alt={roomPhotos[activePhotoIndex]?.title}\n                className=\"size-full object-cover transition-colors duration-300\"\n              />\n              <div className=\"pointer-events-none absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-black/20\" />\n              <div className=\"absolute top-3 left-3 flex flex-wrap gap-1.5\">\n                <Badge\n                  wrap\n                  variant=\"secondary\"\n                  className=\"bg-background/90 text-foreground text-xs font-medium backdrop-blur-xs\"\n                >\n                  Oceanfront View\n                </Badge>\n                <Badge\n                  wrap\n                  variant=\"outline\"\n                  className=\"bg-background/80 text-foreground border-white/20 text-xs backdrop-blur-xs\"\n                >\n                  Floor 16\n                </Badge>\n              </div>\n              <div className=\"absolute top-3 right-3 flex items-center gap-1.5\">\n                <button\n                  type=\"button\"\n                  aria-label=\"Save to favorites\"\n                  className=\"bg-background/80 hover:bg-background text-foreground flex size-8 items-center justify-center rounded-full backdrop-blur-xs transition-colors\"\n                  onClick={() => setIsSaved(!isSaved)}\n                >\n                  <Heart\n                    className={cn(\n                      'size-4 transition-colors',\n                      isSaved ? 'fill-destructive text-destructive' : 'text-foreground',\n                    )}\n                  />\n                </button>\n                <button\n                  type=\"button\"\n                  aria-label=\"Share suite\"\n                  className=\"bg-background/80 hover:bg-background text-foreground flex size-8 items-center justify-center rounded-full backdrop-blur-xs transition-colors\"\n                >\n                  <Share2 className=\"size-4\" />\n                </button>\n              </div>\n              <div className=\"absolute right-3 bottom-3 left-3 flex items-center justify-between text-xs text-white\">\n                <span className=\"font-medium drop-shadow-xs\">{roomPhotos[activePhotoIndex]?.title}</span>\n                <span className=\"rounded bg-black/60 px-2 py-0.5 font-mono text-xs backdrop-blur-xs\">\n                  {activePhotoIndex + 1} / {roomPhotos.length}\n                </span>\n              </div>\n            </div>\n\n            {/* Mini Thumbnail Selector */}\n            <div className=\"grid grid-cols-4 gap-2\">\n              {roomPhotos.map((photo, idx) => (\n                <button\n                  key={idx}\n                  type=\"button\"\n                  aria-label={photo.title}\n                  className={cn(\n                    'border-border relative aspect-16/10 overflow-hidden rounded-lg border transition-colors',\n                    activePhotoIndex === idx ? 'ring-primary border-primary ring-2' : 'opacity-70 hover:opacity-100',\n                  )}\n                  onClick={() => setActivePhotoIndex(idx)}\n                >\n                  <img src={photo.url} alt={photo.title} className=\"size-full object-cover\" />\n                </button>\n              ))}\n            </div>\n          </div>\n\n          {/* Room Meta & Overview Information */}\n          <div className=\"flex flex-col justify-between space-y-4 lg:col-span-6\">\n            <div className=\"space-y-3\">\n              <div className=\"flex flex-wrap items-center justify-between gap-2\">\n                <div className=\"text-warning flex items-center gap-1.5 text-xs font-medium\">\n                  <Star className=\"fill-warning text-warning size-4\" />\n                  <span className=\"font-bold tabular-nums\">{rating.toFixed(1)}</span>\n                  <span className=\"text-muted-foreground underline underline-offset-2\">\n                    {reviewsCount} verified guest reviews\n                  </span>\n                </div>\n                <Badge\n                  wrap\n                  variant=\"outline\"\n                  className=\"border-primary/30 bg-primary/5 text-primary text-xs font-medium\"\n                >\n                  Official Best Rate Guarantee\n                </Badge>\n              </div>\n\n              <div className=\"space-y-1\">\n                <h1 className=\"text-foreground text-2xl font-bold tracking-tight sm:text-3xl\">{roomTitle}</h1>\n                <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs sm:text-sm\">\n                  <Building2 className=\"text-primary size-4 shrink-0\" />\n                  <span className=\"text-foreground font-medium\">{hotelName}</span>\n                </div>\n                <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n                  <MapPin className=\"size-3.5 shrink-0\" />\n                  <span>{location}</span>\n                </div>\n              </div>\n\n              <p className=\"text-muted-foreground text-xs leading-relaxed sm:text-sm\">\n                Expansive oceanfront sanctuary featuring custom King pillowtop bedding, floor-to-ceiling glass doors\n                opening onto an oversized private balcony with sweeping Atlantic panoramas, freestanding soaking tub,\n                and bespoke in-room dining.\n              </p>\n\n              {/* Room Key Amenities Grid */}\n              <div className=\"grid grid-cols-1 gap-2 pt-1 sm:grid-cols-2 md:grid-cols-3\">\n                <div className=\"border-border/60 bg-muted/20 flex items-center gap-2 rounded-md border p-2 text-xs\">\n                  <Maximize2 className=\"text-muted-foreground size-3.5 shrink-0\" />\n                  <span className=\"text-foreground font-medium\">680 sq ft / 63 m²</span>\n                </div>\n                <div className=\"border-border/60 bg-muted/20 flex items-center gap-2 rounded-md border p-2 text-xs\">\n                  <BedDouble className=\"text-muted-foreground size-3.5 shrink-0\" />\n                  <span className=\"text-foreground font-medium\">1 King Bed</span>\n                </div>\n                <div className=\"border-border/60 bg-muted/20 flex items-center gap-2 rounded-md border p-2 text-xs\">\n                  <Waves className=\"text-muted-foreground size-3.5 shrink-0\" />\n                  <span className=\"text-foreground font-medium\">Ocean Balcony</span>\n                </div>\n                <div className=\"border-border/60 bg-muted/20 flex items-center gap-2 rounded-md border p-2 text-xs\">\n                  <Bath className=\"text-muted-foreground size-3.5 shrink-0\" />\n                  <span className=\"text-foreground font-medium\">Marble Soaking Tub</span>\n                </div>\n                <div className=\"border-border/60 bg-muted/20 flex items-center gap-2 rounded-md border p-2 text-xs\">\n                  <Wifi className=\"text-muted-foreground size-3.5 shrink-0\" />\n                  <span className=\"text-foreground font-medium\">Fast Fiber WiFi</span>\n                </div>\n                <div className=\"border-border/60 bg-muted/20 flex items-center gap-2 rounded-md border p-2 text-xs\">\n                  <Coffee className=\"text-muted-foreground size-3.5 shrink-0\" />\n                  <span className=\"text-foreground font-medium\">Nespresso Machine</span>\n                </div>\n              </div>\n            </div>\n\n            <div className=\"border-border/80 bg-muted/30 flex flex-wrap items-center justify-between gap-3 rounded-xl border p-3.5 sm:p-4\">\n              <div>\n                <span className=\"text-muted-foreground block text-xs font-medium tracking-wider uppercase\">\n                  Direct Member Rate\n                </span>\n                <div className=\"flex flex-wrap items-baseline gap-2\">\n                  <span className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums sm:text-3xl\">\n                    {formatCurrency(basePrice)}\n                  </span>\n                  <span className=\"text-muted-foreground text-xs font-normal sm:text-sm\">/ night</span>\n                  <span className=\"text-muted-foreground text-xs tabular-nums line-through sm:text-sm\">$560.00</span>\n                </div>\n              </div>\n              <Badge\n                wrap\n                variant=\"secondary\"\n                className=\"border-success/20 bg-success/10 text-success text-xs font-semibold\"\n              >\n                Save 13% Direct\n              </Badge>\n            </div>\n          </div>\n        </div>\n      </Card>\n\n      {/* Interactive 2-Column Booking Configuration & Price Breakdown Grid */}\n      <div className=\"grid grid-cols-1 gap-8 lg:grid-cols-12 lg:items-start\">\n        {/* Left Column: Reservation Inputs, Guests & Upgrades */}\n        <div className=\"space-y-6 lg:col-span-7\">\n          {/* Stay Dates Selection */}\n          <Card className=\"shadow-xs\">\n            <CardHeader>\n              <div className=\"flex items-center justify-between\">\n                <div className=\"space-y-0.5\">\n                  <CardTitle className=\"text-lg\">Stay Dates &amp; Duration</CardTitle>\n                  <CardDescription>\n                    Select your check-in and check-out dates to calculate live availability.\n                  </CardDescription>\n                </div>\n                <Badge wrap variant=\"outline\" className=\"gap-1 text-xs font-medium\">\n                  <CalendarDays className=\"text-primary size-3.5\" />\n                  {nights} {nights === 1 ? 'Night' : 'Nights'}\n                </Badge>\n              </div>\n            </CardHeader>\n            <CardContent className=\"space-y-5\">\n              {/* Date Inputs */}\n              <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n                <div className=\"space-y-2\">\n                  <label\n                    htmlFor=\"check-in-date\"\n                    className=\"text-foreground flex items-center gap-1.5 text-xs font-semibold\"\n                  >\n                    <Calendar className=\"text-primary size-3.5\" />\n                    Check-in Date (3:00 PM)\n                  </label>\n                  <Input\n                    id=\"check-in-date\"\n                    type=\"date\"\n                    value={checkInDate}\n                    onChange={(e) => setCheckInDate(e.target.value)}\n                  />\n                </div>\n\n                <div className=\"space-y-2\">\n                  <label\n                    htmlFor=\"check-out-date\"\n                    className=\"text-foreground flex items-center gap-1.5 text-xs font-semibold\"\n                  >\n                    <Calendar className=\"text-primary size-3.5\" />\n                    Check-out Date (12:00 PM)\n                  </label>\n                  <Input\n                    id=\"check-out-date\"\n                    type=\"date\"\n                    value={checkOutDate}\n                    onChange={(e) => setCheckOutDate(e.target.value)}\n                  />\n                </div>\n              </div>\n\n              {/* Stay Summary Highlight & Quick Length Presets */}\n              <div className=\"border-border/60 bg-muted/30 flex flex-col gap-3 rounded-lg border p-3 sm:flex-row sm:items-center sm:justify-between\">\n                <div className=\"text-foreground text-xs font-medium\">\n                  <span className=\"text-muted-foreground\">Selected Stay: </span>\n                  <span className=\"font-semibold\">{formattedRange}</span>\n                </div>\n                <div className=\"flex flex-wrap items-center gap-1.5\">\n                  <span className=\"text-muted-foreground mr-1 text-xs\">Quick:</span>\n                  {[3, 5, 7, 10].map((preset) => (\n                    <Button\n                      key={preset}\n                      variant=\"outline\"\n                      size=\"xs\"\n                      className={\n                        nights === preset ? 'bg-primary text-primary-foreground border-primary hover:bg-primary/90' : ''\n                      }\n                      onClick={() => setDuration(preset)}\n                    >\n                      {preset}N\n                    </Button>\n                  ))}\n                </div>\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* Guests & Rooms Steppers */}\n          <Card className=\"shadow-xs\">\n            <CardHeader>\n              <CardTitle className=\"text-lg\">Guests &amp; Rooms</CardTitle>\n              <CardDescription>Configure the number of adults, children, and suites requested.</CardDescription>\n            </CardHeader>\n            <CardContent className=\"space-y-4\">\n              {/* Adults Stepper */}\n              <div className=\"border-border/60 flex flex-wrap items-center justify-between rounded-lg border p-3.5\">\n                <div className=\"flex items-center gap-3\">\n                  <div className=\"bg-primary/10 text-primary border-primary/20 flex size-9 shrink-0 items-center justify-center rounded-lg border\">\n                    <Users className=\"size-4\" />\n                  </div>\n                  <div className=\"space-y-0.5\">\n                    <span className=\"text-foreground text-sm font-medium\">Adults</span>\n                    <p className=\"text-muted-foreground text-xs\">Ages 13 and above</p>\n                  </div>\n                </div>\n                <div className=\"flex items-center gap-3\">\n                  <Button\n                    variant=\"outline\"\n                    size=\"icon-sm\"\n                    disabled={adults <= 1}\n                    aria-label=\"Decrease adults\"\n                    onClick={() => updateAdults(-1)}\n                  >\n                    <Minus className=\"size-3.5\" />\n                  </Button>\n                  <span className=\"text-foreground w-6 text-center text-sm font-bold tabular-nums\">{adults}</span>\n                  <Button\n                    variant=\"outline\"\n                    size=\"icon-sm\"\n                    disabled={adults >= 8}\n                    aria-label=\"Increase adults\"\n                    onClick={() => updateAdults(1)}\n                  >\n                    <Plus className=\"size-3.5\" />\n                  </Button>\n                </div>\n              </div>\n\n              {/* Children Stepper */}\n              <div className=\"border-border/60 flex flex-wrap items-center justify-between rounded-lg border p-3.5\">\n                <div className=\"flex items-center gap-3\">\n                  <div className=\"bg-primary/10 text-primary border-primary/20 flex size-9 shrink-0 items-center justify-center rounded-lg border\">\n                    <Baby className=\"size-4\" />\n                  </div>\n                  <div className=\"space-y-0.5\">\n                    <span className=\"text-foreground text-sm font-medium\">Children</span>\n                    <p className=\"text-muted-foreground text-xs\">Ages 0 to 12 years</p>\n                  </div>\n                </div>\n                <div className=\"flex items-center gap-3\">\n                  <Button\n                    variant=\"outline\"\n                    size=\"icon-sm\"\n                    disabled={children <= 0}\n                    aria-label=\"Decrease children\"\n                    onClick={() => updateChildren(-1)}\n                  >\n                    <Minus className=\"size-3.5\" />\n                  </Button>\n                  <span className=\"text-foreground w-6 text-center text-sm font-bold tabular-nums\">{children}</span>\n                  <Button\n                    variant=\"outline\"\n                    size=\"icon-sm\"\n                    disabled={children >= 6}\n                    aria-label=\"Increase children\"\n                    onClick={() => updateChildren(1)}\n                  >\n                    <Plus className=\"size-3.5\" />\n                  </Button>\n                </div>\n              </div>\n\n              {/* Rooms Stepper */}\n              <div className=\"border-border/60 flex flex-wrap items-center justify-between rounded-lg border p-3.5\">\n                <div className=\"flex items-center gap-3\">\n                  <div className=\"bg-primary/10 text-primary border-primary/20 flex size-9 shrink-0 items-center justify-center rounded-lg border\">\n                    <BedDouble className=\"size-4\" />\n                  </div>\n                  <div className=\"space-y-0.5\">\n                    <span className=\"text-foreground text-sm font-medium\">Suites / Rooms</span>\n                    <p className=\"text-muted-foreground text-xs\">Max 4 guests per suite</p>\n                  </div>\n                </div>\n                <div className=\"flex items-center gap-3\">\n                  <Button\n                    variant=\"outline\"\n                    size=\"icon-sm\"\n                    disabled={rooms <= 1}\n                    aria-label=\"Decrease rooms\"\n                    onClick={() => updateRooms(-1)}\n                  >\n                    <Minus className=\"size-3.5\" />\n                  </Button>\n                  <span className=\"text-foreground w-6 text-center text-sm font-bold tabular-nums\">{rooms}</span>\n                  <Button\n                    variant=\"outline\"\n                    size=\"icon-sm\"\n                    disabled={rooms >= 4}\n                    aria-label=\"Increase rooms\"\n                    onClick={() => updateRooms(1)}\n                  >\n                    <Plus className=\"size-3.5\" />\n                  </Button>\n                </div>\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* Room Upgrades & Add-ons */}\n          <Card className=\"shadow-xs\">\n            <CardHeader>\n              <div className=\"flex items-center justify-between\">\n                <div className=\"space-y-0.5\">\n                  <CardTitle className=\"text-lg\">Room Upgrades &amp; Exclusive Services</CardTitle>\n                  <CardDescription>\n                    Tailor your stay with luxury amenities and curated hotel enhancements.\n                  </CardDescription>\n                </div>\n                <Badge wrap variant=\"secondary\" className=\"text-xs\">\n                  {selectedUpgrades.length} Selected\n                </Badge>\n              </div>\n            </CardHeader>\n            <CardContent className=\"space-y-3\">\n              {/* Upgrade 1: Oceanfront Balcony */}\n              <div\n                role=\"button\"\n                tabIndex={0}\n                className={cn(\n                  'border-border focus-visible:ring-ring flex cursor-pointer items-start justify-between gap-4 rounded-xl border p-4 transition-colors select-none focus-visible:ring-2 focus-visible:outline-none',\n                  selectedUpgrades.includes('balcony')\n                    ? 'border-primary/40 bg-primary/5 shadow-xs'\n                    : 'bg-card hover:border-border/80 opacity-80 hover:opacity-100',\n                )}\n                onClick={() => toggleUpgrade('balcony')}\n                onKeyDown={(e) => {\n                  if (e.key === ' ' || e.key === 'Enter') {\n                    e.preventDefault()\n                    toggleUpgrade('balcony')\n                  }\n                }}\n              >\n                <div className=\"flex flex-wrap items-start gap-3.5\">\n                  <Checkbox\n                    id=\"upgrade-balcony\"\n                    checked={selectedUpgrades.includes('balcony')}\n                    className=\"pointer-events-none mt-1\"\n                    tabIndex={-1}\n                  />\n                  <div className=\"space-y-1\">\n                    <div className=\"flex flex-wrap items-center gap-2\">\n                      <span className=\"text-foreground text-sm font-semibold\">Oceanfront High-Floor Balcony</span>\n                      <Badge wrap variant=\"outline\" className=\"text-xs font-medium\">\n                        +$50 / night\n                      </Badge>\n                    </div>\n                    <p className=\"text-muted-foreground text-xs leading-relaxed\">\n                      Guaranteed unobstructed 180° Atlantic Ocean sunrise view on floors 15+ with premium teak deck\n                      loungers.\n                    </p>\n                  </div>\n                </div>\n                <div className=\"shrink-0 text-right\">\n                  <span className=\"text-foreground text-sm font-bold tabular-nums\">\n                    +{formatCurrency(50 * nights * rooms)}\n                  </span>\n                  <span className=\"text-muted-foreground block text-xs\">for {nights} nights</span>\n                </div>\n              </div>\n\n              {/* Upgrade 2: Gourmet Breakfast */}\n              <div\n                role=\"button\"\n                tabIndex={0}\n                className={cn(\n                  'border-border focus-visible:ring-ring flex cursor-pointer items-start justify-between gap-4 rounded-xl border p-4 transition-colors select-none focus-visible:ring-2 focus-visible:outline-none',\n                  selectedUpgrades.includes('breakfast')\n                    ? 'border-primary/40 bg-primary/5 shadow-xs'\n                    : 'bg-card hover:border-border/80 opacity-80 hover:opacity-100',\n                )}\n                onClick={() => toggleUpgrade('breakfast')}\n                onKeyDown={(e) => {\n                  if (e.key === ' ' || e.key === 'Enter') {\n                    e.preventDefault()\n                    toggleUpgrade('breakfast')\n                  }\n                }}\n              >\n                <div className=\"flex flex-wrap items-start gap-3.5\">\n                  <Checkbox\n                    id=\"upgrade-breakfast\"\n                    checked={selectedUpgrades.includes('breakfast')}\n                    className=\"pointer-events-none mt-1\"\n                    tabIndex={-1}\n                  />\n                  <div className=\"space-y-1\">\n                    <div className=\"flex flex-wrap items-center gap-2\">\n                      <span className=\"text-foreground text-sm font-semibold\">Daily Gourmet Breakfast</span>\n                      <Badge wrap variant=\"outline\" className=\"text-xs font-medium\">\n                        +$35 / person / day\n                      </Badge>\n                    </div>\n                    <p className=\"text-muted-foreground text-xs leading-relaxed\">\n                      Artisanal morning buffet at Artisan Beach House or private veranda in-room breakfast with fresh\n                      juices.\n                    </p>\n                    {/* Guest selection when active */}\n                    {selectedUpgrades.includes('breakfast') && (\n                      <div\n                        className=\"flex flex-wrap items-center gap-2 pt-1.5 text-xs\"\n                        onClick={(e) => e.stopPropagation()}\n                      >\n                        <span className=\"text-muted-foreground\">Breakfast plan for:</span>\n                        <div className=\"flex flex-wrap items-center gap-1.5\">\n                          {[1, 2].map((count) => (\n                            <Button\n                              key={count}\n                              variant=\"outline\"\n                              size=\"xs\"\n                              className={\n                                breakfastGuests === count ? 'bg-primary text-primary-foreground border-primary' : ''\n                              }\n                              onClick={() => setBreakfastGuests(count)}\n                            >\n                              {count} {count === 1 ? 'Guest' : 'Guests'}\n                            </Button>\n                          ))}\n                        </div>\n                      </div>\n                    )}\n                  </div>\n                </div>\n                <div className=\"shrink-0 text-right\">\n                  <span className=\"text-foreground text-sm font-bold tabular-nums\">\n                    +{formatCurrency(35 * breakfastGuests * nights)}\n                  </span>\n                  <span className=\"text-muted-foreground block text-xs\">\n                    {breakfastGuests} {breakfastGuests === 1 ? 'guest' : 'guests'} · {nights}d\n                  </span>\n                </div>\n              </div>\n\n              {/* Upgrade 3: Airport Chauffeur */}\n              <div\n                role=\"button\"\n                tabIndex={0}\n                className={cn(\n                  'border-border focus-visible:ring-ring flex cursor-pointer items-start justify-between gap-4 rounded-xl border p-4 transition-colors select-none focus-visible:ring-2 focus-visible:outline-none',\n                  selectedUpgrades.includes('chauffeur')\n                    ? 'border-primary/40 bg-primary/5 shadow-xs'\n                    : 'bg-card hover:border-border/80 opacity-80 hover:opacity-100',\n                )}\n                onClick={() => toggleUpgrade('chauffeur')}\n                onKeyDown={(e) => {\n                  if (e.key === ' ' || e.key === 'Enter') {\n                    e.preventDefault()\n                    toggleUpgrade('chauffeur')\n                  }\n                }}\n              >\n                <div className=\"flex flex-wrap items-start gap-3.5\">\n                  <Checkbox\n                    id=\"upgrade-chauffeur\"\n                    checked={selectedUpgrades.includes('chauffeur')}\n                    className=\"pointer-events-none mt-1\"\n                    tabIndex={-1}\n                  />\n                  <div className=\"space-y-1\">\n                    <div className=\"flex flex-wrap items-center gap-2\">\n                      <span className=\"text-foreground text-sm font-semibold\">Private Airport Luxury Chauffeur</span>\n                      <Badge wrap variant=\"outline\" className=\"text-xs font-medium\">\n                        +$120 one-time\n                      </Badge>\n                    </div>\n                    <p className=\"text-muted-foreground text-xs leading-relaxed\">\n                      Curbside meet-and-greet with dedicated Cadillac Escalade or Mercedes S-Class transfer from MIA or\n                      FLL.\n                    </p>\n                  </div>\n                </div>\n                <div className=\"shrink-0 text-right\">\n                  <span className=\"text-foreground text-sm font-bold tabular-nums\">+$120.00</span>\n                  <span className=\"text-muted-foreground block text-xs\">flat one-time</span>\n                </div>\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* Special Requests Card */}\n          <Card className=\"shadow-xs\">\n            <CardHeader className=\"pb-3\">\n              <CardTitle className=\"text-base\">Special Requests &amp; Arrival Notes</CardTitle>\n              <CardDescription>\n                Let us know if you are celebrating a special occasion or require early check-in.\n              </CardDescription>\n            </CardHeader>\n            <CardContent>\n              <Input\n                id=\"special-requests\"\n                value={specialRequests}\n                onChange={(e) => setSpecialRequests(e.target.value)}\n                placeholder=\"e.g., Honeymoon celebration, feather-free bedding, quiet high floor...\"\n                maxLength={200}\n                showCount\n              />\n            </CardContent>\n          </Card>\n        </div>\n\n        {/* Right Column: Total Price Breakdown & Checkout Card (Sticky) */}\n        <div className=\"lg:sticky lg:top-8 lg:col-span-5\">\n          <Card className=\"border-border bg-card shadow-xs\">\n            <CardHeader className=\"pb-4\">\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                  Stay Price Breakdown\n                </span>\n                <Badge\n                  wrap\n                  variant=\"secondary\"\n                  className=\"bg-primary/10 text-primary border-primary/20 gap-1 text-xs font-medium\"\n                >\n                  <CheckCircle2 className=\"size-3\" />\n                  Instant Confirmation\n                </Badge>\n              </div>\n\n              <div className=\"mt-3 space-y-1\">\n                <div className=\"text-muted-foreground text-xs\">Total Stay Price (USD)</div>\n                <div className=\"flex items-baseline gap-2\">\n                  <span className=\"text-foreground text-3xl font-bold tracking-tight tabular-nums sm:text-4xl\">\n                    {formatCurrency(totalStayPrice)}\n                  </span>\n                </div>\n                <p className=\"text-muted-foreground text-xs\">\n                  Total for <span className=\"text-foreground font-medium\">{nights} nights</span> · {rooms} suite ·{' '}\n                  {adults + children} guests\n                </p>\n              </div>\n            </CardHeader>\n\n            <CardContent className=\"space-y-4\">\n              <Separator />\n\n              {/* Itemized Pricing Breakdown */}\n              <div className=\"space-y-2.5\">\n                {/* Base Room Subtotal */}\n                <div className=\"flex items-center justify-between text-sm\">\n                  <span className=\"text-muted-foreground\">\n                    Room subtotal ({formatCurrency(basePrice)} × {nights} {nights === 1 ? 'night' : 'nights'}\n                    {rooms > 1 ? ` × ${rooms} rooms` : ''})\n                  </span>\n                  <span className=\"text-foreground font-semibold tabular-nums\">{formatCurrency(roomSubtotal)}</span>\n                </div>\n\n                {/* Selected Add-ons summary / itemized */}\n                <div className=\"space-y-1.5\">\n                  <div className=\"flex items-center justify-between text-sm\">\n                    <span className=\"text-muted-foreground\">Selected Add-ons ({selectedUpgrades.length} active)</span>\n                    <span className=\"text-foreground font-semibold tabular-nums\">\n                      {formatCurrency(selectedAddonsTotal)}\n                    </span>\n                  </div>\n\n                  {/* Addon sub-items */}\n                  {selectedUpgrades.length > 0 && (\n                    <div className=\"border-border/60 bg-muted/20 space-y-1 rounded-md border p-2.5 text-xs\">\n                      {selectedUpgrades.includes('balcony') && (\n                        <div className=\"text-muted-foreground flex items-center justify-between\">\n                          <span>\n                            • Oceanfront Balcony ({formatCurrency(50)} × {nights}n)\n                          </span>\n                          <span className=\"text-foreground font-medium tabular-nums\">\n                            {formatCurrency(balconyCost)}\n                          </span>\n                        </div>\n                      )}\n                      {selectedUpgrades.includes('breakfast') && (\n                        <div className=\"text-muted-foreground flex items-center justify-between\">\n                          <span>\n                            • Gourmet Breakfast ({formatCurrency(35)} × {breakfastGuests}g × {nights}d)\n                          </span>\n                          <span className=\"text-foreground font-medium tabular-nums\">\n                            {formatCurrency(breakfastCost)}\n                          </span>\n                        </div>\n                      )}\n                      {selectedUpgrades.includes('chauffeur') && (\n                        <div className=\"text-muted-foreground flex items-center justify-between\">\n                          <span>• Luxury Airport Chauffeur (one-time)</span>\n                          <span className=\"text-foreground font-medium tabular-nums\">\n                            {formatCurrency(chauffeurCost)}\n                          </span>\n                        </div>\n                      )}\n                      {selectedUpgrades.includes('spa') && (\n                        <div className=\"text-muted-foreground flex items-center justify-between\">\n                          <span>\n                            • Thermal Spa Pass ({formatCurrency(65)} × {adults} guests)\n                          </span>\n                          <span className=\"text-foreground font-medium tabular-nums\">{formatCurrency(spaCost)}</span>\n                        </div>\n                      )}\n                    </div>\n                  )}\n                </div>\n\n                {/* Resort Fee */}\n                <div className=\"flex items-center justify-between text-sm\">\n                  <div className=\"flex items-center gap-1\">\n                    <span className=\"text-muted-foreground\">Resort &amp; Hospitality Fee</span>\n                    <Info className=\"text-muted-foreground/70 size-3.5 cursor-help\" />\n                  </div>\n                  <span className=\"text-foreground font-semibold tabular-nums\">{formatCurrency(resortFee)}</span>\n                </div>\n                <div className=\"text-muted-foreground pl-0.5 text-xs\">\n                  $30.00 / night · Beach loungers, high-speed WiFi, welcome champagne\n                </div>\n\n                {/* Estimated Taxes */}\n                <div className=\"flex items-center justify-between text-sm\">\n                  <span className=\"text-muted-foreground\">Estimated Taxes &amp; Tourism Surcharge (14%)</span>\n                  <span className=\"text-foreground font-semibold tabular-nums\">{formatCurrency(estimatedTaxes)}</span>\n                </div>\n              </div>\n\n              <Separator />\n\n              {/* Cancellation Policy Banner */}\n              <div className=\"border-success/20 bg-success/10 bg-success/15 space-y-1 rounded-xl border p-3.5\">\n                <div className=\"flex items-center gap-2\">\n                  <ShieldCheck className=\"text-success size-4 shrink-0\" />\n                  <span className=\"text-foreground text-xs font-semibold\">\n                    Free cancellation until 48 hours before check-in\n                  </span>\n                </div>\n                <p className=\"text-muted-foreground pl-6 text-xs leading-normal\">\n                  Cancel before <span className=\"text-foreground font-medium\">{cancellationDeadline}</span> for a 100%\n                  full refund with zero fees.\n                </p>\n              </div>\n\n              {/* Trust Bullet Points */}\n              <ul className=\"text-muted-foreground space-y-2 text-xs\">\n                <li className=\"flex items-center gap-2\">\n                  <Check className=\"text-primary size-3.5 shrink-0\" />\n                  <span>No upfront booking fees or surprise service surcharges</span>\n                </li>\n                <li className=\"flex items-center gap-2\">\n                  <Check className=\"text-primary size-3.5 shrink-0\" />\n                  <span>Official Ritz-Carlton direct member rewards applied</span>\n                </li>\n                <li className=\"flex items-center gap-2\">\n                  <Lock className=\"text-primary size-3.5 shrink-0\" />\n                  <span>256-bit encrypted secure bank checkout</span>\n                </li>\n              </ul>\n            </CardContent>\n\n            <CardFooter className=\"flex flex-col gap-2.5 pt-2\">\n              <Button className=\"w-full gap-2 font-semibold shadow-xs\" size=\"lg\" onClick={() => setIsBooked(true)}>\n                <CreditCard className=\"size-4\" />\n                <span>Reserve &amp; Pay Now ({formatCurrency(totalStayPrice)})</span>\n              </Button>\n              <Button\n                variant=\"outline\"\n                className=\"w-full text-xs font-medium\"\n                size=\"default\"\n                onClick={() => setIsBooked(true)}\n              >\n                Hold Room · Pay at Check-in\n              </Button>\n              <p className=\"text-muted-foreground text-center text-xs\">\n                You won't be charged yet. Final confirmation is sent instantly.\n              </p>\n            </CardFooter>\n          </Card>\n        </div>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/HotelBookingReservation.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/checkbox.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/separator.json"
  ],
  "description": "Luxury hotel room booking and reservation widget with interactive date range picker, guest & room steppers, room upgrade checkboxes, live reactive pricing breakdown, and instant reservation checkout.",
  "categories": [
    "commerce",
    "hospitality",
    "booking",
    "ecommerce",
    "app"
  ]
}