{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "typography",
  "type": "registry:ui",
  "title": "Typography",
  "description": "@interlace/ui — typography primitive (shadcn-compatible).",
  "dependencies": [
    "class-variance-authority"
  ],
  "registryDependencies": [
    "theme"
  ],
  "files": [
    {
      "path": "registry/interlace-ui/typography.tsx",
      "target": "components/ui/typography.tsx",
      "type": "registry:ui",
      "content": "// Typography — the single text primitive for the whole type scale.\n// Mirrors MUI <Typography> (variant + polymorphic element), adapted to the\n// Interlace floor: cva over the foundation --text-* tokens (no inline style),\n// the server-safe `as`-prop seam (like Section — NOT useRender, so it stays a\n// server component), semantic `tone` colors. See TYPOGRAPHY_PHILOSOPHY.md.\n\n/**\n * @interlace/ui — Typography\n *\n * One component renders every row of the type scale (h1–h6, body, long-form,\n * UI, caption, code) through a single `variant`, plus an orthogonal semantic\n * `tone`. The reading-vs-UI distinction (TYPOGRAPHY_PHILOSOPHY \"Reading mode vs\n * UI mode\") is encoded in the variant set, not a second axis (R11: one\n * variable). Sizes/leading come from the bridged `--text-*` tokens in\n * foundation.css; weights use the built-in 400/500/600/700 ladder (no 900).\n *\n * | Rule | Concept                          | Where in this file                                   |\n * | ---- | -------------------------------- | ---------------------------------------------------- |\n * | R4   | Extends native el + VariantProps | `React.ComponentProps<'p'> & VariantProps<...>`      |\n * | R6   | data-slot on the part            | `data-slot=\"typography\"` + data-variant/data-tone    |\n * | R7   | className merged + ...rest + ref  | `cn(typographyVariants(...), clamp, className)` + `{...props}` |\n * | R8   | No `isXxx`; enum if >2            | variant/tone/align are enums                         |\n * | R11  | One variable (size), ReactNode    | `children: ReactNode`; one truncation contract (lineClamp) |\n * | R18  | Tailwind only                    | zero inline style; classes from cva + static clamp map |\n * | R19  | Tokens only                      | text-h1/text-body… from foundation --text-*; no raw px |\n * | R20  | AA contrast                      | tone maps to AA-cleared semantic text tokens         |\n * | R25  | Server component                 | no hooks → no 'use client' (as-prop seam, like Section) |\n *\n * API parity: MUI `component=` → our `as`; MUI `color=` palette → semantic\n * `tone` (never raw pigment). `variant`'s natural element (h1→<h1>, body→<p>)\n * is a NON-SEMANTIC default — control the document outline with `as` (e.g. a\n * visual h2 that must be an <h3> for outline correctness: `variant=\"h2\" as=\"h3\"`).\n * Default body weight is 400 (per the token), intentionally MUI-body1-like.\n */\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst typographyVariants = cva('', {\n  variants: {\n    variant: {\n      h1: 'font-body text-h1 font-bold tracking-display text-balance',\n      h2: 'font-body text-h2 font-bold tracking-heading text-balance',\n      h3: 'font-body text-h3 font-semibold tracking-heading',\n      h4: 'font-body text-h4 font-semibold',\n      h5: 'font-body text-h5 font-semibold',\n      h6: 'font-body text-h6 font-semibold',\n      body: 'font-body text-body font-normal',\n      long: 'font-body text-long font-normal',\n      ui: 'font-body text-ui font-normal',\n      'ui-sm': 'font-body text-ui-sm font-normal',\n      caption: 'font-body text-caption font-normal',\n      code: 'font-mono text-code',\n    },\n    tone: {\n      default: '',\n      foreground: 'text-foreground',\n      muted: 'text-muted-foreground',\n      primary: 'text-primary',\n      destructive: 'text-destructive',\n    },\n    align: {\n      start: 'text-left',\n      center: 'text-center',\n      end: 'text-right',\n    },\n  },\n  defaultVariants: { variant: 'body', tone: 'default' },\n});\n\ntype TypographyVariant = NonNullable<\n  VariantProps<typeof typographyVariants>['variant']\n>;\n\n/** Natural element per variant — a NON-SEMANTIC default; override with `as`. */\nconst VARIANT_TAG: Record<TypographyVariant, React.ElementType> = {\n  h1: 'h1',\n  h2: 'h2',\n  h3: 'h3',\n  h4: 'h4',\n  h5: 'h5',\n  h6: 'h6',\n  body: 'p',\n  long: 'p',\n  ui: 'span',\n  'ui-sm': 'span',\n  caption: 'span',\n  code: 'code',\n};\n\n/** Static clamp map — Tailwind can't see runtime-built `line-clamp-${n}`. */\nconst CLAMP_CLASSES: Record<number, string> = {\n  1: 'line-clamp-1',\n  2: 'line-clamp-2',\n  3: 'line-clamp-3',\n  4: 'line-clamp-4',\n  5: 'line-clamp-5',\n  6: 'line-clamp-6',\n};\n\ninterface TypographyProps\n  extends\n    Omit<React.ComponentProps<'p'>, 'color'>,\n    VariantProps<typeof typographyVariants> {\n  /**\n   * Override the rendered element. Defaults to the variant's natural tag\n   * (h1→`h1`, body→`p`, code→`code`). Use this to keep the document outline\n   * correct when the visual level differs from the semantic level.\n   */\n  as?: React.ElementType;\n  /** Clamp to N lines with an ellipsis (single truncation contract). @default none */\n  lineClamp?: 1 | 2 | 3 | 4 | 5 | 6;\n  children?: React.ReactNode;\n}\n\n/**\n * Render scale-aware text. Server component (no hooks).\n */\nfunction Typography({\n  className,\n  variant,\n  tone,\n  align,\n  as,\n  lineClamp,\n  children,\n  ...props\n}: TypographyProps) {\n  const resolvedVariant: TypographyVariant = variant ?? 'body';\n  const Tag = (as ?? VARIANT_TAG[resolvedVariant]) as React.ElementType;\n  return (\n    <Tag\n      data-slot=\"typography\"\n      data-variant={resolvedVariant}\n      data-tone={tone ?? undefined}\n      className={cn(\n        typographyVariants({ variant, tone, align }),\n        lineClamp ? CLAMP_CLASSES[lineClamp] : undefined,\n        className,\n      )}\n      {...props}\n    >\n      {children}\n    </Tag>\n  );\n}\n\nexport { Typography, typographyVariants };\nexport type { TypographyProps };\n"
    }
  ]
}
