{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"portfolio-portfolio-blog-writing-and-previews-featured-article-list","type":"registry:block","title":"Featured Article List","files":[{"path":"components/blocks/portfolio/portfolio-blog-writing-and-previews/featured-article-list.tsx","content":"import {\n  Card,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from '@/components/ui/card';\nimport { Button } from '@/components/ui/button';\nimport { CalendarIcon } from 'lucide-react';\n\nexport default function FeaturedArticleList() {\n  // Sample blog posts data\n  const featuredPost = {\n    id: '1',\n    title: 'Creating Accessible Web Applications with React and ARIA',\n    excerpt:\n      'Learn how to build web applications that are accessible to everyone using React best practices and ARIA attributes. This comprehensive guide covers everything from basic accessibility principles to advanced techniques for creating inclusive user experiences.',\n    date: 'Apr 15, 2023',\n    category: 'Development',\n    imageUrl:\n      'https://images.unsplash.com/photo-1593720213428-28a5b9e94613?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',\n    slug: 'creating-accessible-web-applications',\n  };\n\n  const posts = [\n    {\n      id: '2',\n      title: 'The Future of Design Systems in 2023',\n      excerpt:\n        'Explore the trends and innovations shaping design systems and component libraries this year.',\n      date: 'Mar 28, 2023',\n      category: 'Design',\n      imageUrl:\n        'https://images.unsplash.com/photo-1561070791-2526d30994b5?q=80&w=2000&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',\n      slug: 'future-of-design-systems',\n    },\n    {\n      id: '3',\n      title: 'Optimizing Performance in Next.js Applications',\n      excerpt:\n        'Practical strategies to improve loading times and overall performance in your Next.js web applications.',\n      date: 'Mar 12, 2023',\n      category: 'Performance',\n      imageUrl:\n        'https://images.unsplash.com/photo-1460925895917-afdab827c52f?q=80&w=2015&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',\n      slug: 'optimizing-nextjs-performance',\n    },\n    {\n      id: '4',\n      title: 'Crafting Effective User Onboarding Experiences',\n      excerpt:\n        'How to design user onboarding that reduces friction and increases conversion rates for your product.',\n      date: 'Feb 24, 2023',\n      category: 'UX Design',\n      imageUrl:\n        'https://images.unsplash.com/photo-1559028012-481c04fa702d?q=80&w=2036&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',\n      slug: 'effective-user-onboarding',\n    },\n  ];\n\n  const title = 'From the Blog';\n  const description =\n    'Insights, thoughts, and deep dives into my work and expertise';\n\n  return (\n    <section className=\"w-full py-12\">\n      <div className=\"container mx-auto px-4 md:px-6\">\n        <div className=\"flex flex-col items-start gap-4\">\n          <div className=\"space-y-2\">\n            <h2 className=\"text-3xl font-bold tracking-tight\">{title}</h2>\n            <p className=\"text-muted-foreground max-w-[700px]\">{description}</p>\n          </div>\n\n          <div className=\"grid w-full gap-8 pt-4 lg:grid-cols-3\">\n            {/* Featured Article */}\n            <Card className=\"col-span-full flex flex-col overflow-hidden pt-0 lg:col-span-2\">\n              <div className=\"relative aspect-[16/9] w-full overflow-hidden\">\n                <img\n                  src={featuredPost.imageUrl}\n                  alt={featuredPost.title}\n                  className=\"object-cover transition-transform hover:scale-105\"\n                  sizes=\"(max-width: 768px) 100vw, (max-width: 1200px) 66vw, 50vw\"\n                />\n              </div>\n              <CardHeader className=\"flex-1\">\n                <div className=\"text-muted-foreground mb-2 flex items-center gap-2 text-sm\">\n                  <span className=\"flex items-center gap-1\">\n                    <CalendarIcon className=\"h-3 w-3\" />\n                    {featuredPost.date}\n                  </span>\n                  <span>•</span>\n                  <span>{featuredPost.category}</span>\n                </div>\n                <CardTitle className=\"mb-2 text-2xl\">\n                  {featuredPost.title}\n                </CardTitle>\n                <CardDescription className=\"text-base\">\n                  {featuredPost.excerpt}\n                </CardDescription>\n                <Button asChild variant=\"default\" className=\"mt-4 w-fit\">\n                  <a href=\"#\">\n                    Read Article\n                    <span className=\"sr-only\">Read {featuredPost.title}</span>\n                  </a>\n                </Button>\n              </CardHeader>\n            </Card>\n\n            {/* Article List */}\n            <div className=\"col-span-full space-y-4 lg:col-span-1\">\n              <h3 className=\"border-b pb-2 text-lg font-medium\">\n                Recent Articles\n              </h3>\n              <div className=\"space-y-6\">\n                {posts.map((post) => (\n                  <div key={post.id} className=\"group\">\n                    <div className=\"flex items-start gap-4\">\n                      <div className=\"relative h-16 w-16 flex-shrink-0 overflow-hidden rounded-md\">\n                        <img\n                          src={post.imageUrl}\n                          alt={post.title}\n                          className=\"object-cover\"\n                          sizes=\"64px\"\n                        />\n                      </div>\n                      <div className=\"space-y-1\">\n                        <h4 className=\"group-hover:text-primary line-clamp-2 font-medium transition-colors\">\n                          <a href=\"#\" className=\"hover:underline\">\n                            {post.title}\n                          </a>\n                        </h4>\n                        <div className=\"text-muted-foreground flex items-center text-xs\">\n                          <span>{post.date}</span>\n                          <span className=\"mx-1\">•</span>\n                          <span>{post.category}</span>\n                        </div>\n                      </div>\n                    </div>\n                  </div>\n                ))}\n              </div>\n              <Button asChild variant=\"outline\" className=\"w-full\">\n                <a href=\"#\">View All Posts</a>\n              </Button>\n            </div>\n          </div>\n        </div>\n      </div>\n    </section>\n  );\n}\n","type":"registry:component","target":"components/blocks/portfolio/portfolio-blog-writing-and-previews/featured-article-list.tsx"},{"path":"components/ui/card.tsx","content":"import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Card({\n  className,\n  size = \"default\",\n  ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n  return (\n    <div\n      data-slot=\"card\"\n      data-size={size}\n      className={cn(\n        \"group/card flex flex-col gap-6 overflow-hidden rounded-xl bg-card py-6 text-sm text-card-foreground shadow-xs ring-1 ring-foreground/10 has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-header\"\n      className={cn(\n        \"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-6 group-data-[size=sm]/card:px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-6 group-data-[size=sm]/card:[.border-b]:pb-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-title\"\n      className={cn(\n        \"font-heading text-base leading-normal font-medium group-data-[size=sm]/card:text-sm\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-description\"\n      className={cn(\"text-sm text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-action\"\n      className={cn(\n        \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-content\"\n      className={cn(\"px-6 group-data-[size=sm]/card:px-4\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-footer\"\n      className={cn(\n        \"flex items-center rounded-b-xl px-6 group-data-[size=sm]/card:px-4 [.border-t]:pt-6 group-data-[size=sm]/card:[.border-t]:pt-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Card,\n  CardHeader,\n  CardFooter,\n  CardTitle,\n  CardAction,\n  CardDescription,\n  CardContent,\n}\n","type":"registry:ui","target":"components/ui/card.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"}],"description":"A list that leads with one large featured article followed by smaller entries. Use it to spotlight your best post while listing recent writing.","dependencies":["class-variance-authority","lucide-react","radix-ui"]}