     1→import * as React from "react"
     2→
     3→import { cn } from "@/lib/utils"
     4→
     5→function Card({ className, ...props }: React.ComponentProps<"div">) {
     6→  return (
     7→    <div
     8→      data-slot="card"
     9→      className={cn(
    10→        "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
    11→        className
    12→      )}
    13→      {...props}
    14→    />
    15→  )
    16→}
    17→
    18→function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
    19→  return (
    20→    <div
    21→      data-slot="card-header"
    22→      className={cn(
    23→        "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
    24→        className
    25→      )}
    26→      {...props}
    27→    />
    28→  )
    29→}
    30→
    31→function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
    32→  return (
    33→    <div
    34→      data-slot="card-title"
    35→      className={cn("leading-none font-semibold", className)}
    36→      {...props}
    37→    />
    38→  )
    39→}
    40→
    41→function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
    42→  return (
    43→    <div
    44→      data-slot="card-description"
    45→      className={cn("text-muted-foreground text-sm", className)}
    46→      {...props}
    47→    />
    48→  )
    49→}
    50→
    51→function CardAction({ className, ...props }: React.ComponentProps<"div">) {
    52→  return (
    53→    <div
    54→      data-slot="card-action"
    55→      className={cn(
    56→        "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
    57→        className
    58→      )}
    59→      {...props}
    60→    />
    61→  )
    62→}
    63→
    64→function CardContent({ className, ...props }: React.ComponentProps<"div">) {
    65→  return (
    66→    <div
    67→      data-slot="card-content"
    68→      className={cn("px-6", className)}
    69→      {...props}
    70→    />
    71→  )
    72→}
    73→
    74→function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
    75→  return (
    76→    <div
    77→      data-slot="card-footer"
    78→      className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
    79→      {...props}
    80→    />
    81→  )
    82→}
    83→
    84→export {
    85→  Card,
    86→  CardHeader,
    87→  CardFooter,
    88→  CardTitle,
    89→  CardAction,
    90→  CardDescription,
    91→  CardContent,
    92→}
    93→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→import * as React from "react"
     2→
     3→import { cn } from "@/lib/utils"
     4→
     5→function Input({ className, type, ...props }: React.ComponentProps<"input">) {
     6→  return (
     7→    <input
     8→      type={type}
     9→      data-slot="input"
    10→      className={cn(
    11→        "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
    12→        "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
    13→        "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
    14→        className
    15→      )}
    16→      {...props}
    17→    />
    18→  )
    19→}
    20→
    21→export { Input }
    22→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→"use client"
     2→
     3→import * as React from "react"
     4→import { Label as LabelPrimitive } from "radix-ui"
     5→
     6→import { cn } from "@/lib/utils"
     7→
     8→function Label({
     9→  className,
    10→  ...props
    11→}: React.ComponentProps<typeof LabelPrimitive.Root>) {
    12→  return (
    13→    <LabelPrimitive.Root
    14→      data-slot="label"
    15→      className={cn(
    16→        "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
    17→        className
    18→      )}
    19→      {...props}
    20→    />
    21→  )
    22→}
    23→
    24→export { Label }
    25→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→"use client"
     2→
     3→import * as React from "react"
     4→import { cva, type VariantProps } from "class-variance-authority"
     5→import { Tabs as TabsPrimitive } from "radix-ui"
     6→
     7→import { cn } from "@/lib/utils"
     8→
     9→function Tabs({
    10→  className,
    11→  orientation = "horizontal",
    12→  ...props
    13→}: React.ComponentProps<typeof TabsPrimitive.Root>) {
    14→  return (
    15→    <TabsPrimitive.Root
    16→      data-slot="tabs"
    17→      data-orientation={orientation}
    18→      orientation={orientation}
    19→      className={cn(
    20→        "group/tabs flex gap-2 data-[orientation=horizontal]:flex-col",
    21→        className
    22→      )}
    23→      {...props}
    24→    />
    25→  )
    26→}
    27→
    28→const tabsListVariants = cva(
    29→  "rounded-lg p-[3px] group-data-[orientation=horizontal]/tabs:h-9 data-[variant=line]:rounded-none group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
    30→  {
    31→    variants: {
    32→      variant: {
    33→        default: "bg-muted",
    34→        line: "gap-1 bg-transparent",
    35→      },
    36→    },
    37→    defaultVariants: {
    38→      variant: "default",
    39→    },
    40→  }
    41→)
    42→
    43→function TabsList({
    44→  className,
    45→  variant = "default",
    46→  ...props
    47→}: React.ComponentProps<typeof TabsPrimitive.List> &
    48→  VariantProps<typeof tabsListVariants>) {
    49→  return (
    50→    <TabsPrimitive.List
    51→      data-slot="tabs-list"
    52→      data-variant={variant}
    53→      className={cn(tabsListVariants({ variant }), className)}
    54→      {...props}
    55→    />
    56→  )
    57→}
    58→
    59→function TabsTrigger({
    60→  className,
    61→  ...props
    62→}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
    63→  return (
    64→    <TabsPrimitive.Trigger
    65→      data-slot="tabs-trigger"
    66→      className={cn(
    67→        "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground 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 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
    68→        "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
    69→        "data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground",
    70→        "after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",
    71→        className
    72→      )}
    73→      {...props}
    74→    />
    75→  )
    76→}
    77→
    78→function TabsContent({
    79→  className,
    80→  ...props
    81→}: React.ComponentProps<typeof TabsPrimitive.Content>) {
    82→  return (
    83→    <TabsPrimitive.Content
    84→      data-slot="tabs-content"
    85→      className={cn("flex-1 outline-none", className)}
    86→      {...props}
    87→    />
    88→  )
    89→}
    90→
    91→export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
    92→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→import * as React from "react"
     2→import { cva, type VariantProps } from "class-variance-authority"
     3→import { Slot } from "radix-ui"
     4→
     5→import { cn } from "@/lib/utils"
     6→
     7→const badgeVariants = cva(
     8→  "inline-flex items-center justify-center rounded-full border border-transparent px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
     9→  {
    10→    variants: {
    11→      variant: {
    12→        default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
    13→        secondary:
    14→          "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
    15→        destructive:
    16→          "bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
    17→        outline:
    18→          "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
    19→        ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
    20→        link: "text-primary underline-offset-4 [a&]:hover:underline",
    21→      },
    22→    },
    23→    defaultVariants: {
    24→      variant: "default",
    25→    },
    26→  }
    27→)
    28→
    29→function Badge({
    30→  className,
    31→  variant = "default",
    32→  asChild = false,
    33→  ...props
    34→}: React.ComponentProps<"span"> &
    35→  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
    36→  const Comp = asChild ? Slot.Root : "span"
    37→
    38→  return (
    39→    <Comp
    40→      data-slot="badge"
    41→      data-variant={variant}
    42→      className={cn(badgeVariants({ variant }), className)}
    43→      {...props}
    44→    />
    45→  )
    46→}
    47→
    48→export { Badge, badgeVariants }
    49→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→"use client"
     2→
     3→import * as React from "react"
     4→import { Separator as SeparatorPrimitive } from "radix-ui"
     5→
     6→import { cn } from "@/lib/utils"
     7→
     8→function Separator({
     9→  className,
    10→  orientation = "horizontal",
    11→  decorative = true,
    12→  ...props
    13→}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
    14→  return (
    15→    <SeparatorPrimitive.Root
    16→      data-slot="separator"
    17→      decorative={decorative}
    18→      orientation={orientation}
    19→      className={cn(
    20→        "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
    21→        className
    22→      )}
    23→      {...props}
    24→    />
    25→  )
    26→}
    27→
    28→export { Separator }
    29→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→"use client"
     2→
     3→import * as React from "react"
     4→import { XIcon } from "lucide-react"
     5→import { Dialog as SheetPrimitive } from "radix-ui"
     6→
     7→import { cn } from "@/lib/utils"
     8→
     9→function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
    10→  return <SheetPrimitive.Root data-slot="sheet" {...props} />
    11→}
    12→
    13→function SheetTrigger({
    14→  ...props
    15→}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
    16→  return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
    17→}
    18→
    19→function SheetClose({
    20→  ...props
    21→}: React.ComponentProps<typeof SheetPrimitive.Close>) {
    22→  return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
    23→}
    24→
    25→function SheetPortal({
    26→  ...props
    27→}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
    28→  return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
    29→}
    30→
    31→function SheetOverlay({
    32→  className,
    33→  ...props
    34→}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
    35→  return (
    36→    <SheetPrimitive.Overlay
    37→      data-slot="sheet-overlay"
    38→      className={cn(
    39→        "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
    40→        className
    41→      )}
    42→      {...props}
    43→    />
    44→  )
    45→}
    46→
    47→function SheetContent({
    48→  className,
    49→  children,
    50→  side = "right",
    51→  showCloseButton = true,
    52→  ...props
    53→}: React.ComponentProps<typeof SheetPrimitive.Content> & {
    54→  side?: "top" | "right" | "bottom" | "left"
    55→  showCloseButton?: boolean
    56→}) {
    57→  return (
    58→    <SheetPortal>
    59→      <SheetOverlay />
    60→      <SheetPrimitive.Content
    61→        data-slot="sheet-content"
    62→        className={cn(
    63→          "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
    64→          side === "right" &&
    65→            "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
    66→          side === "left" &&
    67→            "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
    68→          side === "top" &&
    69→            "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
    70→          side === "bottom" &&
    71→            "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
    72→          className
    73→        )}
    74→        {...props}
    75→      >
    76→        {children}
    77→        {showCloseButton && (
    78→          <SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
    79→            <XIcon className="size-4" />
    80→            Close
    81→          </SheetPrimitive.Close>
    82→        )}
    83→      </SheetPrimitive.Content>
    84→    </SheetPortal>
    85→  )
    86→}
    87→
    88→function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
    89→  return (
    90→

    95→  )
    96→}
    97→
    98→function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
    99→  return (
   100→

   105→  )
   106→}
   107→
   108→function SheetTitle({
   109→  className,
   110→  ...props
   111→}: React.ComponentProps<typeof SheetPrimitive.Title>) {
   112→  return (
   113→    <SheetPrimitive.Title
   114→      data-slot="sheet-title"
   115→      className={cn("text-foreground font-semibold", className)}
   116→      {...props}
   117→    />
   118→  )
   119→}
   120→
   121→function SheetDescription({
   122→  className,
   123→  ...props
   124→}: React.ComponentProps<typeof SheetPrimitive.Description>) {
   125→  return (
   126→    <SheetPrimitive.Description
   127→      data-slot="sheet-description"
   128→      className={cn("text-muted-foreground text-sm", className)}
   129→      {...props}
   130→    />
   131→  )
   132→}
   133→
   134→export {
   135→  Sheet,
   136→  SheetTrigger,
   137→  SheetClose,
   138→  SheetContent,
   139→  SheetHeader,
   140→  SheetFooter,
   141→  SheetTitle,
   142→  SheetDescription,
   143→}
   144→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→"use client"
     2→
     3→import * as React from "react"
     4→import { XIcon } from "lucide-react"
     5→import { Dialog as DialogPrimitive } from "radix-ui"
     6→
     7→import { cn } from "@/lib/utils"
     8→import { Button } from "@/components/ui/button"
     9→
    10→function Dialog({
    11→  ...props
    12→}: React.ComponentProps<typeof DialogPrimitive.Root>) {
    13→  return <DialogPrimitive.Root data-slot="dialog" {...props} />
    14→}
    15→
    16→function DialogTrigger({
    17→  ...props
    18→}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
    19→  return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
    20→}
    21→
    22→function DialogPortal({
    23→  ...props
    24→}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
    25→  return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
    26→}
    27→
    28→function DialogClose({
    29→  ...props
    30→}: React.ComponentProps<typeof DialogPrimitive.Close>) {
    31→  return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
    32→}
    33→
    34→function DialogOverlay({
    35→  className,
    36→  ...props
    37→}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
    38→  return (
    39→    <DialogPrimitive.Overlay
    40→      data-slot="dialog-overlay"
    41→      className={cn(
    42→        "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
    43→        className
    44→      )}
    45→      {...props}
    46→    />
    47→  )
    48→}
    49→
    50→function DialogContent({
    51→  className,
    52→  children,
    53→  showCloseButton = true,
    54→  ...props
    55→}: React.ComponentProps<typeof DialogPrimitive.Content> & {
    56→  showCloseButton?: boolean
    57→}) {
    58→  return (
    59→    <DialogPortal data-slot="dialog-portal">
    60→      <DialogOverlay />
    61→      <DialogPrimitive.Content
    62→        data-slot="dialog-content"
    63→        className={cn(
    64→          "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
    65→          className
    66→        )}
    67→        {...props}
    68→      >
    69→        {children}
    70→        {showCloseButton && (
    71→          <DialogPrimitive.Close
    72→            data-slot="dialog-close"
    73→            className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
    74→          >
    75→            <XIcon />
    76→            Close
    77→          </DialogPrimitive.Close>
    78→        )}
    79→      </DialogPrimitive.Content>
    80→    </DialogPortal>
    81→  )
    82→}
    83→
    84→function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
    85→  return (
    86→

    91→  )
    92→}
    93→
    94→function DialogFooter({
    95→  className,
    96→  showCloseButton = false,
    97→  children,
    98→  ...props
    99→}: React.ComponentProps<"div"> & {
   100→  showCloseButton?: boolean
   101→}) {
   102→  return (
   103→

   111→      {children}
   112→      {showCloseButton && (
   113→        <DialogPrimitive.Close asChild>
   114→          <Button variant="outline">Close</Button>
   115→        </DialogPrimitive.Close>
   116→      )}
   117→

   118→  )
   119→}
   120→
   121→function DialogTitle({
   122→  className,
   123→  ...props
   124→}: React.ComponentProps<typeof DialogPrimitive.Title>) {
   125→  return (
   126→    <DialogPrimitive.Title
   127→      data-slot="dialog-title"
   128→      className={cn("text-lg leading-none font-semibold", className)}
   129→      {...props}
   130→    />
   131→  )
   132→}
   133→
   134→function DialogDescription({
   135→  className,
   136→  ...props
   137→}: React.ComponentProps<typeof DialogPrimitive.Description>) {
   138→  return (
   139→    <DialogPrimitive.Description
   140→      data-slot="dialog-description"
   141→      className={cn("text-muted-foreground text-sm", className)}
   142→      {...props}
   143→    />
   144→  )
   145→}
   146→
   147→export {
   148→  Dialog,
   149→  DialogClose,
   150→  DialogContent,
   151→  DialogDescription,
   152→  DialogFooter,
   153→  DialogHeader,
   154→  DialogOverlay,
   155→  DialogPortal,
   156→  DialogTitle,
   157→  DialogTrigger,
   158→}
   159→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→"use client"
     2→
     3→import * as React from "react"
     4→import type { Label as LabelPrimitive } from "radix-ui"
     5→import { Slot } from "radix-ui"
     6→import {
     7→  Controller,
     8→  FormProvider,
     9→  useFormContext,
    10→  useFormState,
    11→  type ControllerProps,
    12→  type FieldPath,
    13→  type FieldValues,
    14→} from "react-hook-form"
    15→
    16→import { cn } from "@/lib/utils"
    17→import { Label } from "@/components/ui/label"
    18→
    19→const Form = FormProvider
    20→
    21→type FormFieldContextValue<
    22→  TFieldValues extends FieldValues = FieldValues,
    23→  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
    24→> = {
    25→  name: TName
    26→}
    27→
    28→const FormFieldContext = React.createContext<FormFieldContextValue>(
    29→  {} as FormFieldContextValue
    30→)
    31→
    32→const FormField = <
    33→  TFieldValues extends FieldValues = FieldValues,
    34→  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
    35→>({
    36→  ...props
    37→}: ControllerProps<TFieldValues, TName>) => {
    38→  return (
    39→    <FormFieldContext.Provider value={{ name: props.name }}>
    40→      <Controller {...props} />
    41→    </FormFieldContext.Provider>
    42→  )
    43→}
    44→
    45→const useFormField = () => {
    46→  const fieldContext = React.useContext(FormFieldContext)
    47→  const itemContext = React.useContext(FormItemContext)
    48→  const { getFieldState } = useFormContext()
    49→  const formState = useFormState({ name: fieldContext.name })
    50→  const fieldState = getFieldState(fieldContext.name, formState)
    51→
    52→  if (!fieldContext) {
    53→    throw new Error("useFormField should be used within <FormField>")
    54→  }
    55→
    56→  const { id } = itemContext
    57→
    58→  return {
    59→    id,
    60→    name: fieldContext.name,
    61→    formItemId: `${id}-form-item`,
    62→    formDescriptionId: `${id}-form-item-description`,
    63→    formMessageId: `${id}-form-item-message`,
    64→    ...fieldState,
    65→  }
    66→}
    67→
    68→type FormItemContextValue = {
    69→  id: string
    70→}
    71→
    72→const FormItemContext = React.createContext<FormItemContextValue>(
    73→  {} as FormItemContextValue
    74→)
    75→
    76→function FormItem({ className, ...props }: React.ComponentProps<"div">) {
    77→  const id = React.useId()
    78→
    79→  return (
    80→    <FormItemContext.Provider value={{ id }}>
    81→      <div
    82→        data-slot="form-item"
    83→        className={cn("grid gap-2", className)}
    84→        {...props}
    85→      />
    86→    </FormItemContext.Provider>
    87→  )
    88→}
    89→
    90→function FormLabel({
    91→  className,
    92→  ...props
    93→}: React.ComponentProps<typeof LabelPrimitive.Root>) {
    94→  const { error, formItemId } = useFormField()
    95→
    96→  return (
    97→    <Label
    98→      data-slot="form-label"
    99→      data-error={!!error}
   100→      className={cn("data-[error=true]:text-destructive", className)}
   101→      htmlFor={formItemId}
   102→      {...props}
   103→    />
   104→  )
   105→}
   106→
   107→function FormControl({ ...props }: React.ComponentProps<typeof Slot.Root>) {
   108→  const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
   109→
   110→  return (
   111→    <Slot.Root
   112→      data-slot="form-control"
   113→      id={formItemId}
   114→      aria-describedby={
   115→        !error
   116→          ? `${formDescriptionId}`
   117→          : `${formDescriptionId} ${formMessageId}`
   118→      }
   119→      aria-invalid={!!error}
   120→      {...props}
   121→    />
   122→  )
   123→}
   124→
   125→function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
   126→  const { formDescriptionId } = useFormField()
   127→
   128→  return (
   129→    <p
   130→      data-slot="form-description"
   131→      id={formDescriptionId}
   132→      className={cn("text-muted-foreground text-sm", className)}
   133→      {...props}
   134→    />
   135→  )
   136→}
   137→
   138→function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
   139→  const { error, formMessageId } = useFormField()
   140→  const body = error ? String(error?.message ?? "") : props.children
   141→
   142→  if (!body) {
   143→    return null
   144→  }
   145→
   146→  return (
   147→    <p
   148→      data-slot="form-message"
   149→      id={formMessageId}
   150→      className={cn("text-destructive text-sm", className)}
   151→      {...props}
   152→    >
   153→      {body}
   154→    </p>
   155→  )
   156→}
   157→
   158→export {
   159→  useFormField,
   160→  Form,
   161→  FormItem,
   162→  FormLabel,
   163→  FormControl,
   164→  FormDescription,
   165→  FormMessage,
   166→  FormField,
   167→}
   168→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→"use client";
     2→
     3→import { useRouter } from "next/navigation";
     4→import { createClient } from "@/lib/supabase/client";
     5→import { Button } from "@/components/ui/button";
     6→import { LogOut } from "lucide-react";
     7→
     8→export function SignOutButton() {
     9→  const router = useRouter();
    10→  const supabase = createClient();
    11→
    12→  async function handleSignOut() {
    13→    await supabase.auth.signOut();
    14→    router.push("/");
    15→    router.refresh();
    16→  }
    17→
    18→  return (
    19→    <Button variant="ghost" size="icon" onClick={handleSignOut} title="Sign out">
    20→      <LogOut className="h-4 w-4" />
    21→    </Button>
    22→  );
    23→}
    24→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→"use client";
     2→
     3→import Link from "next/link";
     4→import { usePathname } from "next/navigation";
     5→import { Home, Briefcase, Plus, MessageSquare, User } from "lucide-react";
     6→import { cn } from "@/lib/utils";
     7→
     8→interface BottomNavProps {
     9→  userType: "contractor" | "worker";
    10→}
    11→
    12→export function BottomNav({ userType }: BottomNavProps) {
    13→  const pathname = usePathname();
    14→
    15→  const isContractor = userType === "contractor";
    16→
    17→  const links = [
    18→    {
    19→      href: "/dashboard",
    20→      label: "Home",
    21→      icon: Home,
    22→    },
    23→    {
    24→      href: isContractor ? "/contractor/matches" : "/worker/jobs",
    25→      label: "Jobs",
    26→      icon: Briefcase,
    27→    },
    28→    {
    29→      href: isContractor ? "/contractor/post-job" : "/worker/jobs",
    30→      label: "Post",
    31→      icon: Plus,
    32→      isCenter: isContractor,
    33→    },
    34→    {
    35→      href: "/messages",
    36→      label: "Messages",
    37→      icon: MessageSquare,
    38→    },
    39→    {
    40→      href: "/profile",
    41→      label: "Profile",
    42→      icon: User,
    43→    },
    44→  ];
    45→
    46→  // Workers don't get the center "Post" button — replace with different layout
    47→  const workerLinks = [
    48→    {
    49→      href: "/dashboard",
    50→      label: "Home",
    51→      icon: Home,
    52→    },
    53→    {
    54→      href: "/worker/jobs",
    55→      label: "Jobs",
    56→      icon: Briefcase,
    57→    },
    58→    {
    59→      href: "/messages",
    60→      label: "Messages",
    61→      icon: MessageSquare,
    62→    },
    63→    {
    64→      href: "/profile",
    65→      label: "Profile",
    66→      icon: User,
    67→    },
    68→  ];
    69→
    70→  const navLinks = isContractor ? links : workerLinks;
    71→
    72→  return (
    73→
    74→

    75→        {navLinks.map((link) => {
    76→          const isActive =
    77→            pathname === link.href ||
    78→            (link.href !== "/dashboard" && pathname.startsWith(link.href));
    79→          const Icon = link.icon;
    80→
    81→          if ("isCenter" in link && link.isCenter) {
    82→            return (
    83→              <Link
    84→                key={link.href}
    85→                href={link.href}
    86→                className="flex -mt-4 items-center justify-center"
    87→              >
    88→

    89→                  <Icon className="h-7 w-7 text-primary-foreground" />
    90→

    91→              </Link>
    92→            );
    93→          }
    94→
    95→          return (
    96→            <Link
    97→              key={link.href + link.label}
    98→              href={link.href}
    99→              className={cn(
   100→                "flex min-w-[4rem] flex-col items-center gap-0.5 py-2 text-xs transition-colors active:scale-95",
   101→                isActive
   102→                  ? "text-primary font-medium"
   103→                  : "text-muted-foreground"
   104→              )}
   105→            >
   106→              <Icon className="h-5 w-5" />
   107→              {link.label}
   108→            </Link>
   109→          );
   110→        })}
   111→

   112→
   113→  );
   114→}
   115→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→"use client";
     2→
     3→import { BottomNav } from "@/components/bottom-nav";
     4→
     5→interface BottomNavWrapperProps {
     6→  userType: "contractor" | "worker";
     7→}
     8→
     9→export function BottomNavWrapper({ userType }: BottomNavWrapperProps) {
    10→  return <BottomNav userType={userType} />;
    11→}
    12→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→import * as React from "react"
     2→import { cn } from "@/lib/utils"
     3→
     4→const Avatar = React.forwardRef<
     5→  HTMLDivElement,
     6→  React.HTMLAttributes<HTMLDivElement>
     7→>(({ className, ...props }, ref) => (
     8→  <div
     9→    ref={ref}
    10→    className={cn(
    11→      "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
    12→      className
    13→    )}
    14→    {...props}
    15→  />
    16→))
    17→Avatar.displayName = "Avatar"
    18→
    19→const AvatarImage = React.forwardRef<
    20→  HTMLImageElement,
    21→  React.ImgHTMLAttributes<HTMLImageElement>
    22→>(({ className, ...props }, ref) => (
    23→  <img
    24→    ref={ref}
    25→    className={cn("aspect-square h-full w-full", className)}
    26→    {...props}
    27→  />
    28→))
    29→AvatarImage.displayName = "AvatarImage"
    30→
    31→const AvatarFallback = React.forwardRef<
    32→  HTMLDivElement,
    33→  React.HTMLAttributes<HTMLDivElement>
    34→>(({ className, ...props }, ref) => (
    35→  <div
    36→    ref={ref}
    37→    className={cn(
    38→      "flex h-full w-full items-center justify-center rounded-full bg-muted",
    39→      className
    40→    )}
    41→    {...props}
    42→  />
    43→))
    44→AvatarFallback.displayName = "AvatarFallback"
    45→
    46→export { Avatar, AvatarImage, AvatarFallback }

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→import { Card } from "@/components/ui/card";
     2→import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
     3→import { Badge } from "@/components/ui/badge";
     4→import { cn } from "@/lib/utils";
     5→import { formatDistanceToNow } from "date-fns";
     6→
     7→interface ConversationPreviewProps {
     8→  id: string;
     9→  name: string;
    10→  avatar?: string;
    11→  lastMessage: string;
    12→  lastMessageTime: Date;
    13→  unreadCount?: number;
    14→  isOnline?: boolean;
    15→  onClick?: () => void;
    16→}
    17→
    18→export function ConversationPreview({
    19→  id,
    20→  name,
    21→  avatar,
    22→  lastMessage,
    23→  lastMessageTime,
    24→  unreadCount = 0,
    25→  isOnline = false,
    26→  onClick,
    27→}: ConversationPreviewProps) {
    28→  const initials = name
    29→    .split(" ")
    30→    .map((n) => n[0])
    31→    .join("")
    32→    .toUpperCase()
    33→    .slice(0, 2);
    34→
    35→  return (
    36→    <Card
    37→      className={cn(
    38→        "border-0 border-b rounded-none last:border-b-0",
    39→        "active:bg-accent transition-colors cursor-pointer"
    40→      )}
    41→      onClick={onClick}
    42→    >
    43→

    44→        {/* Avatar with online indicator */}
    45→

    46→          <Avatar className="h-14 w-14">
    47→            <AvatarImage src={avatar} alt={name} />
    48→            <AvatarFallback className="bg-primary/10 text-primary font-semibold">
    49→              {initials}
    50→            </AvatarFallback>
    51→          </Avatar>
    52→          {isOnline && (
    53→

    54→          )}
    55→

    56→
    57→        {/* Content */}
    58→

    59→

    60→
{name}

    61→
    62→              {formatDistanceToNow(lastMessageTime, { addSuffix: true })}
    63→
    64→

    65→

    66→            {lastMessage}
    67→

    68→

    69→
    70→        {/* Unread badge */}
    71→        {unreadCount > 0 && (
    72→          <Badge
    73→            variant="default"
    74→            className="shrink-0 h-6 min-w-6 px-2 rounded-full text-xs font-semibold"
    75→          >
    76→            {unreadCount > 99 ? "99+" : unreadCount}
    77→          </Badge>
    78→        )}
    79→

    80→    </Card>
    81→  );
    82→}

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


