{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "sf-button", "title": "SF Button", "description": "Brutalist button with signal/ghost/signal intents, 2px borders, invert-on-hover", "dependencies": [ "class-variance-authority" ], "registryDependencies": [ "button" ], "files": [ { "path": "components/sf/sf-button.tsx", "content": "import { Button } from \"@/components/ui/button\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\n\nconst sfButtonVariants = cva(\n \"sf-pressable sf-focusable font-mono uppercase tracking-wider border-2 border-foreground transition-colors duration-[var(--duration-normal)] ease-[var(--ease-default)] cursor-pointer\",\n {\n variants: {\n intent: {\n primary:\n \"bg-primary text-primary-foreground hover:bg-foreground hover:text-background\",\n ghost:\n \"sf-border-thicken bg-transparent text-foreground hover:bg-foreground hover:text-background\",\n // signal: pre-standard extension — kept for SignalframeUX brand accent usage.\n // Blessed intent set: default, primary, secondary, destructive, ghost, outline.\n signal:\n \"bg-foreground text-background border-primary hover:bg-primary hover:text-primary-foreground\",\n },\n size: {\n sm: \"h-8 px-3 text-xs\",\n md: \"h-10 px-6 text-sm\",\n lg: \"h-12 px-8 text-base\",\n xl: \"h-14 px-12 text-lg\",\n },\n },\n defaultVariants: {\n intent: \"primary\",\n size: \"md\",\n },\n }\n);\n\ninterface SFButtonProps\n extends Omit, \"size\">,\n VariantProps {}\n\n/**\n * Primary action button — FRAME layer interactive primitive.\n *\n * Enforces SF button contract: font-mono, uppercase, 2px border,\n * asymmetric hover timing (100ms in / 400ms out), and press transform\n * via .sf-pressable. \"signal\" intent uses primary border accent — use\n * for brand-level CTAs only.\n *\n * @param intent - Visual variant. \"primary\" | \"ghost\" | \"signal\"\n * @param size - Height and padding scale. \"sm\" | \"md\" | \"lg\" | \"xl\"\n * @param className - Merged via cn() — appended, never replaces base classes\n *\n * @example\n * Launch\n * Cancel\n */\nexport function SFButton({\n intent,\n size,\n className,\n ...props\n}: SFButtonProps) {\n return (\n \n );\n}\n", "type": "registry:ui" } ], "meta": { "layer": "frame", "pattern": "A" }, "type": "registry:ui" }