{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"portfolio-portfolio-event-speaking-and-workshops-video-recording-embed","type":"registry:block","title":"Video Recording Embed","files":[{"path":"components/blocks/portfolio/portfolio-event-speaking-and-workshops/video-recording-embed.tsx","content":"import {\n  ArrowRight,\n  PlayCircle,\n  Calendar,\n  MapPin,\n  Clock,\n  Download,\n  Mic,\n} from 'lucide-react';\nimport { Button } from '@/components/ui/button';\nimport { Badge } from '@/components/ui/badge';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\n\n// Sample featured recordings data\nconst featuredRecordings = [\n  {\n    id: 1,\n    title: 'AI-Driven Interfaces',\n    event: 'UXConf 2024',\n    role: 'Keynote Speaker',\n    date: 'April 18, 2024',\n    location: 'San Francisco, CA',\n    duration: '45 min',\n    description:\n      'In this keynote presentation, I explored how artificial intelligence is revolutionizing the way we approach web design, from automated layouts to personalized user experiences. Drawing on case studies and real-world examples, I demonstrated how designers can embrace AI as a powerful collaborator rather than viewing it as a replacement.',\n    videoId: '8WXN9M79ZYA', // YouTube video ID (AI in Web Design talk)\n    thumbnailImage:\n      'https://images.unsplash.com/photo-1587825140708-dfaf72ae4b04?q=80&w=2070&auto=format&fit=crop',\n    slides: '#', // Link to slides\n    resources: '#', // Link to additional resources\n    tags: ['AI', 'Web Design', 'UX', 'Future Trends'],\n  },\n  {\n    id: 2,\n    title: 'Designs That Scale',\n    event: 'DesignOps Global',\n    role: 'Workshop Leader',\n    date: 'September 18, 2023',\n    location: 'Berlin, Germany',\n    duration: '90 min',\n    description:\n      'In this hands-on workshop, I guided participants through the process of creating, implementing, and maintaining design systems for enterprise organizations. We covered everything from component architecture to team workflows, documentation, and scaling strategies.',\n    videoId: 'f1x-g5uTt1E', // YouTube video ID\n    thumbnailImage:\n      'https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?q=80&w=2070&auto=format&fit=crop',\n    slides: '#', // Link to slides\n    resources: '#', // Link to additional resources\n    tags: ['Design Systems', 'DesignOps', 'Enterprise', 'Workflow'],\n  },\n  {\n    id: 3,\n    title: 'Building Accessible Applications',\n    event: 'A11y Summit',\n    role: 'Panel Moderator',\n    date: 'November 12, 2023',\n    location: 'Chicago, IL',\n    duration: '60 min',\n    description:\n      'I moderated this panel discussion with leading accessibility experts, exploring best practices for building truly accessible digital products from the ground up. The conversation covered technical implementation, inclusive design, testing methodologies, and organizational approaches to accessibility.',\n    videoId: 'ZYSceVMX3-U', // YouTube video ID\n    thumbnailImage:\n      'https://images.unsplash.com/photo-1505373877841-8d25f7d46678?q=80&w=2112&auto=format&fit=crop',\n    slides: '#', // Link to slides\n    resources: '#', // Link to additional resources\n    tags: ['Accessibility', 'WCAG', 'Inclusive Design', 'Panel Discussion'],\n  },\n];\n\nexport default function VideoRecordingEmbed() {\n  return (\n    <section className=\"bg-background py-16 md:py-24\">\n      <div className=\"container mx-auto px-4 2xl:max-w-[1400px]\">\n        {/* Section header */}\n        <div className=\"mb-12 text-center md:mb-16\">\n          <Badge className=\"mb-4\" variant=\"outline\">\n            Watch & Learn\n          </Badge>\n          <h2 className=\"text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl\">\n            Speaking Recordings\n          </h2>\n          <p className=\"text-muted-foreground mx-auto mt-4 max-w-2xl text-lg\">\n            Watch recordings of my keynotes, workshops, and panel discussions\n            from events around the world\n          </p>\n        </div>\n\n        <div className=\"mx-auto max-w-5xl\">\n          <Tabs\n            className=\"space-y-8\"\n            defaultValue={featuredRecordings[0]!.id.toString()}\n          >\n            <TabsList className=\"h-fit w-full flex-wrap\">\n              {featuredRecordings.map((recording) => (\n                <TabsTrigger\n                  key={recording.id}\n                  value={recording.id.toString()}\n                  className=\"data-[state=active]:bg-background rounded-md px-3 py-2\"\n                >\n                  <div className=\"text-center\">\n                    <h3 className=\"text-sm font-medium md:text-base\">\n                      {recording.title}\n                    </h3>\n                    <p className=\"text-muted-foreground text-xs\">\n                      {recording.event}\n                    </p>\n                  </div>\n                </TabsTrigger>\n              ))}\n            </TabsList>\n\n            {featuredRecordings.map((recording) => (\n              <TabsContent\n                key={recording.id}\n                value={recording.id.toString()}\n                className=\"mt-6\"\n              >\n                <div className=\"bg-card overflow-hidden rounded-xl border shadow-sm\">\n                  {/* Video embed */}\n                  <div className=\"aspect-video w-full bg-black\">\n                    <iframe\n                      width=\"100%\"\n                      height=\"100%\"\n                      src={`https://www.youtube.com/embed/${recording.videoId}`}\n                      title={recording.title}\n                      frameBorder=\"0\"\n                      allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n                      allowFullScreen\n                    ></iframe>\n                  </div>\n\n                  {/* Content */}\n                  <div className=\"p-6 md:p-8\">\n                    <div className=\"flex flex-wrap items-start justify-between gap-4\">\n                      <div>\n                        <Badge className=\"mb-2\" variant=\"outline\">\n                          {recording.role}\n                        </Badge>\n                        <h3 className=\"mb-1 text-xl font-semibold md:text-2xl\">\n                          {recording.title}\n                        </h3>\n                        <p className=\"text-primary font-medium\">\n                          {recording.event}\n                        </p>\n                      </div>\n                      <div className=\"flex space-x-2\">\n                        <Button variant=\"outline\" size=\"sm\" asChild>\n                          <a\n                            href={recording.slides}\n                            className=\"inline-flex items-center gap-1\"\n                          >\n                            <Download className=\"h-3.5 w-3.5\" />\n                            <span>Slides</span>\n                          </a>\n                        </Button>\n                        <Button variant=\"outline\" size=\"sm\" asChild>\n                          <a\n                            href={recording.resources}\n                            className=\"inline-flex items-center gap-1\"\n                          >\n                            <Download className=\"h-3.5 w-3.5\" />\n                            <span>Resources</span>\n                          </a>\n                        </Button>\n                      </div>\n                    </div>\n\n                    <div className=\"mt-6 mb-6 grid grid-cols-3 gap-4\">\n                      <div className=\"flex flex-col\">\n                        <div className=\"text-muted-foreground mb-1 flex items-center text-xs\">\n                          <Calendar className=\"mr-1.5 h-3.5 w-3.5\" />\n                          Date\n                        </div>\n                        <div className=\"text-sm font-medium\">\n                          {recording.date}\n                        </div>\n                      </div>\n                      <div className=\"flex flex-col\">\n                        <div className=\"text-muted-foreground mb-1 flex items-center text-xs\">\n                          <MapPin className=\"mr-1.5 h-3.5 w-3.5\" />\n                          Location\n                        </div>\n                        <div className=\"text-sm font-medium\">\n                          {recording.location}\n                        </div>\n                      </div>\n                      <div className=\"flex flex-col\">\n                        <div className=\"text-muted-foreground mb-1 flex items-center text-xs\">\n                          <Clock className=\"mr-1.5 h-3.5 w-3.5\" />\n                          Duration\n                        </div>\n                        <div className=\"text-sm font-medium\">\n                          {recording.duration}\n                        </div>\n                      </div>\n                    </div>\n\n                    <div className=\"mb-6\">\n                      <h4 className=\"mb-2 text-lg font-medium\">\n                        About this talk\n                      </h4>\n                      <p className=\"text-muted-foreground text-sm\">\n                        {recording.description}\n                      </p>\n                    </div>\n\n                    <div className=\"flex flex-wrap gap-1.5\">\n                      {recording.tags.map((tag) => (\n                        <Badge\n                          key={tag}\n                          variant=\"secondary\"\n                          className=\"text-xs\"\n                        >\n                          {tag}\n                        </Badge>\n                      ))}\n                    </div>\n                  </div>\n                </div>\n              </TabsContent>\n            ))}\n          </Tabs>\n\n          {/* Other recordings preview */}\n          <div className=\"mt-16\">\n            <div className=\"mb-6 flex items-center justify-between\">\n              <h3 className=\"text-2xl font-semibold\">More Recordings</h3>\n              <Button variant=\"outline\" asChild size=\"sm\">\n                <a href=\"#\" className=\"inline-flex items-center gap-1\">\n                  <span>View all</span>\n                  <ArrowRight className=\"h-3.5 w-3.5\" />\n                </a>\n              </Button>\n            </div>\n\n            <div className=\"grid gap-6 sm:grid-cols-2 lg:grid-cols-3\">\n              {[1, 2, 3].map((index) => (\n                <div\n                  key={`more-${index}`}\n                  className=\"group overflow-hidden rounded-lg border transition-all duration-300 hover:shadow-md\"\n                >\n                  <div className=\"relative aspect-video w-full overflow-hidden\">\n                    <img\n                      src={featuredRecordings[index - 1]!.thumbnailImage}\n                      alt={featuredRecordings[index - 1]!.title}\n                      className=\"object-cover transition-transform duration-500 group-hover:scale-105\"\n                    />\n                    <div className=\"absolute inset-0 flex items-center justify-center bg-black/30 opacity-0 transition-opacity duration-300 group-hover:opacity-100\">\n                      <PlayCircle className=\"h-12 w-12 text-white\" />\n                    </div>\n                  </div>\n                  <div className=\"p-4\">\n                    <h4 className=\"mb-1 line-clamp-1 text-sm font-medium\">\n                      {featuredRecordings[index - 1]!.title}\n                    </h4>\n                    <p className=\"text-muted-foreground text-xs\">\n                      {featuredRecordings[index - 1]!.event}\n                    </p>\n                  </div>\n                </div>\n              ))}\n            </div>\n          </div>\n\n          {/* CTA */}\n          <div className=\"mt-12 text-center\">\n            <Button asChild>\n              <a href=\"#\" className=\"inline-flex items-center gap-2\">\n                <Mic className=\"h-4 w-4\" />\n                <span>Book me for your next event</span>\n              </a>\n            </Button>\n          </div>\n        </div>\n      </div>\n    </section>\n  );\n}\n","type":"registry:component","target":"components/blocks/portfolio/portfolio-event-speaking-and-workshops/video-recording-embed.tsx"},{"path":"components/ui/button.tsx","content":"import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n  \"group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n        outline:\n          \"border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n        ghost:\n          \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n        destructive:\n          \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default:\n          \"h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n        xs: \"h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5\",\n        lg: \"h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n        icon: \"size-9\",\n        \"icon-xs\":\n          \"size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\":\n          \"size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot.Root : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      data-variant={variant}\n      data-size={size}\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n","type":"registry:ui","target":"components/ui/button.tsx"},{"path":"components/ui/badge.tsx","content":"import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst badgeVariants = cva(\n  \"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n        secondary:\n          \"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80\",\n        destructive:\n          \"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20\",\n        outline:\n          \"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground\",\n        ghost:\n          \"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant = \"default\",\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"span\"> &\n  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n  const Comp = asChild ? Slot.Root : \"span\"\n\n  return (\n    <Comp\n      data-slot=\"badge\"\n      data-variant={variant}\n      className={cn(badgeVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { Badge, badgeVariants }\n","type":"registry:ui","target":"components/ui/badge.tsx"},{"path":"components/ui/tabs.tsx","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Tabs as TabsPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Tabs({\n  className,\n  orientation = \"horizontal\",\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.Root>) {\n  return (\n    <TabsPrimitive.Root\n      data-slot=\"tabs\"\n      data-orientation={orientation}\n      className={cn(\n        \"group/tabs flex gap-2 data-horizontal:flex-col\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst tabsListVariants = cva(\n  \"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-9 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-muted\",\n        line: \"gap-1 bg-transparent\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction TabsList({\n  className,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.List> &\n  VariantProps<typeof tabsListVariants>) {\n  return (\n    <TabsPrimitive.List\n      data-slot=\"tabs-list\"\n      data-variant={variant}\n      className={cn(tabsListVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction TabsTrigger({\n  className,\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n  return (\n    <TabsPrimitive.Trigger\n      data-slot=\"tabs-trigger\"\n      className={cn(\n        \"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        \"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent\",\n        \"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground\",\n        \"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TabsContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.Content>) {\n  return (\n    <TabsPrimitive.Content\n      data-slot=\"tabs-content\"\n      className={cn(\"flex-1 text-sm outline-none\", className)}\n      {...props}\n    />\n  )\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }\n","type":"registry:ui","target":"components/ui/tabs.tsx"}],"description":"A section embedding a recorded talk video alongside its title and context. Lets visitors watch you present without ever leaving your portfolio.","dependencies":["class-variance-authority","lucide-react","radix-ui"]}