1→import { cn } from "@/lib/utils";
     2→
     3→interface MessageBubbleProps {
     4→  content: string;
     5→  isOwn?: boolean;
     6→  timestamp: Date;
     7→  status?: "sent" | "delivered" | "read";
     8→}
     9→
    10→export function MessageBubble({
    11→  content,
    12→  isOwn = false,
    13→  timestamp,
    14→  status = "delivered",
    15→}: MessageBubbleProps) {
    16→  const formatTime = (date: Date) => {
    17→    return date.toLocaleTimeString("en-AU", {
    18→      hour: "numeric",
    19→      minute: "2-digit",
    20→      hour12: true,
    21→    });
    22→  };
    23→
    24→  return (
    25→

    26→

    35→
{content}

    36→

    37→          {formatTime(timestamp)}
    38→          {isOwn && (
    39→
    40→              {status === "read" ? "✓✓" : "✓"}
    41→
    42→          )}
    43→

    44→

    45→

    46→  );
    47→}

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Perfect! I've now read all the files. Let me compile a comprehensive report with all the file contents.

## Complete Report: RateRight v2 App and Layout Files

### ROOT LAYOUT (`/home/ccuser/rateright-v2/src/app/layout.tsx`)

**Purpose:** Root layout with PWA configuration and global styles
- Imports Geist fonts (sans and mono)
- Sets metadata for SEO and PWA (manifest, apple-touch-icon, theme-color: #2563eb blue)
- Configures viewport for mobile devices
- Registers service worker for offline support

---

### LANDING PAGE (`/home/ccuser/rateright-v2/src/app/page.tsx`)

**Purpose:** Public landing page with call-to-action buttons
**Key Sections:**
- Header with RateRight logo and Sign In button
- Hero section: "Hire construction workers in seconds"
- How It Works (3 steps): Tell company → AI finds matches → One tap hire
- For Contractors section: AI does work, $50 flat fee, verified workers, hire by tomorrow
- For Workers section: Free signup, 5 questions in 2 mins, location-based matching, known pay rates
- Pricing section: $50 per hire (simple, transparent)
- Final CTA: "Ready to hire smarter?"
- Footer with company info
- Helper components: `Step`, `FeatureCard`, `Benefit`, `BenefitCheck`

---

### AUTHENTICATED LAYOUT (`/home/ccuser/rateright-v2/src/app/(authenticated)/layout.tsx`)

**Purpose:** Protected layout for authenticated users only
**Features:**
- Server-side auth check (redirects to `/auth/login` if not authenticated)
- Header with RateRight logo and user email
- Main content area with bottom padding for nav
- Bottom navigation with 4 tabs:
  - Home → `/dashboard`
  - Jobs → `/contractor/post-job`
  - Messages → `/messages`
  - Profile → `/worker/profile/build`

---

## Auth Pages

### Login (`/home/ccuser/rateright-v2/src/app/auth/login/page.tsx`)

**Purpose:** Email/password authentication
**Features:**
- Email and password inputs (h-14 height for mobile)
- Error display
- Redirects to `/auth/verify-email` if email not verified
- Sign up link at bottom

### Signup (`/home/ccuser/rateright-v2/src/app/auth/signup/page.tsx`)

**Purpose:** User registration with role selection
**Features:**
- Email and password input
- User type selection: Contractor (Building2 icon) or Worker (HardHat icon)
- Grid layout for type selection buttons
- Redirects to email verification after signup

### Email Verification (`/home/ccuser/rateright-v2/src/app/auth/verify-email/page.tsx`)

**Purpose:** Email verification flow
**Features:**
- Displays mail icon and verification message
- Auto-checks if email already verified (redirects to appropriate dashboard)
- Resend verification email button with loading state
- Error and success messages
- Back to login button

---

## Dashboard Page (`/home/ccuser/rateright-v2/src/app/(authenticated)/dashboard/page.tsx`)

**Purpose:** Main hub for both contractors and workers
**Contractor Features:**
- Stats cards: Active Jobs count, New Matches count
- Post a Job CTA card
- View Matches card (if matches exist)
- Company Profile card
- SignOutButton component in header

**Worker Features:**
- Find Work CTA card
- Your Profile card
- SignOutButton component in header

**Features:**
- Server-side fetching of user profile and stats
- Conditional rendering based on user type (contractor vs worker)
- BottomNavWrapper component for navigation

---

## Contractor Pages

### Contractor Signup (`/home/ccuser/rateright-v2/src/app/(authenticated)/contractor/signup/page.tsx`)

**Purpose:** Multi-step contractor onboarding with ABN verification
**Steps:**
1. Auth (email/password) - if not authenticated
2. Company Search - ABN lookup with validation
3. Researching - animated state during ABN lookup
4. Review - editable company fields with logo display

**Features:**
- ABN validation and lookup via `/api/abn-lookup`
- Company logo fetching via `/api/company-logo`
- Editable company fields: name, ABN, address, industry, size, website
- Progress bar showing step completion
- Company logo display (from Clearbit or Google)
- Error handling with user-friendly messages

### Post Job (`/home/ccuser/rateright-v2/src/app/(authenticated)/contractor/post-job/page.tsx`)

**Purpose:** Job posting with AI-generated suggestions
**Steps:**
1. Select Trade - 7 trade categories with icons and colors
2. AI-filled Job Details (combined section):
   - Job title and description (AI pre-filled)
   - Pay rate (min/max with hourly/daily toggle)
   - Location: Site address and suburb
   - Schedule: Start date, duration, workers needed
   - Required certifications (displayed if any)
3. Success - confirmation with View Matches button

**Features:**
- AI_SUGGESTIONS constant with pre-filled job details per trade
- Trade categories: Steel Fixer, Formworker, Labourer, Concreter, Carpenter, Scaffolder, Other
- Sticky bottom CTA when on step 2
- Progress bar (Step 1/2)
- Haptic feedback on success
- Payment info: $50 fee mentioned in bottom text

### Matches (`/home/ccuser/rateright-v2/src/app/(authenticated)/contractor/matches/page.tsx`)

**Purpose:** Swipeable worker matching interface
**Features:**
- Horizontal scrollable job selector (if multiple jobs)
- Job summary with trade badge, location, match count
- Swipeable worker cards:
  - Right swipe (>100px) to hire
  - Left swipe (<-100px) to pass/reject
  - Swipe progress indicator
- Worker card details:
  - Avatar with initials
  - Name, AI summary
  - Experience, location, match score
  - Certifications (up to 3)
  - Hire button with $50 fee mention
- Hired status display
- Match enrichment with worker profile data
- Payment record creation on hire
- Haptic feedback on actions

---

## Worker Pages

### Worker Signup (`/home/ccuser/rateright-v2/src/app/(authenticated)/worker/signup/page.tsx`)

**Purpose:** Multi-step worker profile creation (5 questions in ~2 minutes)
**Steps:**
1. Auth (email/password) - if not authenticated
2. Build Method - Type answers (enabled) vs Voice note (coming soon)
3. Select Trade - Multi-select from 16 trade options
4. Experience - 5 options from "Less than 1 year" to "10+ years"
5. Location - Suburb/area text input
6. Availability - 4 options: Full-time, Casual, Weekends, Flexible
7. Certifications - Optional multi-select from 9 cert types
8. Review - Display AI-generated bio and editable profile

**Features:**
- AI-generated bio from selected answers
- Progress bar (7 steps total, 6 user-facing)
- Bio generation from: trades, experience, suburb, availability, certs
- Bio format: "Experienced [trade] with [exp] in construction, based in [suburb], available for [avail]..."
- Saves to `profiles` and `worker_profiles` tables
- AI-extracted metadata tracking

### Worker Profile Build (`/home/ccuser/rateright-v2/src/app/(authenticated)/worker/profile/build/page.tsx`)

**Purpose:** AI-assisted profile builder (alternative to quick signup)
**Steps:**
1. Trade - Select primary trade
2. Experience - Years in construction
3. Location - Suburb/area
4. Availability - Work schedule
5. Generating - AI is creating bio/skills/certs
6. Review - Edit AI-generated content

**Features:**
- Calls `/api/ai/generate-profile` endpoint
- Generates: bio, skills array, certifications array
- Editable sections:
  - Bio (textarea)
  - Skills (removable badges)
  - Certifications (removable list items)
- Update or create worker profile
- Sticky bottom save button on review step
- Progress bar (4 main steps)

### Worker Jobs (`/home/ccuser/rateright-v2/src/app/(authenticated)/worker/jobs/page.tsx`)

**Purpose:** Job browsing and swipe-to-apply interface
**Features:**
- Horizontal scrollable trade filter tabs (All + 7 trades)
- Swipeable job cards:
  - Right swipe (>100px) to apply
  - Swipe progress indicator
  - Applied status display
- Job card details:
  - Trade badge
  - Title
  - Location (MapPin), pay (DollarSign), date (Calendar), workers needed
- Bottom sheet job detail view:
  - Trade badge
  - Full job title and description
  - Detailed pay, location, dates, workers needed
  - Required certifications
  - Apply button (or "Already Applied" if applied)
- Applied jobs tracking with Set
- Haptic feedback on apply
- BottomNav component for navigation

---

## Messages Pages

### Messages List (`/home/ccuser/rateright-v2/src/app/(authenticated)/messages/page.tsx`)

**Purpose:** Conversation list with search
**Features:**
- Sticky header with total unread count
- Search bar with placeholder "Search conversations..."
- Mock conversation data (5 conversations)
- ConversationPreview components for each
- Empty state with browse jobs link
- Shows: name, last message, time, unread badge, online status

### Conversation (`/home/ccuser/rateright-v2/src/app/(authenticated)/messages/[conversationId]/page.tsx`)

**Purpose:** Individual chat interface
**Features:**
- Header with back button, avatar, name, online status
- Action buttons: Phone, More (MoreVertical icon)
- Message list with MessageBubble components
- Auto-scroll to bottom on new messages
- Message input form (bottom sticky)
- Own vs other message styling (blue vs gray)
- Message timestamps in AU format
- Read receipts (✓ or ✓✓)
- Mock conversation with 5 messages

---

## Component Files

### UI Components (shadcn/ui)

**Button** (`/home/ccuser/rateright-v2/src/components/ui/button.tsx`)
- CVA-based variants: default, destructive, outline, secondary, ghost, link
- Sizes: default, xs, sm, lg, icon, icon-xs, icon-sm, icon-lg
- Supports `asChild` prop for Slot

**Card** (`/home/ccuser/rateright-v2/src/components/ui/card.tsx`)
- Main Card component with rounded-xl border
- CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter
- Container queries for responsive grid layout

**Input** (`/home/ccuser/rateright-v2/src/components/ui/input.tsx`)
- Standard HTML input with Tailwind styling
- Focus states and aria-invalid handling
- File input support

**Label** (`/home/ccuser/rateright-v2/src/components/ui/label.tsx`)
- Radix UI Label with accessible patterns
- Disabled state support

**Tabs** (`/home/ccuser/rateright-v2/src/components/ui/tabs.tsx`)
- Radix UI Tabs component
- Variants: default (background), line (underline)
- Supports horizontal and vertical orientation

**Badge** (`/home/ccuser/rateright-v2/src/components/ui/badge.tsx`)
- CVA-based variants: default, secondary, destructive, outline, ghost, link
- Rounded-full design
- Supports `asChild` for links

**Separator** (`/home/ccuser/rateright-v2/src/components/ui/separator.tsx`)
- Radix UI Separator
- Horizontal and vertical orientations

**Sheet** (`/home/ccuser/rateright-v2/src/components/ui/sheet.tsx`)
- Radix UI Dialog-based sheet component
- Sides: top, right, bottom, left
- Animated slide-in/out with 300ms-500ms duration
- Close button with X icon

**Dialog** (`/home/ccuser/rateright-v2/src/components/ui/dialog.tsx`)
- Radix UI Dialog component
- Modal with overlay
- Centered, zoom animation
- Close button with X icon

**Form** (`/home/ccuser/rateright-v2/src/components/ui/form.tsx`)
- React Hook Form integration
- Components: Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage
- Auto-generated IDs and aria attributes

**Avatar** (`/home/ccuser/rateright-v2/src/components/ui/avatar.tsx`)
- Avatar container with rounded-full
- AvatarImage for displaying image
- AvatarFallback for initials/default

### Custom Components

**SignOutButton** (`/home/ccuser/rateright-v2/src/components/sign-out-button.tsx`)
- Client component
- Calls `supabase.auth.signOut()`
- Redirects to `/` after logout
- Ghost icon button with LogOut icon

**BottomNav** (`/home/ccuser/rateright-v2/src/components/bottom-nav.tsx`)
- Mobile bottom navigation bar
- Props: userType ("contractor" | "worker")
- Contractor links: Home, Matches, Post (center), Messages, Profile
- Worker links: Home, Jobs, Messages, Profile
- Active state styling
- Centered post button for contractors (-mt-4)
- Safe area inset support

**BottomNavWrapper** (`/home/ccuser/rateright-v2/src/components/bottom-nav-wrapper.tsx`)
- Simple wrapper component
- Renders BottomNav with passed userType

**ConversationPreview** (`/home/ccuser/rateright-v2/src/components/ConversationPreview.tsx`)
- Props: id, name, avatar, lastMessage, lastMessageTime, unreadCount, isOnline, onClick
- Avatar with online indicator (green dot)
- Last message text (truncated)
- Time distance using `date-fns` formatDistanceToNow
- Unread badge (red) for unread count
- Clickable card with active state

**MessageBubble** (`/home/ccuser/rateright-v2/src/components/MessageBubble.tsx`)
- Props: content, isOwn, timestamp, status
- Own messages: blue (primary) background, right aligned, rounded-br-md
- Other messages: gray (muted) background, left aligned, rounded-bl-md
- Timestamp in AU locale (h:mm AM/PM format)
- Read receipts (✓ or ✓✓) for own messages
- Max width 75% for responsive sizing

---

## Key Patterns & Architecture

### Authentication Flow
1. User signs up at `/auth/signup` with email, password, and role
2. Email verification at `/auth/verify-email` (server checks `email_confirmed_at`)
3. Role-specific signup flows:
   - **Contractor**: `/contractor/signup` → ABN lookup → Company profile
   - **Worker**: `/worker/signup` (5 quick questions) or `/worker/profile/build` (AI-assisted)
4. Protected routes via authenticated layout (checks `supabase.auth.getUser()`)

### Mobile-First Design
- Large touch targets (h-14 minimum for inputs, h-16 for buttons)
- Swipe gestures for job browsing and worker matching
- Bottom navigation with safe area insets
- Sticky headers and footers
- Horizontal scroll for tab filters

### AI Integration
- `/api/abn-lookup` - Company research via ABN
- `/api/company-logo` - Logo fetching (Clearbit/Google)
- `/api/ai/generate-profile` - AI bio/skills generation
- Pre-filled suggestions for job postings

### Database Tables Referenced
- `profiles` - User base profile (id, name, suburb, type, onboarding_completed, etc.)
- `companies` - Contractor company info (ABN, address, industry, etc.)
- `worker_profiles` - Worker-specific data (trades, experience_years, certifications, availability, bio)
- `jobs` - Job postings (title, description, trade, rate_min/max, rate_type, status, etc.)
- `matches` - Job-worker connections (status, match_score, hired_at, fee_charged)
- `payments` - $50 hire fees (match_id, company_id, amount, status)

---

**Total Files Analyzed:** 28
- **Layout/Page Files:** 13 pages + 2 layouts
- **UI Components:** 9 components
- **Custom Components:** 5 components