{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "receipt",
  "title": "Receipt",
  "description": "Thermal paper with torn edges. Lines print in as they're added; a stamp or seal lands when it's paid.",
  "dependencies": [
    "@base-ui/react",
    "cn"
  ],
  "registryDependencies": [
    "https://bevel-ui.vercel.app/r/bevel.json",
    "https://bevel-ui.vercel.app/r/amount.json",
    "https://bevel-ui.vercel.app/r/stamp.json"
  ],
  "files": [
    {
      "path": "registry/bevel/ui/receipt.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cn } from \"cn\"\n\ntype ReceiptProps = useRender.ComponentProps<\"div\"> & {\n  /** \"carbon\" adds the yellow copy behind, offset like a carbon book. */\n  variant?: \"thermal\" | \"carbon\"\n}\n\nconst ReceiptContext = React.createContext<{ mountedRef: React.RefObject<boolean> }>({\n  mountedRef: { current: false },\n})\n\n/** A strip of thermal paper. Lines added after it renders print in. */\nfunction Receipt({ className, render, variant = \"thermal\", children, ...props }: ReceiptProps) {\n  const mountedRef = React.useRef(false)\n  React.useEffect(() => {\n    mountedRef.current = true\n  }, [])\n  const context = React.useMemo(() => ({ mountedRef }), [])\n\n  const element = useRender({\n    defaultTagName: \"div\",\n    render,\n    props: mergeProps<\"div\">(\n      {\n        \"data-slot\": \"receipt\",\n        \"data-variant\": variant,\n        className: cn(\"receipt-shadow relative isolate w-full max-w-xs\", className),\n        children: (\n          <>\n            {variant === \"carbon\" && (\n              <div\n                aria-hidden\n                data-slot=\"receipt-carbon\"\n                className=\"receipt-edges absolute inset-0 -z-10 translate-x-(--receipt-carbon-offset) translate-y-(--receipt-carbon-offset) rotate-1 bg-(--receipt-carbon)\"\n              />\n            )}\n            <div\n              data-slot=\"receipt-paper\"\n              className=\"bevel-paper receipt-edges flex flex-col gap-3 px-5 py-7 font-mono text-sm shadow-none\"\n            >\n              {children}\n            </div>\n          </>\n        ),\n      } as React.ComponentProps<\"div\">,\n      props\n    ),\n  })\n  return <ReceiptContext value={context}>{element}</ReceiptContext>\n}\n\nfunction ReceiptHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"receipt-header\"\n      className={cn(\"flex flex-col items-center gap-0.5 text-center\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction ReceiptTitle({ className, ...props }: React.ComponentProps<\"p\">) {\n  return (\n    <p\n      data-slot=\"receipt-title\"\n      className={cn(\"font-bold tracking-(--bevel-tracking-label) uppercase\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction ReceiptMeta({ className, ...props }: React.ComponentProps<\"p\">) {\n  return (\n    <p\n      data-slot=\"receipt-meta\"\n      className={cn(\"text-(length:--bevel-fine) text-(--bevel-paper-muted)\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction ReceiptItems({ className, ...props }: React.ComponentProps<\"dl\">) {\n  return <dl data-slot=\"receipt-items\" className={cn(\"flex flex-col gap-1\", className)} {...props} />\n}\n\n/** One line. Lines added after the receipt renders print in from above. */\nfunction ReceiptItem({ className, ...props }: React.ComponentProps<\"div\">) {\n  const { mountedRef } = React.useContext(ReceiptContext)\n  const [prints] = React.useState(() => mountedRef.current)\n  return (\n    <div\n      data-slot=\"receipt-item\"\n      data-enter={prints ? \"\" : undefined}\n      className={cn(\n        \"flex items-baseline gap-2\",\n        \"transition-[translate,opacity] duration-(--bevel-duration-move) ease-(--bevel-ease-out) motion-reduce:transition-none\",\n        \"data-enter:starting:-translate-y-(--receipt-print-in) data-enter:starting:opacity-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/** The item's name, followed by a dotted leader to the value. */\nfunction ReceiptLabel({ className, ...props }: React.ComponentProps<\"dt\">) {\n  return (\n    <dt\n      data-slot=\"receipt-label\"\n      className={cn(\n        \"flex min-w-0 flex-1 items-baseline gap-2 after:min-w-4 after:flex-1 after:border-b after:border-dotted after:border-current/40 after:content-['']\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ReceiptValue({ className, ...props }: React.ComponentProps<\"dd\">) {\n  return <dd data-slot=\"receipt-value\" className={cn(\"whitespace-nowrap\", className)} {...props} />\n}\n\nfunction ReceiptSeparator({ className, ...props }: React.ComponentProps<\"hr\">) {\n  return (\n    <hr\n      data-slot=\"receipt-separator\"\n      className={cn(\"border-0 border-t border-dashed border-current/40\", className)}\n      {...props}\n    />\n  )\n}\n\n/** The total line: same parts as an item, printed bold. A list of its own. */\nfunction ReceiptTotal({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <dl data-slot=\"receipt-total\">\n      <ReceiptItem\n        className={cn(\"text-base font-bold [&_[data-slot=receipt-label]]:after:border-transparent\", className)}\n        {...props}\n      />\n    </dl>\n  )\n}\n\nfunction ReceiptFooter({ className, ...props }: React.ComponentProps<\"p\">) {\n  return (\n    <p\n      data-slot=\"receipt-footer\"\n      className={cn(\"text-center text-(length:--bevel-fine) text-(--bevel-paper-muted)\", className)}\n      {...props}\n    />\n  )\n}\n\ntype ReceiptMarkProps = React.ComponentProps<\"div\"> & {\n  /**\n   * Press the mark over the printed lines instead of in its own space. Only\n   * use it where it can't cover anything that must stay readable.\n   */\n  overlay?: boolean\n}\n\n/** Holds a Stamp or Seal. By default it prints in its own space on the receipt, so it never covers a figure. */\nfunction ReceiptMark({ className, overlay = false, ...props }: ReceiptMarkProps) {\n  return (\n    <div\n      data-slot=\"receipt-mark\"\n      data-overlay={overlay ? \"\" : undefined}\n      className={cn(\n        \"pointer-events-none flex min-h-14 items-center justify-center\",\n        \"data-overlay:absolute data-overlay:right-6 data-overlay:bottom-12 data-overlay:z-10 data-overlay:min-h-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Receipt,\n  ReceiptHeader,\n  ReceiptTitle,\n  ReceiptMeta,\n  ReceiptItems,\n  ReceiptItem,\n  ReceiptLabel,\n  ReceiptValue,\n  ReceiptSeparator,\n  ReceiptTotal,\n  ReceiptFooter,\n  ReceiptMark,\n}\nexport type { ReceiptProps, ReceiptMarkProps }\n",
      "type": "registry:ui"
    }
  ],
  "css": {
    ":root": {
      "--receipt-tooth": "0.625rem",
      "--receipt-carbon": "oklch(0.93 0.07 95)",
      "--receipt-carbon-offset": "0.375rem",
      "--receipt-print-in": "0.5em"
    },
    "@utility receipt-edges": {
      "mask-image": "conic-gradient(from 135deg at top, transparent, black 1deg 89deg, transparent 90deg), conic-gradient(from -45deg at bottom, transparent, black 1deg 89deg, transparent 90deg), linear-gradient(black, black)",
      "mask-size": "var(--receipt-tooth) var(--receipt-tooth), var(--receipt-tooth) var(--receipt-tooth), 100% calc(100% - var(--receipt-tooth))",
      "mask-position": "top, bottom, center",
      "mask-repeat": "repeat-x, repeat-x, no-repeat"
    },
    "@utility receipt-shadow": {
      "filter": "drop-shadow(0 1px 1px var(--bevel-cast)) drop-shadow(0 6px 10px var(--bevel-cast))"
    }
  },
  "categories": [
    "money"
  ],
  "type": "registry:ui"
}