{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "faq",
  "title": "FAQ",
  "description": "Animated FAQ accordion in four styles (minimal, cards, numbered, split) with height-auto reveals, a live filter and keyboard navigation.",
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://trytweenly.vercel.app/r/use-reduced-motion.json",
    "https://trytweenly.vercel.app/r/tweenly-theme.json"
  ],
  "files": [
    {
      "path": "registry/new-york/faq/faq.tsx",
      "content": "\"use client\"\n\nimport {\n  useId,\n  useMemo,\n  useRef,\n  useState,\n  type CSSProperties,\n  type KeyboardEvent,\n  type ReactNode,\n} from \"react\"\nimport { AnimatePresence, motion, useInView, type Transition } from \"motion/react\"\nimport { ArrowRight, ChevronDown, Plus, Search, X } from \"lucide-react\"\nimport { cn } from \"@/lib/utils\"\nimport { useReducedMotion } from \"@/registry/new-york/hooks/use-reduced-motion\"\n\nexport type FaqVariant = \"minimal\" | \"cards\" | \"numbered\" | \"split\"\nexport type FaqIcon = \"plus\" | \"chevron\" | \"arrow\"\n\nexport interface FaqItem {\n  /** The question shown on the trigger. */\n  question: string\n  /** The answer. Plain strings get the richest reveal animations. */\n  answer: ReactNode\n  /** Stable id. Default: the item index */\n  id?: string\n}\n\nexport interface FaqProps {\n  /** Questions and answers. */\n  items: FaqItem[]\n  /** Visual style. Default: \"minimal\" */\n  variant?: FaqVariant\n  /** Allow one or many items open at once. The split variant is always single. Default: \"single\" */\n  type?: \"single\" | \"multiple\"\n  /** Index or indices open initially when uncontrolled. Default: undefined (split opens the first item) */\n  defaultOpen?: number | number[]\n  /** Controlled open indices. */\n  value?: number[]\n  /** Called with the new open indices whenever an item toggles. */\n  onValueChange?: (value: number[]) => void\n  /** Trigger icon. Default: \"plus\" */\n  icon?: FaqIcon\n  /** Accent color for highlights, rings and indicators (any CSS color). Default: \"#ff4d12\" */\n  accent?: string\n  /** Optional section heading. */\n  title?: string\n  /** Optional text under the heading. */\n  description?: string\n  /** Show a filter input. Non-matching items collapse out and matches highlight. Default: false */\n  searchable?: boolean\n  /** Placeholder for the filter input. Default: \"Search questions\" */\n  searchPlaceholder?: string\n  /** Delay between items when the list scrolls into view, in seconds. 0 disables the entrance. Default: 0.06 */\n  stagger?: number\n  /** Open and close duration in seconds. Default: 0.45 */\n  duration?: number\n  /** Corner radius of cards, panels and the search field in px. Default: 16 */\n  radius?: number\n  className?: string\n}\n\nconst EASE_OUT = [0.22, 1, 0.36, 1] as const\nconst EASE_IN_OUT = [0.76, 0, 0.24, 1] as const\nconst SPRING: Transition = { type: \"spring\", stiffness: 450, damping: 34 }\nconst INSTANT: Transition = { duration: 0 }\n\nconst toList = (v: number | number[] | undefined) => (v === undefined ? [] : Array.isArray(v) ? v : [v])\n\nconst textOf = (node: ReactNode): string =>\n  typeof node === \"string\" || typeof node === \"number\" ? String(node) : \"\"\n\nfunction Highlight({ text, query, reduced }: { text: string; query: string; reduced: boolean }) {\n  const q = query.trim()\n  if (!q) return <>{text}</>\n  const lower = text.toLowerCase()\n  const needle = q.toLowerCase()\n  const parts: ReactNode[] = []\n  let from = 0\n  let hit = lower.indexOf(needle)\n  while (hit !== -1) {\n    if (hit > from) parts.push(text.slice(from, hit))\n    parts.push(\n      <mark key={hit} className=\"relative isolate rounded-[3px] bg-transparent px-px text-inherit\">\n        {/* Flat highlight that wipes in from the left */}\n        <motion.span\n          aria-hidden=\"true\"\n          className=\"absolute inset-0 -z-10 origin-left rounded-[3px]\"\n          style={{ backgroundColor: \"color-mix(in oklab, var(--faq-accent) 28%, transparent)\" }}\n          initial={{ scaleX: reduced ? 1 : 0 }}\n          animate={{ scaleX: 1 }}\n          transition={reduced ? INSTANT : { duration: 0.35, ease: EASE_OUT }}\n        />\n        {text.slice(hit, hit + needle.length)}\n      </mark>\n    )\n    from = hit + needle.length\n    hit = lower.indexOf(needle, from)\n  }\n  if (from < text.length) parts.push(text.slice(from))\n  return <>{parts}</>\n}\n\nfunction TriggerIcon({ icon, open, reduced, className }: { icon: FaqIcon; open: boolean; reduced: boolean; className?: string }) {\n  const Glyph = icon === \"chevron\" ? ChevronDown : icon === \"arrow\" ? ArrowRight : Plus\n  const rotate = !open ? 0 : icon === \"plus\" ? 135 : icon === \"chevron\" ? 180 : 90\n  return (\n    <motion.span\n      aria-hidden=\"true\"\n      className={cn(\"inline-flex shrink-0 items-center justify-center\", className)}\n      animate={{ rotate }}\n      transition={reduced ? INSTANT : SPRING}\n    >\n      <Glyph className=\"size-4\" strokeWidth={1.75} />\n    </motion.span>\n  )\n}\n\nfunction Words({ text, reduced, duration }: { text: string; reduced: boolean; duration: number }) {\n  const words = text.split(/(\\s+)/)\n  const step = Math.min(0.03, 0.9 / Math.max(words.length, 1))\n  return (\n    <>\n      {words.map((w, i) =>\n        /^\\s+$/.test(w) ? (\n          w\n        ) : (\n          <motion.span\n            key={i}\n            className=\"inline-block\"\n            initial={reduced ? false : { opacity: 0, y: 8, filter: \"blur(4px)\" }}\n            animate={{ opacity: 1, y: 0, filter: \"blur(0px)\" }}\n            transition={reduced ? INSTANT : { duration: duration * 0.8, delay: 0.06 + (i / 2) * step, ease: EASE_OUT }}\n          >\n            {w}\n          </motion.span>\n        )\n      )}\n    </>\n  )\n}\n\nfunction Collapse({\n  open,\n  id,\n  labelledBy,\n  duration,\n  reduced,\n  children,\n}: {\n  open: boolean\n  id: string\n  labelledBy: string\n  duration: number\n  reduced: boolean\n  children: ReactNode\n}) {\n  return (\n    <AnimatePresence initial={false}>\n      {open && (\n        <motion.div\n          id={id}\n          role=\"region\"\n          aria-labelledby={labelledBy}\n          className=\"overflow-hidden\"\n          initial={{ height: 0 }}\n          animate={{ height: \"auto\" }}\n          exit={{ height: 0 }}\n          transition={reduced ? INSTANT : { duration, ease: EASE_IN_OUT }}\n        >\n          {children}\n        </motion.div>\n      )}\n    </AnimatePresence>\n  )\n}\n\nfunction onTriggerKeyDown(e: KeyboardEvent<HTMLButtonElement>) {\n  const keys = [\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"]\n  if (!keys.includes(e.key)) return\n  const root = e.currentTarget.closest(\"[data-faq-root]\")\n  if (!root) return\n  const triggers = Array.from(root.querySelectorAll<HTMLButtonElement>(\"[data-faq-trigger]\"))\n  const i = triggers.indexOf(e.currentTarget)\n  if (i === -1 || triggers.length === 0) return\n  e.preventDefault()\n  const n = triggers.length\n  const next =\n    e.key === \"ArrowDown\" ? (i + 1) % n : e.key === \"ArrowUp\" ? (i - 1 + n) % n : e.key === \"Home\" ? 0 : n - 1\n  triggers[next]?.focus()\n}\n\nexport function Faq({\n  items,\n  variant = \"minimal\",\n  type = \"single\",\n  defaultOpen,\n  value,\n  onValueChange,\n  icon = \"plus\",\n  accent = \"#ff4d12\",\n  title,\n  description,\n  searchable = false,\n  searchPlaceholder = \"Search questions\",\n  stagger = 0.06,\n  duration = 0.45,\n  radius = 16,\n  className,\n}: FaqProps) {\n  const uid = useId()\n  const reduced = useReducedMotion()\n  const rootRef = useRef<HTMLDivElement>(null)\n  const inView = useInView(rootRef, { once: true, amount: 0.15 })\n\n  const [inner, setInner] = useState<number[]>(() => toList(defaultOpen))\n  const [query, setQuery] = useState(\"\")\n  const open = value ?? inner\n  const isSplit = variant === \"split\"\n\n  const setOpen = (next: number[]) => {\n    if (value === undefined) setInner(next)\n    onValueChange?.(next)\n  }\n\n  const toggle = (index: number) => {\n    const isOpen = open.includes(index)\n    if (isSplit) {\n      if (!isOpen) setOpen([index])\n      return\n    }\n    if (type === \"single\") setOpen(isOpen ? [] : [index])\n    else setOpen(isOpen ? open.filter((i) => i !== index) : [...open, index])\n  }\n\n  const visible = useMemo(() => {\n    const q = query.trim().toLowerCase()\n    return items\n      .map((item, index) => ({ item, index, key: item.id ?? String(index) }))\n      .filter(({ item }) => !q || item.question.toLowerCase().includes(q) || textOf(item.answer).toLowerCase().includes(q))\n  }, [items, query])\n\n  const splitActive = isSplit\n    ? (visible.find((v) => open.includes(v.index)) ?? visible[0])?.index\n    : undefined\n\n  const ids = (index: number) => ({ trigger: `${uid}-t-${index}`, panel: `${uid}-p-${index}` })\n  const anyOpen = !isSplit && visible.some((v) => open.includes(v.index))\n  const enter = (i: number) =>\n    stagger > 0 && !reduced\n      ? {\n          initial: { opacity: 0, y: 14 },\n          animate: inView ? { opacity: 1, y: 0 } : undefined,\n          transition: { duration: 0.6, delay: i * stagger, ease: EASE_OUT },\n        }\n      : { initial: false as const }\n\n  const style = { \"--faq-accent\": accent, \"--faq-radius\": `${radius}px` } as CSSProperties\n  const answerText = (answer: ReactNode) => (typeof answer === \"string\" ? answer : null)\n\n  const header = (title || description) && (\n    <motion.div className=\"mb-8 space-y-2\" {...enter(0)}>\n      {title && <h2 className=\"text-2xl font-semibold tracking-tight text-foreground sm:text-3xl\">{title}</h2>}\n      {description && <p className=\"max-w-prose text-sm leading-relaxed text-muted-foreground\">{description}</p>}\n    </motion.div>\n  )\n\n  const search = searchable && (\n    <motion.div className=\"relative mb-6\" {...enter(title || description ? 1 : 0)}>\n      <Search aria-hidden=\"true\" className=\"pointer-events-none absolute top-1/2 left-3.5 size-4 -translate-y-1/2 text-muted-foreground\" />\n      <input\n        type=\"search\"\n        value={query}\n        onChange={(e) => setQuery(e.target.value)}\n        placeholder={searchPlaceholder}\n        aria-label={searchPlaceholder}\n        className=\"h-11 w-full border bg-foreground/[0.03] pr-10 pl-10 text-sm text-foreground outline-none transition-[border-color,box-shadow] placeholder:text-muted-foreground focus:border-[color:var(--faq-accent)] focus:shadow-[0_0_0_3px_color-mix(in_oklab,var(--faq-accent)_18%,transparent)] [&::-webkit-search-cancel-button]:hidden\"\n        style={{ borderRadius: \"var(--faq-radius)\" }}\n      />\n      <AnimatePresence>\n        {query && (\n          <motion.button\n            type=\"button\"\n            aria-label=\"Clear search\"\n            onClick={() => setQuery(\"\")}\n            className=\"absolute top-1/2 right-2.5 grid size-6 -translate-y-1/2 place-items-center rounded-full text-muted-foreground hover:bg-foreground/[0.06] hover:text-foreground\"\n            initial={{ opacity: 0, scale: 0.6 }}\n            animate={{ opacity: 1, scale: 1 }}\n            exit={{ opacity: 0, scale: 0.6 }}\n            transition={reduced ? INSTANT : SPRING}\n          >\n            <X className=\"size-3.5\" />\n          </motion.button>\n        )}\n      </AnimatePresence>\n    </motion.div>\n  )\n\n  const empty = (\n    <AnimatePresence>\n      {visible.length === 0 && (\n        <motion.p\n          className=\"py-10 text-center text-sm text-muted-foreground\"\n          initial={{ opacity: 0, y: 6 }}\n          animate={{ opacity: 1, y: 0 }}\n          exit={{ opacity: 0 }}\n          transition={reduced ? INSTANT : { duration: 0.3, ease: EASE_OUT }}\n        >\n          No questions match &ldquo;{query}&rdquo;.\n        </motion.p>\n      )}\n    </AnimatePresence>\n  )\n\n  const presence = reduced ? INSTANT : { duration: duration * 0.8, ease: EASE_IN_OUT }\n  const baseOffset = (title || description ? 1 : 0) + (searchable ? 1 : 0)\n\n  // ---------------------------------------------------------------- split\n  if (isSplit) {\n    const active = visible.find((v) => v.index === splitActive)\n    const activeIds = active ? ids(active.index) : null\n    return (\n      <div ref={rootRef} data-faq-root=\"\" style={style} className={cn(\"w-full\", className)}>\n        {header}\n        {search}\n        <div className=\"grid gap-4 sm:grid-cols-[minmax(0,5fr)_minmax(0,7fr)] sm:gap-6\">\n          <div className=\"relative flex flex-col gap-1\">\n            <AnimatePresence initial={false} mode=\"popLayout\">\n              {visible.map(({ item, index, key }, i) => {\n                const isActive = index === splitActive\n                const { trigger, panel } = ids(index)\n                return (\n                  <motion.div\n                    key={key}\n                    layout={!reduced}\n                    initial={{ opacity: 0, scale: 0.96 }}\n                    animate={{ opacity: 1, scale: 1 }}\n                    exit={{ opacity: 0, scale: 0.96 }}\n                    transition={presence}\n                  >\n                    <motion.div {...enter(baseOffset + i)}>\n                      <button\n                        id={trigger}\n                        type=\"button\"\n                        data-faq-trigger=\"\"\n                        aria-expanded={isActive}\n                        aria-controls={panel}\n                        onClick={() => toggle(index)}\n                        onKeyDown={onTriggerKeyDown}\n                        className={cn(\n                          \"relative flex w-full items-center gap-3 px-4 py-3 text-left text-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-[color:var(--faq-accent)]\",\n                          isActive ? \"text-foreground\" : \"text-muted-foreground hover:text-foreground\"\n                        )}\n                        style={{ borderRadius: \"calc(var(--faq-radius) * 0.75)\" }}\n                      >\n                        {isActive && (\n                          <motion.span\n                            layoutId={`${uid}-split-indicator`}\n                            aria-hidden=\"true\"\n                            className=\"absolute inset-0 bg-foreground/[0.05]\"\n                            style={{ borderRadius: \"calc(var(--faq-radius) * 0.75)\" }}\n                            transition={reduced ? INSTANT : SPRING}\n                          >\n                            <span className=\"absolute top-1/2 left-0 h-5 w-[3px] -translate-y-1/2 rounded-full bg-[color:var(--faq-accent)]\" />\n                          </motion.span>\n                        )}\n                        <span className=\"relative flex-1 font-medium\">\n                          <Highlight text={item.question} query={query} reduced={reduced} />\n                        </span>\n                        <TriggerIcon\n                          icon={icon}\n                          open={false}\n                          reduced={reduced}\n                          className={cn(\n                            \"relative transition-[opacity,transform] duration-300\",\n                            isActive ? \"translate-x-0 text-[color:var(--faq-accent)] opacity-100\" : \"-translate-x-1 opacity-0\"\n                          )}\n                        />\n                      </button>\n                    </motion.div>\n                  </motion.div>\n                )\n              })}\n            </AnimatePresence>\n            {empty}\n          </div>\n          <motion.div {...enter(baseOffset + 1)}>\n          <motion.div\n            layout={!reduced}\n            className=\"relative min-h-40 overflow-hidden border bg-card\"\n            style={{ borderRadius: \"var(--faq-radius)\" }}\n            transition={reduced ? INSTANT : SPRING}\n          >\n            <AnimatePresence initial={false} mode=\"popLayout\">\n              {active && activeIds && (\n                <motion.div\n                  key={active.key}\n                  id={activeIds.panel}\n                  role=\"region\"\n                  aria-labelledby={activeIds.trigger}\n                  className=\"p-6 sm:p-8\"\n                  initial={reduced ? false : { opacity: 0, y: 16, filter: \"blur(6px)\" }}\n                  animate={{ opacity: 1, y: 0, filter: \"blur(0px)\" }}\n                  exit={reduced ? { opacity: 0, transition: INSTANT } : { opacity: 0, y: -12, filter: \"blur(6px)\" }}\n                  transition={reduced ? INSTANT : { duration, ease: EASE_OUT }}\n                >\n                  <p className=\"mb-3 font-[family-name:var(--font-display)] text-sm font-medium tracking-[0.2em] text-[color:var(--faq-accent)] uppercase\">\n                    {String(active.index + 1).padStart(2, \"0\")} / {String(items.length).padStart(2, \"0\")}\n                  </p>\n                  <h3 className=\"mb-3 text-lg font-semibold tracking-tight text-foreground\">{active.item.question}</h3>\n                  <div className=\"text-sm leading-relaxed text-muted-foreground\">{active.item.answer}</div>\n                </motion.div>\n              )}\n            </AnimatePresence>\n          </motion.div>\n          </motion.div>\n        </div>\n      </div>\n    )\n  }\n\n  // ---------------------------------------------------------------- stacked variants\n  return (\n    <div ref={rootRef} data-faq-root=\"\" style={style} className={cn(\"w-full\", className)}>\n      {header}\n      {search}\n      <div className={cn(\"flex flex-col\", variant === \"minimal\" && \"border-t\")}>\n        <AnimatePresence initial={false}>\n          {visible.map(({ item, index, key }, i) => {\n            const isOpen = open.includes(index)\n            const { trigger, panel } = ids(index)\n            const text = answerText(item.answer)\n            const question = <Highlight text={item.question} query={query} reduced={reduced} />\n\n            let body: ReactNode\n            if (variant === \"cards\") {\n              body = (\n                <motion.div\n                  className=\"border bg-card transition-[box-shadow,border-color] duration-300\"\n                  style={{\n                    borderRadius: \"var(--faq-radius)\",\n                    borderColor: isOpen ? \"var(--faq-accent)\" : undefined,\n                    boxShadow: isOpen\n                      ? \"0 0 0 1px var(--faq-accent), 0 18px 40px -20px color-mix(in oklab, var(--faq-accent) 55%, transparent)\"\n                      : \"0 0 0 0px transparent, 0 0 0 0 transparent\",\n                  }}\n                  animate={{\n                    y: isOpen && !reduced ? -2 : 0,\n                    opacity: anyOpen && !isOpen ? 0.62 : 1,\n                  }}\n                  whileHover={anyOpen && !isOpen ? { opacity: 0.9 } : undefined}\n                  transition={reduced ? INSTANT : SPRING}\n                >\n                  <h3>\n                    <button\n                      id={trigger}\n                      type=\"button\"\n                      data-faq-trigger=\"\"\n                      aria-expanded={isOpen}\n                      aria-controls={panel}\n                      onClick={() => toggle(index)}\n                      onKeyDown={onTriggerKeyDown}\n                      className=\"flex w-full items-center gap-4 px-5 py-4 text-left text-[15px] font-medium text-foreground outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--faq-accent)]\"\n                      style={{ borderRadius: \"var(--faq-radius)\" }}\n                    >\n                      <span className=\"flex-1\">{question}</span>\n                      <span\n                        className={cn(\n                          \"grid size-7 shrink-0 place-items-center rounded-full transition-colors duration-300\",\n                          isOpen ? \"bg-[color:var(--faq-accent)] text-white\" : \"bg-foreground/[0.05] text-muted-foreground\"\n                        )}\n                      >\n                        <TriggerIcon icon={icon} open={isOpen} reduced={reduced} />\n                      </span>\n                    </button>\n                  </h3>\n                  <Collapse open={isOpen} id={panel} labelledBy={trigger} duration={duration} reduced={reduced}>\n                    <motion.div\n                      className=\"px-5 pb-5 text-sm leading-relaxed text-muted-foreground\"\n                      initial={reduced ? false : { opacity: 0, y: -6 }}\n                      animate={{ opacity: 1, y: 0 }}\n                      exit={{ opacity: 0 }}\n                      transition={reduced ? INSTANT : { duration, ease: EASE_OUT, delay: 0.05 }}\n                    >\n                      {item.answer}\n                    </motion.div>\n                  </Collapse>\n                </motion.div>\n              )\n            } else if (variant === \"numbered\") {\n              body = (\n                <div className=\"grid grid-cols-[4.5rem_minmax(0,1fr)] gap-x-4 border-b py-5 sm:grid-cols-[6rem_minmax(0,1fr)]\">\n                  <span\n                    aria-hidden=\"true\"\n                    className={cn(\n                      \"font-[family-name:var(--font-display)] text-5xl leading-none font-semibold tabular-nums transition-colors duration-300 sm:text-6xl\",\n                      isOpen ? \"text-[color:var(--faq-accent)]\" : \"text-foreground/20\"\n                    )}\n                  >\n                    {String(index + 1).padStart(2, \"0\")}\n                  </span>\n                  <div className=\"min-w-0\">\n                    <h3>\n                      <button\n                        id={trigger}\n                        type=\"button\"\n                        data-faq-trigger=\"\"\n                        aria-expanded={isOpen}\n                        aria-controls={panel}\n                        onClick={() => toggle(index)}\n                        onKeyDown={onTriggerKeyDown}\n                        className=\"group flex w-full items-start gap-4 rounded-md pt-1.5 text-left text-lg font-medium text-foreground outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--faq-accent)] sm:pt-2.5\"\n                      >\n                        <span className=\"flex-1 transition-transform duration-300 group-hover:translate-x-0.5\">{question}</span>\n                        <TriggerIcon\n                          icon={icon}\n                          open={isOpen}\n                          reduced={reduced}\n                          className={cn(\"mt-1 transition-colors\", isOpen ? \"text-[color:var(--faq-accent)]\" : \"text-muted-foreground\")}\n                        />\n                      </button>\n                    </h3>\n                    <Collapse open={isOpen} id={panel} labelledBy={trigger} duration={duration} reduced={reduced}>\n                      <div className=\"pt-3 pr-8 text-sm leading-relaxed text-muted-foreground\">\n                        {text !== null ? <Words text={text} reduced={reduced} duration={duration} /> : item.answer}\n                      </div>\n                    </Collapse>\n                  </div>\n                </div>\n              )\n            } else {\n              body = (\n                <div className=\"border-b\">\n                  <h3>\n                    <button\n                      id={trigger}\n                      type=\"button\"\n                      data-faq-trigger=\"\"\n                      aria-expanded={isOpen}\n                      aria-controls={panel}\n                      onClick={() => toggle(index)}\n                      onKeyDown={onTriggerKeyDown}\n                      className=\"group flex w-full items-center gap-4 py-5 text-left text-[15px] font-medium text-foreground outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--faq-accent)]\"\n                    >\n                      <span className=\"flex-1\">{question}</span>\n                      <TriggerIcon\n                        icon={icon}\n                        open={isOpen}\n                        reduced={reduced}\n                        className={cn(\n                          \"transition-colors\",\n                          isOpen ? \"text-[color:var(--faq-accent)]\" : \"text-muted-foreground group-hover:text-foreground\"\n                        )}\n                      />\n                    </button>\n                  </h3>\n                  <Collapse open={isOpen} id={panel} labelledBy={trigger} duration={duration} reduced={reduced}>\n                    <motion.div\n                      className=\"pr-10 pb-5 text-sm leading-relaxed text-muted-foreground\"\n                      initial={reduced ? false : { opacity: 0, filter: \"blur(6px)\", y: 6 }}\n                      animate={{ opacity: 1, filter: \"blur(0px)\", y: 0 }}\n                      exit={{ opacity: 0, filter: \"blur(4px)\" }}\n                      transition={reduced ? INSTANT : { duration, ease: EASE_OUT, delay: 0.06 }}\n                    >\n                      {item.answer}\n                    </motion.div>\n                  </Collapse>\n                </div>\n              )\n            }\n\n            return (\n              <motion.div\n                key={key}\n                layout={reduced ? false : \"position\"}\n                className={variant === \"cards\" ? \"overflow-clip [overflow-clip-margin:28px]\" : \"overflow-hidden\"}\n                initial={{ height: 0, opacity: 0 }}\n                animate={{ height: \"auto\", opacity: 1 }}\n                exit={{ height: 0, opacity: 0 }}\n                transition={presence}\n              >\n                <motion.div className={variant === \"cards\" ? \"pb-3\" : undefined} {...enter(baseOffset + i)}>\n                  {body}\n                </motion.div>\n              </motion.div>\n            )\n          })}\n        </AnimatePresence>\n        {empty}\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "docs": "Docs, live playground and every prop: https://trytweenly.vercel.app/docs/components/faq",
  "type": "registry:component"
}