{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "event-card",
  "version": "5.1.0",
  "category": "events",
  "meta": {
    "preview": "https://ui.manifest.build/previews/event-card.png",
    "version": "5.1.0",
    "changelog": {
      "1.0.0": "Initial release with default, compact, horizontal and covered variants. Supports physical, online, and hybrid events with signals and vibe tags.",
      "2.0.0": "BREAKING: Simplified Event interface - replaced startDateTime/endDateTime with display-formatted dateTime string, removed image/locationType/onlineUrl, changed ticketTiers to string array",
      "3.0.0": "Added image support to Event type and default variant for displaying cover images.",
      "4.0.0": "BREAKING: Removed View button from all variants. Entire card is now clickable.",
      "4.1.0": "Added image display to horizontal (list) and compact (carousel) variants",
      "5.0.0": "BREAKING: Removed id from Event interface. Use array index for key.",
      "5.0.1": "Added accessibility support with role, tabIndex, keyboard handlers, and aria-label for all card variants",
      "5.0.2": "Moved demo data to separate file for cleaner component code",
      "5.0.3": "Added comprehensive JSDoc documentation",
      "5.0.4": "Updated Props interface with decorative header and sub-parameter JSDoc documentation",
      "5.0.5": "Fixed defensive property access to handle empty objects and null values",
      "5.0.6": "Added types.ts to registry for proper installation",
      "5.0.7": "Added demo/data.ts to registry for proper installation via shadcn CLI",
      "5.0.8": "Removed unused OpenAI types side-effect import",
      "5.0.9": "Removed default content data - component only renders explicitly provided data",
      "5.0.10": "Removed unused button from registry dependencies",
      "5.1.0": "Added demo data defaults - component renders demo content when no data prop is provided"
    }
  },
  "changelog": {
    "1.0.0": "Initial release with default, compact, horizontal and covered variants. Supports physical, online, and hybrid events with signals and vibe tags.",
    "2.0.0": "BREAKING: Simplified Event interface - replaced startDateTime/endDateTime with display-formatted dateTime string, removed image/locationType/onlineUrl, changed ticketTiers to string array",
    "3.0.0": "Added image support to Event type and default variant for displaying cover images.",
    "4.0.0": "BREAKING: Removed View button from all variants. Entire card is now clickable.",
    "4.1.0": "Added image display to horizontal (list) and compact (carousel) variants",
    "5.0.0": "BREAKING: Removed id from Event interface. Use array index for key.",
    "5.0.1": "Added accessibility support with role, tabIndex, keyboard handlers, and aria-label for all card variants",
    "5.0.2": "Moved demo data to separate file for cleaner component code",
    "5.0.3": "Added comprehensive JSDoc documentation",
    "5.0.4": "Updated Props interface with decorative header and sub-parameter JSDoc documentation",
    "5.0.5": "Fixed defensive property access to handle empty objects and null values",
    "5.0.6": "Added types.ts to registry for proper installation",
    "5.0.7": "Added demo/data.ts to registry for proper installation via shadcn CLI",
    "5.0.8": "Removed unused OpenAI types side-effect import",
    "5.0.9": "Removed default content data - component only renders explicitly provided data",
    "5.0.10": "Removed unused button from registry dependencies",
    "5.1.0": "Added demo data defaults - component renders demo content when no data prop is provided"
  },
  "title": "Event Card",
  "author": "MNFST, Inc",
  "description": "Display event information with multiple layouts. Supports events with images, signals, vibe tags, and display-formatted date/time. Entire card is clickable.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "https://ui.manifest.build/r/manifest-types.json"
  ],
  "files": [
    {
      "path": "registry/events/event-card.tsx",
      "content": "'use client'\n\nimport {\n  CalendarX,\n  CirclePause,\n  Clock,\n  Flame,\n  MapPin,\n  Sparkles,\n  Star,\n  Ticket,\n  Timer,\n  TrendingUp,\n  XCircle\n} from 'lucide-react'\nimport type { Event, EventSignal } from './types'\nimport { demoEvent } from './demo/events'\n\n/**\n * ═══════════════════════════════════════════════════════════════════════════\n * EventCardProps\n * ═══════════════════════════════════════════════════════════════════════════\n *\n * Props for the EventCard component. Displays event information with multiple\n * layout variants, signal badges, vibe tags, and organizer ratings.\n */\nexport interface EventCardProps {\n  data?: {\n    /** The event object to display. */\n    event?: Event\n  }\n  actions?: {\n    /** Called when the card is clicked. */\n    onClick?: (event: Event) => void\n  }\n  appearance?: {\n    /**\n     * Card layout variant.\n     * @default \"default\"\n     */\n    variant?: 'default' | 'compact' | 'horizontal' | 'covered'\n    /**\n     * Whether to show the event signal badge.\n     * @default true\n     */\n    showSignal?: boolean\n    /**\n     * Whether to show vibe tags.\n     * @default true\n     */\n    showTags?: boolean\n    /**\n     * Whether to show the organizer rating.\n     * @default true\n     */\n    showRating?: boolean\n  }\n}\n\nfunction EventSignalBadge({ signal }: { signal: EventSignal }) {\n  const config: Record<\n    EventSignal,\n    { label: string; icon: typeof Flame; className: string }\n  > = {\n    'going-fast': {\n      label: 'Going Fast',\n      icon: Flame,\n      className: 'bg-orange-500/10 text-orange-600 border-orange-200'\n    },\n    popular: {\n      label: 'Popular',\n      icon: TrendingUp,\n      className: 'bg-pink-500/10 text-pink-600 border-pink-200'\n    },\n    'just-added': {\n      label: 'Just Added',\n      icon: Sparkles,\n      className: 'bg-blue-500/10 text-blue-600 border-blue-200'\n    },\n    'sales-end-soon': {\n      label: 'Sales End Soon',\n      icon: Timer,\n      className: 'bg-red-500/10 text-red-600 border-red-200'\n    },\n    'few-tickets-left': {\n      label: 'Few Tickets Left',\n      icon: Ticket,\n      className: 'bg-orange-500/10 text-orange-600 border-orange-200'\n    },\n    canceled: {\n      label: 'Canceled',\n      icon: XCircle,\n      className: 'bg-gray-500/10 text-gray-600 border-gray-200'\n    },\n    ended: {\n      label: 'Ended',\n      icon: CalendarX,\n      className: 'bg-gray-500/10 text-gray-600 border-gray-200'\n    },\n    postponed: {\n      label: 'Postponed',\n      icon: CirclePause,\n      className: 'bg-yellow-500/10 text-yellow-600 border-yellow-200'\n    }\n  }\n\n  const { label, icon: Icon, className } = config[signal]\n\n  return (\n    <span\n      className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs font-medium ${className}`}\n    >\n      <Icon className=\"h-3 w-3\" />\n      {label}\n    </span>\n  )\n}\n\n// Format number with commas (consistent across server/client)\nfunction formatNumber(num: number): string {\n  return num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n}\n\n/**\n * An event card component with multiple layout variants.\n * Displays event information with signals, tags, and ratings.\n *\n * Features:\n * - Four layout variants (default, compact, horizontal, covered)\n * - Event signal badges (going fast, popular, etc.)\n * - Vibe tags display\n * - Organizer rating display\n * - Clickable card interaction\n *\n * @component\n * @example\n * ```tsx\n * <EventCard\n *   data={{\n *     event: {\n *       title: \"Concert Night\",\n *       category: \"Music\",\n *       dateTime: \"Sat, Jan 20 · 8pm\",\n *       venue: \"The Fillmore\",\n *       priceRange: \"$45 - $150\"\n *     }\n *   }}\n *   appearance={{ variant: \"default\", showSignal: true }}\n *   actions={{ onClick: (event) => console.log(\"Clicked:\", event.title) }}\n * />\n * ```\n */\nexport function EventCard({ data, actions, appearance }: EventCardProps) {\n  const resolved: NonNullable<EventCardProps['data']> = data ?? { event: demoEvent }\n  const event = resolved.event\n  const onClick = actions?.onClick\n  const variant = appearance?.variant ?? 'default'\n  const showSignal = appearance?.showSignal ?? true\n  const showTags = appearance?.showTags ?? true\n  const showRating = appearance?.showRating ?? true\n\n  if (!event) {\n    return null\n  }\n\n  const handleClick = () => {\n    if (onClick) {\n      onClick(event)\n    }\n  }\n\n  const handleKeyDown = (e: React.KeyboardEvent) => {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault()\n      handleClick()\n    }\n  }\n\n  const cardAriaLabel = [\n    event.title,\n    event.category && `${event.category} event`,\n    event.venue && `at ${event.venue}`,\n    event.dateTime,\n    event.priceRange\n  ].filter(Boolean).join(', ')\n\n  if (variant === 'covered') {\n    return (\n      <div\n        role=\"button\"\n        tabIndex={0}\n        aria-label={cardAriaLabel}\n        className=\"relative overflow-hidden rounded-lg border cursor-pointer min-h-[280px]\"\n        onClick={handleClick}\n        onKeyDown={handleKeyDown}\n      >\n        {/* Background image */}\n        {event.image && (\n          <img\n            src={event.image}\n            alt={event.title}\n            className=\"absolute inset-0 h-full w-full object-cover\"\n          />\n        )}\n        <div className=\"absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-black/20\" />\n        <div className=\"absolute inset-0 flex flex-col justify-end p-4 text-white\">\n          <div>\n            <div className=\"flex items-center gap-2 flex-wrap\">\n              {event.category && (\n                <p className=\"text-[10px] font-medium uppercase tracking-wide text-white/70\">\n                  {event.category}\n                </p>\n              )}\n              {showSignal && event.eventSignal && (\n                <EventSignalBadge signal={event.eventSignal} />\n              )}\n            </div>\n            {event.title && (\n              <h2 className=\"mt-1 text-lg font-semibold leading-tight\">\n                {event.title}\n              </h2>\n            )}\n            <div className=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-white/80\">\n              {event.dateTime && (\n                <span className=\"flex items-center gap-1\">\n                  <Clock className=\"h-3.5 w-3.5\" />\n                  {event.dateTime}\n                </span>\n              )}\n              {event.venue && (\n                <span className=\"flex items-center gap-1\">\n                  <MapPin className=\"h-3.5 w-3.5\" />\n                  {event.venue}\n                  {event.neighborhood && `, ${event.neighborhood}`}\n                </span>\n              )}\n            </div>\n            {showTags && event.vibeTags && event.vibeTags.length > 0 && (\n              <div className=\"mt-2 flex flex-wrap gap-1\">\n                {event.vibeTags.slice(0, 3).map((tag) => (\n                  <span\n                    key={tag}\n                    className=\"rounded-md bg-white/20 px-2 py-0.5 text-xs\"\n                  >\n                    {tag}\n                  </span>\n                ))}\n              </div>\n            )}\n            <div className=\"mt-3 flex items-center gap-3\">\n              {event.priceRange && <span className=\"font-semibold\">{event.priceRange}</span>}\n              {showRating && event.organizerRating && (\n                <span className=\"flex items-center gap-1 text-sm text-white/70\">\n                  <Star className=\"h-3.5 w-3.5 fill-current text-yellow-400\" />\n                  {event.organizerRating}\n                </span>\n              )}\n            </div>\n          </div>\n        </div>\n      </div>\n    )\n  }\n\n  if (variant === 'horizontal') {\n    return (\n      <div\n        role=\"button\"\n        tabIndex={0}\n        aria-label={cardAriaLabel}\n        className=\"flex gap-4 rounded-xl border bg-card p-4 cursor-pointer hover:bg-accent/50 transition-colors\"\n        onClick={handleClick}\n        onKeyDown={handleKeyDown}\n      >\n        {/* Image */}\n        {event.image && (\n          <div className=\"h-[140px] w-[180px] flex-shrink-0 overflow-hidden rounded-lg bg-muted\">\n            <img\n              src={event.image}\n              alt={event.title || 'Event image'}\n              className=\"h-full w-full object-cover\"\n            />\n          </div>\n        )}\n        <div className=\"flex flex-1 flex-col justify-between\">\n          <div>\n            {showSignal && event.eventSignal && (\n              <div className=\"mb-1.5\">\n                <EventSignalBadge signal={event.eventSignal} />\n              </div>\n            )}\n            {event.title && (\n              <h3 className=\"line-clamp-2 text-base font-semibold leading-tight\">\n                {event.title}\n              </h3>\n            )}\n            <div className=\"mt-2 space-y-1 text-sm text-muted-foreground\">\n              {event.dateTime && <p>{event.dateTime}</p>}\n              {(event.city || event.venue) && (\n                <p>\n                  {event.city}\n                  {event.city && event.venue && ' · '}\n                  {event.venue}\n                </p>\n              )}\n            </div>\n          </div>\n          <div className=\"mt-3\">\n            {event.priceRange && <span className=\"font-semibold\">{event.priceRange}</span>}\n          </div>\n        </div>\n      </div>\n    )\n  }\n\n  if (variant === 'compact') {\n    return (\n      <div\n        role=\"button\"\n        tabIndex={0}\n        aria-label={cardAriaLabel}\n        className=\"flex h-full flex-col overflow-hidden rounded-lg border bg-card cursor-pointer hover:bg-accent/50 transition-colors\"\n        onClick={handleClick}\n        onKeyDown={handleKeyDown}\n      >\n        {/* Image */}\n        {event.image && (\n          <div className=\"aspect-[16/9] overflow-hidden bg-muted\">\n            <img\n              src={event.image}\n              alt={event.title || 'Event image'}\n              className=\"h-full w-full object-cover\"\n            />\n          </div>\n        )}\n        <div className=\"flex flex-1 flex-col justify-between p-3\">\n          <div>\n            <div className=\"flex items-center gap-2 flex-wrap mb-0.5\">\n              {event.category && (\n                <p className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n                  {event.category}\n                </p>\n              )}\n              {showSignal && event.eventSignal && (\n                <EventSignalBadge signal={event.eventSignal} />\n              )}\n            </div>\n            {event.title && (\n              <h3 className=\"line-clamp-2 text-sm font-medium\">{event.title}</h3>\n            )}\n            <div className=\"mt-1 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-muted-foreground\">\n              {event.dateTime && (\n                <span className=\"flex items-center gap-1\">\n                  <Clock className=\"h-3 w-3\" />\n                  {event.dateTime}\n                </span>\n              )}\n              {event.venue && (\n                <span className=\"flex items-center gap-1\">\n                  <MapPin className=\"h-3 w-3\" />\n                  {event.venue}\n                </span>\n              )}\n            </div>\n            {showTags && event.vibeTags && event.vibeTags.length > 0 && (\n              <div className=\"mt-1.5 flex flex-wrap gap-1\">\n                {event.vibeTags.slice(0, 2).map((tag) => (\n                  <span\n                    key={tag}\n                    className=\"rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground\"\n                  >\n                    {tag}\n                  </span>\n                ))}\n              </div>\n            )}\n          </div>\n          <div className=\"mt-3 flex items-center gap-2\">\n            {event.priceRange && <span className=\"text-sm font-medium\">{event.priceRange}</span>}\n            {showRating && event.organizerRating && (\n              <span className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n                <Star className=\"h-3 w-3 fill-current text-yellow-500\" />\n                {event.organizerRating}\n              </span>\n            )}\n          </div>\n        </div>\n      </div>\n    )\n  }\n\n  // Default variant\n  return (\n    <div\n      role=\"button\"\n      tabIndex={0}\n      aria-label={cardAriaLabel}\n      className=\"flex h-full flex-col overflow-hidden rounded-lg border bg-card cursor-pointer hover:bg-accent/50 transition-colors\"\n      onClick={handleClick}\n      onKeyDown={handleKeyDown}\n    >\n      {/* Image */}\n      {event.image && (\n        <div className=\"aspect-[16/9] overflow-hidden bg-muted\">\n          <img\n            src={event.image}\n            alt={event.title || 'Event image'}\n            className=\"h-full w-full object-cover\"\n          />\n        </div>\n      )}\n      <div className=\"flex flex-1 flex-col justify-between p-4\">\n        <div>\n          <div className=\"flex items-center gap-2 flex-wrap mb-1\">\n            {event.category && (\n              <p className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n                {event.category}\n              </p>\n            )}\n            {showSignal && event.eventSignal && (\n              <EventSignalBadge signal={event.eventSignal} />\n            )}\n          </div>\n          {event.title && (\n            <h3 className=\"line-clamp-2 font-medium\">{event.title}</h3>\n          )}\n          <div className=\"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-muted-foreground\">\n            {event.dateTime && (\n              <span className=\"flex items-center gap-1\">\n                <Clock className=\"h-3.5 w-3.5\" />\n                {event.dateTime}\n              </span>\n            )}\n            {event.venue && (\n              <span className=\"flex items-center gap-1\">\n                <MapPin className=\"h-3.5 w-3.5\" />\n                {event.venue}\n                {event.neighborhood && `, ${event.neighborhood}`}\n              </span>\n            )}\n          </div>\n          {showTags && event.vibeTags && event.vibeTags.length > 0 && (\n            <div className=\"mt-2 flex flex-wrap gap-1\">\n              {event.vibeTags.slice(0, 3).map((tag) => (\n                <span\n                  key={tag}\n                  className=\"rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground\"\n                >\n                  {tag}\n                </span>\n              ))}\n            </div>\n          )}\n        </div>\n        <div className=\"mt-4 flex items-center gap-3\">\n          {event.priceRange && <span className=\"font-medium\">{event.priceRange}</span>}\n          {showRating && event.organizerRating && (\n            <span className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n              <Star className=\"h-3.5 w-3.5 fill-current text-yellow-500\" />\n              {event.organizerRating}\n              {event.reviewCount && (\n                <span className=\"text-xs\">\n                  ({formatNumber(event.reviewCount)})\n                </span>\n              )}\n            </span>\n          )}\n        </div>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "components/ui/event-card.tsx"
    },
    {
      "path": "registry/events/demo/events.ts",
      "content": "// Demo data for Events category components\n// This file contains sample data used for component previews and documentation\n\nimport type { Event, EventDetails } from '../types'\n\n// Helper to generate dates relative to today\nfunction getDateAt(daysFromNow: number, hour: number): string {\n  const date = new Date()\n  date.setDate(date.getDate() + daysFromNow)\n  date.setHours(hour, 0, 0, 0)\n  return date.toISOString()\n}\n\n// Single event for EventCard default\nexport const demoEvent: Event = {\n  title: 'NEON Vol. 9',\n  category: 'Music',\n  venue: 'Echoplex',\n  neighborhood: 'Echo Park',\n  city: 'Los Angeles',\n  dateTime: 'Tonight 9:00 PM - 3:00 AM',\n  priceRange: '$45 - $150',\n  image: 'https://images.unsplash.com/photo-1470225620780-dba8ba36b745?w=800',\n  vibeTags: ['High energy', 'Late night', 'Dressy'],\n  vibeDescription:\n    'Immersive electronic experience with world-class DJs and stunning visuals.',\n  aiSummary:\n    \"Immersive electronic night with world-class DJs and stunning visuals at LA's top-rated venue.\",\n  lineup: ['DJ Shadow', 'Bonobo', 'Four Tet', 'Caribou'],\n  ticketTiers: [\n    'General Admission $45',\n    'VIP Access $120',\n    'Backstage Pass $150'\n  ],\n  eventSignal: 'going-fast',\n  organizerRating: 4.8,\n  reviewCount: 12453,\n  venueRating: 4.8,\n  ageRestriction: '21+',\n  hasMultipleDates: true\n}\n\n// 15 events for EventList default\nexport const demoEvents: Event[] = [\n  {\n    title: 'NEON Vol. 9',\n    category: 'Music',\n    venue: 'Echoplex',\n    neighborhood: 'Echo Park',\n    city: 'Los Angeles',\n    dateTime: 'Tonight 9:00 PM - 3:00 AM',\n    priceRange: '$45 - $150',\n    image: 'https://images.unsplash.com/photo-1470225620780-dba8ba36b745?w=800',\n    coordinates: { lat: 34.0781, lng: -118.2606 },\n    vibeTags: ['High energy', 'Late night'],\n    eventSignal: 'going-fast',\n    organizerRating: 4.8,\n    reviewCount: 12453,\n    ageRestriction: '21+'\n  },\n  {\n    title: 'The Midnight Show',\n    category: 'Comedy',\n    venue: 'The Comedy Underground',\n    neighborhood: 'Santa Monica',\n    city: 'Los Angeles',\n    dateTime: 'Tonight 10:00 PM - 12:00 AM',\n    priceRange: '$15 - $35',\n    image: 'https://images.unsplash.com/photo-1585699324551-f6c309eedeca?w=800',\n    coordinates: { lat: 34.0195, lng: -118.4912 },\n    vibeTags: ['Social', 'Late night'],\n    eventSignal: 'popular',\n    organizerRating: 4.7,\n    reviewCount: 3241,\n    discount: 'TONIGHT ONLY - 40% OFF'\n  },\n  {\n    title: 'Salsa Sundays @ Echo Park',\n    category: 'Classes',\n    venue: 'Echo Park Lake',\n    neighborhood: 'Echo Park',\n    city: 'Los Angeles',\n    dateTime: 'Saturday 6:00 PM - 10:00 PM',\n    priceRange: 'Free',\n    image: 'https://images.unsplash.com/photo-1504609813442-a8924e83f76e?w=800',\n    coordinates: { lat: 34.0731, lng: -118.2608 },\n    vibeTags: ['High energy', 'Social'],\n    eventSignal: 'just-added',\n    organizerRating: 4.9,\n    reviewCount: 8764\n  },\n  {\n    title: 'Dawn Flow: Griffith Park',\n    category: 'Classes',\n    venue: 'Griffith Park',\n    neighborhood: 'Los Feliz',\n    city: 'Los Angeles',\n    dateTime: 'Tomorrow 6:00 AM - 8:00 AM',\n    priceRange: 'Free',\n    image: 'https://images.unsplash.com/photo-1545205597-3d9d02c29597?w=800',\n    coordinates: { lat: 34.1365, lng: -118.2943 },\n    vibeTags: ['Chill', 'Wellness', 'Outdoor'],\n    organizerRating: 4.9,\n    reviewCount: 8764,\n    discount: 'FREE - First 50 Only'\n  },\n  {\n    title: 'Lakers vs Celtics',\n    category: 'Sports',\n    venue: 'Crypto.com Arena',\n    neighborhood: 'Downtown',\n    city: 'Los Angeles',\n    dateTime: 'Friday 7:30 PM - 10:30 PM',\n    priceRange: '$125 - $850',\n    image: 'https://images.unsplash.com/photo-1546519638-68e109498ffc?w=800',\n    coordinates: { lat: 34.0430, lng: -118.2673 },\n    vibeTags: ['High energy', 'Social', 'Premium'],\n    eventSignal: 'sales-end-soon',\n    organizerRating: 4.5,\n    reviewCount: 2341\n  },\n  {\n    title: 'Smorgasburg LA: Sunday Market',\n    category: 'Food & Drink',\n    venue: 'ROW DTLA',\n    neighborhood: 'Arts District',\n    city: 'Los Angeles',\n    dateTime: 'Sunday 10:00 AM - 4:00 PM',\n    priceRange: 'Free',\n    image: 'https://images.unsplash.com/photo-1555939594-58d7cb561ad1?w=800',\n    coordinates: { lat: 34.0341, lng: -118.2324 },\n    vibeTags: ['Family-friendly', 'Outdoor', 'Social'],\n    organizerRating: 4.8,\n    reviewCount: 5632\n  },\n  {\n    title: 'LACMA After Hours',\n    category: 'Arts',\n    venue: 'LACMA',\n    neighborhood: 'Miracle Mile',\n    city: 'Los Angeles',\n    dateTime: 'Friday 7:00 PM - 11:00 PM',\n    priceRange: '$35 - $75',\n    image: 'https://images.unsplash.com/photo-1531243269054-5ebf6f34081e?w=800',\n    coordinates: { lat: 34.0639, lng: -118.3592 },\n    vibeTags: ['Chill', 'Date night', 'Sophisticated'],\n    organizerRating: 4.7,\n    reviewCount: 1234,\n    ageRestriction: '21+',\n    discount: 'MEMBER PRICE'\n  },\n  {\n    title: 'Blue Note Under Stars',\n    category: 'Music',\n    venue: 'Hollywood Bowl',\n    neighborhood: 'Hollywood Hills',\n    city: 'Los Angeles',\n    dateTime: 'Saturday 8:00 PM - 11:00 PM',\n    priceRange: '$45 - $200',\n    image: 'https://images.unsplash.com/photo-1514320291840-2e0a9bf2a9ae?w=800',\n    coordinates: { lat: 34.1122, lng: -118.3391 },\n    vibeTags: ['Chill', 'Date night', 'Outdoor'],\n    lineup: ['Kamasi Washington', 'Thundercat', 'Terrace Martin'],\n    organizerRating: 4.8,\n    reviewCount: 12453\n  },\n  {\n    title: 'Meraki: Seth Troxler',\n    category: 'Nightlife',\n    venue: 'Sound Nightclub',\n    neighborhood: 'Hollywood',\n    city: 'Los Angeles',\n    dateTime: 'Saturday 10:00 PM - 4:00 AM',\n    priceRange: '$35 - $65',\n    image: 'https://images.unsplash.com/photo-1571266028243-e4733b0f0bb0?w=800',\n    coordinates: { lat: 34.0928, lng: -118.3287 },\n    vibeTags: ['High energy', 'Late night', 'Underground'],\n    lineup: ['Amelie Lens', 'I Hate Models', 'FJAAK'],\n    organizerRating: 4.6,\n    reviewCount: 1876,\n    ageRestriction: '21+'\n  },\n  {\n    title: 'Whitney Cummings + Friends',\n    category: 'Comedy',\n    venue: 'The Laugh Factory',\n    neighborhood: 'Hollywood',\n    city: 'Los Angeles',\n    dateTime: 'In 2 days 8:00 PM - 11:00 PM',\n    priceRange: '$25 - $55',\n    image: 'https://images.unsplash.com/photo-1527224538127-2104bb71c51b?w=800',\n    coordinates: { lat: 34.0901, lng: -118.3615 },\n    vibeTags: ['Chill', 'Social', 'Date night'],\n    organizerRating: 4.7,\n    reviewCount: 3241,\n    ageRestriction: '18+'\n  },\n  {\n    title: 'Venice Beach Drum Circle',\n    category: 'Music',\n    venue: 'Venice Beach Boardwalk',\n    neighborhood: 'Venice',\n    city: 'Los Angeles',\n    dateTime: 'Sunday 4:00 PM - 8:00 PM',\n    priceRange: 'Free',\n    image: 'https://images.unsplash.com/photo-1506157786151-b8491531f063?w=800',\n    coordinates: { lat: 33.9850, lng: -118.4695 },\n    vibeTags: ['Outdoor', 'Social', 'Chill'],\n    eventSignal: 'popular',\n    organizerRating: 4.6,\n    reviewCount: 2145\n  },\n  {\n    title: 'Rooftop Cinema: Blade Runner',\n    category: 'Film',\n    venue: 'Rooftop Cinema Club',\n    neighborhood: 'DTLA',\n    city: 'Los Angeles',\n    dateTime: 'Friday 8:30 PM - 11:00 PM',\n    priceRange: '$25 - $45',\n    image: 'https://images.unsplash.com/photo-1489599849927-2ee91cede3ba?w=800',\n    coordinates: { lat: 34.0407, lng: -118.2468 },\n    vibeTags: ['Date night', 'Views', 'Chill'],\n    organizerRating: 4.8,\n    reviewCount: 892\n  },\n  {\n    title: 'Dodgers vs Giants',\n    category: 'Sports',\n    venue: 'Dodger Stadium',\n    neighborhood: 'Elysian Park',\n    city: 'Los Angeles',\n    dateTime: 'Saturday 1:10 PM - 4:30 PM',\n    priceRange: '$35 - $350',\n    image: 'https://images.unsplash.com/photo-1566577739112-5180d4bf9390?w=800',\n    coordinates: { lat: 34.0739, lng: -118.2400 },\n    vibeTags: ['Family-friendly', 'Social', 'High energy'],\n    eventSignal: 'few-tickets-left',\n    organizerRating: 4.7,\n    reviewCount: 15678\n  },\n  {\n    title: 'Natural Wine Fair',\n    category: 'Food & Drink',\n    venue: 'Grand Central Market',\n    neighborhood: 'Downtown',\n    city: 'Los Angeles',\n    dateTime: 'Sunday 12:00 PM - 6:00 PM',\n    priceRange: '$45 - $85',\n    image: 'https://images.unsplash.com/photo-1510812431401-41d2bd2722f3?w=800',\n    coordinates: { lat: 34.0508, lng: -118.2490 },\n    vibeTags: ['Tasting', 'Social', 'Sophisticated'],\n    eventSignal: 'just-added',\n    organizerRating: 4.5,\n    reviewCount: 567,\n    ageRestriction: '21+'\n  },\n  {\n    title: 'Meditation in the Gardens',\n    category: 'Wellness',\n    venue: 'The Getty Center',\n    neighborhood: 'Brentwood',\n    city: 'Los Angeles',\n    dateTime: 'Sunday 7:00 AM - 9:00 AM',\n    priceRange: 'Free',\n    image: 'https://images.unsplash.com/photo-1506126613408-eca07ce68773?w=800',\n    coordinates: { lat: 34.0780, lng: -118.4741 },\n    vibeTags: ['Wellness', 'Outdoor', 'Chill'],\n    organizerRating: 4.9,\n    reviewCount: 1234\n  }\n]\n\n// Detailed event for EventDetail default\nexport const demoEventDetails: EventDetails = {\n  title: 'Sunglasses at Night: Underground Techno',\n  category: 'Nightlife',\n  venue: 'The White Rabbit',\n  neighborhood: 'The Woodlands',\n  city: 'Houston, TX',\n  startDateTime: getDateAt(2, 22),\n  endDateTime: getDateAt(3, 4),\n  priceRange: '$15 - $30',\n  images: [\n    'https://images.unsplash.com/photo-1470225620780-dba8ba36b745?w=800',\n    'https://images.unsplash.com/photo-1514525253161-7a46d19cd819?w=800',\n    'https://images.unsplash.com/photo-1533174072545-7a4b6ad7a6c3?w=800'\n  ],\n  vibeTags: ['High energy', 'Late night', 'Underground'],\n  eventSignal: 'going-fast',\n  aiSummary: 'Raw, unfiltered techno in an authentic warehouse setting.',\n  description:\n    'Experience the raw energy of underground techno. Industrial beats, immersive visuals, and a crowd that lives for the music.',\n  lineup: ['Amelie Lens', 'I Hate Models', 'FJAAK'],\n  attendeesCount: 537,\n  friendsGoing: [\n    { name: 'Alex', avatar: 'https://i.pravatar.cc/40?u=alex' },\n    { name: 'Sam', avatar: 'https://i.pravatar.cc/40?u=sam' }\n  ],\n  organizer: {\n    name: 'Midnight Lovers',\n    image: 'https://i.pravatar.cc/80?u=midnight',\n    rating: 4.5,\n    reviewCount: 1067,\n    verified: true,\n    followers: 1200,\n    eventsCount: 154,\n    hostingYears: 8,\n    trackRecord: 'great',\n    responseRate: 'very responsive'\n  },\n  venue_details: {\n    name: 'The White Rabbit',\n    address: '8827 Nasher Ave',\n    city: 'Houston TX',\n    coordinates: { lat: 29.7604, lng: -95.3698 }\n  },\n  tiers: [\n    { name: 'General Admission', price: 15, available: 50 },\n    {\n      name: 'VIP Access',\n      price: 30,\n      available: 20,\n      benefits: ['Skip the line', 'Exclusive lounge']\n    }\n  ],\n  goodToKnow: {\n    duration: '2 hours',\n    doorsOpen: '7:00 PM',\n    showtime: '7:30 PM',\n    ageRestriction: '21+',\n    dressCode: 'Casual',\n    parking: 'Limited, leave early to avoid long queues'\n  },\n  policies: {\n    refund: 'No refunds. Tickets are transferable.',\n    entry: 'Open 2 hours before event',\n    idRequired: true,\n    securityOnSite: true\n  },\n  faq: [\n    {\n      question: 'What is the refund policy?',\n      answer: 'No refunds. Tickets are transferable.'\n    },\n    {\n      question: 'When do doors open?',\n      answer: 'Open 2 hours before event.'\n    },\n    {\n      question: 'Is there parking?',\n      answer: 'Limited, leave early to avoid long queues.'\n    }\n  ],\n  relatedTags: ['Houston Events', 'Texas Nightlife', 'Techno Parties']\n}\n\n// Ticket tiers for TicketTierSelect\nexport const demoTicketTiers = [\n  {\n    id: '1',\n    name: 'General Admission',\n    price: 45,\n    fee: 5,\n    available: 100,\n    maxPerOrder: 10,\n  },\n  {\n    id: '2',\n    name: 'VIP',\n    price: 150,\n    fee: 15,\n    available: 20,\n    maxPerOrder: 4,\n    description: 'Includes backstage access',\n  },\n]\n\n// Event confirmation data\nexport const demoEventConfirmation = {\n  orderNumber: 'EVT-12345',\n  eventTitle: 'Summer Music Festival',\n  ticketCount: 2,\n  recipientEmail: 'customer@example.com',\n  eventDate: 'Jan 20, 2024',\n  eventLocation: 'Central Park, New York',\n  organizer: {\n    name: 'Live Nation',\n  },\n}\n",
      "type": "registry:lib",
      "target": "components/ui/demo/events.ts"
    }
  ],
  "categories": [
    "events"
  ],
  "type": "registry:block"
}