{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"portfolio-portfolio-case-studies-side-by-side-image-story","type":"registry:block","title":"Side By Side Image Story","files":[{"path":"components/blocks/portfolio/portfolio-case-studies/side-by-side-image-story.tsx","content":"import { ArrowRight } 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 case study data\nconst caseStudy = {\n  title: 'E-Commerce Platform Redesign',\n  client: 'RetailTech Inc.',\n  category: 'UX/UI Design',\n  year: '2023',\n  duration: '12 weeks',\n  summary:\n    'A complete overhaul of an outdated e-commerce platform, focusing on improving user experience and increasing conversion rates through user-centered design principles.',\n  mainImage:\n    'https://images.unsplash.com/photo-1661956602153-23384936a1d3?q=80&w=2070&auto=format&fit=crop',\n  sections: [\n    {\n      id: 'challenge',\n      title: 'The Challenge',\n      content:\n        'RetailTech Inc. approached me to redesign their outdated e-commerce platform which was suffering from poor conversion rates, high cart abandonment, and frustrated users. The existing platform was built over 5 years ago and had become difficult to navigate with an outdated interface. Key issues included a complicated checkout process, poor mobile experience, and lack of personalization features.',\n      image:\n        'https://images.unsplash.com/photo-1586717791821-3f44a563fa4c?q=80&w=2070&auto=format&fit=crop',\n      bullets: [\n        'Cart abandonment rate of over 75%',\n        'Mobile conversion rate 65% lower than desktop',\n        'Customer satisfaction score of only 3.2/10',\n        'Outdated visual design creating trust issues',\n      ],\n    },\n    {\n      id: 'discovery',\n      title: 'Discovery & Research',\n      content:\n        'I began with extensive user research to understand pain points and expectations. This included user interviews, usability testing of the existing platform, competitive analysis, and a comprehensive review of analytics data. The research phase revealed critical insights into user behavior, preferences, and frustrations with the current platform.',\n      image:\n        'https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?q=80&w=2070&auto=format&fit=crop',\n      bullets: [\n        'Conducted 12 user interviews with diverse customer segments',\n        'Analyzed heatmaps and user recordings from over 2,000 sessions',\n        'Performed competitive analysis of 5 leading e-commerce platforms',\n        'Created detailed user personas and journey maps',\n      ],\n    },\n    {\n      id: 'strategy',\n      title: 'Strategy & Planning',\n      content:\n        'Based on research findings, I developed a comprehensive UX strategy to address key pain points and business objectives. The strategy focused on simplifying the shopping journey, enhancing product discovery, streamlining checkout, and implementing a mobile-first approach to ensure a seamless experience across all devices.',\n      image:\n        'https://images.unsplash.com/photo-1553877522-43269d4ea984?q=80&w=2070&auto=format&fit=crop',\n      bullets: [\n        'Developed a comprehensive information architecture',\n        'Created user flows focusing on critical conversion paths',\n        'Established UX principles and design patterns',\n        'Identified key performance metrics for measuring success',\n      ],\n    },\n    {\n      id: 'design',\n      title: 'Design & Prototyping',\n      content:\n        'The design phase involved creating wireframes, high-fidelity mockups, and interactive prototypes. I implemented a clean, modern aesthetic with a focus on usability, accessibility, and conversion optimization. Key features included a streamlined checkout process, enhanced product filtering, and personalized recommendations.',\n      image:\n        'https://images.unsplash.com/photo-1581291518633-83b4ebd1d83e?q=80&w=2070&auto=format&fit=crop',\n      bullets: [\n        'Created wireframes for key user flows',\n        'Developed a comprehensive design system for consistency',\n        'Built interactive prototypes for usability testing',\n        'Implemented accessibility standards throughout the design',\n      ],\n    },\n    {\n      id: 'testing',\n      title: 'Testing & Iteration',\n      content:\n        'Rigorous testing was conducted throughout the design process to validate assumptions and refine the user experience. This included moderated usability testing, A/B testing of key elements, and gathering feedback from stakeholders. Each round of testing informed iterations and refinements to the design.',\n      image:\n        'https://images.unsplash.com/photo-1592659762303-90081d34b277?q=80&w=2069&auto=format&fit=crop',\n      bullets: [\n        'Conducted 3 rounds of usability testing with 8 participants per round',\n        'Performed A/B testing on critical conversion elements',\n        'Gathered feedback from key stakeholders and internal teams',\n        'Made data-driven refinements based on testing insights',\n      ],\n    },\n    {\n      id: 'results',\n      title: 'Results & Impact',\n      content:\n        'The redesigned platform launched successfully and delivered significant improvements across all key metrics. The new design not only improved the user experience but also drove substantial business outcomes, demonstrating the value of a user-centered design approach.',\n      image:\n        'https://images.unsplash.com/photo-1551288049-bebda4e38f71?q=80&w=2070&auto=format&fit=crop',\n      bullets: [\n        '43% increase in conversion rate',\n        '27% reduction in cart abandonment',\n        '58% increase in mobile sales',\n        'Customer satisfaction score improved from 3.2/10 to 8.7/10',\n      ],\n    },\n  ],\n  testimonial: {\n    quote:\n      'The redesigned platform has transformed our business. Not only have we seen dramatic improvements in conversion rates and sales, but our team finds the new admin interface much easier to use. This project has delivered ROI beyond our expectations.',\n    author: 'Sarah Johnson',\n    role: 'E-Commerce Director, RetailTech Inc.',\n  },\n  tools: ['Figma', 'Adobe XD', 'InVision', 'UserTesting'],\n  tags: ['UX Research', 'UI Design', 'E-commerce', 'Conversion Optimization'],\n  link: '#',\n};\n\nexport default function SideBySideImageStory() {\n  return (\n    <section className=\"bg-background py-16 md:py-24\">\n      <div className=\"container mx-auto px-4 md:px-6 2xl:max-w-[1400px]\">\n        {/* Case Study Header */}\n        <div className=\"mb-12 md:mb-16\">\n          <div className=\"grid grid-cols-1 gap-8 md:grid-cols-2\">\n            <div>\n              <div className=\"mb-4 flex flex-wrap gap-2\">\n                {caseStudy.tags.map((tag) => (\n                  <Badge key={tag} variant=\"secondary\" className=\"text-xs\">\n                    {tag}\n                  </Badge>\n                ))}\n              </div>\n              <h1 className=\"mb-4 text-3xl font-bold tracking-tight sm:text-4xl md:text-5xl\">\n                {caseStudy.title}\n              </h1>\n              <div className=\"mb-4 flex flex-wrap gap-6 text-sm\">\n                <div>\n                  <p className=\"text-muted-foreground font-medium\">Client</p>\n                  <p>{caseStudy.client}</p>\n                </div>\n                <div>\n                  <p className=\"text-muted-foreground font-medium\">Timeline</p>\n                  <p>{caseStudy.duration}</p>\n                </div>\n                <div>\n                  <p className=\"text-muted-foreground font-medium\">Year</p>\n                  <p>{caseStudy.year}</p>\n                </div>\n              </div>\n              <p className=\"text-muted-foreground text-lg\">\n                {caseStudy.summary}\n              </p>\n            </div>\n            <div className=\"relative aspect-[4/3] overflow-hidden rounded-lg shadow-lg\">\n              <img\n                src={caseStudy.mainImage}\n                alt={caseStudy.title}\n                className=\"object-cover\"\n              />\n            </div>\n          </div>\n        </div>\n\n        {/* Case Study Navigation */}\n        <div className=\"mb-12\">\n          <Tabs defaultValue=\"challenge\" className=\"w-full\">\n            <div className=\"mb-6 overflow-auto\">\n              <TabsList className=\"inline-flex h-10 w-auto\">\n                {caseStudy.sections.map((section) => (\n                  <TabsTrigger\n                    key={section.id}\n                    value={section.id}\n                    className=\"px-4 whitespace-nowrap\"\n                  >\n                    {section.title}\n                  </TabsTrigger>\n                ))}\n              </TabsList>\n            </div>\n\n            {/* Tab Content */}\n            {caseStudy.sections.map((section, index) => (\n              <TabsContent key={section.id} value={section.id} className=\"m-0\">\n                <div\n                  className={`grid grid-cols-1 gap-8 md:grid-cols-2 ${\n                    index % 2 !== 0 ? 'md:grid-flow-col-reverse' : ''\n                  }`}\n                >\n                  {/* Image Column (switches sides every other section) */}\n                  <div\n                    className={`${\n                      index % 2 !== 0 ? 'md:order-2' : 'md:order-1'\n                    }`}\n                  >\n                    <div className=\"relative aspect-[4/3] overflow-hidden rounded-lg shadow-lg\">\n                      <img\n                        src={section.image}\n                        alt={section.title}\n                        className=\"object-cover\"\n                      />\n                    </div>\n                  </div>\n\n                  {/* Content Column */}\n                  <div\n                    className={`${\n                      index % 2 !== 0 ? 'md:order-1' : 'md:order-2'\n                    }`}\n                  >\n                    <h2 className=\"mb-4 text-2xl font-bold sm:text-3xl\">\n                      {section.title}\n                    </h2>\n                    <p className=\"mb-6 text-base leading-relaxed sm:text-lg\">\n                      {section.content}\n                    </p>\n\n                    {section.bullets && (\n                      <div className=\"mt-6\">\n                        <h3 className=\"mb-3 text-lg font-semibold\">\n                          Key Points:\n                        </h3>\n                        <ul className=\"space-y-2\">\n                          {section.bullets.map((bullet, idx) => (\n                            <li key={idx} className=\"flex items-start gap-3\">\n                              <span className=\"bg-primary/10 text-primary flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full text-xs font-medium\">\n                                {idx + 1}\n                              </span>\n                              <span>{bullet}</span>\n                            </li>\n                          ))}\n                        </ul>\n                      </div>\n                    )}\n                  </div>\n                </div>\n              </TabsContent>\n            ))}\n          </Tabs>\n        </div>\n\n        {/* Testimonial */}\n        <div className=\"mx-auto mb-12 max-w-3xl\">\n          <div className=\"bg-muted/50 relative rounded-lg p-6 shadow-sm md:p-8\">\n            <div className=\"text-primary mb-4 text-4xl\">&quot;</div>\n            <blockquote className=\"mb-6 text-lg italic\">\n              {caseStudy.testimonial.quote}\n            </blockquote>\n            <div>\n              <div className=\"font-semibold\">\n                {caseStudy.testimonial.author}\n              </div>\n              <div className=\"text-muted-foreground text-sm\">\n                {caseStudy.testimonial.role}\n              </div>\n            </div>\n          </div>\n        </div>\n\n        {/* Tools & CTA */}\n        <div className=\"mx-auto max-w-2xl text-center\">\n          <div className=\"mb-8\">\n            <h3 className=\"mb-4 text-xl font-semibold\">\n              Tools & Technologies Used\n            </h3>\n            <div className=\"flex flex-wrap justify-center gap-2\">\n              {caseStudy.tools.map((tool) => (\n                <Badge key={tool} variant=\"outline\">\n                  {tool}\n                </Badge>\n              ))}\n            </div>\n          </div>\n\n          <Button asChild size=\"lg\">\n            <a href={caseStudy.link} className=\"flex items-center gap-2\">\n              <span>View Full Case Study</span>\n              <ArrowRight className=\"h-4 w-4\" />\n            </a>\n          </Button>\n        </div>\n      </div>\n    </section>\n  );\n}\n","type":"registry:component","target":"components/blocks/portfolio/portfolio-case-studies/side-by-side-image-story.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 two column block placing a project image beside its written story. Pairs visuals and narrative to walk readers through a single case study.","dependencies":["class-variance-authority","lucide-react","radix-ui"]}