{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "contact-channels",
  "title": "Contact Channels",
  "description": "One tile per way to reach a team, with how fast each answers and the recommended one inverted, and a short FAQ underneath.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/manniche/contact-channels/contact-channels.tsx",
      "content": "// Contact channels: one tile per way to reach a team (email, phone, chat, in person), the recommended one inverted,\n// and a short FAQ underneath. Signature: every channel says how fast it answers, in mono.\n// Screen readers get a section named by its h2, a real list of channels with an h3 each, and a FAQ of native\n// <details> elements. Under reduced motion the answer simply appears.\nimport { useId, type HTMLAttributes, type ReactNode } from 'react'\nimport { ArrowUpRight } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport type ContactChannel = {\n  /** Stable key for the channel. */\n  id: string\n  /** A small icon node, e.g. a lucide icon. Decorative. */\n  icon?: ReactNode\n  /** The channel name: \"Email\", \"Phone\". */\n  title: ReactNode\n  /** The address, number or opening line. */\n  detail: ReactNode\n  /** The one link or button of the tile. */\n  action: { label: string; href: string; external?: boolean }\n  /** How fast it answers, in mono: \"Within 2 working days\". */\n  responseTime?: string\n}\n\nexport type ContactFaq = { question: string; answer: ReactNode }\n\nexport type ContactChannelsProps = Omit<HTMLAttributes<HTMLElement>, 'title'> & {\n  /** The section heading (h2). */\n  heading: ReactNode\n  /** One line under the heading. */\n  intro?: ReactNode\n  /** The channels, in reading order. */\n  channels: ContactChannel[]\n  /** The id of the recommended channel, shown as the inverted tile. */\n  recommendedId?: string\n  /** Short questions and answers below the channels. */\n  faq?: ContactFaq[]\n  /** Heading of the FAQ (h3). */\n  faqHeading?: ReactNode\n  /** UI strings, for translation. */\n  labels?: { recommended?: string; responds?: string; newTab?: string }\n}\n\nexport function ContactChannels({\n  heading,\n  intro,\n  channels,\n  recommendedId,\n  faq = [],\n  faqHeading = 'Quick answers',\n  labels = {},\n  className,\n  ...rest\n}: ContactChannelsProps) {\n  const { recommended = 'Recommended', responds = 'Answers', newTab = '(opens in a new tab)' } = labels\n  const hid = useId()\n  return (\n    <section aria-labelledby={hid} className={cn('@container mx-auto w-full max-w-6xl px-4 py-12 sm:px-6', className)} {...rest}>\n      <header className=\"max-w-2xl\">\n        <h2 id={hid} className=\"font-[family-name:var(--font-display,inherit)] text-3xl font-semibold tracking-tight text-balance @min-[40rem]:text-4xl\">\n          {heading}\n        </h2>\n        {intro && <p className=\"mt-3 text-muted-foreground\">{intro}</p>}\n      </header>\n\n      <ul className=\"mt-8 grid list-none gap-3 p-0 @min-[36rem]:grid-cols-2 @min-[64rem]:grid-cols-4\">\n        {channels.map((c) => {\n          const inverted = c.id === recommendedId\n          return (\n            <li key={c.id} className=\"min-w-0\">\n              <article\n                data-inverted={inverted || undefined}\n                className={cn(\n                  'flex h-full flex-col rounded-[26px] p-6',\n                  inverted\n                    ? 'bg-foreground text-background'\n                    : 'bg-card text-card-foreground shadow-[0_0_0_1px_color-mix(in_oklab,var(--foreground)_9%,transparent),0_1px_2px_rgba(0,0,0,0.03)]',\n                )}\n                style={\n                  inverted\n                    ? ({\n                        '--muted-foreground': 'color-mix(in oklab, var(--background) 64%, var(--foreground))',\n                        '--ring': 'var(--background)',\n                      } as React.CSSProperties)\n                    : undefined\n                }\n              >\n                <div className=\"flex items-center justify-between gap-2\">\n                  <span\n                    aria-hidden\n                    className={cn('grid size-10 place-items-center rounded-[14px] [&_svg]:size-5', inverted ? 'bg-background/12' : 'bg-muted')}\n                  >\n                    {c.icon}\n                  </span>\n                  {inverted && (\n                    <span className=\"rounded-full bg-background/12 px-2.5 py-1 font-mono text-[11px] tracking-wide uppercase\">{recommended}</span>\n                  )}\n                </div>\n                <h3 className=\"mt-5 text-lg font-semibold\">{c.title}</h3>\n                <p className=\"mt-1 break-words text-sm text-muted-foreground\">{c.detail}</p>\n                {c.responseTime && (\n                  <p className=\"mt-4 font-mono text-[11px] tabular-nums text-muted-foreground\">\n                    {responds}: {c.responseTime}\n                  </p>\n                )}\n                <a\n                  href={c.action.href}\n                  {...(c.action.external ? { target: '_blank', rel: 'noopener noreferrer' } : {})}\n                  className={cn(\n                    'mt-5 inline-flex min-h-11 w-fit items-center gap-1.5 rounded-full px-4 text-sm font-medium',\n                    'transition-[opacity,transform] duration-200 ease-out-quint active:scale-[0.98] motion-reduce:transition-none motion-reduce:active:scale-100',\n                    'outline-offset-2 focus-visible:outline-2 focus-visible:outline-ring',\n                    inverted ? 'bg-background text-foreground' : 'bg-primary text-primary-foreground',\n                  )}\n                >\n                  {c.action.label}\n                  {c.action.external && <span className=\"sr-only\">{newTab}</span>}\n                  <ArrowUpRight className=\"size-4\" aria-hidden />\n                </a>\n              </article>\n            </li>\n          )\n        })}\n      </ul>\n\n      {faq.length > 0 && (\n        <div className=\"mt-10 max-w-3xl\">\n          <h3 className=\"text-lg font-semibold\">{faqHeading}</h3>\n          <div className=\"mt-3 divide-y divide-border rounded-[26px] bg-card px-6 shadow-[0_0_0_1px_color-mix(in_oklab,var(--foreground)_9%,transparent)]\">\n            {faq.map((f) => (\n              <details key={f.question} className=\"group\">\n                <summary className=\"flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 py-3 text-sm font-medium outline-offset-2 focus-visible:outline-2 focus-visible:outline-ring [&::-webkit-details-marker]:hidden\">\n                  {f.question}\n                  <span aria-hidden className=\"font-mono text-muted-foreground group-open:hidden\">+</span>\n                  <span aria-hidden className=\"hidden font-mono text-muted-foreground group-open:inline\">-</span>\n                </summary>\n                <div className=\"pb-4 text-sm text-muted-foreground motion-safe:group-open:animate-[contact-faq-in_250ms_cubic-bezier(0.22,1,0.36,1)]\">\n                  {f.answer}\n                </div>\n              </details>\n            ))}\n          </div>\n          <style>{`@keyframes contact-faq-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}`}</style>\n        </div>\n      )}\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "templates"
  ],
  "type": "registry:block"
}