{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input",
  "type": "registry:ui",
  "title": "Input",
  "description": "Fluent 2-styled text input with shadcn APIs. 32px medium field, file-input styling, and the signature Fluent bottom brand accent on focus (inset box-shadow, no layout shift).",
  "author": "graundtech <https://github.com/graundtech/fluent2-react-kit>",
  "registryDependencies": [
    "https://fluent2-react-kit.graund.io/r/utils.json"
  ],
  "files": [
    {
      "path": "components/ui/input.tsx",
      "type": "registry:ui",
      "target": "components/ui/input.tsx",
      "content": "import type { ComponentProps } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Input — Fluent 2-styled, shadcn-API text input.\n *\n * Aesthetics follow Fluent 2 (32px medium field, `rounded-md` = 4px, flat at\n * rest); the prop surface is a bare `ComponentProps<\"input\">` — shadcn parity,\n * no size variants (Fluent's small/large field sizes are backlog, not shipped\n * here). No `cva`/variants export: there is only one visual treatment, same\n * reasoning as `Separator`.\n *\n * Server-safe: no `\"use client\"`, no hooks — the React import is type-only,\n * so the file can be dropped straight into an RSC tree.\n *\n * Focus — the signature Fluent detail is a 2px brand underline on the bottom\n * edge while the rest of the border stays put, with **no layout shift**. The\n * generic kit focus ring (conventions §4: `ring-2 ring-ring ring-offset-2`)\n * is a poor fit here — an offset ring around a form field reads as floating\n * outside the field rather than \"this field is active,\" which is the Fluent\n * signature. So this component deliberately swaps it for an **inset\n * box-shadow** (`shadow-[inset_0_-2px_0_0_var(--brand-80)]`), documented here\n * as the allowed per-component deviation conventions §4 anticipates:\n * - It paints *inside* the border box, so nothing reflows — no offset ring,\n *   no extra border width.\n * - `border` also switches to `border-primary` on focus so the whole field\n *   reads as active, not just the underline.\n * - `--brand-80`/`--brand-100` are read directly via `var()` (not a Tailwind\n *   `bg-brand-*` utility) because the ramp is global — same hex in light and\n *   dark (tokens.css §brand ramp comment) — so the light/dark split is a\n *   `dark:` override on which stop is used, exactly as the spec prescribes.\n *\n * Invalid — the shadcn `aria-invalid:` treatment from conventions §4\n * (destructive border + destructive ring tint) is declared *after* the focus\n * classes so it wins the border tie-break when a field is both invalid and\n * focused (same declaration order Button already relies on for its own\n * focus/invalid overlap). The bottom-edge accent itself also swaps to\n * `--destructive` in the invalid+focused compound state, so a required field\n * left invalid doesn't show a reassuring brand-blue underline while the rest\n * of the field is screaming destructive-red.\n */\nfunction Input({ className, ...props }: ComponentProps<\"input\">) {\n  return (\n    <input\n      data-slot=\"input\"\n      className={cn(\n        // layout — Fluent medium field, 32px height. The resting bottom edge\n        // is the darker NeutralStrokeAccessible (#616161) while the other three\n        // sides stay border-input (#d1d1d1) — Fluent's signature field accent.\n        // On focus, border-primary paints all sides (and the inset underline\n        // covers this); aria-invalid's border-destructive likewise wins by\n        // specificity, so the darker bottom only shows at rest.\n        \"flex h-8 w-full min-w-0 rounded-md border border-input border-b-stroke-accessible bg-background px-3 py-1 text-sm\",\n        // placeholder / text selection\n        \"placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground\",\n        // file input button (shadcn parity)\n        \"file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground\",\n        // motion — color transitions plus the focus box-shadow accent below\n        \"outline-none transition-[color,box-shadow] duration-fast ease-ease\",\n        // disabled — opacity-based, matches conventions §4 exactly\n        \"disabled:pointer-events-none disabled:opacity-50\",\n        // focus — Fluent bottom brand accent via inset box-shadow, no reflow.\n        // Replaces the generic ring recipe for this component (documented\n        // deviation, conventions §4).\n        \"focus-visible:border-primary focus-visible:shadow-[inset_0_-2px_0_0_var(--brand-80)] dark:focus-visible:shadow-[inset_0_-2px_0_0_var(--brand-100)]\",\n        // invalid — shadcn aria-invalid treatment, conventions §4. Declared\n        // after focus-visible so it wins the border tie when both apply; the\n        // compound aria-invalid+focus-visible rule swaps the underline accent\n        // to destructive too, so an invalid+focused field reads consistently.\n        \"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40\",\n        \"aria-invalid:focus-visible:shadow-[inset_0_-2px_0_0_var(--destructive)]\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Input };\n"
    }
  ]
}
