{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "alert",
  "title": "Alert",
  "description": "A double bar: in a score, the sign that something changes here.",
  "registryDependencies": [
    "https://thedirectors.agency/ui/r/0nlytype.json",
    "https://thedirectors.agency/ui/r/button.json"
  ],
  "files": [
    {
      "path": "registry/0nlytype/ui/alert.tsx",
      "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype AlertProps = React.ComponentProps<\"div\"> & {\n  /**\n   * default: the double bar down the margin. error: the final bar, in the signal colour, with role=\"alert\"; for what\n   * failed, saying what to fix. cue: one hairline arrow runs in from the margin to the words, for a notice across the page.\n   * errata: a correction, set with AlertCorrection as the printer's \"for … read …\".\n   */\n  variant?: \"default\" | \"error\" | \"cue\" | \"errata\"\n  /** Draw the sign and bring the lines in one by one. Set it when the alert appears because of something the person did. */\n  arriving?: boolean\n}\n\n/** A double bar: in a score, the sign that something changes here. */\nfunction Alert({ className, variant = \"default\", arriving, ...props }: AlertProps) {\n  return (\n    <div\n      data-slot=\"alert\"\n      data-variant={variant === \"default\" ? undefined : variant}\n      data-arriving={arriving || undefined}\n      role={variant === \"error\" ? \"alert\" : \"status\"}\n      className={cn(\"ot-alert\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"p\">) {\n  return <p data-slot=\"alert-title\" className={cn(\"ot-alert-title\", className)} {...props} />\n}\n\nfunction AlertDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n  return <p data-slot=\"alert-description\" className={cn(\"ot-alert-description\", className)} {...props} />\n}\n\n/** The errata slip's formula: for what was printed, read what is true. The words are marked del and ins, so they're heard as a change. */\nfunction AlertCorrection({ was, now, className, ...props }: React.ComponentProps<\"p\"> & { was: React.ReactNode; now: React.ReactNode }) {\n  return (\n    <p data-slot=\"alert-correction\" className={cn(\"ot-alert-correction\", className)} {...props}>\n      <span>\n        <span>for</span>&nbsp;<del>{was}</del>\n      </span>{\" \"}\n      <span>\n        <span>read</span>&nbsp;<ins>{now}</ins>\n      </span>\n    </p>\n  )\n}\n\nfunction AlertActions({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <div data-slot=\"alert-actions\" className={cn(\"ot-alert-actions\", className)} {...props} />\n}\n\nexport { Alert, AlertTitle, AlertDescription, AlertCorrection, AlertActions, type AlertProps }\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/0nlytype/styles/alert.css",
      "content": "@layer components {\n  /* ── ot-alert ── a double bar: in a score, the sign that something changes here */\n  .ot-alert { --c: var(--ot-ink); --bar: 5px; position: relative; display: grid; justify-items: start; gap: var(--ot-space-2); padding-inline-start: calc(var(--ot-space-5) + var(--bar)); color: var(--ot-graphite); }\n  .ot-alert::before {\n    content: \"\"; position: absolute; inset-block: 0.3em 0.2em; inset-inline-start: 0; width: var(--bar); transform-origin: 50% 0;\n    background: linear-gradient(var(--c), var(--c)) 0 0 / var(--ot-hairline) 100% no-repeat, linear-gradient(var(--c), var(--c)) 100% 0 / var(--ot-stroke) 100% no-repeat;\n  }\n  .ot-alert-title { text-wrap: balance; font-size: var(--ot-mp); line-height: var(--ot-mp-lh); color: var(--ot-ink); }\n  /* Error: the final bar, thin then thick. What was happening stopped here. */\n  .ot-alert[data-variant=\"error\"] { --c: var(--ot-signal); --bar: 7px; }\n  .ot-alert[data-variant=\"error\"]::before { background-size: var(--ot-hairline) 100%, 4px 100%; }\n  .ot-alert[data-variant=\"error\"] .ot-alert-title { color: var(--ot-signal); }\n  .ot-alert-actions { display: flex; flex-wrap: wrap; gap: var(--ot-space-5); margin-block-start: var(--ot-space-2); }\n  .ot-alert[data-arriving]::before { animation: ot-draw-y var(--ot-andante) var(--ot-exhale) backwards; }\n  .ot-alert[data-arriving] > * { animation: ot-arrive var(--ot-moderato) var(--ot-exhale) backwards; animation-delay: calc(160ms + (sibling-index() - 1) * 2 * var(--ot-arpeggio)); }\n\n  /* Cue (\"Watch this space.\"): a hairline arrow runs in from the margin and stops at the first word. */\n  .ot-alert[data-variant=\"cue\"] { --cue: clamp(var(--ot-space-6), 12vw, var(--ot-space-9)); --at: calc(var(--ot-mp) * 0.84); padding-inline-start: calc(var(--cue) + var(--ot-space-4)); }\n  .ot-alert[data-variant=\"cue\"]::before { inset-block: var(--at) auto; width: calc(var(--cue) - 3px); height: var(--ot-hairline); background: var(--c); transform-origin: 0 50%; }\n  .ot-alert[data-variant=\"cue\"]::after { content: \"\"; position: absolute; inset-block-start: calc(var(--at) - 3px); inset-inline-start: calc(var(--cue) - 9px); width: 9px; height: 7px; background: var(--c); clip-path: polygon(0 0, 100% 50%, 0 100%, 2px 50%); }\n  :is([dir=\"rtl\"], [dir=\"rtl\"] *).ot-alert[data-variant=\"cue\"]::before { transform-origin: 100% 50%; }\n  :is([dir=\"rtl\"], [dir=\"rtl\"] *).ot-alert[data-variant=\"cue\"]::after { scale: -1 1; }\n  .ot-alert[data-variant=\"cue\"][data-arriving]::before { animation-name: ot-draw-x; }\n  .ot-alert[data-variant=\"cue\"][data-arriving]::after { animation: ot-alert-head var(--ot-moderato) var(--ot-spiccato) 420ms backwards; }\n  .ot-alert[data-variant=\"cue\"][data-arriving] > * { animation-delay: calc(560ms + (sibling-index() - 1) * 2 * var(--ot-arpeggio)); }\n  @keyframes ot-alert-head { from { opacity: 0; scale: 0.4; } }\n  :is([dir=\"rtl\"], [dir=\"rtl\"] *).ot-alert[data-variant=\"cue\"][data-arriving]::after { animation-name: ot-alert-head-rtl; }\n  @keyframes ot-alert-head-rtl { from { opacity: 0; scale: -0.4 0.4; } }\n\n  /* Errata: the printer's slip. \"for\" what was set, \"read\" what is true: small upright words between two large italics. */\n  .ot-alert[data-variant=\"errata\"] { padding-inline-start: 0; }\n  .ot-alert[data-variant=\"errata\"]::before { content: none; }\n  .ot-alert-correction { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--ot-space-4); margin-block: var(--ot-space-1); font-size: clamp(var(--ot-mp), 7vw, var(--ot-mf)); line-height: var(--ot-mf-lh); }\n  .ot-alert-correction > span > span { font-size: var(--ot-pp); letter-spacing: 0.02em; color: var(--ot-pencil); }\n  .ot-alert-correction :is(del, ins) { font-family: var(--ot-expression); font-style: italic; font-size: calc(var(--ot-expression-scale) * 1em); line-height: 1; text-decoration: none; }\n  .ot-alert-correction del { color: var(--ot-pencil); }\n  .ot-alert-correction ins { color: var(--ot-ink); }\n  .ot-alert[data-arriving] .ot-alert-correction del { animation: ot-alert-stale var(--ot-andante) var(--ot-breath) 360ms backwards; }\n  .ot-alert[data-arriving] .ot-alert-correction ins { animation: ot-alert-write var(--ot-andante) var(--ot-exhale) 760ms backwards; }\n  @keyframes ot-alert-stale { from { color: var(--ot-ink); } }\n  @keyframes ot-alert-write { from { clip-path: inset(-0.3em 100% -0.3em -0.3em); } to { clip-path: inset(-0.3em -0.3em -0.3em -0.3em); } }\n  :is([dir=\"rtl\"], [dir=\"rtl\"] *).ot-alert[data-arriving] .ot-alert-correction ins { animation-name: ot-alert-write-rtl; }\n  @keyframes ot-alert-write-rtl { from { clip-path: inset(-0.3em -0.3em -0.3em 100%); } to { clip-path: inset(-0.3em -0.3em -0.3em -0.3em); } }\n\n  @media (forced-colors: active) {\n    .ot-alert { --c: CanvasText; }\n    .ot-alert::before, .ot-alert::after { forced-color-adjust: none; }\n  }\n}\n",
      "type": "registry:file",
      "target": "styles/0nlytype/alert.css"
    }
  ],
  "css": {
    "@import \"../styles/0nlytype/alert.css\"": {}
  },
  "meta": {
    "movement": "VII",
    "underneath": "native",
    "contract": "ot-alert"
  },
  "type": "registry:ui"
}
