{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "card",
  "title": "Card",
  "description": "A column under a rule, not a box. Point at it and an ink stroke passes along the rule.",
  "dependencies": [
    "@radix-ui/react-slot"
  ],
  "registryDependencies": [
    "https://thedirectors.agency/ui/r/0nlytype.json",
    "https://thedirectors.agency/ui/r/meta.json"
  ],
  "files": [
    {
      "path": "registry/0nlytype/ui/card.tsx",
      "content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Meta } from \"@/components/ui/meta\"\n\ntype CardProps = React.ComponentProps<\"article\"> & {\n  /**\n   * rule: a column under a rule, the giant letter hanging from it.\n   * epigraph: someone's words set before the name, the way a book sets a quotation before a chapter.\n   * ledger: figures that add up, the total ruled off the way an account is.\n   */\n  variant?: \"rule\" | \"epigraph\" | \"ledger\"\n}\n\n/** A column under a rule, not a box. Point at it and an ink stroke passes along the rule. */\nfunction Card({ variant = \"rule\", className, ...props }: CardProps) {\n  return <article data-slot=\"card\" data-variant={variant} className={cn(\"ot-card\", className)} {...props} />\n}\n\n/** One giant letter, cropped by the rule like a poster's headline. Decorative. */\nfunction CardFigure({ className, ...props }: React.ComponentProps<\"p\">) {\n  return <p data-slot=\"card-figure\" aria-hidden=\"true\" className={cn(\"ot-card-figure\", className)} {...props} />\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"h3\">) {\n  return <h3 data-slot=\"card-title\" className={cn(\"ot-card-title\", className)} {...props} />\n}\n\n/** The link inside the title. Its hit area stretches over the whole card, so the card is one target. */\nfunction CardLink({ className, asChild = false, ...props }: React.ComponentProps<\"a\"> & { asChild?: boolean }) {\n  const Comp = asChild ? Slot : \"a\"\n  return <Comp data-slot=\"card-link\" className={cn(\"ot-card-link\", className)} {...props} />\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n  return <p data-slot=\"card-description\" className={cn(\"ot-card-body\", className)} {...props} />\n}\n\n/** Ledger figures: pairs of <dt> and <dd> in a <div> each. The last pair is the total. */\nfunction CardSum({ className, ...props }: React.ComponentProps<\"dl\">) {\n  return <dl data-slot=\"card-sum\" className={cn(\"ot-card-sum\", className)} {...props} />\n}\n\n/** A frame row at the foot: small facts held apart by hairlines. */\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return <Meta data-slot=\"card-footer\" className={cn(\"ot-card-foot\", className)} {...props} />\n}\n\nexport { Card, CardFigure, CardTitle, CardLink, CardDescription, CardSum, CardFooter, type CardProps }\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/0nlytype/styles/card.css",
      "content": "@layer components {\n  /* ── ot-card ── a column under a rule, not a box */\n  .ot-card {\n    position: relative; display: grid; align-content: start; gap: var(--ot-space-3); padding-top: var(--ot-space-4);\n    background:\n      linear-gradient(var(--ot-ink), var(--ot-ink)) no-repeat 100% 0 / 0% var(--ot-stroke),\n      linear-gradient(var(--ot-ink), var(--ot-ink)) no-repeat 0 0 / 100% var(--ot-hairline);\n    transition: background-size var(--ot-andante) var(--ot-exhale), background-position 0s;\n  }\n  .ot-card:is(:has(.ot-card-link:is(:hover, :focus-visible)), [data-force~=\"hover\"]) { background-position: 0 0, 0 0; background-size: 100% var(--ot-stroke), 100% var(--ot-hairline); }\n  .ot-card:is([dir=\"rtl\"], [dir=\"rtl\"] *) { background-position: 0 0, 0 0; }\n  .ot-card:is([dir=\"rtl\"], [dir=\"rtl\"] *):is(:has(.ot-card-link:is(:hover, :focus-visible)), [data-force~=\"hover\"]) { background-position: 100% 0, 0 0; }\n  /* The letter hangs from the rule, its top cut off by it, the way SPECTRA's line cuts its word. */\n  .ot-card:has(> .ot-card-figure:first-child) { padding-top: 0; }\n  .ot-card-figure { display: flex; align-items: flex-end; height: 0.5em; margin-bottom: var(--ot-space-2); overflow: clip; font-size: clamp(6rem, 11vw, 9rem); font-weight: 100; font-stretch: 125%; line-height: 0.76; color: var(--ot-ink); user-select: none; }\n  .ot-card-title { font-size: var(--ot-mf); line-height: var(--ot-mf-lh); letter-spacing: var(--ot-mf-tr); font-weight: 300; color: var(--ot-ink); }\n  .ot-card-link { color: inherit; text-decoration: none; outline: 0; }\n  .ot-card-link::after { content: \"\"; position: absolute; inset: 0; }\n  .ot-card:has(.ot-card-link:focus-visible) { outline: var(--ot-stroke) solid var(--ot-accent); outline-offset: 8px; }\n  .ot-card-body { max-width: 34ch; }\n  .ot-card-foot { margin-top: var(--ot-space-3); }\n\n  /* Epigraph: their words set before the name, indented to the end of the column, in the italic\n     a book gives a quotation before a chapter. The rule moves down to open the chapter: the title. */\n  .ot-card[data-variant=\"epigraph\"] { background: none; padding-top: 0; }\n  .ot-card[data-variant=\"epigraph\"] .ot-card-body {\n    justify-self: end; max-width: min(22ch, 84%);\n    font-family: var(--ot-expression); font-style: italic; font-size: calc(var(--ot-mp) * var(--ot-expression-scale)); line-height: 1.3; color: var(--ot-ink);\n  }\n  .ot-card[data-variant=\"epigraph\"] .ot-card-foot { justify-self: end; flex-wrap: nowrap; gap: var(--ot-space-3); margin-top: 0; }\n  .ot-card[data-variant=\"epigraph\"] .ot-card-foot::before { content: \"\"; flex: none; width: var(--ot-space-5); border-top: var(--ot-hairline) solid var(--ot-rule-strong); }\n  .ot-card[data-variant=\"epigraph\"] .ot-card-title {\n    margin-top: var(--ot-space-6); padding-top: var(--ot-space-4);\n    background:\n      linear-gradient(var(--ot-ink), var(--ot-ink)) no-repeat 100% 0 / 0% var(--ot-stroke),\n      linear-gradient(var(--ot-ink), var(--ot-ink)) no-repeat 0 0 / 100% var(--ot-hairline);\n    transition: background-size var(--ot-andante) var(--ot-exhale), background-position 0s;\n  }\n  .ot-card[data-variant=\"epigraph\"]:is(:has(.ot-card-link:is(:hover, :focus-visible)), [data-force~=\"hover\"]) .ot-card-title { background-position: 0 0, 0 0; background-size: 100% var(--ot-stroke), 100% var(--ot-hairline); }\n  .ot-card[data-variant=\"epigraph\"]:is([dir=\"rtl\"], [dir=\"rtl\"] *) .ot-card-title { background-position: 0 0, 0 0; }\n  .ot-card[data-variant=\"epigraph\"]:is([dir=\"rtl\"], [dir=\"rtl\"] *):is(:has(.ot-card-link:is(:hover, :focus-visible)), [data-force~=\"hover\"]) .ot-card-title { background-position: 100% 0, 0 0; }\n\n  /* Ledger: the figures add up in a column that is as wide as the total; the total is ruled off\n     the way an account is, a single rule over it and a double rule under it, both only as wide as the figures. */\n  .ot-card[data-variant=\"ledger\"] .ot-card-sum { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: var(--ot-space-1) var(--ot-space-5); margin: var(--ot-space-3) 0 0; font-variant-numeric: tabular-nums lining-nums; }\n  .ot-card[data-variant=\"ledger\"] .ot-card-sum > div { display: contents; }\n  .ot-card[data-variant=\"ledger\"] .ot-card-sum dt { color: var(--ot-graphite); }\n  .ot-card[data-variant=\"ledger\"] .ot-card-sum dd { margin: 0; text-align: end; color: var(--ot-ink); }\n  .ot-card[data-variant=\"ledger\"] .ot-card-sum > div:last-child > * { margin-top: var(--ot-space-3); color: var(--ot-ink); }\n  .ot-card[data-variant=\"ledger\"] .ot-card-sum > div:last-child > dd {\n    padding: var(--ot-space-2) 0 var(--ot-space-1);\n    font-size: var(--ot-mf); line-height: var(--ot-mf-lh); letter-spacing: var(--ot-mf-tr); font-weight: 200;\n    border-top: var(--ot-hairline) solid var(--ot-ink); border-bottom: calc(3 * var(--ot-hairline)) double var(--ot-ink);\n  }\n\n  /* Forced colours drop background images, so the rule becomes a border. */\n  @media (forced-colors: active) {\n    .ot-card, .ot-card[data-variant=\"epigraph\"] .ot-card-title { background: none; border-top: var(--ot-hairline) solid CanvasText; }\n    .ot-card[data-variant=\"epigraph\"] { border-top: 0; }\n  }\n}\n",
      "type": "registry:file",
      "target": "styles/0nlytype/card.css"
    }
  ],
  "css": {
    "@import \"../styles/0nlytype/card.css\"": {}
  },
  "meta": {
    "movement": "IX",
    "underneath": "native",
    "contract": "ot-card"
  },
  "type": "registry:ui"
}
