{
  "name": "sav",
  "namespace": "@sav",
  "version": "1.0.0",
  "homepage": "https://design.sasv.ch",
  "registry": "https://design.sasv.ch/r/registry.json",
  "template": "https://design.sasv.ch/r/{name}.json",
  "generatedAt": "2026-11-07T22:15:11.195Z",
  "layers": {
    "tokens": {
      "title": "Tokens",
      "description": "Design tokens, fonts and the theme block every SAV app starts from."
    },
    "ui": {
      "title": "UI primitives",
      "description": "shadcn/ui base-sera primitives on Base UI, regenerated with the current CLI and carrying the Cruiser deltas."
    },
    "patterns": {
      "title": "App patterns",
      "description": "Brand-neutral app-shell and page patterns ported from the Cruiser app."
    }
  },
  "items": [
    {
      "name": "tokens",
      "type": "registry:theme",
      "layer": "tokens",
      "title": "Tokens",
      "description": "The SAV theme: neutral oklch colour tokens for light and dark mode, radius 0.625rem, sidebar and chart tokens, and the font mappings (Inter → --font-sans, Figtree → --font-heading, Geist Mono → --font-geist-mono). Byte-equivalent to the Cruiser app's globals.css token block.",
      "dependencies": [],
      "registryDependencies": [
        "@sav/font-inter",
        "@sav/font-figtree",
        "@sav/font-geist-mono"
      ],
      "url": "https://design.sasv.ch/r/tokens.json",
      "page": "https://design.sasv.ch/tokens/",
      "install": "npx shadcn@latest add @sav/tokens"
    },
    {
      "name": "font-inter",
      "type": "registry:font",
      "layer": "tokens",
      "title": "Font: Inter",
      "description": "Body typeface. Google font Inter on the --font-sans variable (next/font/google in Next.js, @fontsource-variable/inter elsewhere).",
      "dependencies": [],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/font-inter.json",
      "page": "https://design.sasv.ch/font-inter/",
      "install": "npx shadcn@latest add @sav/font-inter"
    },
    {
      "name": "font-figtree",
      "type": "registry:font",
      "layer": "tokens",
      "title": "Font: Figtree",
      "description": "Heading typeface. Google font Figtree on the --font-heading variable, used through the `font-heading` utility.",
      "dependencies": [],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/font-figtree.json",
      "page": "https://design.sasv.ch/font-figtree/",
      "install": "npx shadcn@latest add @sav/font-figtree"
    },
    {
      "name": "font-geist-mono",
      "type": "registry:font",
      "layer": "tokens",
      "title": "Font: Geist Mono",
      "description": "Code and metrics typeface. Google font Geist Mono on the --font-geist-mono variable, mapped to --font-mono in @theme inline.",
      "dependencies": [],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/font-geist-mono.json",
      "page": "https://design.sasv.ch/font-geist-mono/",
      "install": "npx shadcn@latest add @sav/font-geist-mono"
    },
    {
      "name": "alert-dialog",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Alert Dialog",
      "description": "Modal confirmation dialog that interrupts the user; sharp-cornered Sera variant on Base UI AlertDialog.",
      "dependencies": [
        "@base-ui/react",
        "cn"
      ],
      "registryDependencies": [
        "@sav/button"
      ],
      "url": "https://design.sasv.ch/r/alert-dialog.json",
      "page": "https://design.sasv.ch/alert-dialog/",
      "install": "npx shadcn@latest add @sav/alert-dialog"
    },
    {
      "name": "avatar",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Avatar",
      "description": "Image avatar with automatic initials fallback and three sizes; Base UI Avatar.",
      "dependencies": [
        "@base-ui/react",
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/avatar.json",
      "page": "https://design.sasv.ch/avatar/",
      "install": "npx shadcn@latest add @sav/avatar"
    },
    {
      "name": "badge",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Badge",
      "description": "Uppercase tracking label in default, secondary, destructive and outline variants; renders as any element via `render`.",
      "dependencies": [
        "@base-ui/react",
        "class-variance-authority",
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/badge.json",
      "page": "https://design.sasv.ch/badge/",
      "install": "npx shadcn@latest add @sav/badge"
    },
    {
      "name": "breadcrumb",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Breadcrumb",
      "description": "Hierarchy trail with separators, ellipsis and link items.",
      "dependencies": [
        "@base-ui/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/breadcrumb.json",
      "page": "https://design.sasv.ch/breadcrumb/",
      "install": "npx shadcn@latest add @sav/breadcrumb"
    },
    {
      "name": "button",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Button",
      "description": "Uppercase tracking button in six variants and eight sizes on Base UI Button. Cruiser delta: `nativeButton` defaults to false when `render` is used so `render={<Link/>}` keeps anchor semantics.",
      "dependencies": [
        "@base-ui/react",
        "class-variance-authority",
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/button.json",
      "page": "https://design.sasv.ch/button/",
      "install": "npx shadcn@latest add @sav/button"
    },
    {
      "name": "card",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Card",
      "description": "Sharp-cornered content container with header, title, description, action, content and footer slots; `size=\"sm\"` for stat tiles.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/card.json",
      "page": "https://design.sasv.ch/card/",
      "install": "npx shadcn@latest add @sav/card"
    },
    {
      "name": "chart",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Chart",
      "description": "Recharts wrapper: ChartContainer with CSS-variable colour config, tooltip and legend styled with the design tokens.",
      "dependencies": [
        "cn",
        "recharts@3.8.0"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/chart.json",
      "page": "https://design.sasv.ch/chart/",
      "install": "npx shadcn@latest add @sav/chart"
    },
    {
      "name": "checkbox",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Checkbox",
      "description": "Square checkbox with an enlarged hit area; Base UI Checkbox.",
      "dependencies": [
        "@base-ui/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/checkbox.json",
      "page": "https://design.sasv.ch/checkbox/",
      "install": "npx shadcn@latest add @sav/checkbox"
    },
    {
      "name": "dialog",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Dialog",
      "description": "Modal dialog with overlay, header, footer and optional close button; Base UI Dialog.",
      "dependencies": [
        "@base-ui/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "@sav/button"
      ],
      "url": "https://design.sasv.ch/r/dialog.json",
      "page": "https://design.sasv.ch/dialog/",
      "install": "npx shadcn@latest add @sav/dialog"
    },
    {
      "name": "dropdown-menu",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Dropdown Menu",
      "description": "Menu with items, checkbox and radio items, groups, labels, shortcuts and submenus; Base UI Menu.",
      "dependencies": [
        "@base-ui/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/dropdown-menu.json",
      "page": "https://design.sasv.ch/dropdown-menu/",
      "install": "npx shadcn@latest add @sav/dropdown-menu"
    },
    {
      "name": "input",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Input",
      "description": "Underlined text input (bottom border only). Mobile rule: text-base below md so iOS does not zoom on focus.",
      "dependencies": [
        "@base-ui/react",
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/input.json",
      "page": "https://design.sasv.ch/input/",
      "install": "npx shadcn@latest add @sav/input"
    },
    {
      "name": "label",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Label",
      "description": "Uppercase tracking form label that relaxes to sentence case next to a checkbox, radio or switch.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/label.json",
      "page": "https://design.sasv.ch/label/",
      "install": "npx shadcn@latest add @sav/label"
    },
    {
      "name": "searchable-select",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Searchable Select",
      "description": "Single-select typeahead on Base UI Combobox: case- and diacritic-insensitive filtering over label and keywords, keyboard support, 16px controls on mobile. Cruiser original (not in shadcn/ui).",
      "dependencies": [
        "@base-ui/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/searchable-select.json",
      "page": "https://design.sasv.ch/searchable-select/",
      "install": "npx shadcn@latest add @sav/searchable-select"
    },
    {
      "name": "select",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Select",
      "description": "Underlined select with groups, labels and scroll buttons; Base UI Select. Cruiser delta: trigger text is text-base below md (no iOS zoom).",
      "dependencies": [
        "@base-ui/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/select.json",
      "page": "https://design.sasv.ch/select/",
      "install": "npx shadcn@latest add @sav/select"
    },
    {
      "name": "separator",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Separator",
      "description": "Horizontal or vertical divider; Base UI Separator.",
      "dependencies": [
        "@base-ui/react",
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/separator.json",
      "page": "https://design.sasv.ch/separator/",
      "install": "npx shadcn@latest add @sav/separator"
    },
    {
      "name": "sheet",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Sheet",
      "description": "Side panel sliding in from any edge, with header and footer; Base UI Dialog.",
      "dependencies": [
        "@base-ui/react",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "@sav/button"
      ],
      "url": "https://design.sasv.ch/r/sheet.json",
      "page": "https://design.sasv.ch/sheet/",
      "install": "npx shadcn@latest add @sav/sheet"
    },
    {
      "name": "sidebar",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Sidebar",
      "description": "Composable sidebar shell: provider, rail, collapsible icon mode, mobile sheet, groups, menus, sub-menus and skeletons.",
      "dependencies": [
        "@base-ui/react",
        "class-variance-authority",
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "@sav/button",
        "@sav/input",
        "@sav/separator",
        "@sav/sheet",
        "@sav/skeleton",
        "@sav/tooltip",
        "@sav/use-mobile"
      ],
      "url": "https://design.sasv.ch/r/sidebar.json",
      "page": "https://design.sasv.ch/sidebar/",
      "install": "npx shadcn@latest add @sav/sidebar"
    },
    {
      "name": "skeleton",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Skeleton",
      "description": "Pulsing placeholder block for loading states.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/skeleton.json",
      "page": "https://design.sasv.ch/skeleton/",
      "install": "npx shadcn@latest add @sav/skeleton"
    },
    {
      "name": "sonner",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Sonner (Toaster)",
      "description": "Toast notifications via sonner, themed through next-themes and the popover tokens, with lucide status icons.",
      "dependencies": [
        "lucide-react",
        "next-themes",
        "sonner"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/sonner.json",
      "page": "https://design.sasv.ch/sonner/",
      "install": "npx shadcn@latest add @sav/sonner"
    },
    {
      "name": "table",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Table",
      "description": "Data table primitives (header, body, footer, row, head, cell, caption) with a scrolling wrapper.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/table.json",
      "page": "https://design.sasv.ch/table/",
      "install": "npx shadcn@latest add @sav/table"
    },
    {
      "name": "textarea",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Textarea",
      "description": "Underlined auto-sizing textarea (field-sizing: content); text-base below md.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/textarea.json",
      "page": "https://design.sasv.ch/textarea/",
      "install": "npx shadcn@latest add @sav/textarea"
    },
    {
      "name": "tooltip",
      "type": "registry:ui",
      "layer": "ui",
      "title": "Tooltip",
      "description": "Tooltip with provider, arrow and positioning; Base UI Tooltip.",
      "dependencies": [
        "@base-ui/react",
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/tooltip.json",
      "page": "https://design.sasv.ch/tooltip/",
      "install": "npx shadcn@latest add @sav/tooltip"
    },
    {
      "name": "use-mobile",
      "type": "registry:hook",
      "layer": "ui",
      "title": "useIsMobile",
      "description": "matchMedia hook for the 768px breakpoint used by the sidebar.",
      "dependencies": [],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/use-mobile.json",
      "page": "https://design.sasv.ch/use-mobile/",
      "install": "npx shadcn@latest add @sav/use-mobile"
    },
    {
      "name": "app-sidebar",
      "type": "registry:component",
      "layer": "patterns",
      "title": "App Sidebar",
      "description": "Authenticated app-shell navigation: brand block, labelled nav groups with active state from usePathname, user menu with links and sign-out callback; icon rail on desktop, drawer on mobile. Brand, groups, user and callbacks are props.",
      "dependencies": [
        "lucide-react"
      ],
      "registryDependencies": [
        "@sav/dropdown-menu",
        "@sav/sidebar",
        "@sav/user-avatar"
      ],
      "url": "https://design.sasv.ch/r/app-sidebar.json",
      "page": "https://design.sasv.ch/app-sidebar/",
      "install": "npx shadcn@latest add @sav/app-sidebar"
    },
    {
      "name": "brand-logo",
      "type": "registry:component",
      "layer": "patterns",
      "title": "Brand Logo",
      "description": "Theme-aware wordmark: a light-mode and a dark-mode asset passed as props, swapped with the dark variant.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/brand-logo.json",
      "page": "https://design.sasv.ch/brand-logo/",
      "install": "npx shadcn@latest add @sav/brand-logo"
    },
    {
      "name": "data-panel",
      "type": "registry:component",
      "layer": "patterns",
      "title": "Data Panel",
      "description": "Sharp bordered container for tables and lists (bg-card + ring, horizontal scroll built in) with an optional DataPanelHeader title/action row.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/data-panel.json",
      "page": "https://design.sasv.ch/data-panel/",
      "install": "npx shadcn@latest add @sav/data-panel"
    },
    {
      "name": "document-viewer",
      "type": "registry:component",
      "layer": "patterns",
      "title": "Document Viewer",
      "description": "Dialog viewer for images and PDFs: zoom, drag-to-pan, multi-page navigation, download, pdf.js rendering with iframe fallback; InlineDocumentView for embedding without the dialog.",
      "dependencies": [
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "@sav/button",
        "@sav/dialog",
        "@sav/pdf-pages"
      ],
      "url": "https://design.sasv.ch/r/document-viewer.json",
      "page": "https://design.sasv.ch/document-viewer/",
      "install": "npx shadcn@latest add @sav/document-viewer"
    },
    {
      "name": "empty-state",
      "type": "registry:component",
      "layer": "patterns",
      "title": "Empty State",
      "description": "Dashed-border centered empty/no-results panel with optional icon, description and action.",
      "dependencies": [
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/empty-state.json",
      "page": "https://design.sasv.ch/empty-state/",
      "install": "npx shadcn@latest add @sav/empty-state"
    },
    {
      "name": "notification-bell",
      "type": "registry:component",
      "layer": "patterns",
      "title": "Notification Bell",
      "description": "Bell button with unread badge and a dropdown of recent notifications; optional polling through a fetchSummary callback, type labels and link targets as props.",
      "dependencies": [
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "@sav/button",
        "@sav/dropdown-menu"
      ],
      "url": "https://design.sasv.ch/r/notification-bell.json",
      "page": "https://design.sasv.ch/notification-bell/",
      "install": "npx shadcn@latest add @sav/notification-bell"
    },
    {
      "name": "page-header",
      "type": "registry:component",
      "layer": "patterns",
      "title": "Page Header",
      "description": "Module page header: heading-font title, optional description, right-aligned action slot, bottom separator.",
      "dependencies": [
        "cn"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/page-header.json",
      "page": "https://design.sasv.ch/page-header/",
      "install": "npx shadcn@latest add @sav/page-header"
    },
    {
      "name": "pdf-pages",
      "type": "registry:component",
      "layer": "patterns",
      "title": "PDF Pages",
      "description": "Renders every page of a PDF to canvases with pdf.js, fit-to-width with zoom and device-pixel-ratio aware; lazy-loads the pdf.js module and worker.",
      "dependencies": [
        "pdfjs-dist"
      ],
      "registryDependencies": [],
      "url": "https://design.sasv.ch/r/pdf-pages.json",
      "page": "https://design.sasv.ch/pdf-pages/",
      "install": "npx shadcn@latest add @sav/pdf-pages"
    },
    {
      "name": "skeletons",
      "type": "registry:component",
      "layer": "patterns",
      "title": "Skeletons",
      "description": "Route-level loading skeletons: StatGridSkeleton, TableSkeleton, CardsGridSkeleton, PageHeaderSkeleton.",
      "dependencies": [],
      "registryDependencies": [
        "@sav/card",
        "@sav/data-panel",
        "@sav/skeleton"
      ],
      "url": "https://design.sasv.ch/r/skeletons.json",
      "page": "https://design.sasv.ch/skeletons/",
      "install": "npx shadcn@latest add @sav/skeletons"
    },
    {
      "name": "stat-card",
      "type": "registry:component",
      "layer": "patterns",
      "title": "Stat Card",
      "description": "KPI tile: uppercase label, large tabular value, optional icon, hint and monochrome delta arrow.",
      "dependencies": [
        "cn",
        "lucide-react"
      ],
      "registryDependencies": [
        "@sav/card"
      ],
      "url": "https://design.sasv.ch/r/stat-card.json",
      "page": "https://design.sasv.ch/stat-card/",
      "install": "npx shadcn@latest add @sav/stat-card"
    },
    {
      "name": "user-avatar",
      "type": "registry:component",
      "layer": "patterns",
      "title": "User Avatar",
      "description": "Avatar from an optional image URL with first+last-name (or email) initials fallback; serializable props only.",
      "dependencies": [],
      "registryDependencies": [
        "@sav/avatar"
      ],
      "url": "https://design.sasv.ch/r/user-avatar.json",
      "page": "https://design.sasv.ch/user-avatar/",
      "install": "npx shadcn@latest add @sav/user-avatar"
    }
  ]
}
