{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "accordion",
  "title": "UI Accordion",
  "description": "A disclosure whose opened/closed state is a pure function of the timeline; the panel reveal, chevron, and background are keyframed presets.",
  "dependencies": ["remotion"],
  "registryDependencies": ["@remocn/remocn-ui"],
  "files": [
    {
      "path": "registry/remocn-ui/accordion/index.tsx",
      "content": "\"use client\";\n\nimport { mixOklch, type RemocnTheme, useRemocnTheme } from \"@/lib/remocn-ui\";\n\nexport type AccordionState = \"opened\" | \"closed\";\n\ntype AccordionVariant = \"default\" | \"ghost\";\n\nexport interface AccordionProps {\n  state?: AccordionState;\n  style?: AccordionStyle;\n  title?: string;\n  content?: string;\n  contentHeight?: number;\n  variant?: AccordionVariant;\n  theme?: Partial<RemocnTheme>;\n  className?: string;\n}\n\nconst CARD_WIDTH = 440;\n\ninterface VariantTokens {\n  bordered: boolean;\n  closedBg: string;\n  openBg: string;\n}\n\nfunction variantTokens(\n  variant: AccordionVariant,\n  theme: RemocnTheme,\n): VariantTokens {\n  const variants = {\n    ghost: {\n      bordered: false,\n      closedBg: theme.background,\n      openBg: mixOklch(theme.background, theme.muted, 0.25),\n    },\n    default: {\n      bordered: true,\n      closedBg: theme.background,\n      openBg: mixOklch(theme.background, theme.muted, 0.5),\n    },\n  };\n\n  return variants[variant] ?? variants.default;\n}\n\nexport interface AccordionStyle {\n  panelHeight: number;\n  panelOpacity: number;\n  chevronRotation: number;\n  background: string;\n}\n\nexport interface AccordionStyleContext {\n  bordered: boolean;\n  closedBg: string;\n  openBg: string;\n  border: string;\n  foreground: string;\n  mutedForeground: string;\n}\n\nexport function accordionStyleContext(\n  variant: AccordionVariant,\n  theme: RemocnTheme,\n): AccordionStyleContext {\n  const tokens = variantTokens(variant, theme);\n  return {\n    bordered: tokens.bordered,\n    closedBg: tokens.closedBg,\n    openBg: tokens.openBg,\n    border: theme.border,\n    foreground: theme.foreground,\n    mutedForeground: theme.mutedForeground,\n  };\n}\n\nexport function accordionStyle(\n  state: AccordionState,\n  ctx: AccordionStyleContext,\n): AccordionStyle {\n  switch (state) {\n    case \"opened\":\n      return {\n        panelHeight: 1,\n        panelOpacity: 1,\n        chevronRotation: 180,\n        background: ctx.openBg,\n      };\n    default:\n      return {\n        panelHeight: 0,\n        panelOpacity: 0,\n        chevronRotation: 0,\n        background: ctx.closedBg,\n      };\n  }\n}\n\nexport function Accordion({\n  state = \"closed\",\n  style,\n  title = \"Is it accessible?\",\n  content = \"Yes. It adheres to the WAI-ARIA design pattern.\",\n  contentHeight = 64,\n  variant = \"default\",\n  theme: themeOverride,\n  className,\n}: AccordionProps) {\n  const theme = useRemocnTheme(themeOverride, \"light\");\n\n  const ctx = accordionStyleContext(variant, theme);\n  const v = style ?? accordionStyle(state, ctx);\n\n  return (\n    <div\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        background: \"transparent\",\n        fontFamily:\n          \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\",\n      }}\n    >\n      <div\n        className={className}\n        style={{\n          width: CARD_WIDTH,\n          background: v.background,\n          border: ctx.bordered\n            ? `1px solid ${ctx.border}`\n            : \"1px solid transparent\",\n          borderRadius: theme.radius,\n          overflow: \"hidden\",\n        }}\n      >\n        {}\n        <div\n          style={{\n            display: \"flex\",\n            alignItems: \"center\",\n            justifyContent: \"space-between\",\n            gap: 24,\n            padding: 16,\n            fontSize: 15,\n            fontWeight: 500,\n            letterSpacing: \"-0.01em\",\n            color: ctx.foreground,\n          }}\n        >\n          <span>{title}</span>\n          <svg\n            width={16}\n            height={16}\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            style={{\n              flexShrink: 0,\n              transform: `rotate(${v.chevronRotation}deg)`,\n            }}\n          >\n            <path\n              d=\"M6 9l6 6 6-6\"\n              stroke={ctx.mutedForeground}\n              strokeWidth=\"2.2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n            />\n          </svg>\n        </div>\n        {}\n        <div\n          style={{\n            height: contentHeight * v.panelHeight,\n            opacity: v.panelOpacity,\n            overflow: \"hidden\",\n          }}\n        >\n          <div\n            style={{\n              padding: \"0 16px 16px\",\n              fontSize: 14,\n              lineHeight: 1.5,\n              color: ctx.mutedForeground,\n            }}\n          >\n            {content}\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/accordion.tsx"
    },
    {
      "path": "registry/remocn-ui/accordion/use-accordion-transition.ts",
      "content": "\"use client\";\n\nimport {\n  type AccordionState,\n  type AccordionStyle,\n  accordionStyle,\n  accordionStyleContext,\n} from \"@/components/remocn/accordion\";\nimport {\n  easings,\n  mixOklch,\n  type RemocnTheme,\n  type Step,\n  useRemocnTheme,\n  useStateTransition,\n} from \"@/lib/remocn-ui\";\n\nexport const DEFAULT_DURATION = 14;\n\nexport function tweenAccordionStyle(\n  a: AccordionStyle,\n  b: AccordionStyle,\n  t: number,\n): AccordionStyle {\n  return {\n    panelHeight: a.panelHeight + (b.panelHeight - a.panelHeight) * t,\n    panelOpacity: a.panelOpacity + (b.panelOpacity - a.panelOpacity) * t,\n    chevronRotation:\n      a.chevronRotation + (b.chevronRotation - a.chevronRotation) * t,\n    background: mixOklch(a.background, b.background, t),\n  };\n}\n\nexport interface AccordionTransitionOptions {\n  variant?: \"default\" | \"ghost\";\n  theme?: Partial<RemocnTheme>;\n  mode?: \"light\" | \"dark\";\n  speed?: number;\n  defaultDuration?: number;\n}\n\nexport function useAccordionTransition(\n  steps: Step<AccordionState>[],\n  opts: AccordionTransitionOptions = {},\n): AccordionStyle {\n  const {\n    variant = \"default\",\n    theme: themeOverride,\n    mode,\n    speed = 1,\n    defaultDuration = DEFAULT_DURATION,\n  } = opts;\n  const theme = useRemocnTheme(themeOverride, mode);\n  const ctx = accordionStyleContext(variant, theme);\n  const { from, to, progress } = useStateTransition(\n    steps,\n    \"closed\",\n    speed,\n    defaultDuration,\n  );\n  const t = easings.out(progress);\n  return tweenAccordionStyle(\n    accordionStyle(from, ctx),\n    accordionStyle(to, ctx),\n    t,\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/use-accordion-transition.ts"
    }
  ],
  "type": "registry:component"
}
