{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "folder",
  "title": "Folder",
  "description": "Labelled folder illustration with a controlled open state. No built-in autoplay.",
  "registryDependencies": [
    "@jbm/tokens"
  ],
  "files": [
    {
      "path": "registry/jbm/ui/folder.tsx",
      "content": "import * as React from \"react\"\nimport { color, font } from \"../lib/tokens\"\n\n/** Shared complete folder silhouette for standalone folders and filing drawers. */\nexport function FolderOutline({\n  x = 25,\n  y = 55,\n  w = 205,\n  h = 144,\n  tabX = x,\n  tabWidth = 83,\n  tabHeight = 27,\n  tabSlope = 17,\n  fill = color.accent,\n}: {\n  x?: number\n  y?: number\n  w?: number\n  h?: number\n  tabX?: number\n  tabWidth?: number\n  tabHeight?: number\n  tabSlope?: number\n  fill?: string\n}) {\n  return (\n    <path\n      d={`M${x} ${y + tabHeight}H${tabX}V${y}H${tabX + tabWidth - tabSlope}L${tabX + tabWidth} ${y + tabSlope}H${x + w}V${y + h}H${x}Z`}\n      fill={fill}\n      stroke={color.ink}\n      strokeWidth={2}\n      strokeLinejoin=\"round\"\n    />\n  )\n}\n\nexport type FolderProps = React.SVGProps<SVGSVGElement> & {\n  label?: string\n  open?: number\n  tone?: \"accent\" | \"ink\"\n  /** SVG contents in the 260×220 folder space, drawn behind its front panel. */\n  children?: React.ReactNode\n}\n\n/** Controlled illustration: open is 0–1; drive it with a slider or video timeline. */\nexport function Folder({\n  label,\n  open = 0,\n  tone = \"accent\",\n  style,\n  children,\n  ...props\n}: FolderProps) {\n  const p = Number.isFinite(open) ? Math.max(0, Math.min(1, open)) : 0\n  const fill = tone === \"accent\" ? color.accent : color.ink\n  // Turn the landscape sheet from 180° to 90°, keeping its size fixed.\n  const paperAngle = 180 - 90 * p\n  // Lift enough to clear the lower corner's sweep, then keep that clearance.\n  // The grip follows a shallow sideways arc as the sheet is pulled upright.\n  const clearanceAngle = Math.min((90 * p * Math.PI) / 180, Math.atan2(79, 44))\n  const paperLift =\n    79 * Math.sin(clearanceAngle) + 44 * Math.cos(clearanceAngle) - 44\n  const paperDrift = 8 * Math.sin(Math.PI * p) - 18 * p\n  // Project the printed label onto the front plane, around its baseline.\n  const labelWidth = 1 + (30 * p * 25) / (205 * 110)\n  const labelShear = (81.5 * 30 * p) / (205 * 110)\n  const labelHeight = 1 - (35 * p) / 110\n  return (\n    <svg\n      viewBox=\"0 0 260 220\"\n      width={260}\n      height={220}\n      role={label ? \"img\" : undefined}\n      aria-label={\n        label ? `${label}, ${p > 0.5 ? \"open\" : \"closed\"} folder` : undefined\n      }\n      aria-hidden={label ? undefined : true}\n      {...props}\n      style={{ display: \"block\", maxWidth: \"100%\", height: \"auto\", ...style }}\n    >\n      <FolderOutline fill={fill} />\n      {children ?? (\n        <g\n          transform={`translate(${256 + paperDrift} ${-paperLift}) scale(-1 1) rotate(${paperAngle - 180} 128 140)`}\n        >\n          <path d=\"M49 78H180L207 104V184H49Z\" fill={color.card} />\n          <path\n            d=\"M180 78H49V184H207V104\"\n            fill=\"none\"\n            stroke={color.ink}\n            strokeWidth={2}\n          />\n          <path d=\"M180 78V104H207\" fill={color.line} />\n          <path d=\"M158 106V164\" stroke={color.accent} strokeWidth={6} />\n          <path\n            d=\"M136 98V164M114 112V164M92 98V164\"\n            stroke={color.line}\n            strokeWidth={4}\n          />\n        </g>\n      )}\n      <path\n        d={`M${25 - p * 15} ${95 + p * 35}H${230 + p * 15}L230 205H25Z`}\n        fill={fill}\n        stroke={color.ink}\n        strokeWidth={2}\n        strokeLinejoin=\"round\"\n      />\n      {label && (\n        <text\n          transform={`matrix(${labelWidth} 0 ${labelShear} ${labelHeight} ${127.5 - 81.5 * labelWidth} ${205 - 25 * labelHeight})`}\n          fontFamily={font.mono}\n          fontSize={16}\n          fontWeight={600}\n          fill={color.bg}\n        >\n          {label.length > 16 ? `${label.slice(0, 15)}…` : label}\n        </text>\n      )}\n    </svg>\n  )\n}\n",
      "type": "registry:ui",
      "target": "src/jbm/ui/folder.tsx"
    }
  ],
  "type": "registry:ui"
}