{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "dcyfr-labs",
  "homepage": "https://www.dcyfr.ai",
  "items": [
    {
      "name": "dcyfr-button",
      "type": "registry:ui",
      "title": "dcyfr Button",
      "description": "Brand-aligned button with dcyfr-labs design tokens. Wraps the shadcn/ui button primitive and adds brand-specific variants."
    },
    {
      "name": "dcyfr-card",
      "type": "registry:ui",
      "title": "dcyfr Card",
      "description": "Brand-aligned card with dcyfr-labs design tokens. Variants: default, elevated, secure, glass, ghostly."
    },
    {
      "name": "dcyfr-badge",
      "type": "registry:ui",
      "title": "dcyfr Badge",
      "description": "Brand-aligned badge with dcyfr-labs design tokens. Variants: brand, secure, danger, info, outline, ghostly. Sizes: sm, md, lg."
    },
    {
      "name": "dcyfr-input",
      "type": "registry:ui",
      "title": "dcyfr Input",
      "description": "Brand-aligned input with built-in validation (error/success with icons + aria). Surface variants: default, secure, ghostly."
    },
    {
      "name": "dcyfr-dialog",
      "type": "registry:ui",
      "title": "dcyfr Dialog",
      "description": "Brand-aligned dialog wrapping Radix primitives. Content variants: default, secure, glass, elevated. Includes header/footer/title/description/close subcomponents."
    },
    {
      "name": "dcyfr-label",
      "type": "registry:ui",
      "title": "dcyfr Label",
      "description": "Brand-aligned label. Variants: default, required (asterisk indicator), secure. Includes required shorthand prop."
    },
    {
      "name": "dcyfr-textarea",
      "type": "registry:ui",
      "title": "dcyfr Textarea",
      "description": "Brand-aligned textarea with built-in validation (error/success with icons + aria). Surface variants: default, secure, ghostly. Mirrors dcyfr-input API."
    },
    {
      "name": "dcyfr-select",
      "type": "registry:ui",
      "title": "dcyfr Select",
      "description": "Brand-aligned select wrapping Radix primitives. Trigger surface variants: default, secure, ghostly; sizes sm/md/lg. Content panel uses glassy popover by default."
    },
    {
      "name": "dcyfr-checkbox",
      "type": "registry:ui",
      "title": "dcyfr Checkbox",
      "description": "Brand-aligned checkbox wrapping Radix primitives. Variants: default, secure. Supports indeterminate state with Minus icon."
    },
    {
      "name": "dcyfr-radio-group",
      "type": "registry:ui",
      "title": "dcyfr RadioGroup",
      "description": "Brand-aligned radio group wrapping Radix primitives. Variants: default, secure. Includes grouped root + item subcomponents."
    },
    {
      "name": "dcyfr-tabs",
      "type": "registry:ui",
      "title": "dcyfr Tabs",
      "description": "Brand-aligned tabs wrapping Radix primitives. List + Trigger variants: default (bordered row), pill (rounded pills), underline (minimal bottom-bar indicator)."
    },
    {
      "name": "dcyfr-separator",
      "type": "registry:ui",
      "title": "dcyfr Separator",
      "description": "Brand-aligned separator wrapping Radix primitives. Variants: default (solid border), gradient (fade via border color), dashed. Horizontal + vertical orientations."
    },
    {
      "name": "dcyfr-scroll-area",
      "type": "registry:ui",
      "title": "dcyfr ScrollArea",
      "description": "Brand-aligned scroll area wrapping Radix primitives. Scrollbar variants: default (neutral), brand-rail (primary-colored thumb)."
    },
    {
      "name": "dcyfr-sheet",
      "type": "registry:ui",
      "title": "dcyfr Sheet",
      "description": "Brand-aligned side-anchored dialog wrapping Radix primitives. Side: left/right/top/bottom. Content variants: default, secure (ring), glass (backdrop-blur). Full subcomponent set."
    },
    {
      "name": "dcyfr-dropdown-menu",
      "type": "registry:ui",
      "title": "dcyfr DropdownMenu",
      "description": "Brand-aligned dropdown menu wrapping Radix primitives. Content variants: default, secure, compact. Item density default/compact + destructive variant. Full subcomponent set including Sub menus."
    },
    {
      "name": "dcyfr-navigation-menu",
      "type": "registry:ui",
      "title": "dcyfr NavigationMenu",
      "description": "Brand-aligned navigation menu wrapping Radix primitives. Root variants: default (bordered, backdrop-blur), centered (max-width container), minimal (no chrome). Includes viewport + indicator animations."
    },
    {
      "name": "dcyfr-alert",
      "type": "registry:ui",
      "title": "dcyfr Alert",
      "description": "Brand-aligned alert with title + description subcomponents. Variants: info, secure, success, warning, danger, ghostly. Supports leading-icon slot."
    },
    {
      "name": "dcyfr-progress",
      "type": "registry:ui",
      "title": "dcyfr Progress",
      "description": "Brand-aligned progress bar wrapping Radix primitives. Variants: default, secure, danger, success. Sizes sm/md/lg. Indeterminate mode supported."
    },
    {
      "name": "dcyfr-skeleton",
      "type": "registry:ui",
      "title": "dcyfr Skeleton",
      "description": "Brand-aligned skeleton loader. Variants: default (pulse), shimmer (gradient sweep, self-contained — no globals.css dependency), text (line-height matched), circle. Respects reduced-motion."
    },
    {
      "name": "dcyfr-sonner",
      "type": "registry:ui",
      "title": "dcyfr Toaster (sonner)",
      "description": "Brand-themed sonner Toaster. Wraps `sonner` with DCYFR tokens for default/success/error/warning/info toast variants. Toast callers import toast() from sonner directly."
    },
    {
      "name": "dcyfr-tooltip",
      "type": "registry:ui",
      "title": "dcyfr Tooltip",
      "description": "Brand-aligned tooltip wrapping Radix primitives. Content variants: default, secure, inverted. Provider + Trigger + Content subcomponents."
    },
    {
      "name": "dcyfr-table",
      "type": "registry:ui",
      "title": "dcyfr Table",
      "description": "Brand-aligned table with full Header/Body/Footer/Row/Head/Cell/Caption set. Variants: default, striped, compact (tight padding + text-xs), elevated (wrapped in card). Context auto-tightens cell density in compact."
    },
    {
      "name": "dcyfr-accordion",
      "type": "registry:ui",
      "title": "dcyfr Accordion",
      "description": "Brand-aligned accordion wrapping Radix primitives. Variants: default (bordered items), bordered (outer border + rounded), ghostly (no borders). Chevron rotation preserved. Requires accordion keyframes in globals.css."
    },
    {
      "name": "dcyfr-avatar",
      "type": "registry:ui",
      "title": "dcyfr Avatar",
      "description": "Brand-aligned avatar wrapping Radix primitives. Variants: default (rounded-full), ring (primary ring + offset), square. Sizes xs/sm/md/lg/xl. Image + Fallback subcomponents."
    },
    {
      "name": "dcyfr-design-tokens",
      "type": "registry:style",
      "title": "dcyfr Design Tokens",
      "description": "Canonical :root + .dark semantic token blocks plus DCYFR-specific tokens (--secure, --success, --warning, --ease-brand). Per-site identity blocks (.theme-<name>) compose on top. Source of truth for the dcyfr-site-scaffold capability spec §Required patterns §5."
    },
    {
      "name": "dcyfr-theme-engine",
      "type": "registry:style",
      "title": "dcyfr Theme Engine",
      "description": "Base layer of the DCYFR theme engine. Identity resolves via data-identity on <html> (stamped at build, SSR-safe), orthogonal to the class-based light/dark scheme; a cut (data-cut on the same element, contract v3) is a colour-only overlay an identity may declare, and the base cut renders when the attribute is absent. Binds type roles, forces mono ligatures off + tabular numerals, encodes the motion split (.motion-snap transform/opacity only, .motion-ease color/layout), one-frame swap suppression, and the reduced-motion policy (colour and opacity transitions keep their timing, movement lands instantly, keyframes collapse, overlay enter and exit become fades). Contract v3 adds the only sanctioned sheen consumers: .field (the one dramatic field per view, with the sheen as a static low-opacity layer at the theme's optional --field-sheen-opacity, 0.2 when unset), .sheen-hover (hidden at rest, visible on hover/focus, opacity-only, a centred layer at the theme's optional --sheen-hover-size, the host's box when unset) and .sheen-scroll (a view() scroll-driven drift behind @supports); all three render their resting state under reduced motion, and chrome never uses them (check-chrome-sheen.mjs). Theme packages (dcyfr-theme-<name>) supply values against the contract in theme-contract.json, enforced by check-theme-contract.mjs in registry CI, which also pins the .sheen-hover layer's size and position; the render matrix reads that geometry as computed for every identity, scheme and cut."
    },
    {
      "name": "dcyfr-theme-slate",
      "type": "registry:style",
      "title": "dcyfr Theme — Slate",
      "description": "The registry-canon identity as an engine theme package: every dcyfr-design-tokens.css value mapped 1:1 onto the full token contract (surfaces, brand + accent ramp, semantic status, type roles, motion, radius, plus the v3 field from the existing secondary plate and --sheen: none), both schemes, scoped to [data-identity=\"slate\"]. Adoption over the legacy blocks is pixel-identical by construction. Requires dcyfr-theme-engine."
    },
    {
      "name": "dcyfr-theme-phosphor",
      "type": "registry:style",
      "title": "dcyfr Theme — Phosphor",
      "description": "The PHOSPHOR identity (visual-identity v3, restrained cut; the flagship default) as an engine theme package: sumi/paper grounds, bone silhouette, the four-step vermilion accent ramp (-400 text-on-dark, -500 fills, -600 filled controls, -700 text-on-paper), separate semantic status, the v3 field (sumi/bone/red sun on dark, paper/ink/-700 on paper) and the dithered spectral R/G/B ribbon as --sheen. Type, motion and radius are slate's values verbatim: slate and phosphor are two colour themes over one design, and the two files differ in colour only. Full contract in both schemes scoped to [data-identity=\"phosphor\"], sRGB with an OKLCH wide-gamut overlay behind @supports. Requires dcyfr-theme-engine."
    },
    {
      "name": "dcyfr-theme-obsidian",
      "type": "registry:style",
      "title": "dcyfr Theme — Obsidian",
      "description": "The Obsidian identity as an engine theme package: one page ground shared by five cuts (black, red, blue, green, rainbow), colour carried by the four-step accent ramp, the v3 field and the hairline (--border). The field differs by scheme: black glass on the glass, where red, blue and green carry a single-hue edge light as --sheen (resting at --field-sheen-opacity 0.5), and a pale cut-tinted plate with ink type on the warm cloth, where they carry none; rainbow's --sheen is multi-hue in both schemes, and a card's hover layer is twice its width (--sheen-hover-size). Bone type on the glass, black type on the cloth; serif in titles, headers and quotes over a sans body (the old-style serif stack in --font-display, the sans stack in --font-body), the hold-then-snap cel motion and a sharp-edged 4px/2px radius, shared by every cut. Black is the base cut and renders from the base blocks; the four other cuts are compound [data-identity=\"obsidian\"][data-cut=\"<cut>\"] overlays that re-author only the ramp, the field, --border and the sheen, both schemes, sRGB with an OKLCH wide-gamut overlay behind @supports. Values measured 2026-09-29 from natural stone; references and anchors approved 2026-09-30 (dcyfr-obsidian-identity Task 3). Requires dcyfr-theme-engine."
    },
    {
      "name": "dcyfr-theme-provider",
      "type": "registry:ui",
      "title": "dcyfr Theme Provider (v1, deprecated)",
      "description": "DEPRECATED. Superseded by dcyfr-theme-provider-v2, which targets components/chrome/theme-provider.tsx instead. Kept published so existing installs keep resolving. next-themes wrapper matching the dcyfr-site-scaffold contract. Consumers render <ThemeProvider attribute=\"class\" defaultTheme=\"system|light|dark\" enableSystem> at layout root."
    },
    {
      "name": "dcyfr-theme-switcher",
      "type": "registry:ui",
      "title": "dcyfr Theme Switcher (v1, deprecated)",
      "description": "DEPRECATED. Superseded by dcyfr-theme-toggle, a three-state cycler with View Transitions. Kept published so existing installs keep resolving. Dropdown Light / Dark / System selector using next-themes. Dependencies on dcyfr-button + dcyfr-dropdown-menu primitives."
    },
    {
      "name": "dcyfr-page-shell",
      "type": "registry:ui",
      "title": "dcyfr Page Shell (v1, deprecated)",
      "description": "DEPRECATED. Chrome v2 has no page-shell: v2 sites compose dcyfr-site-header and dcyfr-site-footer-v2 in the layout directly. Kept published so existing installs keep resolving. Layout primitive composing nav + footer + children. Padding variants (none|sm|md|lg) and max-width variants (prose|md|lg|xl|full)."
    },
    {
      "name": "dcyfr-site-nav",
      "type": "registry:ui",
      "title": "dcyfr Site Nav (v1, deprecated)",
      "description": "DEPRECATED. Superseded by dcyfr-site-header, with dcyfr-mobile-nav and dcyfr-bottom-nav covering the mobile surface. Kept published so existing installs keep resolving. Top-level site navigation. Desktop horizontal row + theme switcher + optional CTA; mobile hamburger + Sheet drawer. Variants: default, centered, minimal."
    },
    {
      "name": "dcyfr-site-footer",
      "type": "registry:ui",
      "title": "dcyfr Site Footer (v1, deprecated)",
      "description": "DEPRECATED. Superseded by dcyfr-site-footer-v2. Both target components/chrome/site-footer.tsx, so installing this one on a v2 site silently overwrites the v2 footer. Kept published so existing installs keep resolving. Standard site footer with brand slot, up to 4 columns of links, and copyright. Columns variant: default or minimal."
    },
    {
      "name": "dcyfr-chrome",
      "type": "registry:block",
      "title": "dcyfr Chrome (v1, deprecated)",
      "description": "DEPRECATED. Superseded by dcyfr-chrome-v2, which all eight consumer sites now ship; nothing installs this block any more. Kept published so existing installs keep resolving. Do not add it to a site already on v2: dcyfr-site-footer and dcyfr-site-footer-v2 both target components/chrome/site-footer.tsx, so a v1 install overwrites the v2 footer and drops four orphan v1 files beside the v2 set, a state openspec/specs/dcyfr-site-scaffold forbids. Bundles theme-provider, theme-switcher, page-shell, site-nav and site-footer as one atomic unit."
    },
    {
      "name": "dcyfr-nav-utils",
      "type": "registry:lib",
      "title": "dcyfr Chrome Nav Utils",
      "description": "Chrome v2 shared types (ChromeNavItem, ChromeNavSection) and active-state helpers (isNavItemActive, getAriaCurrent). Consumers supply nav config shaped as these types; chrome components never import site config directly."
    },
    {
      "name": "dcyfr-use-dropdown",
      "type": "registry:hook",
      "title": "dcyfr useDropdown",
      "description": "Accessible dropdown state hook: trigger/content prop bags (aria-haspopup, aria-expanded, role=menu), click-outside dismissal, and Escape handling. Used by the chrome v2 site header."
    },
    {
      "name": "dcyfr-use-media-query",
      "type": "registry:hook",
      "title": "dcyfr useMediaQuery",
      "description": "SSR-safe matchMedia hook (false before hydration, jsdom guard). Used by the chrome v2 header and bottom nav to toggle `inert` on responsive variants."
    },
    {
      "name": "dcyfr-theme-provider-v2",
      "type": "registry:ui",
      "title": "dcyfr Theme Provider v2",
      "description": "Chrome v2 next-themes wrapper: adds View Transitions detection (stamps .view-transitions-supported on <html>) for smooth theme swaps. Installs under components/chrome/. The cut-over is complete (rei-workspace openspec/changes/archive/2026-09-06-dcyfr-satellite-chrome-v2) and the v1 dcyfr-theme-provider is deprecated; it targets components/theme-provider.tsx, so installing v2 leaves any v1 file in place."
    },
    {
      "name": "dcyfr-theme-toggle",
      "type": "registry:ui",
      "title": "dcyfr Theme Toggle",
      "description": "Single-button three-state theme cycler (system → light → dark → system) with View Transitions when available and a hydration-safe placeholder. Carries touch-target, so the control meets the 44px minimum hit area rather than the button primitive's 36px icon size. onThemeChange callback for analytics."
    },
    {
      "name": "dcyfr-cut-chooser",
      "type": "registry:ui",
      "title": "dcyfr Cut Chooser",
      "description": "Visitor-facing cut chooser for a site whose identity declares cuts (contract v3 data-cut axis): a labelled radio group with one option per cut, each named in words beside a static swatch (compact hides the names visually), roving tabindex and arrow keys, a focus-visible ring, 44px targets via touch-target, options that wrap rather than overflow, and a polite live region. On a pick it writes the dcyfr-cut cookie (Path=/, one year, SameSite=Lax, Secure over https), restamps data-cut on <html> under the engine's one-frame .theme-swap, and calls onChange; choosing the base cut removes the attribute. Props-driven and identity-agnostic: the site passes identity, base, cuts, swatches (CSS colours from its vendored theme file, each cut's --accent-600) and the cookie name. Never touches data-identity, never reads --sheen, keeps no state beyond the cookie. Not chained from dcyfr-chrome-v2: only the flagship mounts it, a satellite pins one cut."
    },
    {
      "name": "dcyfr-mobile-nav",
      "type": "registry:ui",
      "title": "dcyfr Mobile Nav",
      "description": "Hamburger + Sheet drawer with sectioned navigation (56px touch targets, icons, descriptions, badges), active-page indicator, auto-close on navigation, and a theme toggle footer. Sections passed as ChromeNavSection[]."
    },
    {
      "name": "dcyfr-bottom-nav",
      "type": "registry:ui",
      "title": "dcyfr Bottom Nav",
      "description": "Mobile-only fixed bottom bar (5-slot grid, icon + label, backdrop blur) that reveals on scroll-down and hides on scroll-up, inverse of the header. Items passed as ChromeNavItem[]."
    },
    {
      "name": "dcyfr-site-footer-v2",
      "type": "registry:ui",
      "title": "dcyfr Site Footer v2",
      "description": "Chrome v2 single-row footer: copyright line + inline links, server-compatible (no client hooks, plain anchors). Brand and links passed as props. brand is the copyright holder, rendered as \"© <year> <brand>\", so it takes the legal entity: DCYFR sites pass \"DCYFR Labs\", never the bare brand \"DCYFR\" (the prop is required and has no default). The cut-over is complete (rei-workspace openspec/changes/archive/2026-09-06-dcyfr-satellite-chrome-v2) and the v1 dcyfr-site-footer (columned) is deprecated; both target components/chrome/site-footer.tsx, so installing either overwrites the other."
    },
    {
      "name": "dcyfr-site-header",
      "type": "registry:ui",
      "title": "dcyfr Site Header",
      "description": "Chrome v2 fixed header: scroll hide/show, backdrop blur, logo slot, config-driven dropdown menus (HeaderDropdown), actions slot, theme toggle, and integrated mobile drawer. Responsive variants toggled inert for focus/AT correctness."
    },
    {
      "name": "dcyfr-chrome-utilities",
      "type": "registry:style",
      "title": "dcyfr Chrome Utilities",
      "description": "The utility classes the chrome v2 components reference and no package defined: touch-target (44px hit area) plus transition-base and transition-fast, both bound to the theme engine's --motion-snap transform/opacity tier. site-header and site-footer stay bare hooks with no rules anywhere. Chained from dcyfr-chrome-v2. Requires a theme package for --motion-snap; dcyfr-theme-engine is deliberately not chained here, because every chrome consumer already installs it and chaining would re-offer app/dcyfr-theme-engine.css at every chrome install."
    },
    {
      "name": "dcyfr-chrome-v2",
      "type": "registry:block",
      "title": "dcyfr Chrome v2",
      "description": "Bundled chrome v2 cohort — installs site-header, mobile-nav, bottom-nav, site-footer-v2, theme-toggle, theme-provider-v2 (plus nav-utils, the hooks they depend on, and the chrome-utilities CSS) as one atomic unit. Upstreamed from the dcyfr.ai flagship; config-driven, no site imports. This is the cohort every dcyfr-* site ships. The cut-over is complete (rei-workspace openspec/changes/archive/2026-09-06-dcyfr-satellite-chrome-v2) and the v1 dcyfr-chrome block is deprecated."
    },
    {
      "name": "dcyfr-hero-stack",
      "type": "registry:ui",
      "title": "dcyfr HeroStack",
      "description": "Decorative fanned-card hero — three card slots in a shallow fan with pure-CSS hover spread. Server component, zero client JS. Generic over `children` (consumers pass any React node per slot). Sizes sm/md/lg. Defaults to aria-hidden; opt into a meaningful aria-label when the deck IS the content."
    },
    {
      "name": "dcyfr-spotlight",
      "type": "registry:ui",
      "title": "dcyfr Spotlight",
      "description": "Per-render-random featured-item slot. Generic-typed server component — accepts an item array and a render-prop, picks one via Fisher-Yates per request. Returns null when the array is empty (renders optional `empty` fallback). Consuming route MUST set `export const dynamic = \"force-dynamic\"` (or use a dynamic data fetch) for the random pick to actually rotate per visit."
    },
    {
      "name": "dcyfr-animated-counter",
      "type": "registry:ui",
      "title": "dcyfr AnimatedCounter",
      "description": "Counts from 0 up to `value` over `durationMs` using requestAnimationFrame. Fires once on first mount, easeOutCubic. Respects `prefers-reduced-motion: reduce` (renders final value immediately, skips the rAF loop). `tabular-nums` always applied so digits don't dance. Optional custom formatter."
    },
    {
      "name": "dcyfr-status-marquee",
      "type": "registry:ui",
      "title": "dcyfr StatusMarquee",
      "description": "Single-line live-stats marquee for site chrome. Accepts a `{ value, label, animate?, highlight? }[]` and renders horizontally with optional inter-stat dividers (border/dot/none). Server-rendered shell; numeric stats with `animate: true` defer to DcyfrAnimatedCounter (client). Highlight uses the brand `--secure` token."
    },
    {
      "name": "dcyfr-command-palette",
      "type": "registry:block",
      "title": "dcyfr CommandPalette",
      "description": "cmdk-backed global command palette. Provider mounts the dialog once and owns the cmd+k / ctrl+k global shortcut. Consumers pass declarative `Command[]` entries (id, label, hint?, icon?, run? OR href?). Focus trap, ESC + click-outside close, focus restoration handled by cmdk's <Command.Dialog>. Variants: default, secure, glass."
    }
  ]
}
