{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "grid",
  "title": "Grid",
  "description": "A quiet structure behind a section: a faint square grid, or a fine point at each crossing, with a registration cross on each corner and the columns numbered and the rows lettered along the border, like a drafting sheet. It never moves.",
  "registryDependencies": [
    "https://thedirectors.agency/ui/r/0nlytype.json"
  ],
  "files": [
    {
      "path": "registry/0nlytype/ui/grid.tsx",
      "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype GridProps = React.ComponentProps<\"div\"> & {\n  /** rules: faint hairlines, as the posters lay a construction grid under the words. dots: a fine point at each crossing, as a drafting sheet is dotted. */\n  variant?: \"rules\" | \"dots\"\n  /** The side of one square: a number of pixels or any CSS length. The content stands one cell in, on a line. */\n  cell?: number | string\n}\n\n// ponytail: a fixed run of labels, clipped by the box; past column 48 or row Z the lines go on unlabelled.\nconst COLUMNS = Array.from({ length: 48 }, (_, i) => String(i + 1).padStart(2, \"0\"))\nconst CORNERS = [\"start-top\", \"end-top\", \"start-foot\", \"end-foot\"]\nconst ROWS = Array.from({ length: 26 }, (_, i) => String.fromCharCode(65 + i))\n\n/**\n * A quiet structure behind a section: a faint square grid, a registration cross at each corner, and the columns\n * numbered along the top and the rows lettered down the start edge, like a drafting sheet. It never moves.\n */\nfunction Grid({ variant = \"rules\", cell, className, style, children, ...props }: GridProps) {\n  const size = typeof cell === \"number\" ? `${cell}px` : cell\n  return (\n    <div\n      data-slot=\"grid\"\n      data-variant={variant}\n      className={cn(\"ot-grid\", className)}\n      style={size ? ({ \"--ot-grid-cell\": size, ...style } as React.CSSProperties) : style}\n      {...props}\n    >\n      {CORNERS.map((c) => <span key={c} className=\"ot-grid-cross\" data-corner={c} aria-hidden=\"true\" />)}\n      <span className=\"ot-grid-ticks\" data-axis=\"columns\" aria-hidden=\"true\">\n        {COLUMNS.map((n) => <span key={n}>{n}</span>)}\n      </span>\n      <span className=\"ot-grid-ticks\" data-axis=\"rows\" aria-hidden=\"true\">\n        {ROWS.map((n) => <span key={n}>{n}</span>)}\n      </span>\n      {children}\n    </div>\n  )\n}\n\nexport { Grid, type GridProps }\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/0nlytype/styles/grid.css",
      "content": "@layer components {\n  /* ── ot-grid ── a quiet structure behind a section, drawn once and never moved: a faint square grid, as \"the silence that\n     heals\" and \"Less is more.\" lay theirs under the words, or a fine point at each crossing, as Paul Rand's sheet is\n     dotted. A registration cross stands on each corner, and the first row and column are the sheet's border: the columns\n     numbered along the top, the rows lettered down the start edge, each label hugging the corner where its line begins.\n     The content stands one cell in, on a line. */\n  .ot-grid {\n    --cell: var(--ot-grid-cell, var(--ot-space-7));\n    --line: var(--ot-rule);\n    --cross: calc(var(--ot-space-3) + var(--ot-hairline));\n    position: relative; isolation: isolate; padding: var(--cell); min-width: 0;\n    background-image: linear-gradient(to right, var(--line) var(--ot-hairline), transparent var(--ot-hairline)), linear-gradient(to bottom, var(--line) var(--ot-hairline), transparent var(--ot-hairline));\n    background-size: var(--cell) var(--cell);\n    background-position: left top;\n  }\n  .ot-grid:is([dir=\"rtl\"], [dir=\"rtl\"] *) {\n    background-image: linear-gradient(to left, var(--line) var(--ot-hairline), transparent var(--ot-hairline)), linear-gradient(to bottom, var(--line) var(--ot-hairline), transparent var(--ot-hairline));\n    background-position: right top;\n  }\n  /* dots: one fine point on each crossing, the rules left out. */\n  .ot-grid[data-variant=\"dots\"] {\n    --line: var(--ot-rule-strong);\n    background-image: radial-gradient(circle, var(--line) 0 var(--ot-hairline), transparent calc(var(--ot-hairline) + 0.5px));\n    background-position: calc(var(--cell) / -2) calc(var(--cell) / -2);\n  }\n  .ot-grid[data-variant=\"dots\"]:is([dir=\"rtl\"], [dir=\"rtl\"] *) { background-position: right calc(var(--cell) / -2) top calc(var(--cell) / -2); }\n\n  /* The crosses: two hairlines centred on each corner of the sheet. */\n  .ot-grid-cross {\n    position: absolute; z-index: -1; width: var(--cross); height: var(--cross); pointer-events: none;\n    background: linear-gradient(var(--ot-pencil), var(--ot-pencil)) center / 100% var(--ot-hairline) no-repeat, linear-gradient(var(--ot-pencil), var(--ot-pencil)) center / var(--ot-hairline) 100% no-repeat;\n  }\n  .ot-grid-cross[data-corner^=\"start\"] { inset-inline-start: calc(var(--cross) / -2); }\n  .ot-grid-cross[data-corner^=\"end\"] { inset-inline-end: calc(var(--cross) / -2); }\n  .ot-grid-cross[data-corner$=\"top\"] { top: calc(var(--cross) / -2); }\n  .ot-grid-cross[data-corner$=\"foot\"] { bottom: calc(var(--cross) / -2); }\n\n  /* The border's labels: ours, so upright, small and in the pencil, in tabular figures. Only whole cells are labelled: a\n     label with no room wraps onto the next line, which the strip clips away. */\n  .ot-grid-ticks {\n    position: absolute; z-index: -1; display: flex; flex-wrap: wrap; overflow: hidden; pointer-events: none;\n    font-size: var(--ot-pp); line-height: 1; letter-spacing: var(--ot-pp-tr); font-variant-numeric: tabular-nums lining-nums; color: var(--ot-pencil);\n  }\n  .ot-grid-ticks > span { flex: none; display: flex; box-sizing: border-box; width: var(--cell); height: var(--cell); padding: var(--ot-space-1) var(--ot-space-2); }\n  .ot-grid-ticks[data-axis=\"columns\"] { top: 0; inset-inline: var(--cell) 0; height: var(--cell); }\n  .ot-grid-ticks[data-axis=\"columns\"] > span { align-items: flex-end; }\n  .ot-grid-ticks[data-axis=\"rows\"] { flex-direction: column; top: var(--cell); bottom: 0; inset-inline-start: 0; width: var(--cell); }\n  .ot-grid-ticks[data-axis=\"rows\"] > span { justify-content: flex-end; }\n}\n",
      "type": "registry:file",
      "target": "styles/0nlytype/grid.css"
    }
  ],
  "css": {
    "@import \"../styles/0nlytype/grid.css\"": {}
  },
  "meta": {
    "movement": "IV",
    "underneath": "native",
    "contract": "ot-grid"
  },
  "type": "registry:ui"
}
