{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dialog",
  "type": "registry:component",
  "title": "Dialog — accessible stop-the-world behavior",
  "description": "Individually installable Radix Dialog composition. Radix owns focus trapping, Escape, return focus, portal behavior, and ARIA wiring; the component owns only the Subconscious token skin.",
  "dependencies": [
    "@radix-ui/react-dialog"
  ],
  "files": [
    {
      "path": "registry/components/dialog.tsx",
      "type": "registry:component",
      "content": "'use client';\n\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\n\nexport type DialogSize = 'sm' | 'md' | 'lg';\n\nexport interface DialogProps {\n  open: boolean;\n  onOpenChange(open: boolean): void;\n  /** Trigger is rendered with Radix `asChild`, enabling automatic focus return. */\n  trigger?: ReactNode;\n  title: ReactNode;\n  description?: ReactNode;\n  eyebrow?: ReactNode;\n  eyebrowAside?: ReactNode;\n  size?: DialogSize;\n  destructive?: boolean;\n  closeLabel?: string;\n  children?: ReactNode;\n  overlayProps?: HTMLAttributes<HTMLDivElement>;\n  contentProps?: HTMLAttributes<HTMLDivElement>;\n}\n\nfunction classes(...values: Array<string | false | null | undefined>): string {\n  return values.filter(Boolean).join(' ');\n}\n\n/**\n * Accessible stop-the-world behavior. Radix owns focus trapping, Escape,\n * return focus, portal behavior, and ARIA wiring. The registry item owns only\n * the token skin and readable composition API.\n */\nexport function Dialog({\n  open,\n  onOpenChange,\n  trigger,\n  title,\n  description,\n  eyebrow,\n  eyebrowAside,\n  size = 'md',\n  destructive = false,\n  closeLabel = 'Close',\n  children,\n  overlayProps,\n  contentProps,\n}: DialogProps) {\n  return (\n    <DialogPrimitive.Root open={open} onOpenChange={onOpenChange}>\n      {trigger ? <DialogPrimitive.Trigger asChild>{trigger}</DialogPrimitive.Trigger> : null}\n      <DialogPrimitive.Portal>\n        <DialogPrimitive.Overlay {...overlayProps} className={classes('sc-dialog-overlay', overlayProps?.className)} />\n        <DialogPrimitive.Content\n          {...contentProps}\n          aria-modal=\"true\"\n          className={classes(\n            'sc-dialog',\n            size !== 'md' && `sc-dialog--${size}`,\n            destructive && 'sc-dialog--destructive',\n            contentProps?.className,\n          )}\n        >\n          <DialogPrimitive.Close asChild>\n            <button className=\"sc-dialog__close\" type=\"button\" aria-label={closeLabel}>✕</button>\n          </DialogPrimitive.Close>\n          {eyebrow ? (\n            <p className=\"sc-dialog__eyebrow\">\n              <span>{eyebrow}</span>\n              {eyebrowAside ? <span className=\"sc-dialog__eyebrow-aside\">{eyebrowAside}</span> : null}\n            </p>\n          ) : null}\n          <DialogPrimitive.Title className=\"sc-dialog__title\">{title}</DialogPrimitive.Title>\n          {description ? (\n            <DialogPrimitive.Description className=\"sc-dialog__description\">{description}</DialogPrimitive.Description>\n          ) : null}\n          {children}\n        </DialogPrimitive.Content>\n      </DialogPrimitive.Portal>\n    </DialogPrimitive.Root>\n  );\n}\n\nexport const DialogActions = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n  function DialogActions({ className, ...props }, ref) {\n    return <div {...props} className={classes('sc-dialog__actions', className)} ref={ref} />;\n  },\n);\n\nexport const DialogRoot = DialogPrimitive.Root;\nexport const DialogTrigger = DialogPrimitive.Trigger;\nexport const DialogClose = DialogPrimitive.Close;\n"
    },
    {
      "path": "registry/styles/dialog.css",
      "type": "registry:style",
      "target": "~/src/styles/subconscious/dialog.css",
      "content": "/* Accessible Dialog token skin. Import @subconscious-ai/design/full.css first. */\n.sc-dialog-overlay {\n  position: fixed;\n  inset: 0;\n  z-index: 1000;\n  background: color-mix(in srgb, var(--color) 22%, transparent);\n  animation: sc-dialog-fade var(--dur-fast, 200ms) ease-out;\n}\n.sc-dialog {\n  position: fixed;\n  z-index: 1001;\n  top: 50%;\n  left: 50%;\n  width: min(540px, calc(100vw - 2rem));\n  max-height: min(80vh, 720px);\n  overflow: auto;\n  transform: translate(-50%, -50%);\n  border: 0;\n  border-top: var(--rule-heavy, 3px) solid var(--color);\n  border-bottom: 1px solid var(--hairline);\n  border-radius: var(--radius-sharp, 0);\n  background: var(--backgroundColor);\n  color: var(--color);\n  padding: var(--sp-6) var(--sp-7) var(--sp-5);\n  animation: sc-dialog-enter var(--dur-fast, 200ms) var(--ease-out-quart, cubic-bezier(0.25, 1, 0.5, 1));\n}\n.sc-dialog--sm { width: min(420px, calc(100vw - 2rem)); }\n.sc-dialog--lg { width: min(720px, calc(100vw - 2rem)); }\n.sc-dialog--destructive { border-top-color: var(--red); }\n.sc-dialog__eyebrow {\n  margin: 0 0 var(--sp-4);\n  font: 500 var(--fs-meta) / 1.3 var(--font-mono);\n  letter-spacing: .08em;\n  text-transform: uppercase;\n}\n.sc-dialog__eyebrow::before { content: '●'; margin-right: var(--sp-2); color: var(--red); }\n.sc-dialog__eyebrow-aside { margin-left: var(--sp-3); color: var(--grey-500); text-transform: none; }\n.sc-dialog__title { margin: 0; font: 300 var(--fs-h3) / 1.05 var(--font-display); }\n.sc-dialog__description { margin: var(--sp-3) 0 0; max-width: 62ch; color: var(--grey-700); }\n.sc-dialog__close {\n  position: absolute;\n  top: var(--sp-3);\n  right: var(--sp-3);\n  min-width: 44px;\n  min-height: 44px;\n  border: 0;\n  background: transparent;\n  color: var(--color);\n  cursor: pointer;\n}\n.sc-dialog__close:focus-visible { outline: var(--focus-ring); outline-offset: 2px; }\n.sc-dialog__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--sp-3); margin-top: var(--sp-6); }\n@keyframes sc-dialog-fade { from { opacity: 0; } }\n@keyframes sc-dialog-enter { from { opacity: 0; transform: translate(-50%, calc(-50% + 12px)); } }\n@media (prefers-reduced-motion: reduce) {\n  .sc-dialog-overlay,\n  .sc-dialog { animation-duration: 1ms; }\n}\n"
    }
  ]
}
