{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "empty",
  "title": "Empty",
  "description": "An invitation to act, not an apology: what is missing, and the one thing to do about it. Under half a zero, under the score's tacet, or on a page left blank on purpose.",
  "registryDependencies": [
    "https://thedirectors.agency/ui/r/0nlytype.json",
    "https://thedirectors.agency/ui/r/button.json"
  ],
  "files": [
    {
      "path": "registry/0nlytype/ui/empty.tsx",
      "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype EmptyProps = React.ComponentProps<\"div\"> & {\n  /**\n   * arc: a zero cropped to its top half, which is a fermata's arc. tacet: the word a score prints on a part with\n   * nothing to play, which dies away as you reach for the action. blank: the printer's page left blank on purpose,\n   * the words spread to its corners and one small line in the middle of the silence.\n   */\n  variant?: \"arc\" | \"tacet\" | \"blank\"\n}\n\n/** An invitation to act, not a mood. Say what is missing and what to do about it. */\nfunction Empty({ variant = \"arc\", className, ...props }: EmptyProps) {\n  return <div data-slot=\"empty\" data-variant={variant} className={cn(\"ot-empty\", className)} {...props} />\n}\n\n/**\n * The figure, decorative. In arc, a number (a zero by default). In tacet, the term (pass \"Tacet\").\n * In blank, the small line in the middle of the page (\"This space is left blank on purpose.\").\n */\nfunction EmptyFigure({ className, children = \"0\", ...props }: React.ComponentProps<\"p\">) {\n  return (\n    <p data-slot=\"empty-figure\" aria-hidden=\"true\" className={cn(\"ot-empty-figure\", className)} {...props}>\n      <span>{children}</span>\n    </p>\n  )\n}\n\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<\"p\">) {\n  return <p data-slot=\"empty-title\" className={cn(\"ot-empty-title\", className)} {...props} />\n}\n\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n  return <p data-slot=\"empty-description\" className={cn(\"ot-empty-description\", className)} {...props} />\n}\n\nfunction EmptyActions({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <div data-slot=\"empty-actions\" className={cn(\"ot-empty-actions\", className)} {...props} />\n}\n\nexport { Empty, EmptyFigure, EmptyTitle, EmptyDescription, EmptyActions, type EmptyProps }\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/0nlytype/styles/empty.css",
      "content": "@layer components {\n  /* ── ot-empty ── an invitation, not an apology */\n  .ot-empty { display: grid; justify-items: start; gap: var(--ot-space-4); }\n  /* Nothing, as a number: a zero so large it's cropped to its top half, which is a fermata's arc. */\n  .ot-empty-figure {\n    block-size: 0.46em; margin-block-end: var(--ot-space-2); clip-path: inset(-0.5em -0.2em 0); /* crops only the foot, so the arc can rise out of its box */\n    font-size: clamp(7rem, 16vw, 13rem); font-weight: 100; font-stretch: 125%; line-height: 0.76;\n    color: var(--ot-ink); user-select: none;\n  }\n  .ot-empty-figure > span { display: block; margin-inline-start: -0.06em; /* the zero's side-bearing, so its arc shares the title's left edge */ transition: translate var(--ot-andante) var(--ot-exhale); }\n  .ot-empty:has(.ot-btn:is(:hover, :focus-visible, [data-force~=\"hover\"])) .ot-empty-figure > span { translate: 0 -0.07em; }\n  .ot-empty-title { margin: 0; font-size: var(--ot-f); line-height: var(--ot-f-lh); letter-spacing: var(--ot-f-tr); font-weight: 200; color: var(--ot-ink); }\n  .ot-empty-description { max-inline-size: 44ch; }\n  .ot-empty-actions { display: flex; flex-wrap: wrap; gap: var(--ot-space-5); }\n\n  /* Tacet. What a score prints on a part with nothing to play: \"it is silent\". The term (italic, as musical terms are)\n     is set large in the expression face; reaching for the action is your entry, so the word dies away (morendo): it\n     fades to the rule and its letters loosen, a little, as the silence ends. */\n  .ot-empty[data-variant=\"tacet\"] .ot-empty-figure {\n    block-size: auto; margin-block-end: 0; clip-path: none;\n    font-family: var(--ot-expression); font-style: italic; font-weight: 400; font-stretch: normal;\n    font-size: calc(var(--ot-expression-scale) * var(--ot-fff)); line-height: 0.92; letter-spacing: -0.02em;\n  }\n  .ot-empty[data-variant=\"tacet\"] .ot-empty-figure > span { margin-inline-start: -0.03em; transition: color var(--ot-andante) var(--ot-exhale), letter-spacing var(--ot-andante) var(--ot-exhale); }\n  .ot-empty[data-variant=\"tacet\"]:has(.ot-btn:is(:hover, :focus-visible, [data-force~=\"hover\"])) .ot-empty-figure > span { translate: none; color: var(--ot-rule-strong); letter-spacing: 0.01em; }\n\n  /* Blank. The printer's page left blank on purpose. The words spread to its corners, as the posters' labels do (what's\n     missing at the top start, what to do at the top end in a narrow ragged column, the action at the foot), and the middle\n     is silence with one small line in it. Reaching for the action, that line loosens and pales: it makes room. */\n  .ot-empty[data-variant=\"blank\"] {\n    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto 1fr auto; justify-items: stretch;\n    column-gap: var(--ot-gutter); row-gap: var(--ot-space-6); min-block-size: min(34rem, 80vh);\n  }\n  .ot-empty[data-variant=\"blank\"] .ot-empty-title { grid-area: 1 / 1; font-size: var(--ot-mp); line-height: var(--ot-mp-lh); letter-spacing: var(--ot-mp-tr); font-weight: 400; text-wrap: balance; }\n  .ot-empty[data-variant=\"blank\"] .ot-empty-description { grid-area: 1 / 2; justify-self: end; max-inline-size: 24ch; margin: 0; text-align: end; text-wrap: pretty; }\n  .ot-empty[data-variant=\"blank\"] .ot-empty-figure {\n    grid-area: 2 / 1 / 3 / -1; place-self: center; block-size: auto; margin: 0; clip-path: none; max-inline-size: 30ch;\n    font-size: var(--ot-pp); line-height: var(--ot-pp-lh); letter-spacing: var(--ot-pp-tr); font-weight: 400; font-stretch: normal; text-align: center; color: var(--ot-pencil);\n  }\n  .ot-empty[data-variant=\"blank\"] .ot-empty-figure > span { margin: 0; transition: color var(--ot-andante) var(--ot-exhale), letter-spacing var(--ot-andante) var(--ot-exhale); }\n  .ot-empty[data-variant=\"blank\"]:has(.ot-btn:is(:hover, :focus-visible, [data-force~=\"hover\"])) .ot-empty-figure > span { translate: none; color: var(--ot-rule-strong); letter-spacing: 0.08em; }\n  .ot-empty[data-variant=\"blank\"] .ot-empty-actions { grid-area: 3 / 2; justify-self: end; justify-content: end; }\n}\n",
      "type": "registry:file",
      "target": "styles/0nlytype/empty.css"
    }
  ],
  "css": {
    "@import \"../styles/0nlytype/empty.css\"": {}
  },
  "meta": {
    "movement": "VII",
    "underneath": "native",
    "contract": "ot-empty"
  },
  "type": "registry:ui"
}
